有什么方法可以避免为非oo应用程序加载未使用的类?

时间:2010-08-17 10:28:29

标签: php autoload

我的应用程序使用“中央”页面控制器,在获取请求之前,使用require_once抓取每个包含一些相关类的文件(我不犹欢说库)。如:

require_once (dir_lib . 'db.php');              
require_once (dir_lib . 'uuid.php');            
require_once (dir_lib . 'data.php');            
require_once (dir_lib . 'token.php');           
require_once (dir_lib . 'logs.php');            
require_once (dir_lib . 'time.php');

等...

在最近安装(真棒,但巨大的)“HTML Purifier”库并浏览其自动加载器之前,我没有费心去检查内存使用情况。显然,自动加载器没有,每个脚本实例现在重量惊人(甜蜜的耶稣!)5376千字节的内存使用量。 (我不知道内置的自动加载器是什么,如果这是最终的结果,但我离题了)没有HTML净化器,大多数实例仍然超过一兆字节。

阅读PHP autoload functions我的印象是自动加载器严格意味着OOP。除了净化器库,我使用的是非常少的面向对象的代码。我只是误解了这个概念?有没有其他实用的方法可以避免盲目加载每个请求可能不需要的一堆类?我只是懒得试图将它们全部包括在内吗?

编辑 -

在这里重复这个评论以澄清我对非oo的意思,如果这有很大的不同:

  我是   基本上用类来代替   没有使用(几乎)任何名称空间   实际的OOP。也就是说,   “DBFunctions”类可能包含for   例如,函数“执行”和   “的getRow”。调用这些函数   用静态方法调用如   “dbFunctions ::执行($ SQL)。”

3 个答案:

答案 0 :(得分:1)

使用Autoload并不会达到性能,因为在调用或使用它们之前,它们不会加载它们。 Autoload contruct基本上根据需要加载类,因为它们尚未实例化。

在代码中查找首先实例化的类。除非类文件自动实例化,否则它不会占用任何内存。也许并非所有人都被实例化,但在不需要的时候也不会被取消。

如果您发现每个实例的位置或您可以使用的问题,那么:

//Gets the object name using the class.
echo get_class($classinstance) , "\n";

您可以使用memory_get_peak_usage()放置一些断点来处理它。

//Output memory usage at start of class instanciation.
echo memory_get_usage()
#memory_get_peak_usage() prior to 5.2.1.

$classobject1 = new theclass();

//Output memory usage after class instanciation.
echo memory_get_usage()

现在尝试相同的事情,但这次使用后使用unset():

//Output memory usage at start of class instanciation.
echo memory_get_usage()
#memory_get_peak_usage() prior to 5.2.1.

$classobject1 = new theclass();

unset($classobject1);

//Output memory usage after class instanciation.
echo memory_get_usage()

所以基本上理论上,在app中取消设置任何未使用的实例,找到大对象,调试。

这是为了澄清@ greg关于OOP的评论:

把这个块作为样本:

class Tun{
    private $run = 'i\'m running';

    function run(){
        echo $this->run;
    }
}

echo Tun::run;

输出:

Error: Fatal error: Undefined class constant 'run' in C:\Work\pro\debug.php on line 16

上面的示例因为引用了一个使用OOP的函数,在本例中是类私有变量$run。由于该类未实例化(对象实例),因此会出错。所以,是的,您可以通过引用使用类中的函数,但它们通常必须是简单的过程或常量引用。

希望得到这个帮助。

答案 1 :(得分:1)

PHP5的自动加载仅用于动态加载类。您的应用程序中只能使用一个自动加载功能(但请参见下文)。有关详细信息,请阅读autoload docs。基本上,当PHP尝试调用尚未加载的类时,您可以定义一个__autoload()函数来加载您想要的任何文件(或者做任何您想要的事情),包含您想要的任何类。 / p>

您在问题中提供的链接是关于标准PHP库的自动加载,它是不同的,更灵活。 spl_autoload_register()允许您注册一堆自动加载功能,而不仅仅是一个。当你在代码中使用自动加载的库时,这是最有用的,因为他们的自动加载不需要破坏你的或其他库的。

如果您刚开始使用小型项目的OO,您可能只需要__autoload(),但如果您想要集成像HTMLPurifier这样的库,它使用spl_autoload,谷歌为文档的spl_autoload,它们就是第一个结果。

答案 2 :(得分:1)

这些函数文件是否有特殊原因不是类?我唯一能想到的就是PHP4的兼容性,但无论如何都不存在PHP4中的自动加载。

只需将class DBFunctions { ... }中的现有代码文件包装起来,并使用DBFunctions::为函数调用添加前缀,就足以让自动加载器开始工作(在设置spl_autoload_register()回调以适应之后),这是值得的。如果你想以这种方式保存代码,那么它仍然具有风格上的程序性,如果你想这样做,那么向整个代码库进行OOP化也是一个不错的步骤。

(并且HTML Purifier是一个大象,你有没有检查过PHP的内部filter函数?)