重新定义 PHP 函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2640958/
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
Redefining PHP function?
提问by Michael
If I have a function:
如果我有一个功能:
function this($a){
return $a;
}
If I wanted to redefine the function, would it be as simple as rewriting it?
如果我想重新定义函数,会不会像重写一样简单?
function this($a, $b){ //New this function
return $a * $b;
}
采纳答案by Annika Backstrom
Nope, that throws an error:
不,这会引发错误:
Fatal error: Cannot redeclare foo()
The runkit provides options, including runkit_function_rename()and runkit_function_redefine().
runkit 提供了选项,包括runkit_function_rename()和runkit_function_redefine()。
回答by Gordon
If you mean overloading in a Java sense, then the answer is no, this is not possible.
如果您的意思是 Java 意义上的重载,那么答案是否定的,这是不可能的。
Quoting the PHP manual on functions:
PHP does not support function overloading, nor is it possible to undefine or redefine previously-declared functions.
PHP 不支持函数重载,也不可能取消或重新定义先前声明的函数。
You could use the runkitextension but usage of runkit in production scenarios is generally considered doubtful practice. If you want to exchange algorithms at runtime, have a look at the Strategy patternor Anonymous functionsinstead.
您可以使用runkit扩展,但在生产场景中使用 runkit 通常被认为是可疑的做法。如果您想在运行时交换算法,请查看策略模式或匿名函数。
If by redefine you mean add to an existing userland function, refactor, substitute or rewrite, then yes: it is as simple as you've shown. Just add the additional code to the function, but make sure you set a default for backwards compatibility.
如果通过重新定义您的意思是添加到现有的用户空间函数、重构、替换或重写,那么是的:它就像您所展示的一样简单。只需将附加代码添加到函数中,但请确保为向后兼容性设置默认值。
Another option would be to use http://antecedent.github.io/patchwork
另一种选择是使用http://antecedent.github.io/patchwork
Patchwork is a PHP library that makes it possible to redefine user-defined functions and methods at runtime, loosely replicating the functionality
runkit_function_redefinein pure PHP 5.3 code, which, among other things, enables you to replace static and private methods with test doubles.
Patchwork 是一个 PHP 库,可以在运行时重新定义用户定义的函数和方法,松散地复制
runkit_function_redefine纯 PHP 5.3 代码中的功能,除其他外,它使您能够用测试替身替换静态和私有方法。
回答by rustyx
You can't redefine or 'undefine' a function in PHP (without resorting to third-party modules). However, you can define a function conditionally.
您不能在 PHP 中重新定义或“取消定义”一个函数(不求助于第三方模块)。但是,您可以有条件地定义函数。
So, if you know function Acan be defined elsewhere, but not always, you can wrap it like this:
所以,如果你知道函数A可以在别处定义,但并非总是如此,你可以像这样包装它:
if (!function_exists('A')) {
function A() {
// default A implementation
}
}
Then you only need to make sure the implementation you want is encountered first:
然后你只需要确保首先遇到你想要的实现:
function A() {
// another A implementation
}
回答by Cuse70
I've got a library of functions that sometimes I just don't want invoked while I'm testing (typically database updates). If I have, for example, a few different db update functions that are all over the code. instead of commenting out the code, I just create a special class (e.g. class foo {}). Define a global variable (e.g., $DEBUG) and a dummy function (e.g., function dummy {}). Inside foo define all the (public static) functions you need to mimic as
我有一个函数库,有时我只是不想在我测试时调用它(通常是数据库更新)。例如,如果我有一些遍布代码的不同数据库更新函数。我没有注释掉代码,而是创建了一个特殊的类(例如 class foo {})。定义一个全局变量(例如,$DEBUG)和一个虚拟函数(例如,function dummy {})。在 foo 中定义您需要模拟的所有(公共静态)函数
$fn = isset($DEBUG) ? 'dummy' : 'real function'; return call_user_func_array($fn,func_get_args());
$fn = isset($DEBUG) ? 'dummy' : '真正的功能'; 返回 call_user_func_array($fn,func_get_args());
Plus you have the advantages of now doing other things, like logging the calls and parameters.
此外,您现在还可以做其他事情,例如记录调用和参数。
Then simply replace all your calls to real_function(...) with foo::real_function(...). Usually just a simple search/replace (or leave it there; depending on what's going on in the function and how often it's getting called the overhead may be irrelevant).
然后只需将所有对 real_function(...) 的调用替换为 foo::real_function(...)。通常只是一个简单的搜索/替换(或将其留在那里;取决于函数中发生的事情以及它被调用的频率,开销可能无关紧要)。
回答by SapioiT
I have good news and bad news.
我有好消息和坏消息。
The good news
It is possible (link(s) below).
好消息
是有可能的(下面的链接)。
The nadnews
There are 2 bad news:
nadnews
有两个坏消息:
默认情况下,只能删除、重命名或修改用户空间函数。为了覆盖内部函数,您必须在 php.ini 中启用 runkit.internal_override 设置。
And the second bad news: You havbe to sacrifice code readability.
第二个坏消息:你必须牺牲代码可读性。
Example:
例子:
<?php
function this($a){
return $a;
}
echo this(0);
$f_name = 'this';
$f_args = '$a';
$f_code = 'return $a*$b;';
runkit_function_redefine($f_name, f_args, f_code);
echo this(1,3);
Oh, and one more thing, using thisas a name for a function may create confusion, due to the methods of a object of a class being able to use this.somethingto reffer to the variable somethingthat is in the method and have the same name as the variable somethingfrom the object itself. Here is an example
哦,还有一两件事,使用this作为名称为函数可能会造成混淆,因为一类能够使用的对象的方法this.something,以reffer到可变something即在该方法中,并且具有相同的名称作为变量something从对象本身。这是一个例子
<?php
class theclass{
$a = 'a';
function a($a){
echo $a;
$a = this.$a;
}
}
theclass $object = new theclass();
$object -> a('b'); // will echo: ab
回答by googletorp
You can't have both functions declared at the same time, that will give an error.
不能同时声明两个函数,否则会出错。
回答by Tom
You can't redeclare it. If your question is just about overloading that example, how about:
你不能重新声明它。如果您的问题只是关于重载该示例,那么如何:
function this($a, $b=1)
{
return $a * $b;
}
回答by Kzqai
Setting an appropriate default to any new arguments that you add might help for backwards compatibility, i.e.:
为您添加的任何新参数设置适当的默认值可能有助于向后兼容,即:
function this($a, $b=1){ //New this function with a sane default.
return $a * $b;
}
I also recommend, for clarity, generally avoiding using thisfor function/variable names.
为了清楚起见,我还建议通常避免使用this函数/变量名称。

