Я думаю, что я нашел ошибку в PHP crypt()
функции под Windows.
Однако: я понимаю, что это, вероятно, моя ошибка. PHP используется миллионами и обрабатывается тысячами; мой код используется десятками и работал мной. (Этот аргумент лучше объясненный в Coding Horror.)
Итак, я прошу помощи: показать мне свою ошибку. Я пытался найти его в течение нескольких дней, без везения.
Настройка
Я использую установку сервера Windows с Apache 2.2.14 (Win32) и PHP 5.3.2. В моем окне разработки работает Windows XP Professional; сервер "production" (это интрасети) запускает Windows Storage Server 2003. Проблема возникает и на обоих.
Я не вижу ничего в php.ini
, относящегося к crypt()
, но с радостью ответит на вопросы о моей конфигурации.
Проблема
Иногда несколько скриптов в моем приложении PHP зависают: страница сидит там в ожидании localhost и никогда не заканчивается. Каждый из этих сценариев использует crypt
для хеширования пользовательского пароля перед сохранением его в базе данных или, в случае страницы входа, для хеширования введенного пароля, прежде чем сравнивать его с версией, хранящейся в базе данных.
Поскольку страница входа является самой простой, я сосредоточился на ней для тестирования. Я неоднократно вошел в систему и обнаружил, что он может висеть, возможно, 4 раза в 10 раз.
В качестве эксперимента я изменил страницу входа в систему, чтобы использовать простой текстовый пароль и изменил свой пароль в базе данных на его текстовую версию. Страница перестала висит.
Я видел, что последняя версия PHP содержит это исправление:
Исправлена ошибка # 51059 (crypt вылетает, когда недействительная соль указаны [sic]).
Итак, я создал очень простой тест script следующим образом, используя ту же соль, что и в официальный пример:
$foo = crypt('rasmuslerdorf','r1');
echo $foo;
Эта страница тоже будет зависать, если я перезагружу ее, как сумасшедшую. Я только вижу, который висит в Chrome, но независимо от браузера эффект на Apache одинаковый.
Эффект на Apache
Когда эти страницы зависают, Apache страница состояния сервера (что я объяснил здесь, в отношении другой проблемы) увеличивает количество обрабатываемых запросов и уменьшает количество незанятых работников. Обработанные запросы почти все имеют статус "Отправка ответа", хотя иногда на мгновение они будут показывать либо "Чтение запроса", либо "keepalive" (чтение). '
В конце концов, Apache может сбой. Когда это произойдет, отчет о сбое Windows выглядит следующим образом:
szAppName: httpd.exe
szAppVer: 2.2.14.0
szModName: php5ts.dll
szModVer: 5.3.1.0 // OK, this report was before I upgraded to PHP 5.3.2,
// but that didn't fix it
offset: 00a2615
Это моя вина?
У меня возникает соблазн представить отчет об ошибке на PHP. Аргумент против него, как указано выше, в том, что ошибки почти всегда являются моей ошибкой.
Однако мой аргумент в пользу "этого ошибки PHP":
- Я использую Windows, в то время как большинство серверов используют Linux (я не могу это выбрать), поэтому шансов больше, чем я нашел краевой случай
- Недавно была ошибка с
crypt()
, поэтому, возможно, у нее все еще есть проблемы. - Я сделал простейший тестовый пример, и у меня все еще есть проблема.
Может ли кто-нибудь повторить это? Можете ли вы предложить, где я ошибся? Должен ли я записывать ошибку?
Заранее благодарим за любую помощь, которую вы можете дать.