Я уверен, что ответ на этот вопрос – нет, но в случае, если есть какой-то PHP-гуру
возможно ли записать функцию таким образом, что в нее могут быть переданы недопустимые аргументы или несуществующие переменные, а php не будет ошибкой без использования '@'
Очень похоже на пустой и isset. Вы можете передать переменную, которую вы только что создали, и она не будет ошибкой.
ex: empty($someBogusVar); // no error myHappyFunction($someBogusVar); // Php warning / notice
Подводя итог, правильный ответ – нет, вы не должны (см. Ниже).
Обходные пути, упомянутые многими людьми в этом потоке, например, использование ссылочных переменных или isset () или empty () в условиях и подавление уведомлений в конфигурации PHP. Это в дополнение к очевидному обходному пути, используя @, которого вы не хотите.
Подводя итог интересному обсуждению комментариев с Gerry : передача переменной по ссылке действительно действительно, если вы проверяете значение переменной внутри функции и обрабатываете неопределенные или нулевые случаи должным образом. Просто не используйте ссылку, как способ закрытия PHP (вот где мой оригинал не должен указывать).
Вы не получаете никакой ошибки, когда переменная передается по ссылке (PHP будет автоматически создавать новую переменную):
function myHappyFunction(&$var) { }
Но я рекомендую не злоупотреблять этим, чтобы скрывать ошибки программирования.
Вы можете сделать это с помощью func_get_args следующим образом:
error_reporting(E_ALL); ini_set('display_errors', 1); function defaultValue() { $args = func_get_args(); foreach($args as $arg) { if (!is_array($arg)) { $arg = array($arg); } foreach($arg as $a) { if(!empty($a)) { return $a; } } } return false; } $var = 'bob'; echo defaultValue(compact('var'), 'alpha') . "\n"; //returns 'bob' echo defaultValue(compact('var2'), 'alpha') . "\n"; //returns 'alpha' echo defaultValue('alpha') . "\n"; //return echo defaultValue() . "\n";
Этот func идет еще на один шаг и даст вам первое непустое значение любого числа аргументов (вы всегда можете заставить его заняться только двумя аргументами, но это выглядит более полезным для меня таким образом).
EDIT: оригинальная версия не использовала compact, чтобы попытаться создать массив аргументов, и STILL дал ошибку. Сообщение об ошибках натолкнулось на выемку, и эта новая версия с компактностью немного менее аккуратная, но все равно делает то же самое и позволяет предоставить значение по умолчанию для несуществующих варов.
Нет, потому что это не имеет ничего общего с функцией; ошибка исходит от попытки удаления ссылки на несуществующий ключ массива. Вы можете изменить уровень предупреждения вашей установки PHP, чтобы сдержать эти ошибки, но вам лучше не делать этого.
Сказав это, вы можете сделать что-то вроде
function safeLookup($array, $key) { if (isset($array, $key)) return $array[$key]; return 0; }
И используйте его вместо поиска ключа массива
defaultValue(safeLookup($foo, "bar"), "baz);
Теперь мне нужно принять душ 🙂
возможно ли записать функцию таким образом, что в нее могут быть переданы недопустимые аргументы или несуществующие переменные, а php не будет ошибкой без использования '@'
Да, ты можешь!
porneL is correct [edit: У меня недостаточно очков, чтобы ссылаться на его ответ или проголосовать, но он на этой странице]
Он также прав, когда предупреждает «Но я рекомендую не злоупотреблять этим, чтобы скрывать ошибки программирования». однако по этой же причине следует избегать подавления ошибок с помощью оператора управления ошибками (@).
Я новичок в Stack Overflow, но я надеюсь, что неправильный ответ не считается самым высоким на странице, а правильный ответ не получает голосов. 🙁
Существуют действительные случаи, когда проверка становится громоздкой и неуместной.
Поэтому я написал эту маленькую магическую функцию:
/** * Shortcut for getting a value from a possibly unset variable. * Normal: * if (isset($_GET['foo']) && $_GET['foo'] == 'bar') { * Short: * if (value($_GET['foo']) == 'bar') { * * @param mixed $variable * @return mixed Returns null if not set */ function value(&$variable) { if (isset($variable)) { return $variable; } }
Он не требует никаких изменений в myHappyFunction ().
Вы должны будете изменить
myHappyFunction($someBogusVar);
в
myHappyFunction(value($someBogusVar));
Заявить о своем намерении явно. что делает его хорошей практикой в моей книге.
@Brian: Я использую операцию trinary для проверки для меня:
return $value ? $value : $default;
это возвращает либо $ value OR $ default. В зависимости от значения $ value. Если оно равно 0, false, пустое или что-либо подобное, то значение в $ default будет возвращено.
Я больше собираюсь попробовать эмуляцию таких функций, как empty () и isset ()
@Sean На это уже ответил Брайан
return isset($input) ? $input : $default;
Шон, ты мог бы сделать:
$result = ($func_result = doLargeIntenseFunction()) ? $func_result : 'no result';
РЕДАКТИРОВАТЬ:
Я уверен, что может быть отличная дискуссия о вызовах функций vrs ternary. Но суть этого вопроса заключалась в том, чтобы увидеть, можем ли мы создать функцию, которая не будет вызывать ошибку, если несуществующее значение передается без использования '@'
И я сказал вам, проверьте его с isset()
. Первая часть тернарного условного условия не проверяет значение null или не имеет значение null, оно проверяет true
или false
. Если вы попытаетесь проверить true
или false
на значение NULL в PHP, вы получите эти предупреждения. isset()
проверяет, возвращает ли переменная или выражение нулевое значение или нет, и возвращает логическое значение, которое может быть оценено первой частью вашего троичного элемента без каких-либо ошибок.
Я уверен, что может быть отличная дискуссия о вызовах функций vrs ternary. Но суть этого вопроса заключалась в том, чтобы увидеть, можем ли мы создать функцию, которая не будет вызывать ошибку, если несуществующее значение передается без использования '@'
Хотя ответ на исходный вопрос «нет», есть варианты, о которых никто не упомянул.
Когда вы используете знак @, все, что делает PHP, это переопределение уровня error_reporting
и временная установка его на ноль. Вы можете использовать « ini_restore('error_reporting');
« чтобы вернуть его обратно к тому, что было до использования @.
Это было полезно для меня в ситуации, когда я хотел написать функцию удобства, чтобы проверить, была ли установлена переменная, а также какие-то другие свойства, иначе верните значение по умолчанию. Но, отправляя неустановленную переменную, вызвав уведомление PHP, я использовал @ для подавления этого, но затем установил error_reporting
обратно к исходному значению внутри функции.
Что-то вроде:
$var = @foo($bar); function foo($test_var) { ini_restore('error_reporting'); if(is_set($test_var) && strlen($test_var)) { return $test_var; } else { return -1; } }
Итак, в случае выше, если $bar
не установлен, я не получу ошибку, когда вызываю foo()
с несуществующей переменной. Тем не менее, я получу ошибку из функции, где я ошибочно набрал is_set
вместо isset
.
Это может быть полезным вариантом, охватывающим то, что первоначальный вопрос задавал духом, если не на самом деле.
Если вы просто добавите значение по умолчанию в параметр, вы можете пропустить его при вызове функции. Например:
function empty($paramName = ""){ if(isset($paramName){ //Code here } else if(empty($paramName)){ //Code here } }
С помощью одной строки вы можете ее myHappyFunction($someBogusVar="");
: myHappyFunction($someBogusVar="");
Надеюсь, это то, что вы ищете. Если вы прочитаете документацию php, в соответствии со значениями аргументов по умолчанию , вы увидите, что назначение значения по умолчанию аргументу функции помогает предотвратить сообщение об ошибке при использовании функций.
В этом примере вы можете увидеть разницу в использовании аргумента по умолчанию и его преимущества:
PHP-код:
<?php function test1($argument) { echo $argument; echo "\n"; } function test2($argument="") { echo $argument; echo "\n"; } test1(); test1("Hello"); test1($argument); $argument = "Hello world"; test1($argument); test2(); test2("Hello"); test2($argument); $argument = "Hello world"; test2($argument); ?>
Выход для строк test1()
:
Предупреждение : Отсутствует аргумент 1 для test1 ().
Здравствуйте.
,
Привет мир.
Выход для test2()
:
,
Здравствуйте.Привет мир.
Это также можно использовать в сочетании с isset()
и другими функциями для выполнения того, что вы хотите.
И продвигаясь дальше по дереву абстракции, для чего вы это используете?
Вы можете либо инициализировать эти значения в каждом классе по мере необходимости, либо создать определенный класс, содержащий все значения и атрибуты по умолчанию, например:
class Configuration { private var $configValues = array( 'cool' => 'Defaultcoolval' , 'uncool' => 'Defuncoolval' ); public setCool($val) { $this->configValues['cool'] = $val; } public getCool() { return $this->configValues['cool']; } }
Идея заключалась в том, что при использовании функции defaultValue повсюду вверх и вниз в вашем коде, это станет кошмаром обслуживания, когда вам нужно изменить значение, ищите все места, где вы поместили вызов по умолчанию. И это также, вероятно, приведет вас к повторению, нарушив DRY.
В то время как это единственное место для хранения всех этих значений по умолчанию. Возможно, у вас возникнет соблазн избежать создания этих сеттеров и геттеров, но они также помогут в обслуживании, в случае, если это потребует некоторой модификации выходов или проверки входов.