Пути бывают двух видов: абсолютные и относительные.
Абсолютный путь указывает путь к файлу от корня файловой системы:
/home/user/file - в Unix'е корень обозначается как "/".
C:\Folder\file.txt - в Windows корнем является имя диска.
Относительный путь указывает файл относительно текущего каталога:
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. Запускает его. В сценарии есть инструкция:
require_once('./folder1/file1.php');
В файле file1.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) такой вариант вполне рабочий.
Если сценарий может подключаться только из одного исполняемого файла (или возможные исполняемые файлы лежат в одном каталоге), то данный вариант так же прокатывает.
Однако, если файл может подключаться из разных мест, то так не получится, т.к. текущий каталог может быть каждый раз разным.
Указание абсолютных путей
Собственно наиболее верный и наиболее распространенный способ. Однако, и здесь могут быть варианты.
Можно каждый раз прописывать путь явно:
require('/home/site.ru/www/folder1/file1.php');
require('/home/site.ru/www/folder2/file2.php');
Но так можно запариться прописывать и тем более перепрописывать в случае изменения.
Можно вынести в конфиг:
define('DIR_WWW', '/home/site.ru/www/');
…
require(DIR_WWW.'/folder1/file1.php');
require(DIR_WWW.'/folder2/file2.php');
Многие так и делают. И зря. Так как опять таки затруднен перенос из папки в папку, с сервера на сервер. Каждый раз придется отыскивать все подобные дефайны и исправлять.
В PHP есть предопределенная переменная $_SERVER['DOCUMENT_ROOT'], которая содержит путь к корневой папке сайта. Лучше всего плясать от нее:
require($_SERVER['DOCUMENT_ROOT'].'/folder1/file1.php');
require($_SERVER['DOCUMENT_ROOT'].'/folder2/file2.php');
Использование DOCUMENT_ROOT является наиболее разумным способом при подключении различных частей сайта из главного файла или из других частей.
Однако для указания файлов внутри какой-то отдельной части (модуля) этот способ не совсем удобен.
Например, вы пишите библиотеку состоящую из нескольких файлов и подключающих друг друга. Она может использоваться на множестве сайтов и располагаться в различных каталогах. Очевидно, что здесь гораздо лучше привязываться не к корню сайта, а к местоположению самих файлов библиотеки. Здесь может помочь "магическая" константа __FILE__. Она содержит абсолютный путь к текущему обрабатываемому файлу, т.е. к файлу в котором используется. Таким образом, подключение файла расположенного в том же каталоге, что и подключающий:
require_once(dirName(__FILE__).'/file.php');