В любом случае, для включенного файла, который будет использоваться в родительской области, к тому, на который он был вызван? Следующий пример упрощен, но выполняет ту же работу.
По сути, файл будет включен функцией, но хотел бы, чтобы область включенного файла была областью, в которой была вызвана функция, в которую была включена эта функция.
main.php:
<?php if(!function_exists('myPlugin')) { function myPlugin($file) { if(file_exists($file) { require $file; return true; } return false; } } $myVar = 'something bar foo'; $success = myPlugin('included.php'); if($success) { echo $myResult; }
included.php:
<?php $myResult = strlen($myVar);
Заранее спасибо,
Александр.
Ну, вроде, благодаря вкладу Chacha102.
Может быть вызван изнутри класса и сейчас!
main.php
<?php class front_controller extends controller { public function index_page() { $myVar = 'hello!'; // This is the bit that makes it work. // I know, wrapping it in an extract() is ugly, // and the amount of parameters that you can't change... extract(load_file('included.php', get_defined_vars(), $this)); var_dump($myResult); } public function get_something() { return 'foo bar'; } } function load_file($_file, $vars = array(), &$c = null) { if(!file_exists($_file)) { return false; } if(is_array($vars)) { unset($vars['c'], $vars['_file']); extract($vars); } require $_file; return get_defined_vars(); }
included.php:
<?php $myResult = array( $myVar, $c->get_something() );
Если вы хотите ссылаться на метод, он должен быть общедоступным, но результат будет таким, как ожидалось:
array(2) { [0]=> string(6) "hello!" [1]=> string(7) "foo bar" }
Теперь это не имеет практического применения, и единственная причина, по которой я хотел бы знать, как это сделать, – это то, что я упрям. Эта мысль пришла мне в голову и не позволила ей победить меня: D
<rant>
Спасибо всем, кто внес свой вклад. Кроме человека, который меня обманул. Это был довольно простой вопрос, и теперь выяснили, что существует (сложное) решение.
Отверните, соответствует ли он «способу выполнения PHP». Когда-либо говорил клиенту: «О нет, мы не должны этого делать, это не правильный способ сделать что-то!»? Не думал.
</rant>
Еще раз спасибо Chacha102 🙂
function include_use_scope($file, $defined_variables) { extract($defined_variables); include($file); } include_use_scope("file.php", get_defined_vars());
get_defined_vars()
получает ВСЕ переменные, определенные в области, в которой он вызывается. extract()
принимает массив и определяет их как локальные переменные.
extract(array("test"=>"hello")); echo $test; // hello $vars = get_defined_vars(); echo $vars['test']; //hello
Таким образом, достигается желаемый результат. Вы, возможно, захотите вытеснить суперглобалы и прочее из переменных, поскольку их переписывание может быть плохим.
Ознакомьтесь с этим комментарием для снятия плохих.
Чтобы получить обратное, вы можете сделать что-то вроде этого:
function include_use_scope($file, $defined_variables) { extract($defined_variables); return include($file); } extract(include_use_scope("file.php", get_defined_vars()));
include.php
// do stuff return get_defined_vars();
Но в целом, я не думаю, что вы получите желаемый эффект, поскольку это было не так, как был построен PHP.
Единственный способ, которым я знаю, как использовать суперглобальный массив.
main.php:
$GLOBALS['myVar'] = 'something bar foo'; $success = myPlugin('included.php'); if($success) { echo $GLOBALS['myResult']; }
included.php:
<?php $GLOBALS['myResult'] = strlen($GLOBALS['myVar']);