2015-01-31 12 views
1

В Slim Framework есть функция protect, которая обертывает вызывающие вызовы внутри функции (т. Е. Другой вызываемой). Описание в the manual говорит:Тонкие защитные вызовы

Что делать, если вы хотите буквально сохранить закрытие в качестве необработанного значения и не вызвать его? Вы можете сделать это так:

$app->myClosure = $app->container->protect(function() {}); 

Глядя в исходный код, я вижу это:

/** 
* Protect closure from being directly invoked 
* @param Closure $callable A closure to keep from being invoked and evaluated 
* @return Closure 
*/ 
public function protect(\Closure $callable) 
{ 
    return function() use ($callable) { 
     return $callable; 
    }; 
} 

Я задаюсь вопросом, что точка это. Здесь я сделал свой собственный тест:

$foo = function() { 
    echo "Hello"; 
}; 

$bar = function() use ($foo) { 
    return $foo; 
}; 

var_dump($foo); 
var_dump($bar); 

Это то, что я получил:

object(Closure)#1 (0) { 
} 
object(Closure)#2 (1) { 
    ["static"]=> 
    array(1) { 
    ["foo"]=> 
    object(Closure)#1 (0) { 
    } 
    } 
} 

Я могу назвать $bar() вернуть отозваны, но почему бы мне делать, если я могу просто использовать $foo? Может кто-нибудь объяснить это цели?

ответ

2

Это все о замыканиях, вызываемых во время выполнения. Точка зрения становится очевидной, когда вам нужно использовать обратный вызов (пропустите закрытие как вызываемый \Closure в другую функцию), не вызывая его немедленно.

Давайте посмотрим, что происходит внутри нашего Slim run.

Так что, если мы просто присвоить замыкание на ресурс, как и

$app->foo = function() { 
    return 'invoked foo returns this string'; 
}; 

или как одноплодной ресурс Slims

$app->container->singleton('foo', function() { 
    return 'invoked foo returns this string'; 
}); 

будет вызван при каждом вызове или на нашем первом вызове это, соответственно ... так

$app->foo; 

возвращает строку invoked foo returns this string.

Предположим, что мы хотим, чтобы другая функция использовала наш вызываемый (как некоторый средний слой) и хочет вызвать его с помощью call_user_function().Таким образом, мы не хотим, чтобы пройти в вызванной функции (которая будет проходить возвращаемое значение), а скорее uninvoked закрытия, который мы достигаем путем присвоения закрытия к переменному/ресурсу с использованием метода protect()

$app->bar = $app->container->protect(function() { 
    return 'bar returns a callable closure'; 
}); 

а для демонстрации давайте перейдем наш $app->foo и $app->bar к call_user_function():

call_user_func($app->foo); 

выдаст ошибку

"call_user_func() expects parameter 1 to be a valid callback, 
function 'invoked foo returns this string' not found or invalid function name" 

, потому что он пытается вызвать возвращенную строку, где

call_user_func($app->bar); 

вызывает закрытие сохраненную в $app->bar и возвращает его возврата строки, например так:

"bar returns a callable closure" 

Я надеюсь, что этот пример иллюстрирует полезность Слима protect() способ.

Смежные вопросы