В PHP есть проблемы с путями: «./» не указывает, где я этого ожидаю? - PullRequest
1 голос
/ 31 июля 2011

Я разрабатываю php MVC framework с нуля и столкнулся с интересной проблемой относительного пути развертывания WAMP по умолчанию ... проблема возникла, когда я начинал писать, включает в себя и требует изнутри среды ...

Моя точка входа в фреймворк находится в одной папке в корне документа:

http://localhost/platform/index.php <- точка входа в каркас; физический путь c: / wamp / www / platform / </p>

Когда я запускаю следующий код обхода каталога из ЛЮБОГО файла в платформе ...

$handle = opendir('./');
while ($file = readdir($handle))
{    
    echo $file."<br/>";   
}

... я получаю тот же результат:

.
..
ABOUT_APACHE.txt
bin
cgi-bin
CHANGES.txt
conf
error
htdocs
icons
include
INSTALL.txt
lib
LICENSE.txt
logs
manual
modules
NOTICE.txt
OPENSSL-NEWS.txt
OPENSSL-README.txt
README-win32.txt
README.txt
wampserver.conf

Это содержимое папки c: /wamp/bin/Apache2.2.17/

сбросить ini_get ('include_path') ".; C: / php / pear" ... Это любопытно, потому что это установка WAMP по умолчанию, которая помещает php в c: /wamp/bin/php/php5.3.4 / и, насколько я могу судить, нигде не помещает PEAR (я не вижу его в папке php5.3.4!) ...

Первый вопрос : Почему «./» не находится внутри какого-либо конкретного файла в webroot, ссылаясь на каталог, в котором находится файл, из которого он вызывается? Первый вопрос, вторая часть: почему он всегда ссылается на корень развернутой wamp-папки apache, независимо от расположения вызывающего файла?

Сброс содержимого папки в "/" показывает:

$INPLACE.~TR
$RECYCLE.BIN
$WINDOWS.~Q
boot
bootmgr
BOOTSECT.BAK
cert.pfx
Config.Msi
Documents and Settings
DVDPATH.TXT
hiberfil.sys
HP
msdia80.dll
MSOCache
pagefile.sys
PerfLogs
Program Files
Program Files (x86)
ProgramData
Recovery
SWSetup
System Volume Information
System.sav
updatedatfix.log
Users
wamp
Windows

Второй вопрос - почему путь "/" при открытии из моего скрипта ссылается на C: \, а не на корень документа (который будет C: \ wamp \ www)

Последний вопрос - Как мне настроить PHP, чтобы убедиться, что то, что я СЧИТАЮ, является ожидаемым путем в этих ситуациях (/ => корень документа, папка ./ => ссылочного скрипта) на самом деле путь к этим ссылкам?

Я полностью делаю это неправильно? Одно время я думал, что относительный путь относится к сценарию CALLED или к папке точки входа, в данном случае c: / wamp / www / platform / ... Независимо от того, какой файл ссылается, кроме php. Чистая документация говорит об обратном. PHP.net говорит, что любая папка, в которой находится FILE, которая выполняет функцию с использованием относительного пути (с начальным периодом), должна быть начальной точкой относительного пути. Похоже, в моей конфигурации это не так ...

Спасибо за ваше время!

1 Ответ

1 голос
/ 01 августа 2011

Первый вопрос: Относительные пути включения интерпретируются относительно текущего рабочего каталога;при запуске через apache + mod_php обычно это местоположение скрипта верхнего уровня, который вызывается напрямую из apache.Это несколько неудачное дизайнерское решение, которое из-за популярности PHP не может быть отменено.

Второй вопрос: PHP изначально был написан для Unix-подобных систем, где / обозначает абсолютноеКорень файловой системы.В Windows такого нет, поэтому вместо этого PHP использует следующую лучшую вещь - каталог верхнего уровня в основной файловой системе, обычно это C:\.

Третий вопрос: Два решения здесь.Первое решение: установите правильный include_path в вашем скрипте с автоподстановкой и используйте только относительные имена, например, когда у вас есть C:\www\myproject\foo\bar.php, добавьте C:\www\myproject\foo к вашему include_path и просто include 'foo.php'.Второе решение: используйте комбинацию функции dirname() и суперглобального __FILE__, чтобы явно включить ваши включения относительно текущего файла, например, если вы хотите включить C:\www\myproject\foo\bar.php из C:\www\myproject\baz.php, используйте что-то вроде include dirname(__FILE__) . '/foo/bar.php'.На практике вы, вероятно, будете использовать комбинацию обоих методов, т. Е. Использовать трюк dirname(__FILE__) в сценарии автоматического добавления, чтобы задать путь включения относительно самого сценария автоматического добавления.

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

О, и вы, вероятно, захотите прочитатьдокументация: http://www.php.net/manual/en/function.include.php

...