Message erreur sql

Eléphant du PHP | 372 Messages

15 juin 2015, 23:16

Salut,
J'ai un ptit soucis sur le code.
TT marche l'insertion se fait en bdd mais j'ai le message "données inserées en basedonnées" autant de fois que c'est insérér en bdd et a la fois le message "Erreur SQL !INSERT INTO `loisirs` (id_simply_user,titre,price ....".

Si quelqu'un voir le pbm, PS: J'ai 8500 entrées normalement dans mon xml et la il n'en rentre que 3, si vous avez la solution :P

Le code:
<?php
	
	include("include/variables.php");
	
    //connection a la base de donnee
    $dbhost = "localhost";
    $dbuser = "root";      // mysql user
    $dbpass = "";       // mysql password
    $dbname = "mabase";     // mysql database
    $conn=mysql_connect($dbhost,$dbuser,$dbpass) or die(erreurServeurMySQL());
    mysql_select_db($dbname,$conn) or die('Erreur de selection '.mysql_error()); // problème sur la bdd
     
    $flux = simplexml_load_file('http://localhost/csv/zxpd_201506140442_3467_31592008.xml'); // Source du flux.xml
						  
    foreach ($flux->product as $item) {
 
	$titre = $item->titre;
	$price = $item->price;
	$url_fnac = $item->url_fnac;
	$date_debut_sortie = $item->date_debut_sortie;
	$date_fin_sortie = $item->date_fin_sortie;
	$street = $item->street;
	$photo = $item->largeImage;
	$genre = $item->merchantCategoryPath;
	
	$type  = array(  // Spectacle
						'POP|Pop-rock/Folk ' => 11, '12P|Pop-Rock/Musique électronique' => 18, '1MC|Musique/Concerts' => 11,
						);

	foreach ($type as $k => $v) {
}
	

	// On fait un explode afin de récupérer ce qu'il nous interesse
	$postcode  = $item->extra2;
	$pieces = explode(" ", $postcode);

	// On attribut le département en fonction des 2 premiers chiffre du code postal
	$departement = substr($postcode, 0, 2);
	
	$region = regionIdByDepartement($departement);
	
	// Attribution de la valeur id 99 pour la fnac
	$id_simply_user = '99';
	
	// On valide la sortie par default
	$valide = '1';

	$sql = "INSERT INTO `matable` (id_simply_user,titre,price,photo,url_fnac,date_debut_sortie,date_fin_sortie,street,postcode,city,id_region,id_departements,id_type_loisirs,valide) VALUES ('$id_simply_user','$titre','$price','$photo','$url_fnac','$date_debut_sortie','$date_fin_sortie','$street','$pieces[0]','$pieces[2]','$region','$departement','$v','$valide')";
	$req = mysql_query($sql) or die('Erreur SQL !'.$sql.'<br>'.mysql_error());
	echo 'données inserées en base';
  
 
}
 
?>

Mammouth du PHP | 688 Messages

16 juin 2015, 00:02

tu dois avoir un ' dans la requete qui pose problème. il faut donc échapper certains caractères.

Eléphant du PHP | 372 Messages

16 juin 2015, 07:24

Salut,
Alors le message d'erreur est du au fait que dans ce que je récupère dans mon XML comporte de temps en temps des '.
Exemple :
LA MACHINE DE L'HOMME.

Si je supprimer le ' l'insertion se fait du coup comment éviter ce problème svp, afin qu'il m'insère bien quand même.
Merci encore

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

16 juin 2015, 09:08

Bonjour,

Il faut protéger les caractères spéciaux pour éviter ce genre d'erreur, mais également pour se prémunir des injections sql.
Tu peux partir sur un simple addslashes() pour échapper les apostrophes de tes chaines avec un antislash, mais l'idéal serait de partir sur du PDO pour te connecter à ta base de données (les fonctions mysql_* sont obsolètes et disparaissent avec php7).

Tu pourras alors utiliser la méthode quote() qui va doubler l'apostrophe (et ajouter les apostrophes autour de ta variable), ou mieux encore dans ce cas précis, les requêtes préparées vu que tu vas avoir un grand nombre d'enregistrement à insérer :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphant du PHP | 372 Messages

16 juin 2015, 16:37

Alors je suis passé sur pdo comme tu m'as demandé.
J'ai 2 erreur à l'écran
Invalid parameter number: parameter was not defined in C:\wamp\www\csv\index.php on line 95
Array to string conversion in C:\wamp\www\csv\index.php on line 95

Est ce également suffisant pr pouvoir insérer mes chaines ou j'aurais ' Merci à vous.
Mon code:
<?php
	
	include("include/variables.php");
	

		// Connexion à la base
		try
		{
				$bdd = new PDO('mysql:host=127.0.0.1;dbname=lasortie1', 'root', '', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
				$bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); 
				$bdd->exec('SET NAMES utf8');
		}
		 
		catch(PDOException $e)
		{
				exit($e->getMessage());
				die();
		}


     
    $flux = simplexml_load_file('http://localhost/csv/zxpd_201506140442_3467_31592008.xml'); // Source du flux.xml
						  
    foreach ($flux->product as $item) {
 
	$titre = $item->titre;
	$price = $item->price;
	$url_fnac = $item->url_fnac;
	$date_debut_sortie = $item->date_debut_sortie;
	$date_fin_sortie = $item->date_fin_sortie;
	$street = $item->street;
	$photo = $item->largeImage;
	$genre = $item->merchantCategoryPath;
	
	$type  = array(  // Spectacle
						'POP|Pop-rock/Folk ' => 11, '12P|Pop-Rock/Musique électronique' => 18, '1MC|Musique/Concerts' => 11,
						);

	foreach ($type as $k => $v) {
}
	

	// On fait un explode afin de récupérer ce qu'il nous interesse
	$postcode  = $item->extra2;
	$pieces = explode(" ", $postcode);

	// On attribut le département en fonction des 2 premiers chiffre du code postal
	$departement = substr($postcode, 0, 2);
	
	$region = regionIdByDepartement($departement);
	
	// Attribution de la valeur id 99 pour la fnac
	$id_simply_user = '99';
	
	// On valide la sortie par default
	$valide = '1';
	
	
	// Insertion des sorties
	$req = $bdd->prepare('INSERT INTO simply_user (id_simply_user,titre,price,photo,url_fnac,date_debut_sortie,date_fin_sortie,street,postcode,city,id_region,id_departements,id_type_loisirs,valide) VALUES (:id_simply_user,:titre,:price,:photo,:url_fnac,:date_debut_sortie,:date_fin_sortie,:street,:postcode,:city,:id_region,:id_departements,:id_type_loisirs,:valide)');
	$req->execute(array(
					  'id_simply_user'=>$id_simply_user,
					  'titre'=>$titre,
					  'price'=>$price,
					  'photo'=>$photo,
					  'url_fnac'=>$url_fnac,
					  'date_debut_sortie'=>$date_debut_sortie,
					  'date_fin_ssrtie'=>$date_fin_sortie,
					  'street'=>$street,
					  'postcode'=>$pieces[0],
					  'city'=>$pieces[1],
					  'id_region'=>$region,
					  'id_departements'=>$departement,
					  'id_type_loisirs'=>$type,
					  'valide'=>$valide
					  
	)) or die('Problème lors de l\'insertion');
  
 
}
 
?>

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

16 juin 2015, 16:55

Pour ton erreur, c'est à priori une faute de frappe : 'date_fin_ssrtie'=>$date_fin_sortie,

Et oui, le fait de passer par les requête préparées de PDO va avoir pour effet de protéger tes variables et donc d'échapper les apostrophes éventuelles qu'elles contiennent :)

Par contre pour optimiser les performances, tu devrais du coup sortir la préparation de la requête du foreach. En effet, l'avantage de PDO, c'est que tu prépares ta requête une fois et ensuite tu boucles seulement sur les valeurs à injecter :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Avatar du membre
Mammouth du PHP | 1609 Messages

16 juin 2015, 16:59

Salut, j'ai pas l'habitude de PDO mais d'après les exemples dans la doc, dans le tableau passé à $req->execute() les index devraient commencer par : comme dans la requête.

EDIT
D'après certains commentaires il semblerait que le préfixe (:) soit facultatif ?
Développeur web depuis + de 20 ans