Функция определения относительного и абсолютного пути к файлу на PHP
Довольно часто возникает необходимость подтянуть в текущий файл инклюдом какой-либо файл из другой папки или прочитать файл конфигурации, да и просто узнать полный путь к папке с искомым файлом. В жёсткой иерархии сайта можно прописать необходимые смещения относительного пути типа: "../../Dir1/Dir2/file.php". Но что делать если искомый файл подтягивается из разных директорий. К тому же на хостингах по-разному осуществляется организация корневой папки сайта. В нормальном виде корневая папка носит названия домена сайта, но очень часто бывает, что файлы сайта располагаются в подпапке "public_html", которая в URL пути не присутствует или домен привязан к папке с именем аккаунта на хостинге и отследить смещение относительно доменного имени не получится. Как следствие, при переносе сайта межу хостинг провайдерами пути приходится корректировать вручную. Чтобы обойти эти неприятности нам поможет небольшая функция написанная на PHP.
function FileDir($index = "index.html"){ $dirFile = __FILE__; $abs = ''; $infodir[]=""; $ns = substr_count($dirFile, '/'); while ($ns > 1){ $dirFile = trim(dirname($dirFile) . PHP_EOL); $filename = $dirFile."/".$index; if (file_exists($filename)){ $infodir['fulldir']=$dirFile; $infodir['fullpath']=$dirFile."/".$index; $infodir['relativepath']=$abs.$index; return $infodir; }else{ $infodir['fulldir']=$dirFile; $infodir['fullpath']=0; $infodir['relativepath']= 0; } $abs .= '../'; $ns--; } return $infodir; }
Разберём работу функции FileDir. Инициализируем передаваемую в функцию переменную $index значением имени индексного файла, например "index.html". Такой файл обычно является индексным и располагается в корневой директории сайта. Возможно, у Вас индексный файл "index.php", проверьте.
Внутри функции определим переменные.
$dirFile = __FILE__;
— путь к текущему файлу от корня диска.
$abs = '';
— Переменная относительного пути
$infodir[] = "";
— Объявляем массив выводимых функцией значений.
$ns = substr_count($dirFile, '/');
Узнаём количество вхождений слеша "/" для ограничения итераций цикла.
Запускаем цикл while ($ns > 1)
и начинаем перемещаться от конечной директории к корневой директории диска. В этом нам поможет функция dirname()
.
Для отсечения крайних пробелов обернём её в trim()
.
$filename = $dirFile."/".$index;
— Формируем проверочный путь к искомому файлу и проверям на существование файла в текущей для этой итерации цикла директории.
if (file_exists($filename)){ $infodir['fulldir']=$dirFile; $infodir['fullpath']=$dirFile."/".$index; $infodir['relativepath']=$abs.$index; return $infodir; }else{ $infodir['fulldir']=$dirFile; $infodir['fullpath']=0; $infodir['relativepath']= 0; }
Здесь:
$infodir['fulldir']=$dirFile;
//Абсолютный путь к директории с искомым файлам
$infodir['fullpath']=$dirFile."/".$index;
// Абсолютный путь к искомому файлу от коря диска
$infodir['
relativepath
']=$abs.$index;
//Относительный путь к файлу относительно исполняемого файла.
Если искомый файл лежит в текущей для итерации директории то то работа функции прекращается и отдаются данные массива $infodir. Если файл не найден то значения абсолютного и относительного пути к искомому файлу будут равны нулю, а полный путь к дирректории иметь значение имени корневой папки диска.
Для примера возмём ситуацию когда нам нужно подключиться к базе MySql, а данные записаны в файле config.ini который находится в папке "config" в корневой директории сайта.
Преобразуем нашу функцию в класс для более удобного применения.
<?php class Baza{ public function FileDir($index = "index.html"){ $dirFile = __FILE__; $abs = ''; $infodir[]=""; $ns = substr_count($dirFile, '/'); while ($ns > 1){ $dirFile = trim(dirname($dirFile) . PHP_EOL); $filename = $dirFile."/".$index; if (file_exists($filename)){ $infodir['fulldir']=$dirFile; $infodir['fullpath']=$dirFile."/".$index; $infodir['relativepath']=$abs.$index; return $infodir; }else{ $infodir['fulldir']=$dirFile; $infodir['fullpath']=0; $infodir['relativepath']= 0; } $abs .= '../'; $ns--; } return $infodir; } public function connect(){ $dirhome=self::FileDir('config/configBD.ini'); $inimass = parse_ini_file($dirhome['absolute'], true); $link = new MySQLi($inimass['connect']['host'], $inimass['connect']['user'], $inimass['connect']['pass'], $inimass['connect']['baza']); if ($link->connect_error) { die('<p style="color:red">'.$link->connect_errno.' - '.$link->connect_error.'</p>'); }else{//echo "<p>Вы подключились к MySQL!</p>"; } $link->query("SET NAMES 'utf8'"); return $link; } } } $lk = new Baza; $file = 'config/configBD.ini'; $infodir = $lk ->FileDir($file); echo "<br>Абсолютный путь к директории с файлом: " .$infodir['fulldir']; echo "<br>Полный путь к файлу: " .$infodir['fullpath']; echo "<br>Относительный путь к файлу: " .$infodir['relativepath']; if($lk -> connect()){echo "<hr />YES";}else{echo "<hr />NO";} ?>
Обратимся к файлу из браузера на исполнение и при успешном выполнении получим:
Абсолютный путь к директории с файлом: /home/users/d/dmitriatika/domains/my-skills.ru
Относительный путь к файлу: ../../config/configBD.ini
Полный путь к файлу: /home/users/d/dmitriatika/domains/my-skills.ru/config/configBD.ini
Соединение с базой данных установлено
В коде функция connect() сначала вызывает функцию FileDir() для получения пути к файлу конфигурации. Затем парсим файл функцией parse_ini_file и получаем данные для соединения с базой. Следом происходит соединение с базой. Функция возвращает идентификатор соединения.
На заметку! Не забывайте защищать свои конфиурационные файлы. Один из верных способов - поместить ini файлы конфигурации в отдельную папку и добавить в неё же файл ".htaccess" с записью: "deny from all".
Осталось добавить, что в функцию FileDir можно передовать путь к искомому файлу от корневой папки сайта. А если нужен абсолютный путь к корневой дирректории сайта, то передайте в переменную имя любого файла лежащего в корне сайта.
Как получить относительный и абсолютный путь к файлу из URL.
По просьбе трудящихся немного дополню функцию, чтобы была возможность передовать в неё не только путь от корня до файла, но и URL сайта.
function FileDir($index = "index.html"){ //Парсим URL, путь от корня и обрезаем первый слеш $index = ltrim(parse_url($index, PHP_URL_PATH), '/'); $dirFile = __FILE__; $abs = ''; $infodir[]=""; $ns = substr_count($dirFile, '/'); while ($ns > 1){ $dirFile = trim(dirname($dirFile) . PHP_EOL); $filename = $dirFile."/".$index; if (file_exists($filename)){ $infodir['fulldir']=$dirFile; $infodir['fullpath']=$dirFile."/".$index; $infodir['relativepath']=$abs.$index; $infodir['pathbias']= $abs; return $infodir; }else{ $infodir['fulldir']=$dirFile; $infodir['fullpath']=0; $infodir['relativepath']= 0; $infodir['pathbias']= 0;//Путь смещения } $abs .= '../'; $ns--; } return $infodir; }
На выходе добавил в массиве путь смещения по уровням "../../../" - иногда требуется чтобы подключать не один а несколько файлов в дирректорию исполнительного скрипта из смежных каталогов.
Дата публикации: