是否有可能在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"; } 

http://php.net/manual/en/functions.anonymous.php

我将在一个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