php trick: вариант обхда open_basedir restriction

Задача: нужно перечислить файлы не в директории сайта

Проблема: действуют ограничения, например:

Warning: dir() [function.dir]: open_basedir restriction in effect.
File(/etc/awstats) is not within the allowed path(s): (.) in /var/www/site/path/index.php on line 22
Warning: dir(/etc/awstats/) [function.dir]: failed to open dir: Operation not permitted
in /var/www/site/path/index.php on line 22

Есть вариант обойти это, при условии что разрешенно выполнять приложения через exec() и это unix-система

Решение:
Есть консольная утилита, которая выводит список файлов - ls, она есть на всех юникс системах, воспользуемся этим. Если dir() или open_dir() вернули null, значит не удаётся открыть директорию для перечисления. Такая же реакция когда её не существует. Но мы то знаем куда ломимся :)

Функция, которая получает список файлов (НЕ РЕКУРСИВНО) в папке:

function listFiles($folder) {
$result = array();

if ($d = @dir($folder)) {
while (false !== ($entry = $d->read()))
$result[] = $entry;
$d->close();
} else {
exec("ls -a {$folder}", $output);
$output = implode(" ", $output);
$result = explode(" ", $output);
foreach($result as &$r) $r = trim($r);
}
return $result;

}

Хороший такой костыль получился :)

И теперь примерчик применения (вывести все хосты, которые мониторит awstats):

<?php
$awstatsDir = "/etc/awstats/";
?>

<html>
<head></head>
<body link="green" vlink="green">

<h4 style="margin-bottom:0">awstats sites</h4>
<ul style="margin-top:0">
<?php

ini_set('display_errors', true);
error_reporting(E_ALL);

$files = listFiles($awstatsDir);
foreach($files as $file) {
if (!preg_match("/^awstats\.(.*)\.conf$/", $file, $matches)) continue;
echo "<li><a href=\"http://{$matches[1]}/awstats/awstats.pl\">{$matches[1]}</a></li>";
}

?>
</ul>
</body>

<?php
function listFiles($folder) {
$result = array();

if ($d = @dir($folder)) {
while (false !== ($entry = $d->read()))
$result[] = $entry;
$d->close();
} else {
exec("ls -a {$folder}", $output);
$output = implode(" ", $output);
$result = explode(" ", $output);
foreach($result as &$r) $r = trim($r);
}
return $result;

}
?>