Есть ли существенные причины использовать isset () над @ в php - PullRequest
3 голосов
/ 26 сентября 2011

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

Это трудный процесс, с сотнями уведомлений в виде:

Notice: Undefined index: incoming in /path/to/code/somescript.php on line 18

из-за использования переменных, предполагая, что неопределенные переменные будут просто обрабатываться как false, например:

if($_SESSION['incoming']){
    // do something
}

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

Довольно просто заменить экземпляры переменной типа $_REQUEST['incoming'], которые ищут только истинные значения, на

@$_REQUEST['incoming'].

Довольно грязно заменять экземпляры такой переменной, как $_REQUEST['incoming'], на «стандартный» тест, который

(isset($_REQUEST['incoming'])? $_REQUEST['incoming'] : null)

И вы добавляете троичный / встроенный оператор if, что проблематично, потому что вы действительно можете по-разному вкладывать скобки в сложный код и полностью изменять поведение.

Итак .... ... есть ли какой-либо неприемлемый аспект использования символа подавления ошибок @ по сравнению с использованием (isset($something)? $something : null)?

Редактировать: Чтобы быть как можно более ясным, я не сравниваю «переписать код, чтобы он был хорош», с «@», это на более позднем этапе этого процесса из-за дополнительной сложности реального рефакторинга. Я сравниваю только два способа (могут быть и другие), которые мне известны, чтобы заменить $ undefined_variable версией без уведомления, пока.

Ответы [ 7 ]

5 голосов
/ 26 сентября 2011

Другой вариант, который, кажется, хорошо работает с хромым кодом, использующим повсеместно «суперглобальные переменные», - это оборачивать глобалы в выделенные объекты массива с более или менее разумным поведением []:

class _myArray implements ArrayAccess, Countable, IteratorAggregate
{
     function __construct($a) {
       $this->a = $a;
     }

    // do your SPL homework here: offsetExists, offsetSet etc

    function offsetGet($k) { 
        return isset($this->a[$k]) ? $this->a[$k] : null;
        // and maybe log it or whatever
    }
}

, а затем

 $_REQUEST = new _myArray($_REQUEST);

Таким образом вы получаете контроль над "$ REQUEST" и друзьями и можете наблюдать, как их использует остальная часть кода.

2 голосов
/ 26 сентября 2011

Вы должны решить самостоятельно, оцените ли вы использование @ приемлемо или нет. Это трудно оценить от третьей стороны, так как для этого нужно знать код.

Однако, похоже, вы не хотите, чтобы какое-либо подавление ошибок имело код, более доступный для вас, как для программиста, которому нужно с ним работать.

Вы можете создать его спецификацию путем перефакторинга базы кода, на которую вы ссылаетесь, и затем применить ее к базе кода.

Это ваше решение, используйте язык как инструмент.

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

1 голос
/ 26 сентября 2011

Я бы никогда не подавлял ошибки на сервере разработки, но я бы естественным образом подавлял ошибки на работающем сервере. Если вы разрабатываете на живом сервере, ну, вы не должны. Это значит для меня, что символ @ всегда недопустим. Нет причин подавлять ошибку в разработке. Вы должны увидеть все ошибки, включая уведомления.

@ также немного тормозит, но я не уверен, что isset() быстрее или медленнее.

Если вам больно писать isset() столько раз, я просто написал бы функцию, подобную

function request($arg, $default = null) {
   return isset($_REQUEST[$arg]) ? trim($_REQUEST[$arg]) : $default;
}

И просто используйте вместо него request('var').

1 голос
/ 26 сентября 2011

По моему мнению, вы должны использовать метод isset() для правильной проверки ваших переменных.

Подавление ошибки не приводит к ее исчезновению, а просто останавливает ее отображение, потому что по сути говорит "seterror_reporting(0) для этой строки ", и если я правильно помню, это будет медленнее, чем проверка isset().

И если вам не нравится троичный оператор, то вам следует использовать полный оператор if else.Это может сделать ваш код длиннее, но он будет более читабельным.

1 голос
/ 26 сентября 2011

Вы сами ответили на свой вопрос.Это подавляет ошибку, не отлаживает ее.

0 голосов
/ 26 сентября 2011

Большинство так называемых «программистов PHP» вообще не понимают идею назначения переменных.
Просто из-за отсутствия какого-либо образования в области программирования или опыта.

Ну, это не имеет большого значения для обычного php-скрипта, кодируемого значительными усилиями и состоящего из нескольких спагетти HTML / Mysql и очень небольшого количества переменных.

Другой вопрос - несколько больший код, когда писать будет относительно легко, но отладка превращается в кошмар.И вы научитесь ценить КАЖДЫЕ кровавые сообщения об ошибках, когда поймете, что сообщения об ошибках - это ваши ДРУЗЬЯ, а не какие-то раздражающие и беспокоящие вещи, от которых лучше избавиться.

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

Еще одним забавным следствием отсутствия образования является то, что 9 из 10 «программистов PHP» не могут отличить подавление ошибок от выключения и использования , отображающего ошибок и использованиябывший вместо последнего.

0 голосов
/ 26 сентября 2011

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

http://us3.php.net/manual/en/language.operators.errorcontrol.php

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

...