|
Правильное программирование WEB-приложений на PHP
- Не полагайтесь на включенную директиву register_globals.
Все обращения к внешним переменным ведите только через $_GET, $_POST, $_COOKIE. К серверным переменным обращайтесь через $_SERVER. Работу с сессиями (если это необходимо) ведите через $_SESSION. $_REQUEST использовать не рекомендуется.
- $_GET, $_POST, $_COOKIE, $_SESSION, $_REQUEST являются суперглобальными массивами (использование global для них не нужно). Помните про наличие массива $GLOBALS.
- echo и print - не одно и то же!
Читайте manual по этим функциям.
- include и require - не одно и то же!
Хороший программист должен знать, что и когда у него «инклудится». В большинстве случаев include_once и require_once использовать предпочтительнее. include выдает только warning, если файл не удалось подключить. require заставляет скрипт прекратить работу в случае неудачи.
- Если нужно подключить файл от корня сайта, то перед / используйте $_SERVER['DOCUMENT_ROOT'].
- При работе с MySQL используйте функции mysql_connect, mysql_select_db, mysql_query, mysql_num_rows, mysql_fetch_row, myqsl_fetch_array (с явным указанием MYSQL_NUM или MYSQL_ASSOC), mysql_free_result, mysql_insert_id, mysql_error. Не используйте устаревшие функции на подобие mysql_db_query.
Необходимость/возможность использования персистентных соединений должна быть обоснована и обсуждена с техническими специалистами/администраторами хостинга.
- Кавычки: двойные и одиночные (апострофы)
Строки, заключенные в "", обрабатываются интерпретатором на предмет наличия в них переменных и специальных символов (\n, \r, \t и др.). Этот процесс называется интерполяцией. В случае с одиночными кавычками интерполяции не происходит, что увеличивает скорость работы.
- Безопасность СУБД
Необходимо понимать, что web-серверу могут быть переданы параметры, которые без соответствующей обработки могут позволить злоумышленнику модифицировать SQL-запрос. Если magic_quotes_gpc включены, то дополнительные обработки не требуются. В противном случае нужно использовать функцию addslashes для каждой переменной, вставляемой в SQL-запрос. Если в запрос через переменную должно вставляться число, то либо проверьте, что оно действительно число (функция is_numeric), либо оберните эту переменную в кавычки (как если бы Вы вставляли строку в запрос).
Обратите внимание на переменные, которые вставляются в SQL-запрос, но не являются внешними с точки зрения web-сервера. Такие переменные также необходимо предварительно обработать (либо вручную, либо при помощи magic_quotes_runtime).
- Безопасность файловой системы
Не используйте без предварительной обработки переменные, которые применяются в функциях работы с файлами (include, require, fopen и др.)
- Генерируемый HTML-код должен быть синтаксически правильным. Входные параметры ($_GET, $_POST и т.д.) перед выходом должны быть обработаны функцией htmlspecialchars или функцией urlencode (если переменная вставляется в URL-адрес).
- Перед написанием собственной функции проверьте наличие в PHP функции, реализующей подобный функционал. Примеры: in_array, is_numeric, strtolower, и т.д.
- При организации перенаправления (отправку HTTP-заголовка Location) указывайте URL полностью, включая протокол, хост и URI:
header('Location: http://' . $_SERVER['HTTP_HOST'] . '/path/to/redirect/?ok=1');
- Если идет цикл по элементам массива и в цикле не подразумевается изменение числа элементов, то рекомендуется перед циклом присвоить какой-либо переменной число элементов данного массива: $tmp = count($arr); for ($i=0; $i < $tmp; $i++) { // do something }; unset($tmp). Это позволит избежать вызова функции count для каждого элемента массива. Кстати, count и sizeof – одно и то же.
- Если заведенная Вами переменная более не понадобится (в оставшейся части кода), то делайте unset($someVar). Это позволит уменьшить пиковый расход памяти.
- На сервере разработки обязательно включайте ошибки и предупреждения, смотрите логи.
На боевом сервере посетитель не должен увидеть то, что он видеть не должен: всё отправляйте в лог.
- На один сайт предлагается использовать одну БД и одного MySQL-пользователя. Если имена таблиц разных сервисов одного сайта пересекаются, то используйте разные префиксы для имен таблиц.
В скриптах имена таблиц объявляйте в конфигурационном файле.
- Сжатие страниц с помощью gzip в большинстве случаев должно быть включено.
Лучше, если за сжатие отвечает легкий проксирующий web-сервер (например, nginx), тогда процессы апача будут быстрее высвобождаться для новых запросов. Если проксирующего веб-сервера нет, то самое простое - установить zlib.output_compression в значение On (например, в .htaccess-файле).
- При использовании переменных, которые должны инициироваться не Вами, проверяйте их с помощью функции isset. Например, $test = $_GET['test'] может выдать предупреждения. Тут же рекомендуется делать проверку на допустимость значения:
$test = (isset($_GET['test']) && is_numeric($_GET['test'])) ? $_GET['test'] : 0;
- Скобки
Хотя PHP имеет вполне определенный приоритет операторов, рекомендуется для быстроты чтения кода (человеком) ставить «лишние» скобки.
- Для удобства чтения кода (человеком) не используйте альтернативный синтаксис управляющих структур (когда открывающая фигурная скобка заменена на двоеточие, а закрывающая на end и имя управляющей структуры).
- Комментарии
При реализации сложных алгоритмов краткие комментарии просто необходимы. Использование комментариев в стиле Shell и Perl (#) нежелательно.
Алексей Кощеев 12.06.2006 (ревизия 08.05.2008, 10.12.2010)
|
 |