Статьи

PHP Gotchas: часть 1

PHP является удивительно простым языком для начала, но с этого момента, если мой собственный опыт будет чем-то полезен, разработчики, похоже, испытывают «аттракцион на американских горках» с точки зрения производительности. Некоторые люди называют PHP «Visual Basic с открытым исходным кодом», который является как жалобой, так и дополнением. Цитата, приписываемая Бьярне Страуструпу (дизайнер C ++); «Есть только два вида языков программирования: те, о ком всегда говорят, и те, кого никто не использует».…

В течение следующих нескольких недель (возможно, месяцев) мы попытаемся осветить «ошибки» PHP; вещи, которые приводят к замедлению работы разработчиков при работе с PHP. Другими словами, типы проблем, которые не очевидны заранее и становятся понятными только после того, как вы «были там». Некоторые из них будут чисто техническими (конфигурация PHP, устаревшие головные боли и т. Д.), В то время как другие будут более теоретическими (что «работает», а что нет в плане дизайна кода).

Цель состоит в том, чтобы дать понять разработчикам, начинающим работать с PHP, и, надеюсь, предотвратить разочарование до того, как это произойдет. Будут основаны главным образом на моем собственном опыте после почти пяти лет работы с PHP, а также на вещах, которые я видел на PHP-форумах Sitepoint . Дальнейший вклад / понимание высоко ценится, как и запросы по предметам.

Среда PHP и переносимость Gotchas

Начинаем, вот некоторые из распространенных ошибок, связанных с php.ini . Говоря о «переносимости» здесь, я имею в виду запуск кода под различными установками PHP, в отличие от переносимости операционной системы или обратной совместимости со старыми версиями PHP, обе из которых требуют отдельного изучения.

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

Основным заблуждением представляется предположение о том, что все установки PHP одинаковы; код, который работает под одним должен хорошо работать под всеми. Хотя это в значительной степени верно, некоторые ключевые параметры конфигурации PHP и устаревшие проблемы создают головную боль. Можно написать код, который отлично работает при любой установке PHP (при условии сопоставимых версий PHP), но требуется осторожность.

Управление конфигурацией во время выполнения

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

По сути, существует четыре основных механизма управления конфигурацией среды выполнения PHP; файл php.ini, файл Apache httpd.conf (или аналогичный, например, реестр Windows ), с использованием файлов Apache .htaccess или в самих сценариях с использованием таких функций, как ini_set () . Стоит прочитать руководство по настройке времени выполнения, а также просмотреть основные директивы и более или менее полную справочную информацию, найденную в ini_set () . Дальнейшие заметки можно найти в комментариях в самом файле php.ini .

Ключевым моментом, который следует здесь отметить, является то, что на общем веб-сервере (вашем типичном хосте PHP) пользователи будут изменять настройки только с помощью самих скриптов и, возможно, с помощью файлов .htaccess (немногие хосты позволяют пользователям изменять php.ini или httpd.conf ). , Изменение параметров с помощью .htaccess требует, чтобы Apache настроил предоставление пользователям привилегий «AllowOverride Options» или «AllowOverride All» (обычно помещается в httpd.conf под описания) — это довольно распространенное явление, но на него нельзя полагаться на 100%.

Механизм, с помощью которого можно изменить параметр конфигурации времени выполнения, зависит от самого параметра. Глядя на список, найденный в ini_set () , вы увидите значения в столбце «Изменяемые», такие как PHP_INI_PERDIR и PHP_INI_SYSTEM . На самом деле это константы, определенные следующим образом;

PHP_INI_USER : параметр конфигурации может быть изменен внутри скрипта PHP (на самом деле вы никогда не увидите его в списке — он попадает под PHP_INI_ALL ниже).

PHP_INI_PERDIR : настройку можно изменить в файле php.ini , httpd.conf или в файле .htaccess .

PHP_INI_SYSTEM : настройку можно изменить только в php.ini или httpd.conf .

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

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

Директивы Apache

Это две директивы Apache, которые можно использовать в файлах httpd.conf и .htaccess , доступных для изменения параметров конфигурации, а именно php_value для параметров, которые имеют строковые значения, и php_flag для параметров, которые имеют логические (фактически 0 или 1) значения. Пример файла .htaccess, содержащий один из обоих;

# Switch off register_globals php_flag "register_globals" 0

# Установите include_path — Unix! См. ниже…
php_value «include_path» «.: / usr / local / lib / php»

Поместите это в какой-нибудь каталог на вашем сервере и поместите скрипт PHP, содержащий;


Вы должны увидеть, что локальные значения для этих настроек были изменены ( глобальные значения — те, которые установлены в php.ini или httpd.conf ).

Примечание для системных администраторов — здесь также описаны две директивы: php_admin_value и php_admin_flag .

Конфигурация скрипта

Чтобы изменить параметры конфигурации в скрипте PHP, основными функциями являются ini_set () для изменения значения конфигурации, ini_get () для получения текущего локального значения параметра конфигурации, get_cfg_var () для получения глобального значения из php.ini , ini_get_all () для огромного массива всех настроек, содержащего как локальные, так и глобальные значения, и ini_restore () для возврата локального параметра к его глобальному значению (также переопределяя файлы .htaccess). Другие функции, такие как set_include_path (), действуют как псевдонимы для определенного параметра конфигурации, но при их использовании обращают пристальное внимание на информацию о версии PHP в руководстве.

Пример добавления значения к пути включения из скрипта PHP;


Настройки разработки

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

Сообщение об ошибке: E_ALL

При разработке переключите error_reporting на E_ALL . В частности, это отлавливает ошибки типа E_NOTICE, которые обычно можно избежать, но могут отображать сообщения об ошибках для пользователей с этим параметром и могут нарушать код при отправке заголовков HTTP. Это будет означать обновления кода, например, где вы раньше писали;


Вам нужно будет написать;

if ( isset($_GET['doSomething']) && $_GET['doSomething'] == 'yes' ) { // do something } else { // do the default }

Для предотвращения сообщений об ошибках, когда $ _GET [‘doSomething’] не установлен. Обратите внимание, что использование оператора @ для подавления сообщений об ошибках обычно медленнее, чем использование конструкции isset () .

Теги PHP

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

= $ Название?>

становится;

Проблема с short_open_tag в том, что интерпретатор PHP будет сбит с толку тегами XML (плюс любой, у кого он отключен, увидит теги как HTML), например;

$xml_body = file_get_contents('nodeclaration.xml'); ?> =$xml_body?> $xml_body = file_get_contents('nodeclaration.xml'); ?> =$xml_body?>

PHP отключится при объявлении XML, думая, что это PHP. Параметр short_open_tag , к сожалению, является PHP_INI_PERDIR, поэтому нет способа изменить его внутри скрипта (что было бы неплохо, IMO, но, без сомнения, сложно реализовать).

Регистрация глобалов: Off

Надеюсь, вы поняли, что включение register_globals, как правило, является плохой новостью для безопасности, как объясняется здесь . Будем заниматься охраной "гуч" в другой раз.

С точки зрения переносимости код, написанный с выключенным register_globals, должен запускаться с включенным register_globals ( но может быть небезопасным! ) - то же самое, вероятно, не будет работать в обратном порядке.

Короче говоря, переключатель register_globals !

Передача эталонного времени вызова: выкл.

Ссылки в PHP4 - сложная тема, о которой вы узнаете больше, и, возможно, вам понадобится их собственное обсуждение.

Для переносимости отключите allow_call_time_pass_reference . Это относится к коду, как;


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

Магические цитаты

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

С точки зрения переносимости, лучше всего написать код, который не основан на включении magic_quotes_gpc (например, использовать mysql_escape_string () ), но может функционировать правильно независимо от того, включено или выключено magic_quotes_gpc . Быстрый способ сделать это - выполнить что-то вроде следующего перед остальным кодом;

// Is magic quotes on? if (get_magic_quotes_gpc()) {

// Да? Удалите добавленные косые черты

$ _GET = array_map ('stripslashes', $ _GET);
$ _POST = array_map ('stripslashes', $ _POST);
$ _COOKIE = array_map ('stripslashes', $ _COOKIE);

}

Включить разделитель пути

Хотя я и сказал, что не буду говорить о проблемах, связанных с операционной системой, как я уже говорил выше, стоит помнить, что разделитель include_path отличается в Unix и Windows. Если вы устанавливаете его в PHP-скрипте, уловка, которую вы уже видели выше, может помочь;

if (strtoupper(substr(PHP_OS, 0,3) == 'WIN')) { $seperator = ';'; } else { $seperator = ':'; }

[Обновить]
PHP 4.3.4 предоставляет предопределенную константу PATH_SEPARATOR, которая содержит вышеуказанный символ, необходимый для путей включения.

Спасибо Джошелли за отзыв
[/Обновить]

Безопасный режим

Errr - нет, спасибо. Лично не пишите код для пользователей, работающих в безопасном режиме. Если кто-то хочет заполнить этот пробел, пожалуйста.

Проблемы SAPI

У PHP есть несколько серверных API, возможно, двумя наиболее популярными являются API Apache и CGI API. Новый CLI API добавляет дополнительные проблемы. Функция PHP php_sapi_name () может быть полезна.

Здесь обсуждается API-интерфейсы Apache и CGI, в частности, связанные с переменной $ _SERVER ['PATH_TRANSLATED'] . Примечания по совместимости между двоичными файлами CLI и CGI при выполнении сценариев командной строки можно найти в более поздней половине этой страницы .

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