Тонкости с include

Статус
В этой теме нельзя размещать новые ответы.

PHPCod3r

Знаток
Регистрация
7 Июн 2010
Сообщения
257
Реакции
25
Все наверно знают что include служит для подключения файлов, в наш
сценарии, но в пхп есть и аналоги этой конструкции
к примеру
PHP:
eval('?>' . trim(file_get_contents($our_file)));

Понятно что это тоже подключит файл, но директива allow_url_include
здесь уже работать не будет!
То есть это более "опасный" вариант чем просто include.
Но почему то разработчики phpMyAdmin его используют и переходить
но обычный include не хотят.

Чем по сути использование этой конструкции отличается от использование обычного include?
 
из кода в eval можно выйти(вернуться) через return, а из include такого не сделаешь.

добавлено
стыдно, стыдно. был неправ [ виновано :) ]
 
из кода в eval можно выйти(вернуться) через return, а из include такого не сделаешь.
вы бы сначала бы справочник почитали, прежде чем писать такие глупости.
ну или бы проверили хотя бы
стыдно товарищ, в PRO такие глупости писать

по теме же:
на вскидку вижу такие отличия:
ошибка парсинга внутри подключаемого файла, через include остановит выполнение скрипта, а в случае eval - продолжит в корневом файле выполнение дальше
 
возвращает ли eval данные?

например:
foo.php
PHP:
<?php
return array();
?>

test.php
PHP:
<?php
$data = array();
$data['incl'] = include_once 'foo.php';
$data['eval'] = eval('?>' . trim(file_get_contents('foo.php')));   
?>

что будет в $data['eval'] ? нету хоста под рукой ))
 
Запустил то что вы предложили
PHP:
<?php // foo.php
return array('A');
?>
PHP:
$data = array();
$data['incl'] = include_once 'foo.php';
$data['eval'] = eval('?>' . trim(file_get_contents('foo.php'))); 
var_dump($data);
Скрипт выплюнул такое
array(2) {
["incl"]=>
array(1) {
[0]=>
string(1) "A"
}
["eval"]=>
array(1) {
[0]=>
string(1) "A"
}
}
Про возвращение данных тоже думал, вот тут про это подробней пищут

Вот по поводу ошибок интересная мысль, подравил выше приведенный код так, файл foo.php
PHP:
$a = 1  // тута у нас точка с запятой забыта.
return array('A');
Получаем
1.
PHP:
$data = array();
$data['eval'] = @eval('?>' . trim(file_get_contents('foo.php')));
var_dump($data);
скрипт выдаст
array(1) {
["eval"]=>
bool(false)
}
2.
PHP:
$data = array();
$data['incl'] = include 'foo.php';
var_dump($data);
Скрипт выдаст
<br />
<b>Parse error</b>: syntax error, unexpected T_RETURN in <b>/path/to/foo.php</b> on line <b>3</b><br />

Может еще у кого есть мысли на эту тему?
 
Ну, я еще проверил насчет контекста переменных.
переменные объявляемые/используемые в подключаемом файле, остаются в контексте вызова, независимо от конструкции.
с функциями такая же байда.

Идея:
можно пройтись по PMA и заменить один способ вызова на другой(думаю спокойно можно в автоматическом режиме эту операцию проделать)
ну и соовтетсвенно посмотреть что при этом изменится.
самому лень сейчас проверять, но с удовольствием бы послушал о результатах

Добавлено через 15 минут
любопытсво не выдержало, и проверил сам.
итог:

в PMA подобная конструкция используется всего лишь в одном месте.
таким образом подключаются конфиги.
и подключаются они таким способом именно ради того, чтобы корректно обработать ошибку парсинга конфига(которые написан на PHP), в случае если кто-то неосторожно его модифицирует неверным образом
PHP:
        if (function_exists('file_get_contents')) {
            $eval_result =
                eval('?>' . trim(file_get_contents($this->getSource())));
        } else {
            $eval_result =
                eval('?>' . trim(implode("\n", file($this->getSource()))));
        }
        error_reporting($old_error_reporting);

        if ($eval_result === false) {
            $this->error_config_file = true;
        } else  {
            $this->error_config_file = false;
            $this->source_mtime = filemtime($this->getSource());
        }
при этом выводится вполне красиво оформленное сообщение вида "phpMyAdmin was unable to read your configuration file!", вместо "Parse error"

короче все ради удобства пользователя.

PS заодно выянилось, что include возвращает int 1, если в файле нету return, а eval возвращает null
хотя, это и в справке можно найти, полагаю ж)

Добавлено через 26 минут
PHPCod3r.
вы так опубликовали тему, как будто в PMA используют повсеместно такой метод, чем лично меня(например) ввели в заблуждение.
в то время, как достаточно было просто проанализировать небольшой кусок кода, и если он непонятен, то хотя бы привести его, чтобы мы мы могли думать уже над ним, а не идти вслепую.

Ну, чтож, мы разобрались для чего в данном конкретном случае PMA использует такой способ.
Решение интересное, и полагаю оно будет полезно тем, кто не знал о нем(например мне ;) )

Более практического применения финту не вижу.
 
а мне вообще не нравится код в phpmyadmin. вообще не ok
 
Miraage поделись чем-нибудь конкретным
 
Вообще оглядываться на других- не совсем правильная логика. Порой мне ставят в пример- мол вот скрипт, там есть блок кода, который я назвал ересью и атавизмом прошлых лет, но скрипт используют тысячи людей, следовательно этот блок должен считаться шедевром. Вспомнился демотиватор, правда немного более жёсткий для этой ситтуации- "миллионы мух не могут ошибаться!"
вообще про евал и инклуд - темко на хабре,
Скрытое содержимое доступно для зарегистрированных пользователей!

в комментах вся соль.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху