php 是否可以覆盖PHP中的函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3620659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 10:27:26  来源:igfitidea点击:

Is it possible to overwrite a function in PHP

phpfunctionredeclaration

提问by Mark Lalor

Can you declarea function like this...

你能声明一个这样的函数吗...

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

And then redeclareit somewhat like this...

然后像这样重新声明它......

if ($_GET['foolevel'] == 10){
  function ihatefooexamples(){
    return "really boo-foo";
  };
};

Is it possible to overwrite a function that way?

是否有可能以这种方式覆盖一个函数?

Any way?

反正?

回答by Peter Bailey

Edit

编辑

To address comments that this answer doesn't directly address the original question. If you got here from a Google Search, start here

为了解决这个答案没有直接解决原始问题的评论。如果您是通过 Google 搜索来到这里的,请从这里开始

There is a function available called override_functionthat actually fits the bill. However, given that this function is part of The Advanced PHP Debuggerextension, it's hard to make an argument that override_function()is intended for production use. Therefore, I would say "No", it is not possible to overwrite a function with the intent that the original questioner had in mind.

有一个名为override_function的函数可用,它实际上符合要求。但是,鉴于此函数是The Advanced PHP Debugger扩展的一部分,因此很难提出override_function()用于生产用途的参数。因此,我会说“不”,不可能按照原始提问者的意图覆盖一个函数。

Original Answer

原答案

This is where you should take advantage of OOP, specifically polymorphism.

这是您应该利用 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();

回答by nickl-

Monkey patch in namespace php >= 5.3

命名空间 php >= 5.3 中的猴子补丁

A less evasive method than modifying the interpreter is the monkey patch.

比修改解释器更容易回避的方法是猴子补丁。

Monkey patching is the art of replacing the actual implementation with a similar "patch" of your own.

Monkey 补丁是用您自己的类似“补丁”替换实际实现的艺术。

Ninja skills

忍者技能

Before you can monkey patch like a PHP Ninja we first have to understand PHPs namespaces.

在你可以像 PHP 忍者一样猴子补丁之前,我们首先必须了解 PHP 的命名空间。

Since PHP 5.3 we got introduced to namespaces which you might at first glance denote to be equivalent to something like java packages perhaps, but it's not quite the same. Namespaces, in PHP, is a way to encapsulate scope by creating a hierarchy of focus, especially for functions and constants. As this topic, fallback to global functions, aims to explain.

从 PHP 5.3 开始,我们引入了命名空间,乍一看,您可能会认为它等同于 java 包之类的东西,但它并不完全相同。在 PHP 中,命名空间是一种通过创建焦点层次结构来封装范围的方法,尤其是对于函数和常量。作为这个话题,回退到全局函数,旨在解释。

If you don't provide a namespace when calling a function, PHP first looks in the current namespace then moves down the hierarchy until it finds the first function declared within that prefixed namespace and executes that. For our example if you are calling print_r();from namespace My\Awesome\Namespace;What PHP does is to first look for a function called My\Awesome\Namespace\print_r();then My\Awesome\print_r();then My\print_r();until it finds the PHP built in function in the global namespace \print_r();.

如果在调用函数时没有提供命名空间,PHP 首先查找当前命名空间,然后在层次结构中向下移动,直到找到在该前缀命名空间中声明的第一个函数并执行它。在我们的例子,如果你调用print_r();namespace My\Awesome\Namespace;什么PHP做的是先寻找一个调用的函数My\Awesome\Namespace\print_r();,然后My\Awesome\print_r();My\print_r();直到它找到内置函数在全局命名空间的PHP \print_r();

You will not be able to define a function print_r($object) {}in the global namespace because this will cause a name collision since a function with that name already exists.

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

Expect a fatal error to the likes of:

预计会出现以下致命错误:

Fatal error: Cannot redeclare print_r()

But nothing stops you, however, from doing just that within the scope of a namespace.

但是,没有什么可以阻止您在名称空间范围内执行此操作。

Patching the monkey

修补猴子

Say you have a script using several print_r();calls.

假设您有一个使用多个print_r();调用的脚本。

Example:

例子:

<?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);

But you later change your mind and you want the output wrapped in <pre></pre>tags instead. Ever happened to you?

但是您后来改变了主意,您希望将输出包装在<pre></pre>标签中。曾经发生在你身上吗?

Before you go and change every call to print_r();consider monkey patching instead.

在您更改每次调用之前,请print_r();考虑使用猴子补丁。

Example:

例子:

<?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);
    }

Your script will now be using MyNamespace\print_r();instead of the global \print_r();

您的脚本现在将使用MyNamespace\print_r();而不是全局\print_r();

Works great for mocking unit tests.

非常适合模拟单元测试。

nJoy!

快乐!

回答by Sarfraz

Have a look at override_functionto override the functions.

看看override_function覆盖功能。

override_function — Overrides built-in functions

override_function — 覆盖内置函数

Example:

例子:

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

回答by RobertPitt

short answer is no, you can't overwrite a function once its in the PHP function scope.

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

your best of using anonymous functions like so

你最好使用像这样的匿名函数

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

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

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

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

回答by tomlikestorock

You cannot redeclare any functions in PHP. You can, however, override them. Check out overriding functionsas well as renaming functionsin order to save the function you're overriding if you want.

您不能在 PHP 中重新声明任何函数。但是,您可以覆盖它们。查看覆盖函数以及重命名函数,以便根据需要保存您正在覆盖的函数。

So, keep in mind that when you override a function, you lose it. You may want to consider keeping it, but in a different name. Just saying.

所以,请记住,当你覆盖一个函数时,你就会失去它。您可能要考虑保留它,但使用不同的名称。就是说。

Also, if these are functions in classes that you're wanting to override, you would just need to create a subclass and redeclare the function in your class without having to do rename_function and override_function.

此外,如果这些是您想要覆盖的类中的函数,您只需要创建一个子类并在您的类中重新声明该函数,而无需执行 rename_function 和 override_function。

Example:

例子:

rename_function('mysql_connect', 'original_mysql_connect' );
override_function('mysql_connect', '$a,$b', 'echo "DOING MY FUNCTION INSTEAD"; return $a * $b;');

回答by e2-e4

I would include all functions of one case in an includefile, and the others in another include.

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

For instance simple.incwould contain function boofoo() { simple }and really.incwould contain function boofoo() { really }

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

It helps the readability / maintenance of your program, having all functions of the same kind in the same inc.

它有助于提高程序的可读性/维护性,在同一个inc.

Then at the top of your main module

然后在主模块的顶部

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

回答by Gordon

You could use the PECL extension

您可以使用 PECL 扩展

but that is bad practise in my opinion. You are using functions, but check out the Decorator design pattern. Can borrow the basic idea from it.

但在我看来这是不好的做法。您正在使用函数,但请查看装饰器设计模式。可以借鉴它的基本思想。

回答by Chris

No this will be a problem. PHP Variable Functions

不,这将是一个问题。 PHP 变量函数

回答by David Spector

A solution for the related case where you have an include file A that you can edit and want to override some of its functions in an include file B (or the main file):

针对相关案例的解决方案,您有一个包含文件 A,您可以编辑该文件并希望在包含文件 B(或主文件)中覆盖其某些功能:

Main File:

主文件:

<?php
$Override=true; // An argument used in A.php
include ("A.php");
include ("B.php");
F1();
?>

Include File A:

包含文件 A:

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

Include File B:

包含文件 B:

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

Browsing to the main file displays "This is F1() in B".

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

回答by esud

Depending on situation where you need this, maybe you can use anonymous functions like this:

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

$greet = function($name)
{
    echo('Hello ' . $name);
};

$greet('World');

...then you can set new function to the given variable any time

...然后您可以随时为给定的变量设置新函数