Szukam alternatywy mysql_real_escape_string()
dla SQL Server. Czy addslashes()
moja najlepsza opcja, czy jest inna alternatywna funkcja, której można użyć?
Przydałaby się również alternatywa dla mysql_error()
.
php
sql-server
escaping
input-sanitization
Kliknij opcję Głos za głosem
źródło
źródło
Odpowiedzi:
addslashes()
nie jest w pełni adekwatna, ale pakiet mssql PHP nie zapewnia żadnej przyzwoitej alternatywy. Brzydkim, ale w pełni ogólnym rozwiązaniem jest kodowanie danych jako szesnastkowy bajt bajtowy, tj$unpacked = unpack('H*hex', $data); mssql_query(' INSERT INTO sometable (somecolumn) VALUES (0x' . $unpacked['hex'] . ') ');
W skrócie, byłoby to:
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()
odpowiednik jestmssql_get_last_message()
.źródło
SQLSTATE[22007]: Invalid datetime format: 210 [Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting datetime from binary/varbinary string.
uważam, że ta metoda może być poprawna tylko wtedy, gdy działa z każdym typem danych MSSQL.mssql_escape()
zwróconej funkcji nie robi tego za mnie. Tekst wyświetlany po dokonaniu wyboru wygląda tak, że jest0x4a2761696d65206269656e206c652063686f636f6c6174
nieczytelny.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; }
Część kodu została wyrwana z CodeIgniter. Działa dobrze i jest czystym rozwiązaniem.
EDYCJA: istnieje wiele problemów z powyższym fragmentem kodu. Nie używaj tego bez czytania komentarzy, aby wiedzieć, co to jest. Jeszcze lepiej, proszę, w ogóle tego nie używaj. Sparametryzowane zapytania to Twoi przyjaciele: http://php.net/manual/en/pdo.prepared-statements.php
źródło
preg_replace
? Czy to niestr_replace
wystarczy?empty($value)
powrócitrue
nie tylko''
, ale takżenull
,0
a'0'
! We wszystkich tych przypadkach zwróciłbyś pusty ciąg.Dlaczego miałbyś zawracać sobie głowę ucieczką przed czymkolwiek, skoro możesz używać parametrów w zapytaniu ?!
sqlsrv_query( $connection, 'UPDATE some_table SET some_field = ? WHERE other_field = ?', array($_REQUEST['some_field'], $_REQUEST['id']) )
Działa poprawnie w zaznaczeniach, usuwaniu i aktualizacjach, niezależnie od tego, czy parametry wartości są,
null
czy nie. Kieruj się zasadą - nie łącz SQL, a zawsze będziesz bezpieczny, a Twoje zapytania będą czytane znacznie lepiej.http://php.net/manual/en/function.sqlsrv-query.php
źródło
Możesz zajrzeć do Biblioteki PDO . Możesz używać przygotowanych instrukcji z PDO, które automatycznie usuwają wszelkie złe znaki w łańcuchach, jeśli poprawnie wykonasz przygotowane instrukcje. Myślę, że to tylko dla PHP 5.
źródło
Innym sposobem obsługi pojedynczych i podwójnych cudzysłowów jest:
function mssql_escape($str) { if(get_magic_quotes_gpc()) { $str = stripslashes($str); } return str_replace("'", "''", $str); }
źródło
Aby uniknąć apostrofów i cudzysłowów, musisz je podwoić:
$value = 'This is a quote, "I said, 'Hi'"'; $value = str_replace( "'", "''", $value );
$value = str_replace( '"', '""', $value );
$query = "INSERT INTO TableName ( TextFieldName ) VALUES ( '$value' ) ";
itp...
i przypisanie: znak ucieczki w Microsoft SQL Server 2000
źródło
Po wielu godzinach zmagań się z tym, znalazłem rozwiązanie, które wydaje się prawie najlepsze.
Odpowiedź Chaosa dotycząca konwersji wartości na ciąg szesnastkowy nie działa z każdym typem danych, szczególnie z kolumnami z datą i godziną.
Używam PHP
PDO::quote()
, ale ponieważ pochodzi z PHP,PDO::quote()
nie jest obsługiwany przez MS SQL Server i zwracaFALSE
. Rozwiązaniem do jego działania było pobranie niektórych pakietów Microsoft:Następnie możesz połączyć się w PHP z PDO używając DSN, jak w poniższym przykładzie:
sqlsrv:Server=192.168.0.25; Database=My_Database;
Używanie parametrów
UID
iPWD
w DSN nie zadziałało, więc nazwa użytkownika i hasło są przekazywane jako drugi i trzeci parametr w konstruktorze PDO podczas tworzenia połączenia. Teraz możesz używać PHPPDO::quote()
. Cieszyć się.źródło
Odpowiedź od 2009-02-22T121000 od użytkownika chaos nie pasuje do wszystkich zapytań.
Na przykład „UTWÓRZ LOGIN [0x6f6c6f6c6f] Z WINDOWS” da ci wyjątek.
PS: spójrz na sterownik SQL Server dla PHP, http://msdn.microsoft.com/library/cc296181%28v=sql.90%29.aspx i funkcję sqlsrv_prepare, która może wiązać parametry.
PSS: Co również nie pomogło w powyższym zapytaniu;)
źródło
http://php.net/manual/en/function.mssql-query.php
Każdy, kto nadal używa tych funkcji mssql_ *, powinien pamiętać, że zostały one usunięte z PHP w wersji 7.0.0. Oznacza to, że w końcu będziesz musiał przepisać kod modelu, aby użyć biblioteki PDO, sqlsrv_ * itd. Jeśli szukasz czegoś z metodą „cytowania / ucieczki”, polecam PDO.
źródło
Jeśli używasz PDO, możesz użyć tej
PDO::quote
metody.źródło
W celu konwersji, aby uzyskać wartości szesnastkowe w SQL z powrotem do ASCII, oto rozwiązanie, które otrzymałem (używając funkcji od chaosu użytkownika do kodowania na szesnastkowy)
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);
źródło
Lepiej jest też unikać słów zastrzeżonych SQL. Na przykład:
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; }
źródło
Używam tego jako alternatywy dla
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));
źródło
Można toczyć własną wersję
mysql_real_escape_string
(i poprawić na nim) za pomocą następującego wyrażenia regularnego:[\000\010\011\012\015\032\042\047\134\140]
. To zajmuje się następującymi znakami: null, backspace, tabulator poziomy, nowa linia, powrót karetki, zamiana, podwójny cudzysłów, pojedynczy cudzysłów, ukośnik odwrotny, akcent słaby. Backspace i tabulator poziomy nie są obsługiwane przezmysql_real_escape_string
.źródło