J'ai un problème troublant que je n'arrive pas à comprendre.
J'ai deux instructions SQL:
Le problème est qu’il semble qu’un seul devis déclenche une erreur MySQL sur la deuxième entrée seulement! La première instance fonctionne sans problème, mais la deuxième instance déclenche la mysql_error()
.
Les données d'un formulaire sont-elles traitées différemment des données capturées dans un formulaire?
Requête 1 - Cela fonctionne sans problème (et sans échapper à la citation simple)
$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')");
Requête 2 - Cela échoue lors de la saisie d'un nom avec un seul guillemet (par exemple, 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')");
Vous devriez échapper à chacune de ces chaînes (dans les deux extraits) avec mysql_real_escape_string()
.
http://us3.php.net/mysql-real-escape-string
La raison pour laquelle vos deux requêtes se comportent différemment est probablement due au fait que magic_quotes_gpc
est activé (vous devez savoir que c'est une mauvaise idée). Cela signifie que les chaînes rassemblées à partir de $ _GET, $ _POST et $ _COOKIES sont échappées pour vous (c'est-à-dire "O'Brien" -> "O\'Brien"
).
Une fois que vous avez stocké les données, puis récupérées à nouveau, la chaîne que vous récupérez de la base de données ne sera pas automatiquement échappée pour vous. Vous obtiendrez "O'Brien"
. Donc, vous devrez le passer à travers mysql_real_escape_string()
.
Pour tous ceux qui trouvent cette solution en 2015 et vont de l'avant ...
La fonction mysql_real_escape_string()
est obsolète à partir de PHP 5.5.0.
Voir: php.net
Avertissement
Cette extension est obsolète à partir de PHP 5.5.0 et sera supprimée à l'avenir. Au lieu de cela, l'extension MySQLi ou PDO_MySQL doit être utilisée. Voir aussi MySQL: choix d'un guide d'API et de la FAQ associée pour plus d'informations. Les alternatives à cette fonction incluent:
mysqli_real_escape_string()
PDO::quote()
Vous avez un couple de choses qui se battent dans vos cordes.
mysql_real_escape_string()
)Il est également possible que la valeur entre guillemets simples ne soit pas présente dans les paramètres de la première requête. Votre exemple est un nom propre, après tout, et seule la deuxième requête semble traiter de noms.
Vous pouvez faire ce qui suit pour échapper à PHP et à MySQL.
<?
$text = '<a href="javascript:window.open(\\\'http://www.google.com\\\');"></a>';
?>
Cela reflétera MySQL comme
<a href="javascript:window.open('http://www.google.com');"></a>
Comment ça marche?
Nous savons que les apostrophes PHP et MySQL peuvent être échappées avec une barre oblique inverse, puis une apostrophe.
\'
Comme nous utilisons PHP pour insérer dans MySQL, nous avons besoin de PHP pour écrire la barre oblique inversée dans MySQL afin qu'elle puisse également y échapper. Nous utilisons donc le caractère d'échappement PHP de backslash-backslash avec backslash-apostrophe pour y parvenir.
\\\'
Vous devriez faire quelque chose comme ça pour vous aider à déboguer
$sql = "insert into blah blah....";
echo $sql;
Vous constaterez probablement que la citation unique est échappée avec une barre oblique inversée dans la requête de travail. Cela aurait peut-être été fait automatiquement par PHP via le paramètre magic_quotes_gpc, ou peut-être l'avez-vous fait vous-même dans une autre partie du code (addlashes et stripslash pourraient être des fonctions à rechercher).
Voir Citations magiques
Vous devriez juste passer la variable (ou les données) dans "mysql_real_escape_string (trim ($ val))"
où $val
est la donnée qui vous trouble.