PHP dinamik Karşılaştırma Operatörleri

6 Cevap php

Bunu bir işleve değişkenler olarak karşılaştırma operatörleri geçmek için, herhangi bir şekilde, mümkün mü? Ben örneğin, bazı konfor fonksiyonlarını üreten bakıyorum (ve ben bu işe yaramaz biliyorum):

function isAnd($var, $value, $operator = '==')
{
    if(isset($var) && $var $operator $value)
        return true;
}

if(isAnd(1, 1, '===')) echo 'worked';

Şimdiden teşekkürler.

6 Cevap

Nasıl küçük bir sınıfı hakkında:

class compare
{
  function is($op1,$op2,$c)
  {
     $meth = array('===' => 'type_equal', '<' => 'less_than');
     if($method = $meth[$c]) {
        return $this->$method($op1,$op2);
     }
     return null; // or throw excp.
  }
  function type_equal($op1,$op2)
  {
      return $op1 === $op2;
  }
  function less_than($op1,$op2)
  {
      return $op1 < $op2;
  }
}

Eğer üçüncü argüman olarak karşılaştırma için kullanılacak operatörü iletebilirsiniz olarak da, version_compare() işlevini kullanabilirsiniz.

Bu nasıl?

function num_cond ($var1, $op, $var2) {

    switch ($op) {
        case "=":  return $var1 == $var2;
        case "!=": return $var1 != $var2;
        case ">=": return $var1 >= $var2;
        case "<=": return $var1 <= $var2;
        case ">":  return $var1 >  $var2;
        case "<":  return $var1 <  $var2;
    default:       return true;
    }   
}

Testi:

$ops = array( "=", "!=", ">=", "<=", ">", "<" );
$v1 = 1; $v2 = 5;

foreach ($ops as $op) {
    if (num_cond($v1, $op, $v2)) echo "True  ($v1 $op $v2)\n"; else echo "False ($v1 $op $v2)\n";
}

Kesinlikle ısrar ederseniz eval kullanabilirsiniz.

if(isset($var) && eval("return \$var $operator \$value"))
    return true;

Ama ben bunu tavsiye etmem.

Büyük sorun bu fonksiyon oldukça anlamsız olmasıdır. En gerçek bir (varsayımsal) çalışma örneği ile değiştirin edelim:

function isAnd($var, $value, $operator = '==') {
    return isset($var) && $var $operator $value;
}

isAnd($foo, 1, '===');

Bu örnekte $foo ayarlı değil. Bir fonksiyona ($foo) varolmayan bir değişken geçmek için çalışıyoruz çünkü bir hata alırsınız (isAnd). Yani, isset before çağırmak için $foo test etmek gerekir isAnd olacak:

isset($foo) && isAnd($foo, 1, '===');

Yani, hiç isAnd fonksiyonunu giren herhangi bir değişken kesinlikle ayarlanır. Sen işlev içinde bunun için test etmek gerekmez. Yani tüm egzersiz oldukça anlamsızdır.

Ne kafa karıştırıcı olabilir ki isset() ve hata olmadan onlara varolmayan bir değişken geçirebilirsiniz yani empty(), bu sınırlama yoktur. Şey özel dil yapıları (; PHP suçlama fonksiyonları gibi bakmak olur) demektir, bu normal fonksiyonlarını değil, olsa. Ne yazık ki you yapıları bu tür yapamaz, senin işlevleri için parametreler her zaman bulunması gerekir.

Sadece yazmaya alışmalıyız isset($foo) && $foo === 1. Düzgün yapılandırılmış kod ile, her zaman yine de iyi bir uygulama olduğu, kullanmak için gidiyoruz tüm değişkenleri bildirerek az bu azaltabilir.

Dinamik operatörü için ... Yine de kullanmak için hangi operatör karar if ... else yerde çeşit gerekir. Bunun yerine operatör değişken ayarlama ve sonra değerlendirilmesi, orada doğru bir değerlendirme yapmak daha kolay değil mi?

Michael Krelin anlaşılacağı gibi eval kullanabilirsiniz - ama bu potansiyel kod enjeksiyon saldırılarına bir sürü sağlar.

Bir operatör için bir değişken yerine değil - ama bir fonksiyon için bir değişken yerine kullanabilirsiniz:

function is_equal($a, $b) {
  return $a==$b;
} 
function is_same($a, $b) {
  return $a===$b;
}
function is_greater_than($a, $b)
....

$compare='is_equal';
if ($compare($a, $b)) {
   ....

C.