[英]Is it possible to overwrite a function in PHP
你能宣布一个这样的函数......
function ihatefooexamples(){
return "boo-foo!";
};
然后重新宣布它有点像这样......
if ($_GET['foolevel'] == 10){
function ihatefooexamples(){
return "really boo-foo";
};
};
是否有可能以这种方式覆盖一个函数?
无论如何?
为了解决这些答案没有直接解决原始问题的评论。 如果您从Google搜索到达此处,请从此处开始
有一个名为override_function的函数实际上适合账单。 但是,鉴于此函数是高级PHP调试器扩展的一部分,因此很难创建override_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忍者一样修补补丁之前,我们首先要了解PHP的命名空间。
从PHP 5.3开始,我们引入了名称空间,你可能乍一看它们可能等同于java包这样的东西,但它们并不完全相同。 PHP中的命名空间是一种通过创建焦点层次结构来封装范围的方法,尤其是对于函数和常量。 作为这个话题, 回归全球功能 ,旨在解释。
如果在调用函数时没有提供命名空间 ,PHP首先查找当前命名空间,然后向下移动层次结构,直到找到在该前缀命名空间内声明的第一个函数并执行该命名空间。 对于我们的示例,如果您正在调用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();
找到PHP内置函数\\print_r();
。
您将无法在全局命名空间中定义function print_r($object) {}
,因为这将导致名称冲突,因为具有该名称的函数已存在。
预计会出现致命错误:
Fatal error: Cannot redeclare print_r()
但是,没有什么能阻止你在命名空间范围内做这件事。
假设你有一个使用几个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();
适用于模拟单元测试。
的nJoy!
看看override_function
来覆盖这些函数。
override_function - 覆盖内置函数
例:
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";
}
您无法在PHP中重新声明任何函数。 但是,您可以覆盖它们。 查看覆盖功能以及重命名功能 ,以便在需要时保存您要覆盖的功能。
所以,请记住,当你覆盖一个函数时,你会失去它。 您可能需要考虑保留它,但使用其他名称。 只是说。
此外,如果这些是您想要覆盖的类中的函数,则只需创建一个子类并重新声明类中的函数,而无需执行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;');
我将一个案例的所有功能都包含在一个include
文件中,而另一个include
在另一个案例中。
例如, simple.inc
将包含function boofoo() { simple }
和really.inc
将包含function boofoo() { really }
它有助于程序的可读性/维护,在同一个inc
具有相同类型的所有功能。
然后在主模块的顶部
if ($_GET['foolevel'] == 10) {
include "really.inc";
}
else {
include "simple.inc";
}
您可以使用PECL扩展
runkit_function_redefine
- 用新实现替换函数定义 但在我看来这是不好的做法。 您正在使用函数,但请查看Decorator设计模式 。 可以借用它的基本思想。
不,这将是一个问题。 PHP变量函数
对于相关案例的解决方案,您有一个包含文件A,您可以编辑并希望覆盖包含文件B(或主文件)中的某些功能:
主文件:
<?php
$Override=true; // An argument used in A.php
include ("A.php");
include ("B.php");
F1();
?>
包含文件A:
<?php
if (!@$Override) {
function F1 () {echo "This is F1() in A";}
}
?>
包括文件B:
<?php
function F1 () {echo "This is F1() in B";}
?>
浏览到主文件显示“ 这是B中的F1() ”。
根据您需要的情况,也许你可以使用这样的匿名函数:
$greet = function($name)
{
echo('Hello ' . $name);
};
$greet('World');
...然后您可以随时为给定变量设置新功能
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.