Этот сайт не наркоманов. Это сайт программистов.

Добро пожаловать на Пыху!

Логин:
Пароль:
 

Нет прописки? Зарегистрируйся!

Новости

Мы в твиттере!
Мы вконтакте!
Мы на яндексе!

Краснодарское время: 22 Май, 2012, 06:28:26

Страниц: [1]
Печать
Автор Тема: Указание пути к подключаемому файлу  (Прочитано 15156 раз)
0 Пользователей и 1 Гость смотрят эту тему.
vasa_c    ↓ 
13 Август, 2007, 09:17:43
НЕ ХУЕТА! ХУЕТА!

Группа: в ухо

Карма: 81
Сообщений: 2458
Сила слова: 3.3

При использовании include/require, а так же других файловых функций, требуется указывать путь к файлу.
Пути бывают двух видов: абсолютные и относительные.
 
Абсолютный путь указывает путь к файлу от корня файловой системы:
Text (Unknown Language)
/home/user/file - в Unix'е корень обозначается как "/".
C:\Folder\file.txt - в Windows корнем является имя диска.

Относительный путь указывает файл относительно текущего каталога:
Text (Unknown Language)
script.php - файл в текущем каталоге
./script.php - тоже самое, "." обозначает текущий каталог
./folder/script.php - файл находится в каталоге folder, являющимся подкаталогом текущего
../script.php - файл находится в каталоге, являющимся родительским для текущего
./../folder/script.php - файл из каталога folder, находящимся в одном родительском каталоге вместе с текущим.

Каждый исполняющийся сценарий имеет связанный с ним текущий каталог, относительно которого и разруливаются относительные пути. Текущим каталогом назначается каталог в котором хранится файл сценария. В процессе работы он может быть изменен с помощью функции chDir().
 
Очень важно понимать, что является исполняющимся сценарием.
Например, запрашиваем из браузера документ httр://site.ru/script.php. web-сервер находит соответствующий ему сценарий, допустим /home/site.ru/www/script.php. Запускает его. В сценарии есть инструкция:
PHP
require_once('./folder1/file1.php');
В файле file1.php есть строчка:
PHP
require_once('./folder2/file2.php');

То есть изначальный файл подключает другой файл, а тот, в свою очередь, третий.
 
Так вот, подобных включений может быть сколько угодно и какой угодно может быть степень вложенности. Однако, исполняемый сценарии (процесс операционной системы) будет только один - изначальный сценарий /home/site.ru/www/script.php. А текущим каталогом будет /home/site.ru/www/. Будет на всем протяжении сценария, вне зависимости от require().
 
Таким образом, при выполнении require_once('./folder2/file2.php') папка folder2 будет искаться не в папке folder1, где лежит file1.php, а в папке изначального сценария - /home/site.ru/www/.
 
От непонимания данной вещи очень часто случаются сложноуловимые ошибки. Что же делать, как избежать геморроя при указании пути? Рецептов несколько.
 

Изменение текущего каталога
 
Перед каждым require() изменять текущий каталог при помощи chDir() на каталог подключаемого файла. Старое значение сохранять в какой-либо переменной (желательно в стеке) и восстанавливать после require().
 
Данное решение я привел "до кучи". Несоменно, заниматься подобным маразмом не стоит.
 

Указание путей относительно текущего каталога
 
Если использующий require() сценарий может быть только исполняемым (вызываться из браузера, но не подключаться через require) такой вариант вполне рабочий.
 
Если сценарий может подключаться только из одного исполняемого файла (или возможные исполняемые файлы лежат в одном каталоге), то данный вариант так же прокатывает.
 
Однако, если файл может подключаться из разных мест, то так не получится, т.к. текущий каталог может быть каждый раз разным.
 

Указание абсолютных путей
Собственно наиболее верный и наиболее распространенный способ. Однако, и здесь могут быть варианты.
 
Можно каждый раз прописывать путь явно:
PHP
require('/home/site.ru/www/folder1/file1.php');
require('/home/site.ru/www/folder2/file2.php');
Но так можно запариться прописывать и тем более перепрописывать в случае изменения.
 
Можно вынести в конфиг:
PHP

define('DIR_WWW', '/home/site.ru/www/');
...
require(DIR_WWW.'/folder1/file1.php');
require(DIR_WWW.'/folder2/file2.php');
 
Многие так и делают. И зря. Так как опять таки затруднен перенос из папки в папку, с сервера на сервер. Каждый раз придется отыскивать все подобные дефайны и исправлять.
 
В PHP есть предопределенная переменная $_SERVER['DOCUMENT_ROOT'], которая содержит путь к корневой папке сайта. Лучше всего плясать от нее:
PHP

require($_SERVER['DOCUMENT_ROOT'].'/folder1/file1.php');
require($_SERVER['DOCUMENT_ROOT'].'/folder2/file2.php');
 

Использование DOCUMENT_ROOT является наиболее разумным способом при подключении различных частей сайта из главного файла или из других частей.
 
Однако для указания файлов внутри какой-то отдельной части (модуля) этот способ не совсем удобен.
Например, вы пишите библиотеку состоящую из нескольких файлов и подключающих друг друга. Она может использоваться на множестве сайтов и располагаться в различных каталогах. Очевидно, что здесь гораздо лучше привязываться не к корню сайта, а к местоположению самих файлов библиотеки. Здесь может помочь "магическая" константа __FILE__. Она содержит абсолютный путь к текущему обрабатываемому файлу, т.е. к файлу в котором используется. Таким образом, подключение файла расположенного в том же каталоге, что и подключающий:
PHP
require_once(dirName(__FILE__).'/file.php');
Записан

adw0rd    ↓ 
18 Август, 2007, 11:11:19 , спустя 5 дней 1 час 53 минуты 36 секунд
НЕ ХУЕТА! ХУЕТА!

эдво
Группа: в ухо

Карма: не нужна
Сообщений: 17610
Сила слова: 1.67

Также можно использовать include_path
 
set_include_path();
Только для PHP 4 >= 4.3.0, PHP 5
PHP

<?php
 
if(!defined( "PATH_SEPARATOR" )) {
    if(strpos( $_ENV[ "OS" ], "Win" ) !== false ) {
        define( "PATH_SEPARATOR", ";" );
    } else {
        define( "PATH_SEPARATOR", ":" );
    }
}
 
$path = '/home/user/siteru/www/libdir/';
 
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
 
?>
 

ini_set();
Для всех версий PHP
PHP

ini_set('include_path', '/inc');
 
« Последнее редактирование: 18 Август, 2007, 11:14:15 от ad3000 » Записан

Python, Django, Git, Emacs, Nginx, MySQL, SphinxSearch, FreeBSD/Linux
Мой блог * Кинсбург * Либург * Я на GitHub
Страниц: [1]
Печать
 

Перейти в: