PHP7 et GROUP BY

Résolu/Fermé
arthezius Messages postés 3538 Date d'inscription jeudi 15 mai 2008 Statut Membre Dernière intervention 11 septembre 2016 - 11 sept. 2016 à 01:27
arthezius Messages postés 3538 Date d'inscription jeudi 15 mai 2008 Statut Membre Dernière intervention 11 septembre 2016 - 11 sept. 2016 à 05:18
Bonjour à toutes et tous,

Après une mise à jour de mon Linux, je me retrouve sur PHP7.
Toutes les fonctions mysql_*** ne fonctionnant plus, je migre le tout vers PDO.

J'ai remarqué toutefois un fonctionnement différent de GROUP BY.

Voici une requête qui fonctionne très bien en PHP5 et qui ne réagit plus pareil avec PHP7.
$req = $bdd->prepare('SELECT * FROM table WHERE type="cmd" AND date>? GROUP BY produc');
$req->execute(array('2016-09-11'));
$nb0 = $req->rowCount();
echo $nb0;


Sur un serveur en PHP5 avec les même données, j'obtiens 8 sur l'echo de fin.
Sur un serveur en PHP7, le même code et les même données me donne 0.
Quand je vire le GROUP BY, j'obtiens 12 sur les deux serveurs.
Il semble donc que le version de PHP (ou de MySQL d'ailleurs) soit en cause.

Une idée?
Merci par avance.


1 réponse

jordane45 Messages postés 38427 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 17 février 2025 4 735
11 sept. 2016 à 02:33
Bonjour,

Le souci ne vient, à mon avis, pas du GROUP BY.
(qui au passage est une instruction sql... et n'a rien à voir avec la version de php utilisée....).
Le problème c'est que des gens utilisent la fonction rowCount(); sans en avoir regardé la notice d'utilisation ! https://www.php.net/manual/fr/pdostatement.rowcount.php

On n'y li clairement :

Si la dernière requête SQL exécutée par l'objet PDOStatement associé est une requête de type SELECT, quelques bases de données retourneront le nombre de lignes retournées par cette requête. Néanmoins, ce comportement n'est pas garanti pour toutes les bases de données et ne devrait pas être exécuté pour des applications portables.


Pense également à séparer les variables (la requête et les datas) de l'exécution de la requête. Cela permet d'en faire des echo si besoin.

Il faut également activer la gestion des erreurs PDO et utiliser, pour chaque requête, un bloc try/catch.


Voici à quoi devrait ressembler ton code :
//on prepare la requete et les variables associées
$sql = "SELECT * 
            FROM table 
            WHERE type='cmd' 
            AND date>? 
            GROUP BY produc";
$datas = array('2016-09-11');
//on exécute la requete
try{
  $req = $bdd->prepare($sql);
  $req->execute($datas);
   //on stocke le résultat dans un array
  $result = $req->fetchAll()
}catch(Exception $e){
  echo "<br>Erreur dans la requete :".$sql."<br><pre>";
  print_r($datas);
  echo "</pre><br>".$e->getMessage();
}
//affichage du résultat :
$nb0 = count($result);
echo "<br>il y a $nb0 resultats";
echo "<br> Qui sont :<pre>";
print_r($result):
echo "</pre>";


0
jordane45 Messages postés 38427 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 17 février 2025 4 735
11 sept. 2016 à 02:34
0
arthezius Messages postés 3538 Date d'inscription jeudi 15 mai 2008 Statut Membre Dernière intervention 11 septembre 2016 475
11 sept. 2016 à 05:12
Merci pour tes conseils qui me seront utile.
Je me rend compte que j'ai encore peu sur PDO finalement.

J'ai activé les erreurs comme tu l'indiques et j'ai trouvé le source du problème.
J'ai ce message d'erreur:
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'base.table.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
Notice: Undefined variable: result in /var/www/amap/test.php on line 47

J'ai donc modifié le code comme suis:
$sql = 'SELECT produc
	FROM table 
	WHERE type="cmd" 
	AND date>?
	GROUP BY produc';
$datas = array('2016-09-11');
//on exécute la requete
try{
	$req = $bdd->prepare($sql);
	$req->execute($datas);
	//on stocke le résultat dans un array
	$result = $req->fetchAll();
	}
catch(Exception $e)
	{
	echo "<br>Erreur dans la requete :".$sql."<br><pre>";
	print_r($datas);
	echo "</pre><br>".$e->getMessage();
	}
//affichage du résultat :
$nb0 = count($result);
echo "<br>il y a $nb0 resultats";
echo "<br> Qui sont :<pre>";
print_r($result);
echo "</pre>";

J'ai bien mes résultats.
Il semble que PHP7 ou MySQL impose maintenant qu'on mette derrière le SELECT la colonne correspondant au GROUP BY
Ça fonctionnait malgré tout avant. Peut-être que ça vient de la config.

Bref, merci encore!
0
arthezius Messages postés 3538 Date d'inscription jeudi 15 mai 2008 Statut Membre Dernière intervention 11 septembre 2016 475
11 sept. 2016 à 05:18
Après une petite recherche, il semblerai que ça vienne bien de la config de MySQL 5.7 et du mode sql_mode (info qu'on retrouve bien dans mon message d'erreur).

J'ai fais quelques test et en rajoutant juste avant:
$req = $bdd->query('SET sql_mode=""');
$req->execute(array());

ça fonctionne avec mon script de départ.
0