Как вы знаете правильный путь для использования в операторе PHP require_once () - PullRequest
12 голосов
/ 06 ноября 2008

Как много у меня есть файл config.php в корне веб-приложения, который я хочу включить почти в любой другой файл php. Таким образом, большинство из них имеют следующую строку:

require_once("config.php");

или иногда

require_once("../config.php");

или даже

require_once("../../config.php");

Но я никогда не понимаю это правильно с первого раза. Я не могу понять, что php будет считать текущим рабочим каталогом при чтении одного из этих файлов. Очевидно, это не каталог, в котором выполняется файл, содержащий вызов require_once (), потому что в одном каталоге я могу иметь два файла с разными путями для config.php.

Как у меня возникает ситуация, когда один путь верен для обновления страницы, но для ajax, который обновляет часть страницы, требуется другой путь к config.php в операторе require_once ();

В чем секрет? Откуда этот путь оценивается?

Стреляй, я боялся, что это не будет распространенной проблемой - это происходит под apache 2.2.8 и PHP 5.2.6, работающими на windows.

Ответы [ 9 ]

23 голосов
/ 06 ноября 2008

Текущий рабочий каталог для PHP - это каталог, в котором находится вызываемый файл скрипта. Если ваши файлы выглядят так:

/A
   foo.php
   tar.php
   B/
       bar.php

Если вы вызываете foo.php (например: http://example.com/foo.php),, рабочий каталог будет / A /. Если вы вызываете bar.php (например: http://example.com/B/bar.php),, рабочий каталог будет / A / B /.

Там есть, где это сложно. Допустим, что foo.php такой:

<?php
require_once( 'B/bar.php' );
?>

И bar.php это:

<?php
require_once( 'tar.php');
?>

Если мы вызовем foo.php, то bar.php успешно вызовет tar.php, потому что tar.php и foo.php находятся в одном каталоге, который является рабочим каталогом. Если вы вместо этого вызовете bar.php, он потерпит неудачу.

Как правило, вы увидите либо во всех файлах:

require_once( realpath( dirname( __FILE__ ) ).'/../../path/to/file.php' );

или с файлом конфигурации:

// config file
define( "APP_ROOT", realpath( dirname( __FILE__ ) ).'/' );

с остальными файлами, используя:

require_once( APP_ROOT.'../../path/to/file.php' );
8 голосов
/ 06 ноября 2008

Мне нравится это делать:

require_once(dirname(__FILE__)."/../_include/header.inc");

Таким образом, ваши пути всегда могут быть относительно текущего местоположения файла.

3 голосов
/ 06 ноября 2008

Большую часть времени я использую dirname(<code>__FILE__) , например bobwienholt , но за это стоит заплатить базовую точку входа, которая загружает весь ваш другой код, определяющий постоянную ссылку в корень проекта, т.е.

define("ROOT",dirname(__FILE__).'/' ); 

, а затем все, что вам нужно знать, это где путь относительно корня, то есть:

require(ROOT . "/lib/tool/error.php"); 

примечание,

вам следует REALLY избегать путей с "../" в начале их, они не относятся к файлу, а относительно того, где вы ARE , и это создает код с ошибками ,
 cd foo
 php bar/baz.php 
 -> some error saying it cant find the file
 cd bar 
 php baz.php 
 -> suddenly working.

Важно

Если вы используете нотацию "../", потребуется complete незнание пути PHP Include, и ONLY определяет, где находится человек, который его запускает.

2 голосов
/ 06 ноября 2008

Я добавляю этот код вверху каждой страницы:

//get basic page variables
$self=$_SERVER['PHP_SELF']; 
$thispath=dirname($_SERVER['PHP_SELF']);
$sitebasepath=$_SERVER['DOCUMENT_ROOT'];

//include the global settings, variables and includes

include_once("$sitebasepath/globals/global.include.php");

Включите и укажите оба пути: либо относительный, либо полный путь. Я предпочитаю работать с полным путем и делать все мои ссылки, как приведенное выше утверждение inlcude. Это позволяет мне ввести общую переменную $ sitebasepath, которая обрабатывает специфическую для аккаунта информацию, которая может меняться от машины к машине, а затем просто введите путь от webroot, т.е. /globals/whatever_file.php

Я также использую переменную $ self в формах, которые могут вызывать себя для обработки ввода данных.

Надеюсь, это поможет.

1 голос
/ 06 ноября 2008

Если у вас достаточно прав доступа, попробуйте изменить настройку PHP include_path для всего сайта. Если вы не можете этого сделать, вам придется либо направлять каждый запрос через один и тот же PHP-скрипт (например, используя Apache mod_rewrite), либо вам придется использовать скрипт «initialization», который устанавливает include_path:

$includeDir = realpath(dirname(__FILE__) . '/include'); 
ini_set('include_path', $includeDir . PATH_SEPARATOR . ini_get('include_path'));

После того, как этот файл включен, используйте пути относительно каталога include:

require_once '../init.php'; // The init-script
require_once 'MyFile.php'; // Includes /include/MyFile.php
1 голос
/ 06 ноября 2008

Поскольку require и require_once очень похожи на include и include_once, вся документация размещена в области документации «include» функций на php.net. С этой страницы

Сначала просматриваются файлы для включения для каждой записи include_path относительно текущей работы каталог, а затем в каталоге текущего скрипта. Например. если твой include_path - это библиотеки, текущие рабочий каталог / www /, вы включены include / a.php и есть включите "b.php" в этот файл, b.php впервые просматривается в / www / библиотеки / а затем в / www / include /. Если имя файла начинается с ./ или ../, это выглядит только в текущем рабочем каталоге.

Кроме того, вы можете найти все текущие пути включения, выполнив команду "php -i" из командной строки. Вы можете редактировать путь включения в файле php.ini, а также через ini_set (). Вы также можете запустить функцию php_info () на своей странице, чтобы получить распечатку ваших переменных env, если CLI неудобен.

0 голосов
/ 06 ноября 2008

Путь к файлу PHP, запрошенному в исходном GET или POST, по сути является «рабочим каталогом» этого скрипта. Любые «включенные» или «обязательные» сценарии также будут наследовать его как свой рабочий каталог.

Я буду либо использовать абсолютные пути в операторах require, либо изменить PHP include_path, чтобы включить любой путь в мое приложение, которое я могу использовать, чтобы избавить меня от лишней типизации. Вы найдете это в php.ini.

include_path = ".: / List / of / paths /: / another / path /: / и / another / one"

Я не знаю, поможет ли это вам в данном конкретном случае, но магические константы, такие как FILE и DIR , могут пригодиться, если вам когда-нибудь понадобится узнать Путь, в котором выполняется конкретный файл.

http://us2.php.net/manual/en/language.constants.predefined.php

0 голосов
/ 06 ноября 2008

Посмотрите на функцию getcwd. http://us2.php.net/getcwd

0 голосов
/ 06 ноября 2008

Единственное место, где я видел оцененный путь, - это файл, который вы в данный момент редактируете. У меня никогда не возникало с этим проблем, но если да, вы можете предоставить больше информации (версия PHP, ОС и т. Д.).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...