Случайная несогласованность путей файлов PHP на Mac/MAMP?
Я разрабатываю PHP-программу на MAMP и просто понимаю следующее шуточное поведение:
echo "<br/>PATH = ".dirname(__FILE__);
include 'include.php';
include.php:
<?php
echo "<br/>PATH = ".dirname(__FILE__);
?>
Результат:
PATH =/users/me/stuff/mamp_server/my_site (все строчные буквы)
PATH =/Пользователи/me/Stuff/mamp_server/my_site (смешанный случай)
Что вызывает это непоследовательное поведение и как я могу защитить его? (Обратите внимание: я не могу просто преобразовать все в нижний регистр, потому что приложение предназначено для Linux-сервера, где пути к файлам чувствительны к регистру.)
Update:
Эта проблема существует для __FILE__
и __DIR__
.
Похоже, что это может быть реальной проблемой, когда нет работы... собираюсь подать отчет об ошибке, если не услышу иначе.
Отчет об ошибке:
https://bugs.php.net/bug.php?id=60017
Обновление:
И еще одно примечание. Если вы делаете абсолютный путь, включите (...) на Mac, для него требуется версия смешанного варианта.
Ответы
Ответ 1
У меня были схожие проблемы с разработкой PHP на MAC OS X. Вы можете форматировать файловую систему, чувствительную к регистру, но если вы используете программное обеспечение Adobe для разработки, вы можете столкнуться с проблемами: http://forums.adobe.com/thread/392791
Реальная проблема заключается в том, что файловая система, которая, как говорят, нечувствительна к регистру, на самом деле частично нечувствительна к регистру. Вы можете создать два файла с именами "Filename" и "filename" в том же каталоге, но "Filename" и "filename" могут указывать на оба файла: http://systemsboy.com/2005/12/mac-osx-command-line-is-partially-case-insensitive.html
Ответ 2
Как создать файл include в том же каталоге, что и ваше приложение.
<?php return __DIR__; ?>
Используйте его так:
$trueDIR = include('get_true_dir.php');
Из того, что вы опубликовали выше, это должно сработать. Да, это немного хакерское решение, но это обходной путь, и он должен работать даже в системах, не страдающих этой проблемой.
Ответ 3
Это код, который я использую для получения правильной оболочки определенного имени файла:
function get_cased_filename($filename)
{
$globbable = addcslashes($filename, '?*[]\\');
$globbable = preg_replace_callback('/[a-zA-Z]/', 'get_bracket_upper_lower', $globbable);
$files = glob($globbable);
if (count($files)==1)
{
return $files[0];
}
return false;
}
function get_bracket_upper_lower($m)
{
return '['.strtolower($m[0]).strtoupper($m[0]).']';
}
Glob должен соответствовать только одному файлу, но если он используется в файловой системе, чувствительной к регистру, то он может соответствовать большему - требуемое поведение зависит от вас - например, возвратите [0]
или выбросьте E_NOTICE
или что-то еще.
Вам может показаться полезным: $mydir = get_cased_filename(dirname(__FILE__));
Работает для моего CLI PHP 5.3.6 на Mac 10.6.8.
Я использую его для общения с коллегами, которые не замечают такие вещи, как "Имя файла" и "имя файла". (Эти люди также задаются вопросом, почему имена файлов, которые содержат " > " или "?", Не работают при копировании с Mac на сервер Windows, но я отвлекаюсь...)
Ответ 4
Я использовал apache, и я обнаружил, что __DIR__
исполняемого файла был тем же, что и в DOCUMENT_ROOT конфигурации apache.
Это означает, что если config Apache имел
DocumentRoot /users/me/stuff/my_site
script из вопроса была печать:
PATH = /users/me/stuff/my_site (All lower case)
PATH = /Users/me/stuff/my_site (Mixed case)
И если в конфигурации apache:
DocumentRoot /users/me/stuff/my_site
script из вопроса была печать:
PATH = /Users/me/stuff/my_site (Mixed case)
PATH = /Users/me/stuff/my_site (Mixed case)
Что было намного лучше.
Если вы столкнулись с этой проблемой, проверьте конфигурацию apache, учитывая, что она чувствительна к регистру.