Подавление ошибок аргумента функции Php, эмуляция empty() isset()

Я уверен, что ответ на этот вопрос-нет, но в случае, если есть какой-то PHP guru

можно ли написать функцию таким образом, чтобы можно было передать недопустимые аргументы или несуществующие переменные, и php не будет ошибаться без использования '@'

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

ex:

empty($someBogusVar); // no error

myHappyFunction($someBogusVar); // Php warning / notice

14 ответов


Подводя итог, правильный ответ нет, вы не должны (см. пример ниже).

есть обходные пути, уже упомянутые многими людьми в этом потоке, например, использование ссылочных переменных или isset() или empty () в условиях и подавление уведомлений в конфигурации PHP. Это в дополнение к очевидному обходному пути, используя @, который вы не хотите.

подведение итогов интересного обсуждения комментариев с Джерри: передача переменной по ссылке действительно, если вы проверьте значение переменной внутри функции и ручки undefined или null дела надлежащим образом. Просто не используйте ссылку, проходящую как способ закрытия 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 идет на один шаг дальше и даст вам первое непустое значение любого количества args (вы всегда можете заставить его принимать только до двух args, но это выглядит более полезным для меня).

EDIT: оригинальная версия не использовала compact для создания массива args и все равно дала ошибку. Отчет об ошибках поднялся на ступеньку, и эта новая версия с компактом немного менее аккуратна, но все же делает то же самое и позволяет предоставить значение по умолчанию для несуществующих vars.


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

сказав Это, ты мог бы сделайте что-нибудь вроде

function safeLookup($array, $key)
{
  if (isset($array, $key))
    return $array[$key];

  return 0;
}

и использовать его вместо поиска ключа массива

defaultValue(safeLookup($foo, "bar"), "baz);

теперь мне нужно принять душ :)


можно ли написать функцию таким образом, чтобы можно было передать недопустимые аргументы или несуществующие переменные, и php не будет ошибаться без использования '@'

Да, вы можете!

porneL правильно [edit: у меня недостаточно очков, чтобы связать его ответ или проголосовать за него, но это на этой странице]

Он также прав, когда предупреждает: "но я рекомендую не злоупотреблять этим для сокрытия ошибок программирования."однако ошибка по этой же причине следует избегать подавления с помощью оператора контроля ошибок ( @ ).

Я новичок в переполнении стека, но я надеюсь, что неправильный ответ не будет оценен как самый высокий на странице, а правильный ответ не получит голосов. :(


существуют допустимые случаи, когда проверка становится громоздкой и несущественной.
Поэтому я написал эту маленькую магическую функцию:--5-->

/**
 * 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);

to

myHappyFunction(value($someBogusVar));

откровенно заявляя о своем намерении. что делает его хорошая практика в моей книге.


@Brian: я использую операцию тринария, чтобы сделать проверку для меня:

return $value ? $value : $default;

это возвращает либо $value, либо $default. В зависимости от значения $value. Если это 0, false, empty или что-то подобное, будет возвращено значение в $default.

Я больше собираюсь эмулировать функции, такие как empty() и isset()


@Sean, на который уже ответил Брайан

return isset($input) ? $input : $default;

Шон, ты мог бы сделать:

$result = ($func_result = doLargeIntenseFunction()) ? $func_result : 'no result';

EDIT:

Я уверен, что может быть большой обсуждение троичных операторов vrs вызов функции. Но смысл этого вопрос был в том, можем ли мы создать функция, которая не выдаст ошибку, если несуществующее значение передается в без использования '@'

и я сказал вам, проверьте это с isset(). Первая часть троичного условия не проверяет null или not null, она проверяет true или false. Если вы попытаетесь проверить true или false при нулевом значении в PHP вы получаете эти предупреждения. isset() проверяет, возвращает ли переменная или выражение нулевое значение или нет, и возвращает логическое значение, которое может быть оценено первой частью вашего тернарного без каких-либо ошибок.


Я уверен, что может быть большое обсуждение вызовов функций троичных операторов vrs. Но смысл этого вопроса состоял в том, чтобы увидеть, можем ли мы создать функцию, которая не будет выдавать ошибку, если несуществующее значение передается без использования '@'


в то время как ответ на исходный вопрос "нет", есть варианты, которые никто не упомянул.

когда вы используете знак@, все PHP делает переопределение error_reporting level и временно установив его на ноль. Вы можете использовать "ini_restore('error_reporting');", чтобы вернуть его к тому, что было до использования@.

это было полезно для меня в ситуации, когда я хотел написать функцию удобства, чтобы проверить и посмотреть, установлена ли переменная, а также некоторые другие свойства, в противном случае верните значение по умолчанию. Но отправка переменной unset вызвала уведомление 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
    }
}

С одной строкой, вы можете acomplish его: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 везде вверх и вниз в вашем коде это станет кошмаром обслуживания, когда вам нужно изменить значение, ища все места, где вы положили свойство DefaultValue звонок. И это также, вероятно, приведет вас к повторению себя, нарушая сухой.

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