你能声明这样的函数吗?
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";
};
};
这样可以覆盖函数吗?
可以吗
Answers:
要解决此答案未直接解决原始问题的评论。如果您来自Google搜索,请从此处开始
有一个名为override_function的函数可以实际使用。但是,由于此函数是Advanced PHP Debugger扩展的一部分,因此很难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();
$foo = new Foo()
一个else
块中。
猴子补丁是一种比修改解释器更容易避免的方法。
猴子补丁是用您自己的类似“补丁”代替实际实现的艺术。
在您像PHP Ninja这样的猴子补丁之前,我们首先必须了解PHP名称空间。
从PHP 5.3开始,我们就引入了名称空间,乍一看,它们可能等同于java包之类的名称空间,但并不完全相同。在PHP中,命名空间是一种通过创建焦点层次结构(尤其是对于函数和常量)来封装范围的方法。作为本主题,回退到全局功能旨在说明。
如果调用函数时未提供名称空间,则PHP首先在当前名称空间中查找,然后向下移动层次结构,直到找到在该前缀名称空间中声明的第一个函数并执行该功能。对于我们的示例,如果您print_r();
要从namespace My\Awesome\Namespace;
PHP的作用中进行调用,则首先要查找一个称为的函数,My\Awesome\Namespace\print_r();
然后My\Awesome\print_r();
再My\print_r();
寻找该函数,直到在全局名称空间中找到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();
非常适合模拟单元测试。
欢乐!
namespace SeparateInclude {}
然后在主文件中可以再次命名空间namespace MainFile {}
,包括新文件function B()
再次在调用的主文件中创建猴子补丁\SeparateInclude\B();
。B();
现在,当您调用主文件时,\MainFile\B();
它将调用\SeparateInclude\B();
成功避免\B();
从大/原始包含文件中调用的文件。
看一下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";
}
unset
吗?我知道这样做并不坏,只是很好奇(我没有尝试过这种特殊情况)...
unset
您不能在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";
}
$iam = "really"
或$iam = "simple"
。
您可以使用PECL扩展名
runkit_function_redefine
—用新的实现替换功能定义 但这在我看来是不好的做法。您正在使用函数,但请查看Decorator设计模式。可以从中借鉴基本思想。
针对相关情况的解决方案,其中有一个包含文件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() ”。