comment boucler une condition avec une chaine explosée

Eléphant du PHP | 115 Messages

03 sept. 2008, 17:21

Bonjour,

Je cherche le moyen de transformer une chaine de caractère séparée par des ";" du type :
$chaine = ;23;51;42;...;
en une suite de condition if reprenant chaque valeur entre les ";" pour arriver à :
if((ereg("23",$code)) || (ereg("51",$code)) || (ereg("42",$code)) || ...){
     echo "ok";
}
Pour l'instant, j'arrive à récupérer chaque valeur à l'intérieure des ";" en faisant :
$tab = split(';', $chaine);
foreach($tab as $elem) {
	...
}
mais je ne vois pas comment arriver a créer le code final avec les if et surtout l'interprêter correctement.

Pourriez vous éclairer ma lanterne svp ? :D
Quelques réalisations www.cdi-interactiv.com

Eléphant du PHP | 169 Messages

03 sept. 2008, 17:53

Si au lieu de ereg tu utilises in_array ca va pas mieux ?

Ca te donnera un truc du genre :
if((in_array("23",$tab)) || (in_array("51",$tab)) || (in_array("42",$tab)) || ...){ 
     echo "ok"; 
}

Toujours en utilisant ton
$tab = split(';', $chaine); 
foreach($tab as $elem) { 
    ... 
}

Eléphant du PHP | 115 Messages

04 sept. 2008, 08:56

merci _activmik, mais mon soucis n'est pas là.

C'est plutôt comment insérer mes valeurs explosées dans une boucle if, générée automatiquement en fonction de la longueur de la chaine $chaine.
Ex: Si $chaine = ;12;56;89;78; créer :

Code : Tout sélectionner

$code_a_interpreter="if((ereg('12',$code)) || (ereg('56',$code)) || (ereg('89',$code)) || (ereg('78',$code)))";
avec quelque chose comme :
$final="";
$tab = split(';', $chaine);
foreach($tab as $elem) {
	$final .="(ereg('$elem',$code)) || ";
}
// rajouter une fonction pour enlever les deux || à la fin

$code_a_interpreter="if($final)"
et mon gros soucis interpréter $code_a_interpreter !
Quelques réalisations www.cdi-interactiv.com

Eléphanteau du PHP | 38 Messages

05 sept. 2008, 06:32

Pour interpréter du code dans une chaine de caractère, y a la fonction eval()
<?php

$chaine = '27;53;45';
$tab = explode(';', $chaine);

$code = 'if (';
for ($i = 0, $count = count($tab); $i < $count; $i++) {
   $code .= 'preg_match(\'#' . $tab[$i] . '#\', $chaine)';
   
   /* Si on n'est pas à la dernière itération */
   if ($i != ($count - 1))
      $code .= ' || ';
}

$code .= ') { echo \'ok\'; }';

eval($code);

Eléphant du PHP | 115 Messages

05 sept. 2008, 16:05

Parfait!

Merci beaucoup!
Quelques réalisations www.cdi-interactiv.com

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

05 sept. 2008, 17:08

Modération :
toony.m, si ta question est résolue, pense à ajouter le tag [Résolu]
pour indiquer aux personnes qui voudront consulter ce sujet qu'il contient une solution.
Tu peux réaliser cette opération en cliquant sur le bouton Image en haut à gauche de ce sujet.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

05 sept. 2008, 17:14

Et sinon, tester au fur et à mesure ?
<?php 

$chaine = '27;53;45'; 
$tab = explode(';', $chaine); 

// Tant qu'un test n'est pas positif, le résultat global est négatif
$result = false;

foreach($tab as $code)
{
  // Si le test courant est positif
  if( preg_match('#' . $tab[$i] . '#', $chaine);
  {
    // On mémorise que le test est positif (au moins une valeur match)
    $result = true;
    // On arrete l'exécution du foreach (pas la peine de continuer, on sais que le résultat final est true)
    break;
  }
}

// Si le résultat est true
if( $result === true )
  echo 'ok'
Non seulement on évite le eval(), qui est un gouffre à performance et une potentielle faille de sécurité, mais on optimise le traitement en ne bouclant que le nombre nécessaire d'occurence.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

05 sept. 2008, 19:02

Qui dit mieux ?

Bien sur il y a cette autre méthode :
<?php
    //Chaine d'origine 
    $chaine = '27;53;45';  

    //Remplacer par | (l'opérateur OU)
    $chaine = str_replace(";", "|", $chaine);

    //Test par expression régulière
    if ( preg_match("#$chaine#", $code) ) echo "Ok"; else echo "Pas Ok!";
?>
ça donne un test de type :

Code : Tout sélectionner

if ( preg_match("#27|53|45#", $code) ) echo "Ok"; else echo "Pas Ok!";
qui veut dire : est ce que $code est = 27 ou 53 ou 45

voici l'écriture simplifiée :
<?php
    //Test par expression régulière
    if ( preg_match(str_replace(";", "|", $chaine) , $code) ) echo "Ok"; else echo "Pas Ok!";
?>
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

05 sept. 2008, 19:56

Bien joué sadeq.

Effectivement, j'y avais pas pensé ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphanteau du PHP | 38 Messages

06 sept. 2008, 00:10

Bien vu (pour les deux méthodes), vaut mieux éviter le eval()