Page 1 sur 1

Fonction à comprendre !

Posté : 27 avr. 2011, 11:15
par Jonathan
Bonjour,

Je suis nouveau sur ce forum, et espère trouver de l'aide à mon problème auprès de vous.
Novice en PHP, mon entreprise m'a donné un travail : comprendre (et modifier pour que ça marche !) ce qu'à codé un précédent employé. Je me débrouille, tant bien que mal, mais je bloque à un niveau : la compréhension de cette fonction. Elle ne fonctionne pas, le navigateur me retourne l'erreur "Erreur SQL ! Query est vide".
Pourriez-vous m'éclairer ? :?

Code : Tout sélectionner

function SupprimerLigne($NomTable,$ClefPrimaire){ $ExplodeClefPrimaire = explode(" ", $ClefPrimaire); $Sql = 'Delete from '.$NomTable.' where'; $i = 0; while ($i < count($ExplodeClefPrimaire)-1){ $Sql .= ' '.$ExplodeClefPrimaire[$i].' = "'.$ExplodeClefPrimaire[$i+1].'" and'; $i = $i + 2; } $Sql = substr($Sql, 0, strrpos($Sql, "and")); $Req = mysql_query($Sql) or die('Erreur SQL !<br>'.$Sql.'<br>'.mysql_error()); $ExplodeURL = explode("&supprimer", url_actuelle()); /*echo "<script language='javascript'>document.location=$ExplodeURL[0]</script>"; */ echo '<meta http-equiv="Refresh" content="0;URL='.$ExplodeURL[0].'">'; }

Re: Fonction à comprendre !

Posté : 27 avr. 2011, 11:39
par Mazarini
Bonjour,

A mon avis le second paramètre de la fonction est sensé contenir une chaine de type "cle1 12 cle2 34
L'explode permet d'avoir un tableau (cle1,12,cle2,34)
On complete l'instruction SQL avec cle1 = '12' and cle2 = '34' and via une boucle
On supprime le dernier and

Ton problème provient surement d'une mauvaise alimentation du second paramètre. Le tableau est vide et il n'y a pas de and à la fin.
strrpos($Sql, "and") retourne 0
et donc $Sql = substr($Sql, 0, strrpos($Sql, "and")); retourne une chaine vide

Il faut donc que tu retrouve l'appel à cette fonction et que tu vérifie les paramètres

Re: Fonction à comprendre !

Posté : 27 avr. 2011, 12:25
par Jonathan
Bonjour Mazarini, et merci pour ta réponse rapide.
Mais malgré tes explications, je n'arrive pas à y voir clair. Le seul endroit où il y a un appel à cette fonction, c'est ici :

Code : Tout sélectionner

if(isset($_GET['supprimer'])){ $Table->SupprimerLigne($NomTable,$_GET['supprimer']); }
Désolé, je suis vraiment débutant dans le domaine...

Re: Fonction à comprendre !

Posté : 27 avr. 2011, 13:58
par Mazarini
Bonjour,

Et que contiennent les variables $NomTable et $_GET['supprimer']
echo 'NomTable = "',$NomTable,'"<br>";
echo 'GET['supprimer'] = "',$_GET['supprimer'] ,'"<br>";

Quelques explication de ton script :
function SupprimerLigne($NomTable,$ClefPrimaire){
      $ExplodeClefPrimaire = explode(" ", $ClefPrimaire);  // transforme $ClefPrimaire en un tableau en se basant sur les blancs comme séparateur
      $Sql = 'Delete from '.$NomTable.' where';
      $i = 0;
      while ($i < count($ExplodeClefPrimaire)-1){       // boucle sur les élément du tableau en commencant à 0, puis 2 puis 4.... cf $i = £i +2 plus bas
         $Sql .= ' '.$ExplodeClefPrimaire[$i].' = "'.$ExplodeClefPrimaire[$i+1].'" and';     // alimentation de la clause where à partir de 2 éléments successifs du tableau  avec and à la fin
         $i = $i + 2;
      }

      $Sql = substr($Sql, 0, strrpos($Sql, "and"));    // suppression du dernier and ajouter en plus par la boucle (pb si le tableau $ExplodeClefPrimaire est vide ce qui doit être le cas)

      $Req = mysql_query($Sql) or die('Erreur SQL !<br>'.$Sql.'<br>'.mysql_error());  // execution du delete

      $ExplodeURL =  explode("&supprimer", url_actuelle());

      /*echo "<script language='javascript'>document.location=$ExplodeURL[0]</script>"; */

      echo '<meta http-equiv="Refresh" content="0;URL='.$ExplodeURL[0].'">';

   }

re:Fonction à comprendre !

Posté : 27 avr. 2011, 14:44
par Jonathan
Pour echo NomTable; , ça me retourne un résultat.
Mais quand il s'agit de echo ($_GET['supprimer']); , ça cloche, et j'obtiens le message d'erreur suivant :

"Notice: Undefined index: supprimer in C:\Program Files\EasyPHP-5.3.5.0\www\Site Actuel\centre-solutions\csc_formation.php on line 294"


Si le problème vient du tableau $ExplodeClefPrimaire, comment puis-je y remédier ?
Excuse mon ignorance... Et merci beaucoup de prendre du temps sur mon pauvre cas...

Re: Fonction à comprendre !

Posté : 27 avr. 2011, 16:21
par Mazarini
if(isset($_GET['supprimer'])){

     il faut mettre les echos ici

               $Table->SupprimerLigne($NomTable,$_GET['supprimer']);
            }
normalement, pas de message d'erreur.

En fait, je pense que $_GET['supprimer'] doit contenir le nom d'une colonne de la table $Nomtable suivi d'un blanc et d'une valeur de cette colonne. Cette valeur peut venir d'un formulaire que tu valide ou d'un lien que tu active juste avant le problème.
Regarde donc la page précédent le plantage pour retrouver l'origine du $_GET['supprimer']

Vue que ca doit être du "get" tu dois avoir http://domaine.com/centre-solutions/csc ... supprimer=[/b]quelquechose dans l'adresse lors du plantage.

Re: Fonction à comprendre !

Posté : 27 avr. 2011, 16:58
par Jonathan
D'accord, alors en mettant les echo au bon endroit, j'obtiens des choses différentes.

-Pour echo $NomTable; , j'obtiens ce message d'erreur :

"Nom de ma table
Erreur SQL ! Query est vide"




-Pour echo ($_GET['supprimer']); , j'obtiens ce message d'erreur :

"Ereur SQL ! Query est vide"





Lors du plantage, il n'y a que "http://domaine.com/centre-solutions/csc ... supprimer=" dans la barre d'adresse, et rien après... :?

Re: Fonction à comprendre !

Posté : 27 avr. 2011, 17:03
par xTG
Donc ton script appelle l'url sans renseigner la valeur supprimer.
Il ne sait donc pas quoi supprimer...
Commences déjà par remplacer dans le if la fonction isSet par !empty ainsi tu ne tomberas plus sur cette erreur loufoque... (Beh oui on demande une suppression mais on dit pas de quoi...)

Donc le problème provient de ce qui t'amène à cette page. Un lien ? Un bouton ?
Quelque soit cet élément son url de destination est mal renseignée (oubli de la valeur de supprimer).

Re: Fonction à comprendre !

Posté : 27 avr. 2011, 17:14
par Mazarini
Désolé, je ne suis plus dispo

Il faut que tu cherche d'ou viens "http://domaine.com/centre-solutions/csc ... supprimer=" pour comprendre pourquoi il n'y a rien après "supprimer=". Ca viens de la page juste avant le plantage.

Pour xTG :
le script attends une valeur genre "cle valeur" pour supprimer.
Via un explode sur " ", il ajoute "cle = 'valeur' and" à du SQL
ensuite il recherche le dernier "and" avec strrpos pour tronquer la requete et fais un substr($sql,0,0) => requete vite car pas de "and"

Re: Fonction à comprendre !

Posté : 27 avr. 2011, 17:30
par Jonathan
Bonjour xTG, merci de t'intéresser à mon problème.
J'ai fait le changement de IsSet à !empty dans le if, et ai cherché ce qui m'amène cette page. En fait il y a un lien J'ai trouvé ce qui suit. Est-ce convenable ? Ou ça n'a rien à voir ?...

echo '<td><a href= '.$ExplodeURL[0].'&supprimer='.$ClefPrimaire.'><img src="../images/delete.png" alt="supprimer"></a></td></tr>';		

			$CptCss = $CptCss + 1;

Si je suis à côté de la plaque, et si vous avez le temps/courage pour voir ça, voici une plus grande partie du code (fait et commenté par l'ancien employé) :
$CptCss = 0;

		while ($Row = mysql_fetch_array($Req, MYSQL_NUM)){

			echo '<tr align="center">';

			$ClefPrimaire = '';

			for($i = 0; $i < count($this->Fields); $i++){

				//On recherche les champs qui sont clef primaires

				$Meta = mysql_fetch_field($Req, $i);

				//Permettra de ne pas afficher les auto-increments

				$Flags = mysql_field_flags($Req, $i);

				if ($Meta->primary_key == 1){

					$ClefPrimaire .= $Meta->name.'+'.$Row[$i].'+';

				}

				//Cas d'une clef étrangère

				$Sql2 = '';

				if (substr($Meta->name, 0, 3) == 'FK_'){

					$Sql2 = ExplodeChampAfficher($Meta->name);

					$Sql3 = 'Select * from '.substr($Sql2,strrpos($Sql2," "),strlen($Sql2)-1).' limit 1,1';

					$Req3 = mysql_query($Sql3) or die('Erreur SQL !<br>'.$Sql3.'<br>'.mysql_error());

					$TotalFields3 = mysql_num_fields($Req3);

					for($i3 = 0; $i3 <= $TotalFields3 - 1; $i3++) {

						$Meta3 = mysql_fetch_field($Req3, $i3);

						if ($Meta3->primary_key == 1){

							$Sql2 .= ' where '.$Meta3->name.' = "'.$Row[$i].'"';

						}

					}

					mysql_free_result($Req3);

			

					$Req2 = mysql_query($Sql2) or die('Erreur SQL !<br>'.$Sql2.'<br>'.mysql_error());

					$Row2 = mysql_fetch_assoc($Req2);

					if ($CptCss%2 == 0){

						if (strpos($Flags, 'auto_increment') === false){

							echo '<td class="default">'.$Row2['concatenation'].'</td>';

						}

					}

					else{

						if (strpos($Flags, 'auto_increment') === false){

							echo '<td class="alt">'.$Row2['concatenation'].'</td>';

						}

					}	

					mysql_free_result($Req2);

				}

				else{

					if ($CptCss%2 == 0){ 

						if (strpos($Flags, 'auto_increment') === false){

							echo '<td class="default">'.$Row[$i].'</td>';

						}

					}

					else{

						if (strpos($Flags, 'auto_increment') === false){

							echo '<td class="alt">'.$Row[$i].'</td>';

						}

					}

				}	

			}

			echo '<td><a href= '.$ExplodeURL[0].'&modifier='.$ClefPrimaire.'><img src="../images/modifier.png" alt="modifier"></a>
				  <a href= '.$ExplodeURL[0].'&supprimer='.$ClefPrimaire.'><img src="../images/delete.png" alt="supprimer"></a></td></tr>';		

			$CptCss = $CptCss + 1;

		}

		echo '</table>';

		mysql_free_result($Req);

	}
(Evidemment, "modifier" ne marche pas non plus. Je vous demandais de l'aide uniquement pour le "supprimer", pensant m'en sortir ensuite pour le "modifier"...)

Re: Fonction à comprendre !

Posté : 28 avr. 2011, 08:09
par Mazarini
Bonjour,

Est ce que l'appli fonctionne sur d'autres tables ?
Quelle est le but de cette appli ?
Y a t'il eu des modifications de la base de donnée ?

D'après ce que je peux voir, le plus simple est de mettre une clé primaire sur la table et ca devrait marcher. Eventuellement si l'appli ne fait que de la gestion de tables sans contrôle, son remplacement peut être fait par phpmyadmin.

Re: Fonction à comprendre !

Posté : 28 avr. 2011, 10:47
par Jonathan
Bonjour,

En fait c'est une page du site internet de l'entreprise, mais je ne peux pas travailler directement sur leur serveur, donc je dois travailler en local. Ainsi, j'ai du prendre la base de données et la transférer, et j'ai aussi procédé à quelques modifications de la base de données, notamment au niveau du nom des tables (certaines comportaient des "$", et ça se mélangeait avec les variables).

Le but de cette appli est le suivant :
Si on est logué en tant qu'admin, on affiche un menu de gestion des tables. Ca, ça marche.
Ensuite, on doit pouvoir ajouter un champ à une table, en cliquant sur un bouton "ajouter". Ca, ça marche à peu près, mais pour le moment ce n'est pas le problème.
Enfin, on doit pouvoir modifier un champ en cliquant sur "modifier", ou supprimer un champ, en cliquant sur "supprimer". J'ai bien les deux boutons "modifier" et "supprimer", mais en cliquant dessus, Erreur SQL, comme signalé dans les posts précédents.

Note : Pour chaque table, le bouton "ajouter" fonctionne, mais au contraire, les boutons "modifier" et "supprimer" ne fonctionnent jamais.

Re: Fonction à comprendre !

Posté : 28 avr. 2011, 11:03
par Jonathan
C'est bon ! Tu avais raison Mazarini, les clés primaires n'étaient jamais définies dans les tables ! Une fois définies, il y avait quelque chose après le "=" dans l'adresse, et mieux encore, ça fonctionnait !
Problème résolu, un grand merci à vous deux, Mazarini et xTG.
A très bientôt, je reviendrai sûrement demander votre aide.

Re: Fonction à comprendre !

Posté : 28 avr. 2011, 11:30
par Mazarini
A mon avis, s'il n'y a pas de contrôles sur les valeurs ou sur les liens, phpmyadmin qui est très largement utilisé par les hébergeurs devrait remplacer ton application et être beaucoup plus fiable. D'ailleurs je soupçonne le code que tu as d'en être inspiré mais la flemme de regarder.

phpmyadmin s'installe généralement automatiquement avec les outils wamp (easyphp, wampserver...) sous windows et est présent dans les distributions linux.

Re: Fonction à comprendre !

Posté : 28 avr. 2011, 11:51
par Jonathan
Oui, mais ils veulent absolument un menu de gestion des tables sur la page en question, et pas passer par PHPMyAdmin, ce qui serait en effet largement plus simple et plus fiable. Qu'ils se débrouillent avec ça hein !
Merci encore...


(Comment fait-on pour marquer "résolu" sur le titre du topic ? Je crois que je ne peux pas le faire, car quand j'ai ouvert le topic, je n'étais pas inscrit sur le forum...)