Стратегия PHP и неопределенных переменных

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

Существуют ли другие стратегии, чтобы заметить ранее эти недостатки? (что-то вроде C ++, когда одна компиляция дает вам все необходимые подсказки)

Спасибо за любые идеи

14
задан tru7 25 August 2010 в 10:06
поделиться

11 ответов

Это частая жалоба на PHP. Вот несколько идей:

  1. Используйте инструмент анализа кода . Многие IDE, такие как Netbeans , также помогут.

  2. Просто запустите код. В PHP нет дорогостоящего этапа компиляции, как в C ++.

  3. Используйте модульное тестирование. Общие побочные эффекты включают: лучший код.

  4. Установите error_reporting (-1) или эквивалент в вашем ini-файле .

  5. Получите xdebug . Это не профилактика, но трассировки стека помогают избавиться от ошибок.

  6. isset () , === null (оператор идентификации) и защитные предложения - ваши друзья.

Свободный и динамический набор текста - особенность языка. Тот факт, что PHP не строг в отношении ввода , не означает, что вы не можете этого сделать. Если вас это действительно беспокоит и у вас есть выбор, вы можете попробовать Python - это немного строже с набором текста.

10
ответ дан 1 December 2019 в 08:51
поделиться

На этапах разработки использование

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 = для присвоения значения!

2
ответ дан 1 December 2019 в 08:51
поделиться

Я считаю, что различные инструменты Code Coverage, доступные для PHP, подчеркнут это.

0
ответ дан 1 December 2019 в 08:51
поделиться

если вы хотите скрыть ошибку неопределенной переменной, то используйте @. пример: @ $ var

1
ответ дан 1 December 2019 в 08:51
поделиться

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

Идея по структурированию вашей страницы

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

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

alt text

Никто не любит спагетти-код.

Если вы покажете нам часть своего кода, мы сможем посоветовать, как его лучше структурировать для устранения подобных ошибок. Вы можете запутаться из-за фона C, поток может работать иначе, чем веб-страницы.

2
ответ дан 1 December 2019 в 08:51
поделиться

Лично я пытаюсь установить переменные, даже если это пустая строка, массив, логическое значение и т. д. Затем используйте функцию, такую ​​​​как 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().

0
ответ дан 1 December 2019 в 08:51
поделиться

Просто следите за тем, чтобы не выполнять операции, требующие значения переменной при первом использовании, например оператор concat.=

Если вы программист на C++, вы должны использовать его для объявления всех переменных. Сделайте что-то похожее на это в PHP с нуля -ing переменные или создание пустого массива, если вы хотите их использовать.

Обратите внимание на пользовательский ввод, убедитесь, что глобальные регистры отключены, и проверяйте ввод из $_GET и $_POST с помощью isset().

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

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

2
ответ дан 1 December 2019 в 08:51
поделиться

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

$variable = default_value;

Это решит большинство проблем. Как предлагалось ранее, используйте xdebug или встроенные средства отладки в таких редакторах, как Netbeans

.
1
ответ дан 1 December 2019 в 08:51
поделиться

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

6
ответ дан 1 December 2019 в 08:51
поделиться

Нет. В 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) { /* ... */ }

Конечно, вы можете использовать isset1, чтобы проверить в данной точке, существует ли переменная. Однако, если ваш код полагается на это, он, вероятно, плохо структурирован. Моя точка зрения заключается в том, что, в отличие, например.C/Java, вы не можете во время компиляции определить, является ли доступ к переменной допустимым. Это усугубляется отсутствием области блокировки в PHP.

1 Строго говоря, isset не скажет вам, установлена ли переменная, она покажет, установлена ли она и не равна нулю. В противном случае вам понадобится get_defined_vars.

5
ответ дан 1 December 2019 в 08:51
поделиться

Из того, что я знаю, единственный способ справиться с ними - это смотреть выход во время выполнения.

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

Я согласен, что иногда это отстой, но это необходимо. В готовом производственном коде не должно быть никаких уведомлений - они съедают производительность, даже если их отображение отключено, плюс они очень полезны для выявления опечаток, которые можно было сделать при использовании переменной. (Но вы это уже знаете.)

2
ответ дан 1 December 2019 в 08:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: