(如果你喜欢挑战。请投票提出这个问题。)
亲爱的stackoverflow研究员。我想为钩子/扩展提供一种出色的方式。
我在访问类或函数之外的变量引用时遇到问题。
问题式:
静态虚拟钩子示例(没有任何动态):
<?php
class hook {
function before_process() {
global $couldbeanything;
$couldbeanything = 'hello dummy';
}
}
?>
适用于全球范围:
<?php
$couldbeanything = 'hello world';
$hook = new hook;
$hook->before_process();
echo $couldbeanything;
?>
在函数(本地范围)中不起作用:
<?php
function foobar() {
$couldbeanything = 'hello world';
$hook = new hook;
$hook->before_process();
echo $couldbeanything;
}
foobar();
?>
我几乎需要这样的东西(如果有这样的东西):
parent $couldbeanything;
或
outer $couldbeanything;
我能想出的唯一解决方案与PunBB使用的解决方案相同,eval(php_code_from_an_xml_doc)。它也有缺点。如果不说明您想要访问的外部引用,则可能会意外地使用相同的名称覆盖变量。此外,XML格式化的PHP代码被评估是一种很难调试。
在这里,谁是最聪明的家伙,其解决方案优于eval()。
也许这些是一些创意工具:get_defined_vars,extract,pass-by-reference,call_user_func
答案 0 :(得分:0)
到目前为止,谁可以提出比这更好的解决方案?它不使用引用,而是使用可变重复项。但它足够接近并且在嵌套变量范围内消除了对钩子的eval()的需要。
<?php
class hook {
function before_process($args) {
extract($args);
$couldbeanything = 'good bye world';
return compact('couldbeanything');
}
}
function foobar() {
$couldbeanything = 'hello world';
$hook = new hook;
extract($hook->before_process(get_defined_vars()), EXTR_OVERWRITE);
echo $couldbeanything;
}
foobar();
?>
请参阅hook类,以及如何在foobar()中执行钩子。
答案 1 :(得分:-1)
使用你的示例函数,我能够得到hook-&gt; before_process()来修改$ couldbeanything变量 - 即使它是从foobar()函数中调用的。这是你的目标吗?
$couldbeanything=NULL;
class hook {
function before_process() {
global $couldbeanything;
$couldbeanything = 'hello dummy';
}
}
function foobar() {
global $couldbeanything;
$couldbeanything = 'hello world';
$hook=new hook;
$hook->before_process();
echo $couldbeanything;
}
foobar();
这会返回'hello dummy'。
关键是在$ foobar()函数中使$ canbeanything成为一个全局变量 - 这个函数和钩子类中的before_process()函数都修改了相同的全局变量。
另一个选项,如果你想保留两个值,就是让$ couldbeanything成为一个数组。
$ couldbeanything = NULL;
class hook {
function before_process() {
global $couldbeanything;
$couldbeanything['hook'] = 'hello dummy';
}
}
function foobar() {
global $couldbeanything;
$couldbeanything['foobar'] = 'hello world';
$hook=new hook;
$hook->before_process();
echo'Foobar is "'.$couldbeanything['foobar'].'", while Hook is "'.$couldbeanything['hook'].'".';
}
foobar();
这将返回'Foobar is“hello world”,而Hook则是“hello dummy”。'
否则,为了不改变全局变量,这将起作用:
$couldbeanything='Original Value';
class hook {
function before_process() {
global $couldbeanything;
$newValue=$couldbeanything.' - added value';
return $newValue;
}
}
function foobar() {
$couldbeanything = 'hello world';
$hook=new hook;
$newValue=$hook->before_process();
echo'The local value is "'.$couldbeanything.'", while the hook modified value is "'.$newValue.'". ';
}
foobar();
echo'Global value is "'.$couldbeanything.'"';
这将返回'本地值为“hello world”,而钩子修改值为“原始值 - 增值”。全球价值是“原始价值”'