hexblot / mssql-compat
Small wrapper for PDO that emulates the deprecated mssql_* functions, and allows legacy software to work on PHP 5.3 through 8.x
Requires
- php: >=5.3
- ext-pdo: *
Requires (Dev)
None
Suggests
- ext-pdo_dblib: *
- ext-pdo_sqlite: Only needed to run the smoke test
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-09 15:30:06 UTC
README
MSSQL Compat is a small and simple drop-in library that allows a legacy PHP project that uses MSSQL via the mssql_* functions ( eg mssql_connect() et al ), removed in PHP 7.0, to work transparently on PHP 5.3 through 8.x with PDO DBLib by providing the missing functions as wrappers around the equivalent PDO syntax - and all that with a single line!
The story
I recently started migrating internal web applications to new servers that use PHP7.
Thus I stumbled on a couple of old applications that use MSSQL with PHP, which I dearly hoped to avoid rewriting and debugging now that PHP 7 has removed the mssql_* family of functions.
The result is this single-file solution: just include it before your first mssql_* call, and it will transparently wrap them to the equivalent PDO calls.
What it is not
- This library is not a security enhancement by any measure. It assumes that your program logic escapes what needs to be escaped, since you cannot benefit from PDO goodness without changing the function syntax.
- That being said, kindly let me know if you can provide better security in the given code.
- It is not meant as a means to develop new software using mssql_* functions - use PDO or similar!
Requirements
- PHP 5.3 through 8.x (tested on 5.6, 7.4, 8.3 and 8.4)
- PDO ( usually via the php-pdo package )
- PDO DBLib installed (FreeTDS based; still shipped with PHP 8)
Hint: On RHEL-like systems the Remi repository provides
php-pdo-dblib; on the official Docker images runapt-get install freetds-dev && docker-php-ext-install pdo_dblib.
How to use
Option A: Manually
Just download and add an include to this library on the top of the old application index.php file.
<?php include("path/to/mssql_compat.php"); # Insert old application logic here
Option B: Via Composer
$ composer require hexblot/mssql-compat
If your app doesn't already have one, add a require towards the autoload.php file generated by composer in your index.php:
<?php require __DIR__.'/path/to/vendor/autoload.php';
Optional tuning
Extra DSN parameters (charset, TDS version, application name...) can be passed by defining a constant before the library is loaded:
define('MSSQL_COMPAT_DSN_OPTIONS', 'charset=UTF-8;version=7.4');
If your application already has an open PDO connection (for instance from a framework), legacy code can share it instead of opening a second one:
$link = mssql_compat_register_pdo($pdo); // becomes the default link
Note that the library switches the supplied connection to PDO::ERRMODE_EXCEPTION.
Behaviour notes: how this differs from the original extension
- Results are fully buffered at query time. This mirrors the original extension's default (
batch_size = 0), keeps the connection free so nested queries on the same link work, and makesmssql_num_rows(),mssql_data_seek()andmssql_result()reliable. Queries returning very large result sets will use memory accordingly; thebatch_sizeargument tomssql_query()is accepted but ignored. - Link and result identifiers are strings, not resources.
is_resource($link)checks will fail;if (!$link)/=== falsechecks work as before. - Errors set the text returned by
mssql_get_last_message()and raise anE_USER_WARNING, like the original extension's warnings. Prefix them with@if your code did. mssql_query()returnsTRUEfor statements that produce no result set (INSERT, UPDATE, DELETE, DDL) andFALSEon error, as the original did.- Stored procedures returning several result sets are supported through
mssql_next_result(). AddSET NOCOUNT ONto procedures if you see spurious empty result sets. mssql_min_error_severity()/mssql_min_message_severity()are no-ops.
Under the hood: Which functions are covered
- mssql_bind
- mssql_close
- mssql_connect
- mssql_data_seek
- mssql_execute
- mssql_fetch_array
- mssql_fetch_assoc
- mssql_fetch_batch (always returns 0: everything is already buffered)
- mssql_fetch_field
- mssql_fetch_object
- mssql_fetch_row
- mssql_field_length
- mssql_field_name
- mssql_field_seek
- mssql_field_type
- mssql_free_result
- mssql_free_statement
- mssql_get_last_message
- mssql_guid_string
- mssql_init
- mssql_min_error_severity NOTE: Placeholder only to avoid errors!
- mssql_min_message_severity NOTE: Placeholder only to avoid errors!
- mssql_next_result
- mssql_num_fields
- mssql_num_rows
- mssql_pconnect
- mssql_query
- mssql_result
- mssql_rows_affected
- mssql_select_db
The stored procedure API (mssql_init / mssql_bind / mssql_execute) is not covered; call procedures with mssql_query("EXEC ...") instead. Patches are of course very welcomed!
Upgrading from 0.2.x
Version 0.3.1 changes behaviour in ways your application may notice:
- Database errors used to be swallowed (PHP 5/7) or crash (PHP 8); they now return
FALSEand raise a warning, so error paths in your code that never ran before will run now. mssql_connect()returnsFALSEon failure instead of a truthy link.mssql_select_db()returnsTRUEon success instead of0.mssql_rows_affected()takes a link identifier, per the original API, instead of a result.- Results are buffered in memory; very large result sets need proportionally more memory.
License
MIT, since version 0.3.1. Versions up to 0.2.2 were released under the Apache License 2.0.
Running the smoke test
The test uses an in-memory SQLite database, so it needs no SQL Server:
$ composer test # or against any PHP version: $ docker run --rm -v "$PWD":/app php:5.6-cli php /app/tests/smoke_test.php