2010-04-22 20 views
119

ich ein verwirrendes Problem, dass ich nicht zu begreifen scheinen ... Ich bin der Hoffnung, jemand hier vielleicht in der Lage sein, mich in die richtige Richtung weisen ...Escaping Apostroph in PHP beim Einfügen in MySQL

Ich habe zwei SQL-Anweisungen: - der erste gibt Informationen aus einem Formular in die Datenbank ein. - die Sekunde nimmt Daten von der Datenbank, die oben eingegeben wird, schickt eine E-mail und notiert dann die Details der Verhandlung

Das Problem ist, dass es scheint, dass ein einzelner Anführungsstrich einen MySQL Fehler nur auf dem zweiten Eintrag löst !! ! Die erste Instanz funktioniert ohne Problem, aber die zweite Instanz löst die mysql_error() aus.

Werden die Daten aus einem Formular anders gehandhabt als die in einem Formular erfassten Daten?

Abfrage # 1 - Das funktioniert ohne Problem (und ohne das Apostroph entweichende)

$result = mysql_query("INSERT INTO job_log 
(order_id, supplier_id, category_id, service_id, qty_ordered, customer_id, user_id, salesperson_ref, booking_ref, booking_name, address, suburb, postcode, state_id, region_id, email, phone, phone2, mobile, delivery_date, stock_taken, special_instructions, cost_price, cost_price_gst, sell_price, sell_price_gst, ext_sell_price, retail_customer, created, modified, log_status_id) 
VALUES 
('$order_id', '$supplier_id', '$category_id', '{$value['id']}', '{$value['qty']}', '$customer_id', '$user_id', '$salesperson_ref', '$booking_ref', '$booking_name', '$address', '$suburb', '$postcode', '$state_id', '$region_id', '$email', '$phone', '$phone2', '$mobile', STR_TO_DATE('$delivery_date', '%d/%m/%Y'), '$stock_taken', '$special_instructions', '$cost_price', '$cost_price_gst', '$sell_price', '$sell_price_gst', '$ext_sell_price', '$retail_customer', '".date('Y-m-d H:i:s', time())."', '".date('Y-m-d H:i:s', time())."', '1')"); 

Abfrage # 2 - Dies schlägt fehl, wenn Sie einen Namen mit einem Apostroph eingeben (zB O'Brien)

$query = mysql_query("INSERT INTO message_log 
(order_id, timestamp, message_type, email_from, supplier_id, primary_contact, secondary_contact, subject, message_content, status) 
VALUES 
('$order_id', '".date('Y-m-d H:i:s', time())."', '$email', '$from', '$row->supplier_id', '$row->primary_email' ,'$row->secondary_email', '$subject', '$message_content', '1')"); 

Antwort

85

Sie sollten jede dieser Saiten zu entkommen (in beiden Snippets) mit mysql_real_escape_string().

http://us3.php.net/mysql-real-escape-string

Der Grund Ihre beiden Abfragen anders verhalten ist wahrscheinlich, weil Sie haben magic_quotes_gpc eingeschaltet (die Sie sollten wissen, eine schlechte Idee ist). Dies bedeutet, dass Strings, die aus $ _GET, $ _POST und $ _COOKIES gesammelt wurden, für Sie maskiert werden (d. H. "O'Brien" -> "O\'Brien").

Sobald Sie die Daten speichern und anschließend erneut abrufen, wird die Zeichenfolge, die Sie aus der Datenbank abrufen, nicht automatisch für Sie entkam. Du wirst zurück "O'Brien" bekommen. Also, müssen Sie es durch mysql_real_escape_string() übergeben.

+0

Ja ok, danke für die Lektion jedoch in der richtigen Codierung, dies nicht die Frage beantworten, warum die beiden Abfragen nicht den gleichen Fehler zu werfen ... – sjw

+0

Ich bin nicht auf der Suche nach der Antwort, wie es zu beheben - ich weiß, wie es zu beheben. Ich suche das "Warum"! – sjw

+1

Es geht nicht um * richtige * Codierung, es geht um eine klaffende und gefährliche Sicherheitslücke. Nachdem dies gesagt wurde, füge ich meiner ursprünglichen Antwort ein Snippet hinzu, um das zugrunde liegende Problem zu veranschaulichen. Ich würde es hier tun, aber die Formatierung wäre alles wackelig. :) – awgy

9

Sie sollten etwas tun Sie

$sql = "insert into blah blah...."; 
echo $sql; 

zu helfen, debuggen Sie werden wahrscheinlich feststellen, dass das Apostroph mit einem umgekehrten Schrägstrich in der Arbeits Abfrage entkommen ist. Dies könnte automatisch von PHP über die Einstellung magic_quotes_gpc gemacht worden sein, oder vielleicht hast du es selbst in einem anderen Teil des Codes getan (addslashes und stripeslashes könnten Funktionen sein, nach denen du suchen musst).

Siehe http://php.net/manual/en/security.magicquotes.php

9

Sie haben ein paar Dinge in die Saiten zu kämpfen.

  • Mangel an richtigen MySQL unter Angabe (mysql_real_escape_string())
  • Potenzial automatische ‚Magie Zitat‘ - überprüfen Sie Ihre gpc_magic_quotes
  • eingebetteten Stringvariablen einstellen, das heißt, dass Sie wissen, wie PHP findet korrekt Variablen

Es ist auch möglich, dass der Wert in den einzelnen Anführungszeichen in den Parametern der ersten Abfrage nicht vorhanden ist.Ihr Beispiel ist schließlich ein richtiger Name, und nur die zweite Abfrage scheint mit Namen zu tun zu haben.

-3

Ich hatte das gleiche Problem, und ich löste es wie folgt aus:

$text=str_replace("'","\'",$YourContent); 

Es ist wahrscheinlich ein besserer Weg, dies zu tun, aber es funktionierte für mich, und es sollte auch für Sie arbeiten.

+0

Es gibt einen besseren Weg ... irgendeinen anderen als diesen. Im Ernst, tu das nicht, wenn du nicht willst, dass deine Datenbank Bobby Table'd bekommt. Verwenden Sie PDO (der richtige Weg) - es kümmert sich um die Flucht für Sie. Verwenden Sie den veralteten mysql_real_escape_string sogar (nicht den richtigen Weg)! Oder 'addslashes' (nicht der richtige Weg). Alles andere als das. –

+0

Sie sollten zu diesem Zweck eine native Funktion ausführen. –

6

Sie sollten nur die Variable oder Daten innerhalb passieren "mysql_real_escape_string (trim ($ val))"

wobei $ val = die Daten, die Sie ist beunruhigend.

9

Sie können Folgendes tun, was sowohl PHP als auch MySQL entzieht.

<? 
$text = '<a href="javascript:window.open(\\\'http://www.google.com\\\');"></a>'; 
?> 

Dies wird reflektieren MySQL als

<a href="javascript:window.open('http://www.google.com');"></a> 

Wie funktioniert es?

Wir wissen, dass PHP und MySQL Apostrophe mit Backslash und dann Apostroph entkommen können.

\' 

Weil wir PHP verwenden in MySQL einfügen, müssen wir PHP noch den umgekehrten Schrägstrich zu MySQL schreiben, so auch sie es entweichen kann. Also verwenden wir das PHP-Escape-Zeichen von Backslash-Backslash zusammen mit Backslash-Apostroph, um dies zu erreichen.

\\\' 
33

Für alle diese Lösung im Jahr 2015 zu finden und voran ...

Die mysql_real_escape_string() Funktion ist ab PHP 5.5.0 veraltet.

See: php.net

Warnung

Diese Erweiterung als PHP ist veraltet 5.5.0 und wird in der Zukunft entfernt werden. Stattdessen sollte die Erweiterung MySQLi oder PDO_MySQL verwendet werden. Siehe auch MySQL: Wählen Sie einen API-Leitfaden und verwandte FAQ für weitere Informationen. Alternativen zu dieser Funktion sind:

mysqli_real_escape_string()

PDO::quote()

+2

mysqli_real_escape_string erfordert 2 Parameter sagt es – coolcool1994

+0

@ coolcool1994 - Ich hatte dieses Problem auch, bis ich diese SO Frage gefunden - http://Stackoverflow.com/questions/25636975/warning-mysqli-real-escape-string-expects- genau-2-Parameter-1-gegeben-wh. Es scheint, dass mysqli _ **() - Funktionen erfordern, dass der erste Parameter Ihre mysqli-Datenbankverbindungsvariable ist (normalerweise nenne ich mir etwas wie "$ conn"). – RoboBear

+0

@ coolcool1994 - ja, Sie brauchen Ihre Verbindungszeichenfolge sowie die Sache, die Sie entkommen. Für viele Benutzer wird dies "$ con" oder "$ conn" sein. –