У меня есть функция с двумя аргументами: строкой и вызываемым. Я хочу, чтобы вызываемый объект был необязательным. Смотри ниже.
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 Обнуляемый параметр функции по умолчанию не предлагает решения для этой ситуации.
?callable
тогда?
@ Джулиан, тогда обратитесь к комментарию Малдера ..
Возможный дубликат PHP 7.1 Обнуляемый параметр функции по умолчанию
@u_mulder Я не знал о ?callable
, не могли бы вы поделиться дополнительной информацией о ?callable
? Ссылка на официальную документацию по php будет полезна.
@Julian, проверь мой связанный дубликат ..
@treyBake Я попробовал образец, который они предоставили по вашей ссылке. Это выдало мне эту ошибку: Fatal error: Uncaught Error: Function name must be a string.
Следовательно, это не дублирующий вопрос. На данный момент я думаю, что вызов по умолчанию невозможен.
@Julian, принцип тот же - у вас синтаксическая ошибка в объявлении функции - ответ, вероятно, правильный, если он введен правильно
@treyBake Я сделал это: function saySomething($str, ?callable $callback = null){
. Но фатальная ошибка срабатывает в этой строке: $res = $callback();
. Где синтаксическая ошибка?
@ Джулиан, как ты назвал функцию?
@treyBake вот так: saySomething('piet'); // deliberately not supplying a callback
@ Джулиан, ну да .. это фатальная ошибка .. вы объявляете тип параметра равным нулю или функцией обратного вызова .. не строкой?
@treyBake Думаю, можно с уверенностью сказать, что аргумент функции с объявлением вызываемого типа не может иметь обратный вызов по умолчанию. И это все, что я хотел знать на данный момент.
не только обратные вызовы, но любой аргумент по умолчанию должен быть постоянное выражение, для которого, к сожалению, я не могу найти специальную страницу phpdoc
@chiliNUT Единственная страница, которую я нашел, это: php.net/manual/en/…. Объясняют это так: The default value must be a constant expression
. Но здравый смысл заключается в том, что значение аргумента по умолчанию должно быть постоянным выражением.
Единственным допустимым аргументом по умолчанию для вызываемого объекта является 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: спасибо, что указали на ошибку. Первоначально речь шла только о строках, а к ним добавились массивы. Ответ поспешили отправить в прессу.
что.... что ты хочешь сделать? о.О