是否有可能在PHP中覆盖一个函数
你可以申报这样的function…
function ihatefooexamples(){ return "boo-foo!"; };
然后重新宣布它有点像这样…
if ($_GET['foolevel'] == 10){ function ihatefooexamples(){ return "really boo-foo"; }; };
这样可以覆盖一个函数吗?
任何方式?
编辑
要解决这个问题的答案不直接解决原来的问题。 如果您通过Googlesearch来到这里,请从这里开始
有一个可用的函数叫做override_function ,它实际上适合账单。 但是,鉴于这个函数是Advanced PHP Debugger扩展的一部分,很难说override_function()
是用于生产的。 因此,我会说“不”,不可能以原始提问者的意图覆盖一个函数。
原始答复
这是你应该利用面向对象,特别是多态的地方。
interface Fooable { public function ihatefooexamples(); } class Foo implements Fooable { public function ihatefooexamples() { return "boo-foo!"; } } class FooBar implements Fooable { public function ihatefooexamples() { return "really boo-foo"; } } $foo = new Foo(); if (10 == $_GET['foolevel']) { $foo = new FooBar(); } echo $foo->ihatefooexamples();
命名空间php> = 5.3中的Monkey修补程序
猴子补丁比修改解释程序less一个回避的方法。
猴子修补是用自己的一个类似的“补丁”replace实际实现的艺术。
忍者技能
在像PHP忍者之类的猴子补丁之前,我们首先需要了解PHP的命名空间。
从PHP 5.3开始,我们已经介绍了名称空间,你可能乍一看就像java包一样,但是不完全相同。 PHP中的命名空间是通过创build焦点层次来封装范围的一种方法,特别是对于函数和常量。 作为这个话题, 回到全球function ,旨在解释。
如果在调用函数时没有提供名称空间 ,则PHP首先查看当前名称空间,然后向下移动层次结构,直到find在该前缀名称空间内声明的第一个函数并执行该函数。 对于我们的例子,如果你正在调用print_r();
从namespace My\Awesome\Namespace;
PHP所做的是首先寻找一个名为My\Awesome\Namespace\print_r();
的函数My\Awesome\Namespace\print_r();
那么My\Awesome\print_r();
那么My\print_r();
直到在全局命名空间\print_r();
find内置的PHP函数\print_r();
。
您将无法在全局名称空间中定义function print_r($object) {}
,因为这将导致名称冲突,因为具有该名称的函数已经存在。
期待一个致命的错误,如:
Fatal error: Cannot redeclare print_r()
但是,没有什么能阻止你在名称空间范围内做这件事。
修补猴子
假设你有一个脚本使用了几个print_r();
调用。
例:
<?php print_r($some_object); // do some stuff print_r($another_object); // do some other stuff print_r($data_object); // do more stuff print_r($debug_object);
但是您后来改变了主意,而希望将输出封装在<pre></pre>
标记中。 曾经发生过你?
在你去之前把每一个调用改成print_r();
考虑猴子补丁。
例:
<?php namespace MyNamespace { function print_r($object) { echo "<pre>", \print_r($object, true), "</pre>"; } print_r($some_object); // do some stuff print_r($another_object); // do some other stuff print_r($data_object); // do more stuff print_r($debug_object); }
您的脚本现在将使用MyNamespace\print_r();
而不是全局的\print_r();
适用于模拟unit testing。
的nJoy!
看看override_function
来覆盖函数。
override_function – 覆盖内置函数
例:
override_function('test', '$a,$b', 'echo "DOING TEST"; return $a * $b;');
你不能在PHP中重新声明任何函数。 但是,您可以覆盖它们。 查看覆盖函数以及重命名函数 ,以便保存您要覆盖的函数。
所以,请记住,当你覆盖一个函数,你会失去它。 你可能要考虑保留它,但用一个不同的名字。 只是说。
另外,如果这些是你想要覆盖的类中的函数,那么你只需要创build一个子类并在你的类中重新声明这个函数,而不必做rename_function和override_function。
例:
rename_function('mysql_connect', 'original_mysql_connect' ); override_function('mysql_connect', '$a,$b', 'echo "DOING MY FUNCTION INSTEAD"; return $a * $b;');
简短的答案是否定的,你不能覆盖一个函数一旦它在PHP函数范围内。
你最好的使用匿名函数如此
$ihatefooexamples = function() { return "boo-foo!"; } //... unset($ihatefooexamples); $ihatefooexamples = function() { return "really boo-foo"; }
我将在一个include
文件中include
一个案例的所有function,另一个include
在另一个案例中。
例如simple.inc
将包含function boofoo() { simple }
, really.inc
将包含function boofoo() { really }
它有助于您的程序的可读性/维护性,在同一inc
具有相同types的所有function。
然后在主模块的顶部
if ($_GET['foolevel'] == 10) { include "really.inc"; } else { include "simple.inc"; }
你可以使用PECL扩展
-
runkit_function_redefine
– 用新的实现replace函数定义
但在我看来这是不好的做法。 你正在使用函数,但检查装饰devise模式 。 可以借用它的基本思路。
不,这将是一个问题。 PHPvariables函数
根据你需要的情况,也许你可以使用这样的匿名函数:
$greet = function($name) { echo('Hello ' . $name); }; $greet('World');
…然后你可以随时给给定的variables设置新的function