PHP Force экземпляр Closure, своего рода - PullRequest
4 голосов
/ 15 июля 2011

Цитируя PHP:

В настоящее время анонимные функции реализуются с использованием класса Closure .Это деталь реализации, и на нее не следует полагаться.

Теперь, при этом, следующие проверки считаются ненадежными:

function myFunction(Closure $callback){}

if(!($callback instanceof Closure)){}

, что приводит нас к использованию is_callable(),Это нормально, однако, если для одного требуется истинное " замыкание ", ( в качестве аргумента или что-то такое ), тогда is_callable() не является строгимдовольно.Следующие, конечно, дампы bool(true) для каждого:

function myFunction(){}

class MyClass{
    public function __invoke(){}
}

var_dump(is_callable('myFunction'));
var_dump(is_callable(new MyClass));

Как, не полагаясь на класс Closure ( дано , на самом деле ненадежно )Можно ли строго идентифицировать « замыкание »?


Обновление

Мне пришло в голову, что я падаю в сторону плохого дизайна.Однако, несмотря на ответ на этот вопрос, я думаю, было бы полезно, если бы кто-то мог предложить ответы на поставленный вопрос, если не только для академического элемента этого.

Обновление ( снова )

С момента выпуска PHP 5.4 ( некоторое время назад ) тип Closure больше не является «деталью реализации», и на него можно положиться.function f(Closure $g) { } все хорошо.

Ответы [ 3 ]

6 голосов
/ 07 февраля 2012

Похоже, что разработчики PHP передумали о том, что класс Closure является деталью реализации:

Анонимные функции, реализованные в PHP 5.3, дают объекты этого типа. Этот факт раньше считался деталью реализации, , но теперь на него можно положиться .

См. http://php.net/manual/en/class.closure.php

Следовательно, теперь вы должны считать, что ваши чеки надежны:

function myFunction(Closure $callback){}

if(!($callback instanceof Closure)){}
3 голосов
/ 15 июля 2011

Единственный раз, когда вы должны набирать аргументы, это когда в этом конкретном классе есть что-то, что вам нужно . Даже тогда вам лучше использовать интерфейс. Это просто хороший ООП дизайн.

Я не могу представить себе ситуацию, в которой было бы полезно принуждать что-либо к Замкнутости. Единственное, что должно иметь значение, в этом случае, является ли параметр is_callable или нет. Даже если бы удалось достичь вашей цели, я бы сказал, что это неожиданная функциональность фреймворка и, следовательно, анти-паттерн.

2 голосов
/ 05 октября 2011

Статические / глобальные функции были бы строкой, а вызываемые ООП - массивом ... Так не могли бы вы:

if ( ! is_string( $var ) && ! is_array( $var ) && is_callable( $var ) )

Мне тоже нужны строгие замыкания.Зачем?Мой уровень абстракции БД имеет свои запросы / конфигурации, отделенные от остальной части моего приложения.Я реализовал функции Tier / Shard, где ключ представляет собой БД, которая затем может быть загружена по требованию (или была ранее загружена). Этот ключ может быть, например, «по умолчанию», и если такая функция существует в глобальной области (сомнительно)поскольку я кодирую в основном ООП, я бы не хотел, чтобы он вызывался, а вместо этого использовал бы ключ.

Продолжая приведенный выше код:

{
    $var = $var( $inputs );
}

$ входные значения - это значения, используемые для генерации запроса,позволяя Closure возвращать другой ключ на основе его значений.Следовательно, при правильных методах проектирования теперь возможно использование шардинга.

Конечно, моя ситуация не имеет значения, но я надеюсь, что это может помочь другому.

...