Я программист на C ++, начинающий с PHP. Я обнаружил, что теряю большую часть времени отладки (и свою самооценку!) Из-за неопределенных переменных. Из того, что я знаю, единственный способ справиться с ними - это посмотреть результат во время выполнения.
Существуют ли другие стратегии, чтобы заметить ранее эти недостатки? (что-то вроде C ++, когда одна компиляция дает вам все необходимые подсказки)
Спасибо за любые идеи
Это частая жалоба на PHP. Вот несколько идей:
Используйте инструмент анализа кода . Многие IDE, такие как Netbeans , также помогут.
Просто запустите код. В PHP нет дорогостоящего этапа компиляции, как в C ++.
Используйте модульное тестирование. Общие побочные эффекты включают: лучший код.
Установите error_reporting (-1)
или эквивалент в вашем ini-файле .
Получите xdebug . Это не профилактика, но трассировки стека помогают избавиться от ошибок.
isset ()
, === null
(оператор идентификации) и защитные предложения - ваши друзья.
Свободный и динамический набор текста - особенность языка. Тот факт, что PHP не строг в отношении ввода , не означает, что вы не можете этого сделать. Если вас это действительно беспокоит и у вас есть выбор, вы можете попробовать Python - это немного строже с набором текста.
На этапах разработки использование
error_reporting(E_ALL);
ведьмы покажет все вызванные ошибки, все ошибки УВЕДОМЛЕНИЯ и т. Д.
Также следите за вашим error_log
, что покажет вам ошибки
используйте систему отчетов об ошибках, например:
http://php.net/manual/en/function.set-error-handler.php
class ErrorReporter
{
public function catch($errno, $errstr, $errfile, $errline)
{
if($errno == E_USER_NOTICE && !defined('DEBUG'))
{
//Catch all output buffer and clear states, redirect or include error page.
}
}
}
set_error_handler(array(new ErrorReporter,'catch'));
всегда используются несколько других советов isset
для переменных, которые вы могли или не могли устанавливать из-за того, что, скажем, оператор if.
всегда используйте if (isset ($ _ POST ['key']))
или даже лучше просто используйте if (! Empty ($ _ POST ['key']))
как это проверяет, существует ли ключ и НЕ пусто ли значение.
убедитесь, что вы также знаете свои операторы сравнения, языки вроде C # используют == для проверки состояния bool, тогда как, как и в php, для проверки типов данных вы должны использовать ===
и использовать = =
для проверки состояний значений и single =
для присвоения значения!
Я считаю, что различные инструменты Code Coverage, доступные для PHP, подчеркнут это.
если вы хотите скрыть ошибку неопределенной переменной, то используйте @.
пример: @ $ var
Если я что-то не упустил, то почему никто не предлагает правильно структурировать вашу страницу? У меня никогда не было постоянной проблемы с ошибками неопределенных переменных.
Идея по структурированию вашей страницы
Определите все свои переменные вверху, при необходимости назначьте значения по умолчанию, а затем используйте эти переменные оттуда. Именно так я пишу веб-страницы и никогда не сталкиваюсь с проблемами с неопределенными переменными.
Не привыкайте определять переменные только тогда, когда они вам нужны, это быстро создает спагетти-код, которым может быть очень трудно управлять.
Никто не любит спагетти-код.
Если вы покажете нам часть своего кода, мы сможем посоветовать, как его лучше структурировать для устранения подобных ошибок. Вы можете запутаться из-за фона C, поток может работать иначе, чем веб-страницы.
Лично я пытаюсь установить переменные, даже если это пустая строка, массив, логическое значение и т. д. Затем используйте функцию, такую как isset()
, прежде чем использовать их. Например:
$page_found = false;
if ($page_found==false) {
// do page not found stuff here
}
if (isset($_POST['field'])) {
$value = $_POST['field'];
$sql = "UPDATE table SET field = '$value'";
}
И так далее. И прежде чем какой-нибудь умник скажет это: я знаю, что этот запрос небезопасен. Это был просто пример использования isset()
.
Просто следите за тем, чтобы не выполнять операции, требующие значения переменной при первом использовании, например оператор concat.=
Если вы программист на C++, вы должны использовать его для объявления всех переменных. Сделайте что-то похожее на это в PHP с нуля -ing переменные или создание пустого массива, если вы хотите их использовать.
Обратите внимание на пользовательский ввод, убедитесь, что глобальные регистры отключены, и проверяйте ввод из $_GET и $_POST с помощью isset().
Вы также можете попытаться закодировать классы в соответствии со структурным кодом и создать каждую переменную в начале объявления класса с правильной политикой конфиденциальности.
Вы также можете отделить логику приложения от представления, подготовив все переменные, которые должны быть выведены в первую очередь, и когда они перейдут к их отображению, вы будете знать, какие переменные вы подготовили.
Хорошей практикой является определение всех переменных перед использованием, т.е. установка значения по умолчанию
$variable = default_value;
Это решит большинство проблем. Как предлагалось ранее, используйте xdebug или встроенные средства отладки в таких редакторах, как Netbeans
.Записывайте E_NOTICE сообщения в текстовый файл. Затем можно обрабатывать журналы с помощью автоматических сценариев, чтобы указать файлы и строки, в которых они возникают.
Нет. В PHP вы можете знать, что переменная не существует, только когда вы пытаетесь получить к ней доступ.
Рассмотрим:
if ($data = file('my_file.txt')) {
if (count($data) >= 0)
$line = reset($data);
}
var_dump($line);
Вы должны реструктурировать свой код таким образом, чтобы все пути кода вели к определенной переменной, например:
$line = "default value";
if ($data = file('my_file.txt')) {
if (count($data) >= 0)
$line = reset($data);
}
var_dump($line);
Если нет значения по умолчанию, которое делает, это все равно лучше, чем isset
, потому что вы предупредите, если у вас есть опечатка в имени переменной в последнем if
:
$line = null;
if ($data = file('my_file.txt')) {
if (count($data) >= 0)
$line = reset($data);
}
if ($line !== null) { /* ... */ }
Конечно, вы можете использовать isset
1, чтобы проверить в данной точке, существует ли переменная. Однако, если ваш код полагается на это, он, вероятно, плохо структурирован. Моя точка зрения заключается в том, что, в отличие, например.C/Java, вы не можете во время компиляции определить, является ли доступ к переменной допустимым. Это усугубляется отсутствием области блокировки в PHP.
1 Строго говоря, isset
не скажет вам, установлена ли переменная, она покажет, установлена ли она и не равна нулю. В противном случае вам понадобится get_defined_vars
.
Из того, что я знаю, единственный способ справиться с ними - это смотреть выход во время выполнения.
Не совсем: чтобы предотвратить появление этих уведомлений, вам просто нужно убедиться, что вы инициализируете переменные, прежде чем обращаться к ним в первый раз. У нас (к сожалению, IMO) нет объявления переменных в PHP, но инициализация их в начале вашего блока кода так же хороша:
$my_var = value;
Используя синтаксис phpDocumentor, вы также можете объявить их определенным типом, по крайней мере, таким образом, чтобы многие IDE могли выполнять поиск кода с помощью:
/** @desc optional description of what the variable does
@var int */
$my_var = 0;
Кроме того, вы можете (а иногда и должны) использовать условия isset()
/ empty()
/ array_key_exists()
перед попыткой доступа к переменной.
Я согласен, что иногда это отстой, но это необходимо. В готовом производственном коде не должно быть никаких уведомлений - они съедают производительность, даже если их отображение отключено, плюс они очень полезны для выявления опечаток, которые можно было сделать при использовании переменной. (Но вы это уже знаете.)