web-dev-qa-db-fra.com

Échappe de guillemets simples dans PHP lors de l'insertion dans MySQL

J'ai un problème troublant que je n'arrive pas à comprendre.

J'ai deux instructions SQL:

  • Le premier entre les informations d'un formulaire dans la base de données.
  • La seconde prend les données de la base de données entrée ci-dessus, envoie un courrier électronique, puis consigne les détails de la transaction.

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')");
173
sjw

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().

126
awgy

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

50
Amy McCrobie

Vous avez un couple de choses qui se battent dans vos cordes.

  • absence de citations MySQL correctes (mysql_real_escape_string())
  • "devis magique" automatique potentiel - vérifiez votre paramètre gpc_magic_quotes
  • variables de chaîne incorporées, ce qui signifie que vous devez savoir comment PHP trouve correctement les variables

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.

15
staticsan

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.

\\\'
14
Error404

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

14
goat

Vous devriez juste passer la variable (ou les données) dans "mysql_real_escape_string (trim ($ val))"

$val est la donnée qui vous trouble.

10
user3272729