использование php is_dir(‘~/tmp’) работает на одной машине, но не на другой. Почему?

#php #apache #zend-server-ce

#php #apache #zend-сервер-ce

Вопрос:

Я пытаюсь запустить следующий код:

 is_dir('~/tmp');
 

В общем стеке LAMP. Он работает нормально и возвращает TRUE. (Этот каталог существует.) Когда я запускаю тот же код на своем локальном компьютере (Mac OSX 10.5, работает Zend Server Community Ed), я получаю FALSE, что неверно, потому что ~/tmp существует и имеет разрешения, установленные на 777.

Я думаю, мне где-то не хватает директивы сервера.

Я проверил с помощью phpInfo, и у меня есть (как на локальном, так и на рабочем месте):

 safe_mode           Off         Off

safe_mode_exec_dir  no value    no value

safe_mode_gid           Off         Off

safe_mode_include_dir   no value    no value

open_basedir    no value    no value
 

Поэтому я думаю, что мне чего-то не хватает, но чего?

[править …] Еще немного информации…

запускаю следующее на моем локальном

 get_current_user()
 

выдает мне ‘username’, который является правильным пользователем, чей каталог ~ / tmp я хочу проверить, НО

 shell_exec('whoami')
 

выдает мне ‘daemon’. Так что я думаю, что знаю, откуда берется моя проблема. Теперь мне просто нужно выяснить, могу ли я изменить пользователя, который запускает веб-сервер на моем локальном сервере.

Комментарии:

1. Вы бы использовали этот каталог для хранения временных файлов (прочитали, использовали один раз, а затем удалили)?

2. Точно. Это место для размещения журнала отладки, например.

3. Вы могли бы использовать sys_get_temp_dir функцию. Я добавлю пример.

Ответ №1:

Вы ожидаете ~ , что он будет расширен до вашего домашнего каталога? Я бы не хотел полагаться на это внутри PHP. (Только что протестировал его на моем Mac, и он не расширился.)

Если возможно, попробуйте изменить ~/tmp полное имя пути на любое другое (например, что-то вроде /Users/meriial/tmp ).

ОБНОВЛЕНИЕ: в качестве альтернативы вы можете ~ заменить $_ENV['HOME'] следующим образом:

 is_dir($_ENV['HOME'] . '/tmp');
 

В идеале, вы должны сначала проверить, что array_key_exists('HOME',$_ENV) возвращает TRUE , и предпринять некоторые соответствующие действия (например, использовать системный временный каталог), если это не так.

В этом отношении, как указывает @xmarcos, вы могли бы просто использовать системный каталог temp независимо от использования sys_get_temp_dir() и tempnam() . Это может быть наиболее переносимым и, следовательно, вашим лучшим выбором. Я думаю, вы также можете создать атомарный временный файл таким образом, чтобы он был более безопасным и менее подверженным условиям гонки.

Комментарии:

1. Да, я ожидаю, что ~ расширится в мой домашний каталог. Он работает на Linux-компьютере с общим хостингом, но не на моем mac. Проблема в том, что я хотел бы писать в ~/tmp, не имея другого кода на машинах для производства и разработки.

2. Вместо использования ~ вы могли бы использовать переменную $HOME среды.

3. Я должен был быть менее уверен, что ~ расширяется до домашнего каталога на моем рабочем сервере. (Потому что это не так.) Можем ли мы с уверенностью сказать, что php никогда не расширяет ~ до домашнего каталога?

4. Я считаю, что расширение тильды является функцией оболочки, и я не вижу документации, предполагающей, что PHP ее копирует. Я бы не сказал с уверенностью, что он никогда этого не делает, но я сильно подозреваю, что это правда.

Ответ №2:

Вы уверены, что этот каталог существует внутри вашего пользовательского каталога?

Перейдите Terminal и введите cd ~/tmp . Работает ли это?

Обновление: вы могли бы использовать sys_get_temp_dir , если доступно, пример кода:

 $some_log = tempnam(sys_get_temp_dir(), 'some_log');    
var_dump($some_log);
// will return '/private/var/folders/.../some_logbqzDvg'
 

Комментарии:

1. 1 для sys_get_temp_dir . Проблема, вероятно, в том, что PHP запускается от имени другого пользователя, поэтому ~ в PHP и ~ в терминале есть два разных каталога.

Ответ №3:

для всех виртуальных путей попробуйте сначала развернуть их. сделайте:

 var_dump(realpath('~/tmp'));
 

а затем посмотрите, что произойдет,
а затем попробуйте opendir() и посмотрите, какую ошибку он получает.

Комментарии:

1. ах-ха! хороший совет. оказывается, на моем рабочем сервере is_dir(‘~/tmp’) возвращал значение TRUE, потому что существовал каталог /path/to/working/directory/~/tmp, который я обнаружил после использования realpath(). Поскольку ~/tmp также существовал, я предположил, что он расширяет ~ до домашнего каталога, но это было не так.

2. означает ли это, что php может / никогда не будет расширять ~ до домашнего каталога?

3. @meriial php здесь имеет очень мало общего. PHP работает в системе, и если система расширяется, то и PHP работает.

4. когда вы говорите «система», вы имеете в виду оболочку? Оболочка как на моих производственных (linux), так и на серверах разработки (mac) расширяется ~ , но php realpath() и is_dir() этого не делают. См. Комментарий Тротта выше.