4

我的应用程序使用一个“中央”页面控制器,它在获取请求之前使用 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');

ETC...

直到最近安装(真棒,但巨大的)“HTML Purifier”库并查看它的自动加载器之前,我才费心检查内存使用情况。显然,没有自动加载器,每个脚本实例现在的内存使用量高达(天哪!)5376 KB。(如果这是最终结果,我不知道内置自动加载器的用途,但我离题了)没有 HTML Purifier,大多数实例的重量仍然超过 1 MB。

阅读有关PHP 自动加载函数的信息,我得到的印象是自动加载器严格用于 OOP。除了净化器库之外,我使用的面向对象代码很少。我只是误解了这个概念吗?有没有其他实用的方法来避免盲目加载每个请求可能不需要的一堆类?我只是因为试图将它们全部包含在内而懒惰吗?

编辑 -

在此处重复此评论以澄清我所说的非 oo 的意思,如果这有很大的不同:

我基本上使用类来代替命名空间,而不使用(几乎)任何实际的 OOP。也就是说,“DBFunctions”类可能包含例如函数“execute”和“getRow”。这些函数通过诸如“dbFunctions::execute($sql)”之类的静态方法调用来调用。

4

3 回答 3

1

使用 Autoload 不会影响性能,因为在调用或使用它们之前不会加载它们本身的类。自动加载结构基本上根据需要加载类,它们还没有被实例化。

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

当您找到每个实例化的位置或有问题的位置时,您可以使用:

//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()

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

这是为了澄清@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。由于该类未实例化(对象实例),因此会出错。所以,是的,您可以通过引用在类内部使用函数,但它们大多必须是普通的过程或常量引用。

希望这有帮助。

于 2010-08-17T11:54:45.133 回答
1

PHP5 的自动加载仅用于动态加载类。在您的应用程序中只能使用一种自动加载功能(但请参见下文)。阅读自动加载文档了解详情。基本上,您可以定义一个 __autoload() 函数,当 PHP 尝试调用尚未加载的类时,该函数将加载您想要的任何文件(或做任何您想做的事情),包含您想要的任何类。

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

如果您刚开始在小型项目中使用 OO,您可能只需要 __autoload(),但如果您想集成 HTMLPurifier 之类的库,它确实使用 spl_autoload,google 用于文档的 spl_autoload,它们是第一个结果。

于 2010-08-18T00:01:45.513 回答
1

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

只需将那些现有的代码文件包装在其中class DBFunctions { ... }并在函数调用前加上DBFunctions::匹配的前缀就足以让自动加载器开始工作(在设置 spl_autoload_register() 回调以适应之后),这是值得的。如果您想以这种方式保留代码,它在风格上仍然是程序性的,并且如果您想采用这种方式,那么朝着 OOPifying 您的整个代码库迈出了不错的一步。

(而 HTML Purifier 是一头大象,你检查过 PHP 的内部过滤功能吗?)

于 2010-08-18T00:41:19.037 回答