Вызов по умолчанию в определении функции в php 7

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

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 Обнуляемый параметр функции по умолчанию не предлагает решения для этой ситуации.

что.... что ты хочешь сделать? о.О

treyBake 09.04.2019 10:09
?callable тогда?
u_mulder 09.04.2019 10:10

@ Джулиан, тогда обратитесь к комментарию Малдера ..

treyBake 09.04.2019 10:12

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

treyBake 09.04.2019 10:13

@u_mulder Я не знал о ?callable, не могли бы вы поделиться дополнительной информацией о ?callable? Ссылка на официальную документацию по php будет полезна.

Julian 09.04.2019 10:19

@Julian, проверь мой связанный дубликат ..

treyBake 09.04.2019 10:25

@treyBake Я попробовал образец, который они предоставили по вашей ссылке. Это выдало мне эту ошибку: Fatal error: Uncaught Error: Function name must be a string. Следовательно, это не дублирующий вопрос. На данный момент я думаю, что вызов по умолчанию невозможен.

Julian 09.04.2019 10:39

@Julian, принцип тот же - у вас синтаксическая ошибка в объявлении функции - ответ, вероятно, правильный, если он введен правильно

treyBake 09.04.2019 10:42

@treyBake Я сделал это: function saySomething($str, ?callable $callback = null){. Но фатальная ошибка срабатывает в этой строке: $res = $callback();. Где синтаксическая ошибка?

Julian 09.04.2019 10:47

@ Джулиан, как ты назвал функцию?

treyBake 09.04.2019 10:49

@treyBake вот так: saySomething('piet'); // deliberately not supplying a callback

Julian 09.04.2019 10:52

@ Джулиан, ну да .. это фатальная ошибка .. вы объявляете тип параметра равным нулю или функцией обратного вызова .. не строкой?

treyBake 09.04.2019 10:56

@treyBake Думаю, можно с уверенностью сказать, что аргумент функции с объявлением вызываемого типа не может иметь обратный вызов по умолчанию. И это все, что я хотел знать на данный момент.

Julian 09.04.2019 11:16

не только обратные вызовы, но любой аргумент по умолчанию должен быть постоянное выражение, для которого, к сожалению, я не могу найти специальную страницу phpdoc

chiliNUT 09.04.2019 22:45

@chiliNUT Единственная страница, которую я нашел, это: php.net/manual/en/…. Объясняют это так: The default value must be a constant expression. Но здравый смысл заключается в том, что значение аргумента по умолчанию должно быть постоянным выражением.

Julian 10.04.2019 09:18
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
15
2 046
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

Default value for parameters with callable type can only be NULL

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

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

Я с тобой согласен. Необязательные вызываемые объекты должны иметь NULL по умолчанию и БЕЗ объявления типа.. Кстати, массивы НЕ являются скалярами. Scalar variables are those containing an integer, float, string or boolean. Types array, object and resource are not scalar. . См. ссылку: php.net/manual/en/function.is-scalar.php

Julian 10.04.2019 09:09

@Julian: спасибо, что указали на ошибку. Первоначально речь шла только о строках, а к ним добавились массивы. Ответ поспешили отправить в прессу.

outis 10.04.2019 10:04

Другие вопросы по теме