Simplification de condition

ViPHP
xTG
ViPHP | 7331 Messages

21 févr. 2011, 12:05

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 ?

Eléphanteau du PHP | 12 Messages

21 févr. 2011, 12:33

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>'; }  

ViPHP
xTG
ViPHP | 7331 Messages

21 févr. 2011, 12:49

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;
	}
}

ViPHP
ViPHP | 4039 Messages

21 févr. 2011, 13:37

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
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

ViPHP
xTG
ViPHP | 7331 Messages

21 févr. 2011, 13:48

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.