防止 PHP require_once 永远运行

Posted

技术标签:

【中文标题】防止 PHP require_once 永远运行【英文标题】:Prevent PHP require_once from ever running 【发布时间】:2011-03-12 10:49:47 【问题描述】:

调试别人的 php 代码,我想选择性地覆盖他们的一个类。该类通过以下方式包含:

require_once('classname.php');

但是,它出现在应用程序的各个地方。我宁愿“模拟”require_once,这样它就永远不会运行。 IE。只需根据我的需要定义class classname。然后,下次文件被require_once'ed 时,它会被标记为已经加载,因此不会重新加载。

我可以创建自己的 classname.php 文件,但我宁愿将我正在做的测试包含在一个文件中,因为我可能会为许多类执行此操作,而且我希望更轻松控制覆盖。

在 Perl 中,我想做的是:

$INC'classname.pm' = 1;

有没有办法访问 PHP 的等价于 Perl 的 %INC

更新:一直对 PHP 不允许您做的事情感到惊讶...

我的解决方法是使用runkit 的runkit_method_redefine。我加载了我试图阻止加载的类,然后重新定义了我试图“模拟”的所有方法,例如:

require_once('classname.php');
runkit_method_redefine('classname','method','$params','return "testdata";');

【问题讨论】:

如果你想包含 newclass.php 而不是 classname.php,为什么不在 classname.php 的顶部添加两行?:require_once 'newclass.php'; return; 因为我对很多类都这样做,我不想改变原来的类文件。而且因为我想要更好的控制,我宁愿有一个非基于文件的解决方案。 (即我可能会满足于将 /tmp 目录添加到 include_path 并仅创建我想要覆盖的类文件。) Benizi 别担心,我知道你的意思,这是一个最重要的问题。我在 PHP 中找不到任何东西,它是一种有限的语言。我仍然不知道当 perl 存在时它是如何变得如此流行的。我猜人们都懒得学了。 【参考方案1】:

我在想你的意思是完全有可能在代码的其他地方有另一个“required_once”会导致你的被覆盖。

你可以做两件事:

1) 找出第一个“必需”,然后将其注释掉。

2) 进入类文件并包含您的类并在定义其他类之前返回。

【讨论】:

【参考方案2】:

然后,下次文件被 require_once'ed 时,它会被标记为已经加载,因此不会重新加载。

require_once 会为您执行此操作..

此外,您还可以使用一些 hacky 之类的东西

if(!class_exists("my_class")) 
  class my_class   // define your class here

【讨论】:

对不起,解释中可能不清楚:“下一次”是第一次。我希望在我自己的代码中不创建另一个文件,以防止require_once('somefile.php'); 加载 somefile.php。你的 class_exists 得到了我为什么要这样做的要点。【参考方案3】:

地点:

<?php return; ?>

classname.php 文件的最顶部。

【讨论】:

以上是关于防止 PHP require_once 永远运行的主要内容,如果未能解决你的问题,请参考以下文章

你可以在 php 中递归运行 require_once 吗?

如何在 PHP 的 require_once 中指定文件系统绝对路径?

PHP中防止SQL注入

require_once 在 php 5.3.0 中不起作用 [关闭]

防止XSS攻击封装

php的include(),require(),include_once(),require_once()