php Slim framework - передача параметра для закрытия

0

Я пытаюсь изучить код для Slim framework. В конструкторе для класса Slim $ c передается в закрытие (например, при сохранении/установке объекта запроса/ответа в контейнере):

 public function __construct(array $userSettings = array())
    {
        // Setup IoC container
        $this->container = new \Slim\Helper\Set();
        $this->container['settings'] = array_merge(static::getDefaultSettings(), $userSettings);

        // Default request
        $this->container->singleton('request', function ($c) {
          return new \Slim\Http\Request($c['environment']);
        });

        // Default response
        $this->container->singleton('response', function ($c) {
          return new \Slim\Http\Response();
        });

Но $ c не определяется/не объявляется нигде до этого утверждения, так как это работает? Я начал прослеживать все с самого начала, и я не могу найти $ c где-нибудь до того, как он будет использоваться таким образом.

Теги:
closures
slim

3 ответа

2

$ c - параметр функции замыкания. Представьте, что у вас есть функция сама по себе:

function myFunction($c) {
    echo $c;
}

В случае закрытия вы можете сохранить анонимную функцию в переменной:

$someFunction = function ($c) {
    echo $c;
}
$someFunction("hello world");

Поэтому вместо прямого хранения замыкания в переменной код выше передает анонимную функцию в качестве параметра для $this-> container-> singleton(). Таким образом, $ c не создается до тех пор, пока не будет вызвано замыкание. Метод singleton сохраняет это в переменной с именем $ value, поэтому, если эта функция работает:

$value(array('environment'=>'test'));

$ c теперь будет содержать массив ('environment' => 'test')

Slim также использует малые методы __get() __set() совсем немного, поэтому из кода примера, который вы установили, в классе Slim можно было бы вызвать:

$request = $this->container->request(array('environment'=>'test'));

Контейнер имеет класс Slim\Helper\Set. Поскольку это не имеет метода запроса, это вызовет метод __get() контейнера. Он будет искать сохраненный метод, сконфигурированный выше для "запроса", и передать массив в виде $ c

  • 0
    Да, я понимаю, что анонимная функция может храниться в переменной. И я также вижу, что анонимная функция передается в качестве параметра в метод singleton. Но я до сих пор не понимаю, откуда берется $ c. Вы говорите, что оно не создано, пока не будет вызвано замыкание ... Итак, когда оно создано, оно приравнивается к чему? Что хранит переменная $ c? Спасибо!
  • 0
    Когда вызывается анонимная функция, тогда присваивается значение $ c. Другими словами, чтобы вызвать замыкание, вам нужно передать ему значение, которое вы хотите присвоить $ c (см. Конец отредактированного ответа)
Показать ещё 1 комментарий
0

$c является ссылкой на сам контейнер, так что любые зависимости будут автоматически разрешены при вызове.

Таким образом, используя, например, объект запроса:

    // Default request
    $this->container->singleton('request', function ($c) {
        return new \Slim\Http\Request($c['environment']);
    });

Посмотрев на конструктор Request вы увидите, что он ожидает экземпляр Environment, который мы только что сказали, что контейнер должен быть уже доступен с помощью ключевой "среды".

0

Я думаю, что хартнетт дал прекрасный ответ. Чтобы сделать это более понятным для вас, пример.

Когда вы определяете функцию, вы описываете, как она работает. Вы не задаете никаких конкретных значений. Например, когда я пишу:

function sum($a, $b) {    
    return $a + $b;
}

Я не говорю, что здесь значения $a и $b. Я просто описываю, что я делаю с этими переменными, чтобы вычислить результат. Пока я не вызываю эту функцию, я работаю с фактическими значениями:

sum(3, 4); // returns 7

В вашем вопросе переменная $c похожа на переменную $a и $b.

Как показал хартнетт в его ответе, он работает следующим образом:

// Definition time
$someFunction = function ($c) {
    echo $c;
}

// Calling time
$someFunction("hello world");

Только время вызова, которое получает значение $c (в этом примере значение "hello world").

Ещё вопросы

Сообщество Overcoder
Наверх
Меню