Вызывается по умолчанию в определении функции в php 7 - PullRequest
0 голосов
/ 09 апреля 2019

У меня есть функция с 2 аргументами: строка и вызываемый.Я хочу, чтобы призыв был необязательным.Увидеть ниже.

function saySomething($str, $callback){

    echo $str;

    $res = false;
    if(is_callable($callback)){
        $res = $callback();
    }

    if($res){
        echo ', I am cool';
    } else {
        echo ', I am not cool';
    }
}

// This works as I expect
saySomething('piet');// deliberately not supplying a callback
// I want the output to be: piet, I am not cool.
// The output in this case: "piet, I am not cool."

В php 5.4 и php 7 можно объявить / напечатать подсказку, вызываемую в аргументе функции.is_callable больше не требуется в теле функции.Затем, если это так, вызываемый аргумент ДОЛЖЕН быть действительным, поэтому он больше не является обязательным.

Что я хочу?

Я хочу знать, возможно ли использовать объявление вызываемого типа, но оставить его в качестве необязательного аргумента.

Я пробовал это:

// This is not possible :-(
// Fatal error: Uncaught ArgumentCountError: Too few arguments to function saySomething()
function saySomething($str, callable $callback = function(){return false;}){

    echo $str;

    $res = $callback();
    if($res){
        echo ', I am cool';
    } else {
        echo ', I am not cool';
    }
}

saySomething('piet'); // deliberately not supplying a callback
// I want the output to be: piet, I am not cool.

Я хочу, чтобы вызываемое возвращало false, когда вызываемый код не был предоставлен в коде клиента.

Возможный дубликат PHP 7.1 Обнуляемый параметр функции по умолчанию не предлагает решения для этой ситуации.

1 Ответ

2 голосов
/ 09 апреля 2019

Единственным допустимым аргументом по умолчанию для вызываемого объекта является NULL. Это частично документировано, но не ясно и не полностью документировано (насколько я могу найти). Синтезируя из руководства, вы можете сделать вывод, что анонимные функции запрещены. Другие допустимые типы, которые можно вызывать, также не допускаются в качестве значений по умолчанию для параметров с подсказкой, которую можно вызвать, но этого нет в руководстве (насколько я могу судить).

Страница справки аргументов указывает, что только скаляры, массивы и NULL могут быть аргументами по умолчанию. Вызываемыми объектами могут быть объекты (Closure или объекты с методом __invoke), массивы из 2 элементов (класс или объект и имя метода) или строки. Объекты не являются скалярами (как указано на справочной странице is_scalar) и, следовательно, не могут использоваться в качестве аргументов по умолчанию (что исключает анонимные функции), даже для нетипизированных параметров. Если исходить из руководства, это может показаться, что для параметров, которые можно вызвать, по умолчанию используются строки и массивы, но если вы попытаетесь использовать строку или массив, PHP выдаст ошибку:

Значение по умолчанию для параметров с вызываемым типом может быть только NULL

Хотя массивы и строки (как правило) разрешены в качестве значений по умолчанию, они не всегда могут быть проверены на тип во время компиляции для вызываемых; они могут ссылаться на вызываемый объект, который еще не определен, в результате чего проверка типа приводит к ложному отрицанию. Я подозреваю, что из-за этого они исключены из значений по умолчанию для вызываемых абонентов.

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

...