Page 1 sur 1

Simplification de condition

Posté : 21 févr. 2011, 12:05
par xTG
Bonjour à toutes et à tous,

j'ai une recherche traitant plusieurs opérateurs, le soucis c'est que tout est typé en String et ce dans plusieurs variables.
J'étais donc parti dans le plus simple mais pas le plus optimisé pour commencer :
if($valeur['op'] == '=' && $val != $valeur['val'])
{
	$trouve = false;
	break;
}
elseif($valeur['op'] == '!=' && $val == $valeur['val'])
{
	$trouve = false;
	break;
}
elseif($valeur['op'] == '>' && $val <= $valeur['val'])
{
	$trouve = false;
	break;
}
elseif($valeur['op'] == '>=' && $val < $valeur['val'])
{
	$trouve = false;
	break;
}
elseif($valeur['op'] == '<' && $val >= $valeur['val'])
{
	$trouve = false;
	break;
}
elseif($valeur['op'] == '<=' && $val > $valeur['val'])
{
	$trouve = false;
	break;
}
PS : les break servent à me couper ma boucle de recherche (que je ne vous ai pas mis).

Mais c'est tiptop, donc je cherchais un truc plus condensé, plus dynamique.
Je me suis donc penché vers eval(), même si je n'aime pas tellement son utilisation à vrai dire...
J'ai donc fait ceci mais qui m'envoie dans les choux :
eval('if(' . $val . ' ' . $valeur['op'] . ' ' . $valeur['val'] . ')
{
	$trouve = false;
	break;
}');
Auriez-vous une idée ? Ou même une meilleure méthode que eval() ?
Un article traitant de recherche ?

Re: Simplification de condition

Posté : 21 févr. 2011, 12:33
par Myrina
Essaies ceci:

Code : Tout sélectionner

$op=array(); $op['=']='!='; $op['!=']='=='; $op['<']='>='; $op['<=']='>'; $op['>']='<='; $op['>=']='<'; foreach ($op as $oper) {     $test='return (5'.$oper.'10);';     $rep=eval($test);     echo $test.' => '.($rep?'ok':'ko').'<br>'; }  

Re: Simplification de condition

Posté : 21 févr. 2011, 12:49
par xTG
Impeccable, avec ce return j'obtiens donc bien ce que je veux.
Merci. :)
if(in_array($valeur['op'],$this->_operateurs))
{
	if( $valeur['op'] == '=')
		$valeur['op'] = "==";
		
	$test='return ('.$val.$valeur['op'].$valeur['val'].');';
	$rep=eval($test);
	if($rep === false)
	{
		$trouve = false;
		break;
	}
}

Re: Simplification de condition

Posté : 21 févr. 2011, 13:37
par Berzemus
Mais c'est horrible, utiliser un eval...

J'opterais pour le switch, à l'intérieur d'une fonction
switch($op)
   {
   case '='  : return $v1 == $v2;
   case '!=' : return $v1 != $v2;
   case '>'  : return $v1 >  $v2;
   //etc...
   }
qui pourrait s'appeler comme ceci:
valide(12,24,'='); // renvoie false
!valide(12,45,'>'); // renvoie true

Re: Simplification de condition

Posté : 21 févr. 2011, 13:48
par xTG
Tu réponds bien plus à mes critères, je porte en horreur la fonction eval(). :)

Si cela intéresse quelqu'un voici donc ce que cela donne :
/*
* Application d'un opérateur
* @param String opérateur
* @param mixed valeur de comparaison (motif pour opérateur like)
* @param mixed valeur à comparer
*/
function op($op,$val1,$val2)
{
	switch($op)
	{
		case '='  : return $v1 == $v2;
		case '!=' : return $v1 != $v2;
		case '>'  : return $v1 >  $v2;
		case '>=' : return $v1 >= $v2;
		case '<' : return $v1 < $v2;
		case '<=' : return $v1 <= $v2;
		case 'like' : return like($v1,$v2);
		default : return false;
	}
  
}

/*
* Emulation de la fonction LIKE de MySQL
* @param String Motif (ex : Je*n%)
* @param String Valeur (ex : Jeanne)
* @return Bool
*/
function like($motif,$val)
{
	if( !is_string($val) )
		$val = (String)$val;
		
	$motif = str_replace("*",".",$motif);
	$motif = str_replace("%","(.*)",$motif);
	$motif = "(" . $motif . ")";
	$like = preg_match('#^'.$motif.'$#',$val);
	$like = ( $like == 1 )? true : false;
		
	return $like;
}
Les opérateurs courant, ainsi qu'une fonction pour l'opérateur LIKE.