Как экранировать строки в SQL Server, используя PHP? - PullRequest
86 голосов
/ 22 февраля 2009

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

Редактировать : Альтернатива для mysql_error() также будет полезна.

Ответы [ 14 ]

70 голосов
/ 22 февраля 2009

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().

40 голосов
/ 27 марта 2010
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. Хорошо работает и является чистым решением.

EDIT: Есть много проблем с этим фрагментом кода выше. Пожалуйста, не используйте это, не читая комментарии, чтобы знать, что это такое. Еще лучше, пожалуйста, не используйте это вообще. Параметризованные запросы ваших друзей: http://php.net/manual/en/pdo.prepared-statements.php

14 голосов
/ 09 сентября 2015

Зачем вам что-либо избегать, если вы можете использовать параметры в своем запросе?!

sqlsrv_query(
    $connection, 
    'UPDATE some_table SET some_field = ? WHERE other_field = ?', 
    array($_REQUEST['some_field'], $_REQUEST['id'])
)

Он работает правильно при выборе, удалении, обновлении независимо от того, являются ли ваши значения параметров null или нет. Принципиально - не объединяйте SQL, и вы всегда в безопасности, а ваши запросы читаются намного лучше.

http://php.net/manual/en/function.sqlsrv-query.php

10 голосов
/ 22 февраля 2009

Вы можете заглянуть в библиотеку PDO . Вы можете использовать подготовленные операторы с PDO, который автоматически уберет все плохие символы в ваших строках, если вы правильно подготовите операторы. Я думаю, это только для PHP 5.

4 голосов
/ 02 марта 2014

Еще один способ обработки одинарных и двойных кавычек -

function mssql_escape($str)
{
   if(get_magic_quotes_gpc())
   {
    $str= stripslashes($str);
   }
   return str_replace("'", "''", $str);
}
2 голосов
/ 08 сентября 2012

Чтобы избежать одинарных и двойных кавычек, вы должны удвоить их:

$value = 'This is a quote, "I said, 'Hi'"';

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

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

$query = "INSERT INTO TableName ( TextFieldName ) VALUES ( '$value' ) ";

и т.д ...

и атрибуция: Escape-символ в Microsoft SQL Server 2000

2 голосов
/ 19 июня 2012

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

Ответ Хаоса на преобразование значений в шестнадцатеричную строку не работает с каждым типом данных, особенно со столбцами даты и времени.

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

После этого вы можете соединиться в PHP с PDO, используя DSN, как показано в следующем примере:

sqlsrv:Server=192.168.0.25; Database=My_Database;

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

1 голос
/ 11 мая 2011

я знаю, немного поздно, но ответ от 'Feb 22 '09 в 12:10' хаосом не подходит для всех запросов. Например: «CREATE LOGIN [0x6f6c6f6c6f] ИЗ WINDOWS» выдаст вам исключение

p.s. посмотрите на драйвер mssql для функций php, http://msdn.microsoft.com/library/cc296181%28v=sql.90%29.aspx и sqlsrv_prepare, которые могут связывать параметры.

p.s.s. который также не помог вам с запросом выше;)

0 голосов
/ 05 ноября 2017

Не лучше ли избежать экранированных 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;
}
0 голосов
/ 16 августа 2017

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

function htmlsan($htmlsanitize){
    return $htmlsanitize = htmlspecialchars($htmlsanitize, ENT_QUOTES, 'UTF-8');
}
$data = "Whatever the value's is";
$data = stripslashes(htmlsan($data));
...