Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 18
На сайте нет зарегистрированных пользователей

Пользователей: 13,361
новичок: uehuat
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

База данных студентов на Delphi (файл записей) + Блок схемы
База данных - рабочее место кассира на Delphi + бд Access
Моделирование станции технического обслуживания на GPSS + Отчет

Пишем PHP код, устойчивый к ошибкам
Александр Неткачев
alex@devlink.crimea.ua
devlink.crimea.ua
Предисловие

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

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

Для проверки типа используются следующие функции:
gettype(Mixed $var) - возвращает тип переменной.
Наиболее часто используемые типы: "boolean", "integer", "double", "string", "array", "object", "resource", "NULL".
Функции проверки на тип: is_bool(Mixed $var), is_integer(Mixed $var), is_double(Mixed $var), is_string(Mixed $var), is_array(Mixed $var), is_object(Mixed $var), is_resource(Mixed $var) - возвращают true или false.
Для определения класса объекта используются функции:
get_class(Object $obj) - возвращает имя класса, экземпляром которого является obj.
is_a(Object $obj, String $class) - проверяет, является ли obj экземпляром сласса class или класса, унаследованного от class.

Для 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 . '
';
$backtrace = debug_backtrace();
for($i = 0; $i < count($backtrace); $i++) {
print $i . ': ' . $backtrace[$i]['file'] . '(' .
$backtrace[$i]['line'] . ')
';
}
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. Для реализации этого принципа разделяйте программу на логические блоки. Для этого можно воспользоваться следующими методами:

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

Использование классов.
Организуйте программный код в виде объектов, взаимодействующих друг с другом. Выделяйте сущности и оформляйте их в виде объектов. Внимательно рассматривайте, как они взаимодействуют друг с другом. Используйте, где это разумно, лучшие шаблоны проектирования (design patterns).

Разделяйте логику и HTML.
Для этого существует множество способов: темплейтные библиотеки, XML, XML/XSL. Подберите для себя наилучший и используйте.

Разделяйте логику самого приложения при помощи enterprise design patterns.
Используйте разделение приложения на уровни (layering) и другие технологии, позволяющие структурно разделить проект на крупные блоки.
Заключение

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

Если у Вас есть комментарии или собственные приемы работы, которые не упомянуты в этой статье, я буду рад услышать и обсудить их с Вами.
Опубликовал Kest November 05 2008 21:38:17 · 0 Комментариев · 6876 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
PHP 5 для "чайников"
Delphi 7 Enterpri...
DS_Group
С# для профессион...
Нестандартные при...
GamesBase 3.0
TelBook
MpegPlay
Язык программиров...
KOL & MCK v1.69
Print Grid
Srinilist
Swing. Эффектные...
Голосование для ...
PHP, MySQL и Drea...
PDJXPPack
Visual Basic Script
RbControls
Text effect
Архив значков

Топ загрузок
Приложение Клие... 100772
Delphi 7 Enterp... 97809
Converter AMR<-... 20261
GPSS World Stud... 17014
Borland C++Buil... 14189
Borland Delphi ... 10267
Turbo Pascal fo... 7372
Калькулятор [Ис... 5972
Visual Studio 2... 5206
Microsoft SQL S... 3661
Случайные статьи
Онлайн-казино Вулкан
tell(X)
Безопасность ящиков
Отчет об ошибках: ...
Работа с сообщением
Играть в зале игро...
Работа с WDDX в РНР
Список тем для изу...
Целостность информ...
Регистровая адресация
Настройка IPv4-aAp...
административных г...
Method Identifier ...
Генерация всех пер...
Понимание системы ...
Всплывающие сообще...
Строительство домов
Геотермальная энергия
Пицца Подольск
Настройка ЖК-диспл...
Пакеты компонентов
Установка адаптера...
состав группы, соб...
Списочное представ...
Заключение
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?