Я шукаю альтернативу mysql_real_escape_string()
для SQL Server. Це addslashes()
мій найкращий варіант або є інша альтернативна функція, яку можна використовувати?
Альтернатива для mysql_error()
також була б корисною.
Я шукаю альтернативу mysql_real_escape_string()
для SQL Server. Це addslashes()
мій найкращий варіант або є інша альтернативна функція, яку можна використовувати?
Альтернатива для mysql_error()
також була б корисною.
Відповіді:
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()
.
SQLSTATE[22007]: Invalid datetime format: 210 [Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting datetime from binary/varbinary string.
я вважаю, що цей метод може бути правильним, лише якщо він працює з кожним типом даних MSSQL.
mssql_escape()
функції, що повертається, не робить це замість мене. Відображення тексту після вибору виглядає 0x4a2761696d65206269656e206c652063686f636f6c6174
таким чином, таким чином нечитабельним.
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
preg_replace
? Хіба не str_replace
достатньо?
empty($value)
повернеться true
не тільки для ''
, але і для null
, 0
і '0'
! Ви б повернули порожній рядок у всіх цих випадках.
Чому б вам турбуватися, уникаючи чого-небудь, коли ви можете використовувати параметри у своєму запиті ?!
sqlsrv_query(
$connection,
'UPDATE some_table SET some_field = ? WHERE other_field = ?',
array($_REQUEST['some_field'], $_REQUEST['id'])
)
Він працює правильно при виборі, видаленні, оновленні незалежно від того, є ваші параметри значень null
чи ні. Будьте принциповими - не об’єднуйте SQL, і ви завжди в безпеці, а ваші запити читаються набагато краще.
Ви можете заглянути в бібліотеку PDO . Ви можете використовувати підготовлені оператори з PDO, які автоматично уникнуть будь-яких поганих символів у ваших рядках, якщо ви правильно зробите підготовлені оператори. Це лише для PHP 5, я думаю.
Іншим способом обробки одинарних і подвійних лапок є:
function mssql_escape($str)
{
if(get_magic_quotes_gpc())
{
$str = stripslashes($str);
}
return str_replace("'", "''", $str);
}
Щоб уникнути одинарних та подвійних лапок, вам потрібно подвоїти їх:
$value = 'This is a quote, "I said, 'Hi'"';
$value = str_replace( "'", "''", $value );
$value = str_replace( '"', '""', $value );
$query = "INSERT INTO TableName ( TextFieldName ) VALUES ( '$value' ) ";
тощо ...
та атрибуція: символ втечі в Microsoft SQL Server 2000
Поборвавшись із цим годинами, я придумав рішення, яке відчуває себе чи не найкращим.
Відповідь Хаосу на перетворення значень у шістнадцятковий рядок працює не з кожним типом даних, зокрема зі стовпцями дати та часу.
Я використовую 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()
. Насолоджуйтесь
Відповідь хаосу користувача від 22.02.20091212000 не відповідає всім запитам.
Наприклад, "СТВОРИТИ ВХОД [0x6f6c6f6c6f] З ВІКН" дасть вам виняток.
PS: подивіться на драйвер SQL Server для PHP, http://msdn.microsoft.com/library/cc296181%28v=sql.90%29.aspx та функцію sqlsrv_prepare, яка може пов’язувати параметри.
PSS: що також не допомогло вам із наведеним вище запитом;)
Попередження: Ця функція ВИДАЛЕНА в PHP 7.0.0.
http://php.net/manual/en/function.mssql-query.php
Для тих, хто все ще використовує ці функції mssql_ *, майте на увазі, що вони були видалені з PHP станом на v7.0.0. Отже, це означає, що з часом вам доведеться переписати код моделі, щоб використовувати бібліотеку PDO, sqlsrv_ * тощо. Якщо ви шукаєте щось із методом "цитування / екранування", я б рекомендував PDO.
Альтернативи цієї функції включають: PDO :: query (), sqlsrv_query () та odbc_exec ()
Якщо ви використовуєте PDO, ви можете використовувати PDO::quote
метод.
Також краще уникати зарезервованих слів 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;
}
Я використовую це як альтернативу 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));
Для перетворення, щоб повернути шістнадцяткові значення в 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);
Ви можете згорнути свою власну версію mysql_real_escape_string
, (і поліпшити його) з наступним регулярним виразом: [\000\010\011\012\015\032\042\047\134\140]
. Це піклується про такі символи: нуль, зворотний простір, горизонтальна вкладка, новий рядок, повернення каретки, заміна, подвійна лапка, одинарна лапка, коса коса риса, серйозний акцент. Пробіл і горизонтальна вкладка не підтримуються mysql_real_escape_string
.