Как избежать строк в SQL Server с помощью PHP?

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

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

Ответ 1

addslashes() не вполне адекватен, но пакет PHP mssql не предоставляет достойной альтернативы. Уродливое, но полностью общее решение - это кодирование данных как hex-критерий, т.е.

$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. Работает хорошо и является чистым решением.

РЕДАКТИРОВАТЬ: есть много проблем с этим фрагментом кода выше. Пожалуйста, не используйте это, не читая комментарии, чтобы знать, что это такое. Еще лучше, пожалуйста, не используйте это вообще. Параметризованные запросы - ваши друзья: http://php.net/manual/en/pdo.prepared-statements.php

Ответ 3

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

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

Ответ 5

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

function mssql_escape($str)
{
    if(get_magic_quotes_gpc())
    {
        $str = stripslashes($str);
    }
    return str_replace("'", "''", $str);
}

Ответ 6

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

Ответ Chaos на преобразование значений в hexstring не работает с каждым типом данных, в частности с столбцами datetime.

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

  • Microsoft Drivers 3.0 для PHP для SQL Server (SQLSRV30.EXE): Загрузите и следуйте инструкциям для установки.
  • Родительский клиент Microsoft® SQL Server® 2012: выполните поиск по обширной странице для собственного клиента. Несмотря на то, что в 2012 году я использую его для подключения к SQL Server 2008 (установка собственного клиента 2008 года не сработала). Загрузите и установите.

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

sqlsrv:Server=192.168.0.25; Database=My_Database;

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

Ответ 7

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

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

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

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

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

и т.д...

и атрибуция: Escape Character В Microsoft SQL Server 2000

Ответ 8

Ответ от 2009-02-22T121000, созданный пользователем, не соответствует всем запросам.

Например, "CREATE LOGIN [0x6f6c6f6c6f] FROM WINDOWS" выдаст вам исключение.

PS: посмотрите на драйвер SQL Server для PHP, http://msdn.microsoft.com/library/cc296181%28v=sql.90%29.aspx и функцию sqlsrv_prepare, которая может связывать параметры.

PSS: Что также не помогло вам с запросом выше;)

Ответ 9

Предупреждение: эта функция была удалена в PHP 7.0.0.

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

Для тех, кто все еще использует эти функции mssql_ *, имейте в виду, что они были удалены с PHP с версии 7.0.0. Таким образом, это означает, что вам в конечном итоге придется переписать код модели, чтобы использовать библиотеку PDO, sqlsrv_ * и т.д. Если вы ищете что-то с методом "цитирования/экранирования", я бы рекомендовал PDO.

Альтернативы этой функции включают: PDO:: query(), sqlsrv_query() и odbc_exec()

Ответ 10

Если вы используете PDO, вы можете использовать метод PDO::quote.

Ответ 11

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

Ответ 12

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

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);

Ответ 13

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

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

Ответ 14

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