Большой архив статей, книг, документации по программированию, вебдизайну, компьютерной графике, сетям, операционным системам и многому другому
 
<Добавить в Избранное>    <Сделать стартовой>    <Реклама на сайте>    <Контакты>
  Главная Документация Новости ИТ Программы Книги Games   Обои   Экспорт RSS E-Books
 
10 новых программ
CodeLobster PHP Edition 3.7.2
WinToFlash 0.7.0008
Free Video to Flash Converter 4.7.24
Total Commander v7.55
aTunes 2.0.1
Process Explorer v12.04
Backup42 v3.0
Predator 2.0.1
FastStone Image Viewer 4.1
Process Lasso 3.70.4
FastStone Image Viewer 4.0
Xion Audio Player 1.0.125
Notepad GNU v.2.2.8.7.7
K-Lite Codec Pack 5.3.0 Full
 
Наши сервисы
Рассылка новостей. Подпишитесь на рассылку сейчас и вы всегда будете в курсе последних событий в мире информационных технологий.
Новостные информеры. Поставьте наши информеры к себе и у вас на сайте появится дополнительный постоянно обновляемый раздел.
Добавление статей. Если вы являетесь автором статьи или обзора на тему ИТ присылайте материал нам, мы с удовольствием опубликуем его у себя на сайте.
 
Поиск по сайту

 
 

   Интернет технологии -> PHP -> Пишем PHP код, устойчивый к ошибкам


Пишем PHP код, устойчивый к ошибкам

Предисловие

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

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

if (ini_get('display_errors') != 1) { // проверяет значение опции display_errors
    
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 . '<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. Для реализации этого принципа разделяйте программу на логические блоки. Для этого можно воспользоваться следующими методами:

  • Использование функций. Выносите структурные части алгоритма в функции. Проверяйте каждую часть отдельно и затем работу всего алгоритма в целом.
  • Использование классов. Организуйте программный код в виде объектов, взаимодействующих друг с другом. Выделяйте сущности и оформляйте их в виде объектов. Внимательно рассматривайте, как они взаимодействуют друг с другом. Используйте, где это разумно, лучшие шаблоны проектирования (design patterns).
  • Разделяйте логику и HTML. Для этого существует множество способов: темплейтные библиотеки, XML, XML/XSL. Подберите для себя наилучший и используйте.
  • Разделяйте логику самого приложения при помощи enterprise design patterns. Используйте разделение приложения на уровни (layering) и другие технологии, позволяющие структурно разделить проект на крупные блоки.

Заключение

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

Если у Вас есть комментарии или собственные приемы работы, которые не упомянуты в этой статье, я буду рад услышать и обсудить их с Вами.

Также хочу выразить признательность участникам клуба phpclub.ru за помощь в написании статьи.

Автор: Александр Неткачев
Источник: www.devlink.crimea.ua

 
 


 

загрузка...

Новости ИТ
17.05.2012  Zalman планирует представить на Computex пять процессорных кулеров серии CNPS
17.05.2012  Virgin Mobile USA начала продажи смартфона LG Optimus Elite
17.05.2012  ROCCAT начала продажи бюджетной игровой мышки Savu
17.05.2012  Securify анонсировала выпуск в США Wi-Fi маршрутизатора Almond с цветным тачскрином
17.05.2012  Названа цена смартфона LG Optimus LTE II с 2 ГБ оперативной памяти
17.05.2012  Sony анонсировала поставки камеры SLT-A37 и объектива SAL18135
17.05.2012  Стали известны спецификации и цена процессора Intel Core i5-3210M
17.05.2012  В Сети появились концептуальные изображения Apple iPhone 5
17.05.2012  Мышь Razer Ouroboros «засветилась» на сайте FCC
17.05.2012  Sony анонсировала выпуск объектива SEL18200LE E18-200mm F3.5-6.3 OSS LE
17.05.2012  Беспроводной маршрутизатор PROLiNK WNR1012 может играть роль мобильной точки доступа
17.05.2012  Внешний оптический привод Buffalo BRXL-PC6VU2 поддерживает чтение и запись дисков BDXL
17.05.2012  Представлена беззеркальная камера начального уровня Sony NEX-F3
17.05.2012  Galaxy выпускает видеокарты серии GeForce GT 600, включая модель GeForce GT 610 с пассивным охлаждением
17.05.2012  QNAP представляет свои первые шестнадцатидисковые сетевые хранилища
17.05.2012  NVIDIA представила первый в мире виртуализированный GPU для ускорения облачной графики
17.05.2012  Для снижения цены кулера Alpenfцhn Matterhorn Pure Edition производитель отказался от никелирования
17.05.2012  По подсчетам Gartner, продажи сотовых телефонов уменьшились на 2%, лидером рынка является Samsung
17.05.2012  ADATA начинает продажи двухканальных наборов модулей памяти XPG Xtreme DDR3-2133X
17.05.2012  Портативный монитор PROLiNK PRO1301WE питается от порта USB
16.05.2012  AOC начала продажи 22-дюймового LED-монитора e2219P2
16.05.2012  Palit представила три видеокарты моделей GeForce GT 630, GeForce GT 620 и GeForce GT 610
16.05.2012  Смартфон LG Optimus 4X HD появится в Европе уже в июне
16.05.2012  Lenovo планирует вывести на рынок суперлегкий ультрабук ThinkPad X1 Carbon
16.05.2012  Toshiba уже в этом месяце начнет продажи в Японии четырех планшетников линейки Regza
16.05.2012  Xilence Technology начала продажи 750-Вт и 850-Вт блоков питания серии XQ
16.05.2012  Zotac готовит к выходу высококачественную и производительную видеокарту модели GeForce GTX 670 Extreme
16.05.2012  Google готовит пять смартфонов Nexus?
16.05.2012  Nokia показала двухсимные телефоны для развивающихся стран
16.05.2012  AMD анонсировала второе поколение APU Trinity

 
Advertisment



 
Интересное в сети

Copyright © CompDoc.Ru
При цитировании и перепечатке ссылка на www.compdoc.ru обязательна. Карта сайта.
 
Rambler's Top100