Назад | Перейти на главную страницу

Как устранить ошибку PHP «Требуется неудачное открытие» в контексте символической ссылки?

Я использую Apache / PHP на MacOS X Lion 10.7.4. Моя структура каталогов настроена так:

/Users/achan/Sites/
lrwxrwx---   1 achan  staff    23B Apr 27 16:21 epwbst@ -> /Users/achan/dev/epwbst`

где epwbst/ это символическая ссылка внутри ~/Sites.

Если я положу test.php внутри Sites/ каталог, Apache правильно обслуживает файл; это извергает phpinfo() как и положено. Если я помещаю тот же файл под символическую ссылку, я получаю такую ​​ошибку:

[Mon May 28 14:47:13 2012] [error] [client ::1] PHP Warning:  Unknown: failed to open stream: No such file or directory in Unknown on line 0
[Mon May 28 14:47:13 2012] [error] [client ::1] PHP Fatal error:  Unknown: Failed opening required '/Users/achan/Sites/epwbst/test.php' (include_path='.:/usr/lib/php/pear') in Unknown on line 0

Чтобы убедиться, что Apache работает, я создал тестовый html-файл в ~/Sites/epwbst/ и Apache обслужил его, как ожидалось.

Почему Apache не может запустить php в моем каталоге с символической ссылкой?

Я вставил сюда свою конфигурацию php: http://pastebin.com/gg27JyVZ

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

/Users/achan/Sites/
lrwxrwx---   1 achan  staff23B Apr 27 16:21 epwbst@ -> /Users/achan/dev/epwbst`

Вот в чем загвоздка: chmod обычно не меняет разрешения на символические ссылки, потому что (за очевидным исключением php5_module и некоторые другие случаи, выходящие за рамки этого ответа) эти разрешения в значительной степени не имеют значения, поскольку они игнорируются почти во всех контекстах. Вот исправление:

chmod -h 755 /Users/achan/Sites/epwbst

Обратите внимание -h. На странице руководства:

...
-h  If the file is a symbolic link, change the mode of the link itself
rather than the file that the link points to.
...

По какой-то причине php5_module на самом деле обращает внимание на разрешения на символическую ссылку. Если они слишком строгие, php5_module откажется видеть цель, даже если httpd в противном случае пользователь мог бы прочитать и запустить ту же самую цель, используя /usr/bin/php.

Обратите внимание на следующее:

% umask 027
% cd ~/Sites
% mkdir bar
% chmod 755 bar
% ln -sv bar foo
foo -> bar
% ls -al ~/Sites/foo
lrwxr-x---  1 xyz  xyz  3 Apr 22 13:17 foo -> bar
% ls -adl ~/Sites/foo/.
drwxr-xr-x  2 xyz  xyz  68 Apr 22 13:17 /Users/xyz/Sites/foo/.
% echo 'Hello!' >bar/hello.txt
% chmod 644 bar/hello.txt
% curl http://localhost/~xyz/bar/hello.txt
Hello!
% curl http://localhost/~xyz/foo/hello.txt
Hello!

Все идет нормально. Теперь рассмотрим:

% echo '<?php phpinfo(); ?>' >bar/info.php
% chmod 644 bar/info.php
% curl http://localhost/~xyz/bar/info.php
<html xmlns="http://www.w3.org/1999/xhtml"><head>
...
</div></body></html>
% curl http://localhost/~xyz/foo/info.php
<br />
<b>Warning</b>:  Unknown: failed to open stream: No such file or directory in <b>Unknown</b> on line <b>0</b><br />
<br />
<b>Fatal error</b>:  Unknown: Failed opening required '/Users/xyz/Sites/foo/info.php' (include_path='.:') in <b>Unknown</b> on line <b>0</b><br />

Хммм. Мой httpd работает как пользователь _www, поэтому давайте проверим, может ли этот пользователь читать .../foo/info.php:

% sudo sudo -u _www cat ~/Sites/foo/info.php
Password:
<?php phpinfo(); ?>

Ага. Теперь посмотрим, может ли этот пользователь бегать .../foo/info.php:

% sudo sudo -u _www /usr/bin/php ~/Sites/foo/info.php
Password:
phpinfo()
PHP Version => 5.4.24
...
If you did not receive a copy of the PHP license, or have any
questions about PHP licensing, please contact license@php.net.

Да?! Какого черта ?! Гррр! Теперь отремонтируйте:

% chmod -h 755 foo
% curl http://localhost/~xyz/foo/info.php
<html xmlns="http://www.w3.org/1999/xhtml"><head>
...
</div></body></html>

Взрыв. Готово.

Так да. Кажется, что php5_module делает что-то параноидальное и нестандартное. Это могло быть упущено из виду, поскольку umask часто по умолчанию 022, который, по крайней мере, создаст символические ссылки с 755. Кроме того, многие файловые системы (не HFS +) устанавливают на уровне ядра разрешения 777 во время создания символической ссылки, независимо от umask.

Вы и я кажемся двумя людьми в солнечной системе, использующими Apache + PHP на HFS +, при этом устанавливая для нашей umask что-то более ограничительное, чем значение по умолчанию. Готов поспорить, вы даже используете HFS + с учетом регистра. ; о)