Web

Как экранировать строки в SQL Server с помощью PHP

Я ищу альтернативу mysql_real_escape_string() для SQL Server. Является ли addslashes() для меня лучшим вариантом, или есть другая альтернативная функция, которую можно использовать? Альтернатива для mysql_error() также была бы полезна.

 

Ответ 1

addslashes() не вполне корректен, но пакет PHP mssql не предоставляет никакой достойной альтернативы. Не лучшим, но вполне универсальным решением является кодирование данных в виде шестнадцатеричной строки, т.е.:

$unpacked = unpack('H*hex', $data);

mssql_query('

    INSERT INTO sometable (somecolumn)

    VALUES (0x' . $unpacked['hex'] . ')

');

Абстрактно это было бы:

function mssql_escape($data) {

    if(is_numeric($data))

        return $data;

    $unpacked = unpack('H*hex', $data);

    return '0x' . $unpacked['hex'];

}

 

mssql_query('

    INSERT INTO sometable (somecolumn)

    VALUES (' . mssql_escape($somevalue) . ')

');

Эквивалентом mysql_error() является mssql_get_last_message().

 

Ответ 2

function ms_escape_string($data) {

        if ( !isset($data) or empty($data) ) return '';

        if ( is_numeric($data) ) return $data;

 

        $non_displayables = array(

            '/%0[0-8bcef]/',            // url encoded 00-08, 11, 12, 14, 15

            '/%1[0-9a-f]/',             // url encoded 16-31

            '/[\x00-\x08]/',            // 00-08

            '/\x0b/',                       // 11

            '/\x0c/',                       // 12

            '/[\x0e-\x1f]/'              // 14-31

        );

        foreach ( $non_displayables as $regex )

            $data = preg_replace( $regex, '', $data );

        $data = str_replace("'", "''", $data );

        return $data;

    }

Часть кода здесь была позаимствована из CodeIgniter. Работает хорошо и является чистым решением. 

 

Ответ 3

После нескольких часов поиска ответа я пришел к решению, которое кажется почти лучшим.

Я использую PDO::quote() из PHP, но PDO::quote() не поддерживается для MS SQL Server и возвращает FALSE. Решением для работы стало скачивание некоторых пакетов Microsoft:

Microsoft Drivers 3.0 for PHP for SQL Server (SQLSRV30.EXE): Скачайте и следуйте инструкциям для установки. Microsoft® SQL Server® 2012 Native Client: Найдите на главной странице Native Client. Несмотря на то, что это сделано в 2012 году, я использую его для подключения к SQL Server 2008 (установка Native Client 2008 не помогла). Скачайте и установите. После этого вы можете подключиться в PHP с помощью PDO, используя DSN, как показано в следующем примере:

sqlsrv:Server=192.168.0.25; Database=My_Database;

Использование параметров UID и PWD в DSN не сработало, поэтому имя пользователя и пароль передаются как второй и третий параметры в конструкторе PDO при создании соединения. Теперь вы можете использовать PHP PDO::quote().

 

Ответ 4

Для преобразования шестнадцатеричных значений в SQL обратно в ASCII вот решение, которое я получил (используя функцию из user chaos для кодирования в шестнадцатеричный формат):

function hexEncode($data) {

    if(is_numeric($data))

        return $data;

    $unpacked = unpack('H*hex', $data);

    return '0x' . $unpacked['hex'];

}

 

function hexDecode($hex) {

    $str = '';

    for ($i=0; $i<strlen($hex); $i += 2)

        $str .= chr(hexdec(substr($hex, $i, 2)));

    return $str;

}

 

$stringHex = hexEncode('Test String');

var_dump($stringHex);

$stringAscii = hexDecode($stringHex);

var_dump($stringAscii);

 

Ответ 5

Лучше также избегать зарезервированных слов SQL. Например:

function ms_escape_string($data) {

    if (!isset($data) or empty($data))

        return '';

    if (is_numeric($data))

        return $data;

    $non_displayables = array(

        '/%0[0-8bcef]/',        // URL encoded 00-08, 11, 12, 14, 15

        '/%1[0-9a-f]/',          // url encoded 16-31

        '/[\x00-\x08]/',         // 00-08

        '/\x0b/',                    // 11

        '/\x0c/',                    // 12

        '/[\x0e-\x1f]/',         // 14-31

        '/\27/'

    );

    foreach ($non_displayables as $regex)

        $data = preg_replace( $regex, '', $data);

    $reemplazar = array('"', "'", '=');

    $data = str_replace($reemplazar, "*", $data);

    return $data;

}

 

Ответ 6

Я использовал это как альтернативу mysql_real_escape_string():

function htmlsan($htmlsanitize){

    return $htmlsanitize = htmlspecialchars($htmlsanitize, ENT_QUOTES, 'UTF-8');

}

$data = "Какова бы ни была стоимость";

$data = stripslashes(htmlsan($data));

 

Ответ 7

Вы можете создать свою собственную версию mysql_real_escape_string (и улучшить ее) с помощью следующего регулярного выражения: [\000\010\011\012\015\032\042\047\134\140]. Это позволяет избавиться от следующих символов: ноль, пробел, горизонтальная табуляция, новая строка, возврат каретки, замена, двойная кавычка, одинарная кавычка, обратная косая черта, подчеркивание. Backspace и горизонтальная табуляция не поддерживаются в mysql_real_escape_string.

 

Схожие статьи

Web

Лучшие практики для настраиваемых помощников в Laravel 5

Как создать грамотное оформление страницы 404 на собственном сайте
Web

Как создать грамотное оформление страницы 404 на собственном сайте

Web

Преобразование форматов даты в PHP

Web

PHP — объединение или прямая вставка переменных в строку