Передмова

Помилки – це бич будь-якої програми. Чим більше проект, тим важче виправляти і
знаходити помилки. Але найбільш важливим у процесі роботи з програмою є
кваліфікація програміста і його бажання написати правильний і акуратний код,
містить мінімальну кількість помилок.

У цій статті я постараюся зібрати техніки і прийоми, що дозволяють
мінімізувати кількість помилок в програмі, написаній на PHP. Але деякі з
представлених методів можуть стати в нагоді якщо ви пишете на будь-якій мові
програмування.


Знання – половина успіху


Дізнаємося, про що повідомляє PHP


У будь-якій мові існує безліч потенційно небезпечних ситуацій, які
чреваті неявними помилками. При розборі транслятором вихідного коду програми він
може повідомляти розробнику про цих ситуаціях. Для цього треба лише включити
відповідну опцію, яка дуже часто за умовчанням вимкнена за деякими
міркувань.

У PHP контроль виведення повідомлень транслятора визначається функцією error_reporting і значенням директиви
error_reporting в php.ini. Рекомендоване її значення
E_ALL – Тобто виводити повідомлення про всі потенційно небезпечних
ситуаціях. До них в PHP відносяться, наприклад, використання неініціалізованої
змінної, звернення до неіснуючого елементу масиву і т.д.

Для включення максимально докладного виведення повідомлень транслятора поставте в
початку програми виклик функції error_reporting:

/ / Для PHP4
error_reporting(E_ALL);

або поставте значення error_reporting = E_ALL в
php.ini.

З більш докладному описі можливих рівнів reporting можна знайомиться в PHP
документації – Error Handling and Logging Functions.

Для PHP5 введений рівень E_STRICT, Який включає висновок
повідомлень про використання в коді застарілих методів програмування (наприклад,
використовується var для опису внутрішніх змінних класу). Він не
входить до E_ALL, Тому для PHP5 рекомендований рівень повідомлень
E_ALL | E_STRICT (Тобто E_ALL і E_STRICT).
Відповідно, для завдання виведення всіх повідомлень від транслятора треба викликати
error_reporting з таким параметром:

/ / Для PHP5
error_reporting(E_ALL | E_STRICT);

Якщо ні про що не повідомляє


Якщо Ви встановили висновок помилок і помилки по не виводяться, то можливо висновок
помилок у script output відключений. Перевірте значення опції ini файлу display_errors (вона включає висновок помилок непосрественно в
script output) і, якщо вона вимкнена, увімкніть її.

/ / Перевіряє значення опції display_errors
if (ini_get(“display_errors”) != 1) {
/ / Включає висновок помилок разом з результатом роботи скрипта
ini_set(“display_errors”, 1);
}

Якщо раптом повідомить


Вкрай рідко вдається протестувати програму повністю до випуску і в той-же
час краще не показувати користувачеві повідомлення про помилки бо його реакція на
них непередбачувана. Краще перенаправляти помилки транслятора, які відбулися
безпосередньо під час роботи програми, в log файл помилок. Включити це
перенаправлення можна опцією log_errors у файлі php.ini.

Корисно також поставити свій оброблювач помилок, якщо Ви хочете не тільки
заносити помилки в Log файл але і додати деяку додаткову логіку їх
обробки. Наприклад, відправити лист при повідомленні транслятора або вивести
деяке спеціальне повідомлення для користувача. Детальніше про це написано в
статті Ловля помилок в PHP, яку написав Антон Довгаль.


Порівнюємо константу зі змінною, а не навпаки


Скільки разів Вам доводилося з'ясовувати, що помилка у програмі пов'язана з
використанням оператора "="Замість"=="? Що б
доводилося рідше, використовуйте порівняння виду

if (10 == $i) {
/ / Щось робимо
}

У випадку використання "="Замість"=="Транслятор
видасть помилку "Parse error: parse error in … on line …". Таким чином
помилка виявляється значно швидше.


Не використовуємо значення двічі


Звичайно, це перебільшення. Але якщо в програмі виникає необхідність
використовувати значення кілька разів, можна порекомендувати оголосити константу і
використовувати її замість значення.

Для PHP4 існує єдиний спосіб оголосити константу – використовувати
функцію define.

Наприклад:

define (“BEFORE_RENDER”, “beforeRender”);

Констант в класах оголошувати не можна.

Розширення PHP 5 для визначення констант схоже з тим, яке було
здійснено при розширенні від C до C + + – використовується ключове слово const. Але
константи таким чином можна створювати тільки всередині класів.

Наприклад:

class ControlEvents {
const BEFORE_RENDER = “beforeRender”;
}
print ControlEvents::BEFORE_RENDER;

Але для звернення до такої константі необхідно знати ім'я класу.

Константи можуть бути також додані безпосередньо в клас. Але PHP не
підтримує такий метод. Тому доведеться оголосити їх як звичайні змінні:

class Control {

var $BEFORE_RENDER = “beforeRender”;
function render() {
$eventFunction = $this->BEFORE_RENDER;
$this->$eventFunction();
}
}


Перевірка параметрів функції


У PHP параметром у функцію можна передати будь-яку змінну. Але ось алгоритмом
функції може бути зовсім не все одно, що за змінну йому передали. Тому в
початку функції корисно перевіряти її вхідні параметри на необхідний тип і
діапазон значень.

Для перевірки типу використовуються наступні функції:


Для PHP4 не існує автоматичного способу перевірки параметрів функції.
Всі необхідні перевірки необхідно робити самостійно.

Код функції, що здійснює перевірку аргументів, може бути приблизно такою:

/**
* Функція showControl приймає один параметр $ control,
* Цей параметр повинен бути класом і бути
* Екземпляром класу HTMLControl або класом,
* Успадкованим від HTMLControl.
*/
function showControl(&$control) {
is_a ($ control, "HTMLControl") or $ control == null or exit ("Type missmatch.");

}

Перевага цього методу полягає в тому, що можна керувати повідомленнями про
помилки і використовувати власний обробник помилок. Наприклад, Ви можете
використовувати такі функції для перевірки параметрів:

function checkParameter(&$var, $class) {
if (!is_a($var, $class) && $var != null)
SFExit(“Type missmatch.”);
}

function SFExit(&$message) {
print $message . “<br>”;
$backtrace = debug_backtrace();
for($i = 0; $i < count($backtrace); $i++) {
print $i . “: ” . $backtrace[$i][“file”] . “(” .
$backtrace[$i][“line”] . “)<br>”;
}
exit();
}


Примітка: Функція debug_backtrace введена тільки в PHP 4.3.0.

Приклад їх застосування:

function showControl(&$control) {
checkParameter($control, “HTMLControl”);

}

Для PHP5 деякі перевірки типів параметрів можна задати безпосередньо в
описі функції. Попередній приклад на PHP5 буде виглядати наступним чином:

function showControl(HTMLControl $control) {

}

Asserts


Під час створення та налагодження програми можна використовувати вбудований механізм
додавання перевірок в код програми. Він називається asserts (або assert-перевірки). Ідея його полягає в тому, що в
код програми додаються спеціальні перевірочні конструкції, які можна
відключити для production сайту, але в будь-який момент включити при розробці.

Наступні фрагменти коду приблизно аналогічні:

/ * Використання Asserts * /
assert_options (ASSERT_ACTIVE, 1);

function showControl(&$control) {
assert(“is_a($var, “HTMLControl”) || $var == null”);

}

 / * Використання if конструкцій * /
define(“ASSERT_ACTIVE”, 1);
function showControl(&$control) {
if (ASSERT_ACTIVE & &! (is_a ($ var, "HTMLControl") | | $ var == null "))
trigger_error(“Assertion failed”, E_USER_ERROR);

}

За допомогою таких перевірок також можна перевіряти параметри функцій,
повертаються функціями значення й т.д. Потрібно лише врахувати, що assert-перевірки не
повинні бути включені в реально діючому сайті – якщо програма нормально
працює і проходить всі перевірки, то їх можна відключити.


Перевіряти значення параметрів скрипта $ _REQUEST, $ _GET, $ _POST,
$_COOKIES


PHP скрипт можна розглядати як велику функцію, яка викликається за
невизначеним списком string параметрів. Якщо передбачається, що деякі
параметри будуть використовуватися у деяких обчисленнях, чи вирушати в базу
даних, то їх обов'язково треба перетворювати до необхідного типу і використовувати
тільки після явного приведення!

Всі масиви REQUEST є є звичайними масивами,
тому значення в них можуть бути перевизначені безпосередньо.

Наприклад:

if (isset($_GET[“id”]))
$_GET[“id”] = (int)$_GET[“id”];
else
$_GET[“id”] = null;

Розділяй і володарюй


Відомий з часів стародавнього Риму принцип "Розділяй і володарюй" цілком може
стане в нагоді при розробці програм будь-якою мовою програмування. У тому числі
і на PHP. Для реалізації цього принципу розділяйте програму на логічні
блоки. Для цього можна скористатися такими методами:


Висновок


Можливо, комусь матеріал статті здасться збором прописних істин. Але я
думаю, що більшості він все-таки стане в нагоді, а для початківців програмістів
останній розділ "Розділяй і володарюй" може виявитися особливо корисним,
оскільки задає напрям вивчення програмування.

Якщо у Вас є коментарі або власні прийоми роботи, які не
згадані в цій статті, я буду радий почути і обговорити їх з Вами.

Також хочу висловити вдячність учасникам клубу phpclub.ru за
допомогу в написанні статті.


Історія змін


2004-04-06: Виправлена помилка в прикладі коду для розділу "Перевіряти значення
параметрів скрипта …".

2004-03-22: Невеликі зміни розділів "Якщо раптом повідомить", "Asserts".

2004-03-06: Додані посилання на PHP документацію. Додано інформацію про
E_STRICT, display_errors, Призначених для користувача
обробниках помилок, використанні "==“.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*