Skip to main content
The docker-php-mssql images come with both sqlsrv and pdo_sqlsrv extensions pre-installed, allowing you to connect to Microsoft SQL Server databases using either the native sqlsrv driver or PDO.

Prerequisites

Before connecting, ensure you have:
  • A running SQL Server instance (SQL Server 2017 or later recommended)
  • Database credentials (username and password)
  • Network connectivity between your container and SQL Server
  • Microsoft ODBC Driver 18 (pre-installed in the images)

Connection Methods

Using sqlsrv Extension

The sqlsrv extension provides a direct interface to SQL Server:
1

Basic Connection

<?php
$serverName = "sqlserver,1433"; // host,port format
$connectionOptions = [
    "Database" => "myDatabase",
    "UID" => "sa",
    "PWD" => "YourPassword123",
    "Encrypt" => false,
];

$conn = sqlsrv_connect($serverName, $connectionOptions);

if ($conn === false) {
    die(print_r(sqlsrv_errors(), true));
}

echo "Connected successfully!\n";
2

Execute Query

<?php
$sql = "SELECT TOP 10 * FROM users";
$stmt = sqlsrv_query($conn, $sql);

if ($stmt === false) {
    die(print_r(sqlsrv_errors(), true));
}

while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
    echo $row['name'] . "\n";
}

sqlsrv_free_stmt($stmt);
3

Close Connection

<?php
sqlsrv_close($conn);

Using PDO_SQLSRV Extension

PDO provides a consistent interface across different database systems:
1

Basic PDO Connection

<?php
$host = "sqlserver";
$port = 1433;
$database = "myDatabase";
$username = "sa";
$password = "YourPassword123";

try {
    $dsn = "sqlsrv:server={$host},{$port};Database={$database};ConnectionPooling=0;Encrypt=no";
    $pdo = new PDO($dsn, $username, $password, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    ]);

    echo "Connected successfully!\n";
} catch (PDOException $e) {
    die("Connection failed: " . $e->getMessage());
}
2

Execute Query

<?php
$sql = "SELECT TOP 10 * FROM users WHERE status = :status";
$stmt = $pdo->prepare($sql);
$stmt->execute(['status' => 'active']);

$results = $stmt->fetchAll();

foreach ($results as $row) {
    echo $row['name'] . "\n";
}
3

Close Connection

<?php
$pdo = null;

Connection Options

SSL/TLS Encryption

<?php
$connectionOptions = [
    "Database" => "myDatabase",
    "UID" => "sa",
    "PWD" => "YourPassword123",
    "Encrypt" => true,
    "TrustServerCertificate" => false,
];
For production environments, always use Encrypt=true. Only disable encryption for development or when connecting to SQL Server instances that don’t support TLS.

Connection Timeout

<?php
$connectionOptions = [
    "Database" => "myDatabase",
    "UID" => "sa",
    "PWD" => "YourPassword123",
    "LoginTimeout" => 30,
    "ConnectRetryCount" => 3,
    "ConnectRetryInterval" => 10,
];

Connection Pooling

<?php
$connectionOptions = [
    "Database" => "myDatabase",
    "UID" => "sa",
    "PWD" => "YourPassword123",
    "ConnectionPooling" => true,
];

Using Environment Variables

Store connection details in environment variables for better security:
1

Set Environment Variables

Create a .env file:
MSSQL_HOST=sqlserver
MSSQL_PORT=1433
MSSQL_DATABASE=myDatabase
MSSQL_USERNAME=sa
MSSQL_PASSWORD=YourPassword123
2

Use in docker-compose.yml

services:
  app:
    image: namoshek/php-mssql:8.4-cli
    env_file:
      - .env
    volumes:
      - ./:/app
3

Access in PHP

<?php
$host = getenv('MSSQL_HOST');
$port = getenv('MSSQL_PORT');
$database = getenv('MSSQL_DATABASE');
$username = getenv('MSSQL_USERNAME');
$password = getenv('MSSQL_PASSWORD');

$conn = sqlsrv_connect("{$host},{$port}", [
    'Database' => $database,
    'UID' => $username,
    'PWD' => $password,
    'Encrypt' => false,
]);

Complete Example

Here’s a complete, reusable connection example based on the test file:
<?php

function connectWithSqlsrv(): ?
{
    $host = getenv('MSSQL_HOST');
    $port = getenv('MSSQL_PORT');

    $connection = sqlsrv_connect("{$host},{$port}", [
        'UID' => getenv('MSSQL_USERNAME'),
        'PWD' => getenv('MSSQL_PASSWORD'),
        'Database' => getenv('MSSQL_DATABASE'),
        'Encrypt' => false,
    ]);

    if ($connection === false) {
        $errors = sqlsrv_errors();
        error_log("SQL Server Connection Error: " . json_encode($errors));
        return null;
    }

    return $connection;
}

function testConnection($connection): bool
{
    $result = sqlsrv_query($connection, 'SELECT 1');

    if ($result === false) {
        $errors = sqlsrv_errors();
        error_log("SQL Server Query Error: " . json_encode($errors));
        return false;
    }

    sqlsrv_free_stmt($result);
    return true;
}

// Usage
$conn = connectWithSqlsrv();

if ($conn && testConnection($conn)) {
    echo "Connected and tested successfully!\n";
    
    // Your application code here
    
    sqlsrv_close($conn);
} else {
    die("Failed to connect to SQL Server");
}

Docker Compose Setup

Complete docker-compose.yml with PHP and SQL Server:
version: '3.8'

services:
  sqlserver:
    image: mcr.microsoft.com/mssql/server:2022-latest
    environment:
      ACCEPT_EULA: "Y"
      MSSQL_PID: "Developer"
      SA_PASSWORD: "YourStrong@Password123"
    ports:
      - "1433:1433"
    volumes:
      - sqlserver-data:/var/opt/mssql
    networks:
      - app-network
    healthcheck:
      test: [
        "CMD",
        "/opt/mssql-tools18/bin/sqlcmd",
        "-S", "localhost",
        "-U", "sa",
        "-P", "YourStrong@Password123",
        "-No",
        "-Q", "SELECT 1"
      ]
      interval: 10s
      timeout: 3s
      retries: 20

  php:
    image: namoshek/php-mssql:8.4-cli
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MSSQL_HOST: sqlserver
      MSSQL_PORT: 1433
      MSSQL_DATABASE: master
      MSSQL_USERNAME: sa
      MSSQL_PASSWORD: "YourStrong@Password123"
    depends_on:
      sqlserver:
        condition: service_healthy
    networks:
      - app-network
    command: php /app/test_connection.php

volumes:
  sqlserver-data:

networks:
  app-network:
    driver: bridge

Testing the Connection

Create a simple test script:
test_connection.php
<?php

echo "PHP Version: " . phpversion() . "\n";
echo "sqlsrv version: " . phpversion('sqlsrv') . "\n";
echo "pdo_sqlsrv version: " . phpversion('pdo_sqlsrv') . "\n\n";

echo "Environment Variables:\n";
echo "MSSQL_HOST: " . getenv('MSSQL_HOST') . "\n";
echo "MSSQL_PORT: " . getenv('MSSQL_PORT') . "\n";
echo "MSSQL_DATABASE: " . getenv('MSSQL_DATABASE') . "\n\n";

// Test sqlsrv
echo "Testing sqlsrv extension...\n";
$conn = sqlsrv_connect(
    getenv('MSSQL_HOST') . "," . getenv('MSSQL_PORT'),
    [
        'UID' => getenv('MSSQL_USERNAME'),
        'PWD' => getenv('MSSQL_PASSWORD'),
        'Database' => getenv('MSSQL_DATABASE'),
        'Encrypt' => false,
    ]
);

if ($conn === false) {
    echo "❌ sqlsrv connection failed\n";
    print_r(sqlsrv_errors());
} else {
    echo "✓ sqlsrv connection successful\n";
    sqlsrv_close($conn);
}

// Test PDO
echo "\nTesting pdo_sqlsrv extension...\n";
try {
    $dsn = sprintf(
        "sqlsrv:server=%s,%s;Database=%s;ConnectionPooling=0;Encrypt=no",
        getenv('MSSQL_HOST'),
        getenv('MSSQL_PORT'),
        getenv('MSSQL_DATABASE')
    );
    
    $pdo = new PDO(
        $dsn,
        getenv('MSSQL_USERNAME'),
        getenv('MSSQL_PASSWORD'),
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
    );
    
    echo "✓ PDO connection successful\n";
    $pdo = null;
} catch (PDOException $e) {
    echo "❌ PDO connection failed: " . $e->getMessage() . "\n";
}
Run the test:
docker compose up

Common Issues and Solutions

Problem: Connection times out before establishing.Solutions:
  1. Verify SQL Server is running and accessible
  2. Check network connectivity between containers
  3. Ensure SQL Server is listening on the correct port
  4. Increase LoginTimeout in connection options
  5. Check firewall rules
$connectionOptions = [
    'LoginTimeout' => 60,
    'ConnectRetryCount' => 5,
    'ConnectRetryInterval' => 10,
];
Problem: SSL/TLS certificate validation fails.Solutions:
  1. For development, disable encryption:
    'Encrypt' => false
    
  2. For production, use valid certificates or trust server certificate:
    'Encrypt' => true,
    'TrustServerCertificate' => true,
    
  3. Install proper CA certificates in the container
Problem: Login failed for user.Solutions:
  1. Verify credentials are correct
  2. Check SQL Server authentication mode (Windows vs Mixed)
  3. Ensure SQL Server authentication is enabled:
    EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', 
      N'Software\Microsoft\MSSQLServer\MSSQLServer',
      N'LoginMode', REG_DWORD, 2
    
  4. Restart SQL Server after changing authentication mode
Problem: Connection fails to SQL Server named instance.Solution: Use the instance name in the server string:
$serverName = "hostname\\INSTANCENAME,1433";
// or
$dsn = "sqlsrv:server=hostname\\INSTANCENAME,1433;Database=mydb";

Best Practices

Use Connection Pooling

Enable connection pooling for better performance in production:
'ConnectionPooling' => true

Error Handling

Always implement proper error handling:
if ($conn === false) {
    error_log(json_encode(sqlsrv_errors()));
    // Handle error appropriately
}

Use Prepared Statements

Prevent SQL injection with parameterized queries:
$stmt = $pdo->prepare(
    'SELECT * FROM users WHERE id = :id'
);
$stmt->execute(['id' => $userId]);

Close Connections

Always close connections when done:
sqlsrv_close($conn);
// or
$pdo = null;

Next Steps

PHP Configuration

Optimize PHP settings for database operations

Running Containers

Learn more about running containers effectively

Build docs developers (and LLMs) love