2014-05-21 12 views
7

Jaka jest różnica między dwoma. oba te działają dokładnie w ten sam sposób.PHP: ReflectionParameter, isOptional vs isDefaultValueAvailable

public static function getArgsArray($reflectionMethod,$argArray){ 
    $arr = array(); 
    foreach($reflectionMethod->getParameters() as $key => $val){ 
     $arr[$val->getName()] = isset($argArray[$val->getName()]) ? 
     $argArray[$val->getName()] : (isset($_REQUEST[$val->getName()]) 
       ? $_REQUEST[$val->getName()] : ($val->*isDefaultValueAvailable()* ? $val->getDefaultValue() : NULL)); 
    } 
    return $arr; 
} 
+1

Bądź bardzo ostrożny z tych stwierdzeń zagnieżdżonych trójskładnikowych. Nic tylko kłopoty IMHO – Phil

+0

Masz jakiś przykład, że się nie udaje? Deklaracje trójstronne? – LNT

+2

Są po prostu trudne do odczytania, a proces logiczny nie zawsze jest jasny. Zobacz notatkę tutaj ~ http://php.net/manual/language.operators.comparison.php#example-137 – Phil

Odpowiedz

7

Dobre pytanie. Rozważmy następujący przykład

function foo($foo = 'foo', $bar) {} 

parametru $foo, isDefaultValueAvailable() byłoby zrozumiałe powrócić true jednak isOptional() wróci false jako kolejny parametr ($bar) ma wartość domyślną, a zatem nie jest obowiązkowe. Aby obsłużyć nie-opcjonalny parametr $bar, sam musi być nieopcjonalny.

Nadzieja to sens;)

mam zauważyć, że zachowanie różni się w poszczególnych wersjach PHP. 5.5 zwraca powyższe, natomiast 5.4 mówi, że parametr 1 nie jest opcjonalny i nie ma wartości domyślnej.

+0

Masz na myśli, w twoim przykładzie, $ foo = 'foo' będzie miało sens, jeśli nazwałbym to jak ten foo (null, 'hello'), ale nie foo ('helllo') – LNT

+1

@LNT Cóż, po prostu ustawi '$ foo' na' null'. To głupi sposób na napisanie funkcji, ale nie jest to niemożliwe, dlatego narzędzia do refleksji muszą różnicować – Phil

4

Funkcja isDefaultValueAvailable może pracować tylko na funkcje zdefiniowane przez użytkownika, a nie działa na funkcje systemu (rdzeń PZP).

Tak, jak przykładowo:

class Foo 
{ 
    public function foo($var = null) 
    { 
    } 
} 

// Get the "var" argument in method Foo::foo 
$refParameter = (new ReflectionClass('Foo'))->getMethod('foo')->getParameters()[0]; 

print "User function Foo::foo:\n\n"; 

print 'Optional: ' . ($refParameter->isOptional() ? 'true' : 'false') . "\n"; 
print 'Default available: ' . ($refParameter->isDefaultValueAvailable() ? 'true' : 'false') . "\n"; 
if ($refParameter->isDefaultValueAvailable()) { 
    print 'Default value: ' . var_export($refParameter->getDefaultValue(), 1); 
} 

print "\n\n"; 

print "System function substr\n\n"; 

// Get the "length" parameter from function substr 
$refParameter = (new \ReflectionFunction('substr'))->getParameters()[2]; 

print 'Optional: ' . ($refParameter->isOptional() ? 'true' : 'false') . "\n"; 
print 'Default available: ' . ($refParameter->isDefaultValueAvailable() ? 'true' : 'false') . "\n"; 
if ($refParameter->isDefaultValueAvailable()) { 
    print 'Default value: ' . var_export($refParameter->getDefaultValue(), 1); 
} 

print "\n\n"; 

, a ten kod: twój może uzyskać wartość domyślną tylko z funkcji zdefiniowanej przez użytkownika i nie mogą dostać od funkcji systemu (substr jako przykład). Ale metoda zwróciła w funkcji zdefiniowanej przez użytkownika i funkcji systemu.

Wniosek:

  • Jeśli chcesz sprawdzić swój parametr jest opcjonalny, musi wykorzystać swoje isOptional metody.
  • Możesz pobrać domyślną wartość tylko z funkcji zdefiniowanej przez użytkownika.
  • Nie można użyć metody isDefaultValueAvailable dla zdefiniowanej funkcji systemowej (PHP).

Źródło: https://github.com/php/php-src/blob/ccf863c8ce7e746948fb060d515960492c41ed27/ext/reflection/php_reflection.c#L2536-L2573

+1

Dzięki, rozumiesz, używam go tylko do definiowania przez użytkownika fucntions – LNT