2017-02-18 4 views
1

Допустим, у меня есть замыкание:Передача переменной закрытия

$object->group(function() { 
    $object->add('example'); 
    $object->add('example'); 
}); 

Это не будет работать, потому что $ объект не определен в замыкании.

Примечание: Undefined переменной: менеджер

Так что я бы use ($object):

$object->group(function() use ($object) { 
    $object->add('example'); 
    $object->add('example'); 
}); 

Теперь я хочу, чтобы держать его так просто, как первый, так как-то объект $ должен быть введен к закрытию.

Laravel Framework делает это с маршрутами, например:

Route::group(['middleware' => 'auth'], function() { 
    Route::get('/', function() { 
     // Uses Auth Middleware 
    }); 

    Route::get('user/profile', function() { 
     // Uses Auth Middleware 
    }); 
}); 

Я считаю, что Laravel делает это с Reflection класса.

Как я мог достичь этого?

+0

Я не вижу абсолютно ничего плохого в 'function() use ($ object)'. С другим подходом нет ничего более чистого. Абсолютно zilch. –

+0

Я просто хочу знать, как это делает Laravel. –

+0

Laravel использует 'static'. Вы используете объекты. –

ответ

0

Ваша цель состоит в том, чтобы знать, как предоставить параметр закрытию. Это достигается с помощью call_user_func_array.

Определим метод в классе, который принимает замыкание.

class MyTestClass 
{ 
    public function doWork(callable $callback) 
    { 
     return call_user_func_array($callback, [$this]); 
    } 
} 

$obj = new MyTestClass(); 

$obj->doWork(function(MyTestClass $obj) { 
    // 
}); 

Примечание: не проверялось, но я беру его, это то, что вы были после?

+0

В этом случае вам все равно нужно установить параметр, правильно? Я хочу сделать это точно так же, как Laravel. Так что каким-то образом зависимость вводится в закрытие. Может быть, контент клонируется и добавляется? Я понятия не имею. –

+0

Я нашел очень уродливый способ сделать это, поэтому я просто решил придерживаться параметров. Что вы можете сделать, так это получить содержание метода, например: http://stackoverflow.com/questions/7026690/reconstruct-get-code-of-php-функция. Затем используйте 'create_function' для создания функции, которая принимает параметр, а затем вводит зависимость. –

+1

У вас может быть переменное количество параметров в вашем закрытии. У вас могут быть параметры с нулевым значением. Если вы хотите набрать хинт против переменного количества параметров, вам, вероятно, придется играть с «Reflection», и это становится уродливым (чтобы проверить, что он ожидает в качестве параметров). Я не думаю, что вам нужно переусердствовать на самом деле :) –

0

Вам не нужно беспокоиться о отражении. Позорный контейнер для инъекций Laravel будет обрабатывать его для вас. Все, что вам нужно, это сказать ему, что вводить, когда class или interface - это тип намека.

// xXxServiceProvider.php 
function register(){ 
    ... 
    this->app->bind('ObjNamespace\ObjClass', function ($app) { 
     return new ObjNamepsace\ObjClass(); 
    }); 
} 

Теперь предположим, что вы хотите в вашем маршруте обрабатывать ObjNamepsace\ObjClass.

Route::get('user/profile', function (ObjNamepsace\ObjClass $object) { 
    // $object is resolved via type hinting 
}); 

Кроме того, есть три обязательных методов, вы можете выбрать один подходит для вашего сценария использования:

  • bind: впрыскивает новый экземпляр при каждом вызове, Laravel создаст новый объект $ каждый раз.

  • singleton: вводит тот же экземпляр, Laravel создает экземпляр при первом вызове и вводит его при каждом необходимости вызова. Используйте его, если вы хотите создать $object один раз.

  • instance: вы связываете class или interface с экземпляром объекта.

+0

Маршруты laravel были примером того, чего я хочу достичь. Этот проект не сделан в Laravel –

+0

Почему Laravels Service Container «печально известен» –

+0

Насколько я знаю, потребление инъекций зависимостей не сильно отличается в рамках каркасов. Эти же принципы применяются повсеместно. – motia

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

  • Нет связанных вопросов^_^