是否可以在PHP中覆盖函数

是否可以在PHP中覆盖函数,php,function,redeclaration,Php,Function,Redeclaration,你能声明这样一个函数吗 function ihatefooexamples(){ return "boo-foo!"; }; if ($_GET['foolevel'] == 10){ function ihatefooexamples(){ return "really boo-foo"; }; }; 然后重新声明,有点像这样 function ihatefooexamples(){ return "boo-foo!"; }; if ($_GET['fooleve

你能声明这样一个函数吗

function ihatefooexamples(){
  return "boo-foo!";
};
if ($_GET['foolevel'] == 10){
  function ihatefooexamples(){
    return "really boo-foo";
  };
};
然后重新声明,有点像这样

function ihatefooexamples(){
  return "boo-foo!";
};
if ($_GET['foolevel'] == 10){
  function ihatefooexamples(){
    return "really boo-foo";
  };
};
是否可以用这种方式覆盖函数


有什么办法吗?

没有,这是个问题。

查看覆盖功能的方法

覆盖功能-覆盖内置 功能

示例:

override_function('test', '$a,$b', 'echo "DOING TEST"; return $a * $b;');

简短的回答是否定的,一旦函数在PHP函数范围内,就不能覆盖它

您最好使用这样的匿名函数

$ihatefooexamples = function()
{
  return "boo-foo!";
}

//...
unset($ihatefooexamples);
$ihatefooexamples = function()
{
   return "really boo-foo";
}

您可以使用PECL扩展

  • -用新的实现替换函数定义

但在我看来,这是一种糟糕的做法。您正在使用函数,但请查看。可以借用它的基本思想。

我会将一个案例的所有功能包含在一个
include
文件中,其他的则包含在另一个
include
文件中

例如,
simple.inc
将包含
function boofoo(){simple}
really.inc
将包含
function boofoo(){really}

它有助于程序的可读性/维护,在相同的
inc
中具有相同类型的所有功能

然后在主模块的顶部

  if ($_GET['foolevel'] == 10) {
    include "really.inc";
  }
  else {
    include "simple.inc";
  }

不能在PHP中重新声明任何函数。但是,您可以覆盖它们。签出并保存要重写的函数(如果需要)

因此,请记住,重写函数时,会丢失它。你可能想考虑保留它,但是换个名字。只是说说而已

此外,如果这些函数是类中要重写的函数,则只需创建一个子类并在类中重新声明该函数,而无需执行重命名函数和重写函数

例如:

rename_function('mysql_connect', 'original_mysql_connect' );
override_function('mysql_connect', '$a,$b', 'echo "DOING MY FUNCTION INSTEAD"; return $a * $b;');
编辑 来解决这个答案没有直接解决问题的评论 原来的问题。如果你是通过谷歌搜索来的,从这里开始

有一个名为的函数,它实际上符合要求。然而,鉴于此函数是扩展的一部分,很难证明
override\u function()
是用于生产的。因此,我会说“不”,这是不可能覆盖一个功能的意图,原来的提问者的想法

原始答案 这就是您应该利用OOP的地方,特别是多态性

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 patching是将实际实现替换为您自己的类似“补丁”的艺术

忍者技能 在您可以像PHP忍者一样使用monkey补丁之前,我们首先必须了解PHPs名称空间

从PHP5.3开始,我们就开始使用名称空间,乍一看,名称空间可能等同于java包之类的东西,但它并不完全相同。在PHP中,名称空间是一种通过创建焦点层次结构来封装作用域的方法,特别是对于函数和常量。作为本课题,目的在于说明

如果调用函数时不提供名称空间,PHP首先查找当前名称空间,然后向下移动层次结构,直到找到在前缀名称空间中声明的第一个函数并执行该函数。对于我们的示例,如果您正在调用
print_r()来自
名称空间我的\Awesome\namespacePHP首先查找名为
My\Awesome\Namespace\print\r()的函数然后
My\Awesome\print\r()然后
My\print\r()
直到它在全局命名空间中找到PHP内置函数
\print\u r()

您将无法在全局命名空间中定义
函数print\r($object){}
,因为这将导致名称冲突,因为具有该名称的函数已存在

以下情况可能会出现致命错误:

Fatal error: Cannot redeclare print_r()
但是,没有什么可以阻止您在名称空间的范围内这样做

给猴子打补丁 假设您有一个使用多个
print_r()的脚本呼叫

例子: "; } 打印(某些对象); //做点什么 打印(另一个对象); //做些别的事情 打印(数据对象); //多做事 打印(调试对象); }
您的脚本现在将使用
MyNamespace\print\u r();
而不是全局
\print\u r();

非常适合模拟单元测试


nJoy!

根据您需要的情况,也许您可以使用以下匿名函数:

<?php
if (!@$Override) {
   function F1 () {echo "This is F1() in A";}
}
?>

…然后,您可以随时将新函数设置为给定变量

一种解决方案,适用于您有一个可编辑的包含文件A,并希望在包含文件B(或主文件)中覆盖其某些函数的相关情况:

主文件:

<?php
   function F1 () {echo "This is F1() in B";}
?>

包括文件A:


包括文件B:



浏览主文件时会显示“这是B中的F1()”

这是一个很好的观点,但是如果函数很大,那么传入那么长的字符串就不好了!:(,另一点是,这只能用于内置函数,而不是用户定义的!@RobertPitt:同意这是我们目前的解决方案,您的解决方案看起来不错,但这取决于所使用的php版本。为什么您不希望使用php版本<5.3.0?除非您构建了一个脚本,该脚本将被零售/发布给公众那么你就有了一个正确的观点。@RobertPitt:我使用的是5.3,希望OP也使用相同的:)我尝试过使用覆盖函数,但它是PECL的一部分,需要首先配置PECL。+1用于解决实际问题,而不是简单地试图回答确切的问题……我唯一要做的更改是将
$foo=new foo()
else
块中,如果
<?php
if (!@$Override) {
   function F1 () {echo "This is F1() in A";}
}
?>
<?php
   function F1 () {echo "This is F1() in B";}
?>