【问题标题】:php - Autoloader implementation, preload all the classesphp - 自动加载器实现,预加载所有类
【发布时间】:2016-07-23 04:06:41
【问题描述】:

我是 php 新手,继承了一个包含数百个页面的网站项目,所有页面都是程序性的(当我对文件进行文本搜索时,任何地方都没有函数定义)。我来自 c# 和 Java 世界。我正在寻找一种增量添加 OOP 的方法。 (他们希望我更新前端,我试图说服他们同时修复后端,他们不想使用框架(该死)。

在研究自动加载器时...嗯,这是我的理解。这是一种注册存储类的文件夹的方法,当您实例化一个类、特征等时,它会根据类/文件名/命名空间搜索文件夹并加载适当的定义。

我有几个问题:

自动加载器是否搜索文件夹并在每个页面生命周期加载适当的定义(或者是否缓存它们)?

预加载: 有没有办法使用自动加载器或其他替代方法将所有类定义预加载到内存中并使它们在所有会话中可用?

如果是这样,在更新类文件时,我如何告诉这个机制在我对类文件进行更改时将所有内容重新加载到内存中?

问题更新:

感谢您的回答,这对您有所帮助,但是...我确实有在 StackOverflow 上提出错误问题的坏习惯。

我要避免的事情是通过添加类来减慢页面速度。所以假设我添加了一个库并使用自动加载器注册路径。一个页面实例化一个具有多个依赖项的类。假设依赖图包含 15 个文件。对于每个请求生命周期,服务器仅在该页面上加载页面和 15 个其他文件。

由于我来自编译语言,我觉得没有将这些类加载到内存中有点奇怪。所有的类加起来不应该超过 5MB。

(或者也许我应该只创建一个 RAM 磁盘并在启动时复制其中的所有文件并只拥有一个符号链接?)

【问题讨论】:

  • 如果您还没有,我想看看PHP-FIG: AutoloaderComposer
  • 我想我需要走这条路:en.wikipedia.org/wiki/List_of_PHP_accelerators
  • @PaulPerrick 感谢您的链接。让我思考我自己的部署设置。
  • 在每个请求周期都加载类文件(很少更改的文件)对我来说太奇怪了,而文件访问是您可以执行的最慢操作之一。

标签: php autoloader


【解决方案1】:

PHP 中的自动加载器是惰性的。当 PHP 遇到一个它不知道的类的使用时,它会要求注册的自动加载器(或自动加载器链)去寻找它。自动加载器的工作是找出在哪里获取定义类的文件并将其包含在内。对类命名和组织类文件有某种约定是拥有一个有用的自动加载器的关键,PHP 社区中已经出现了一些约定,例如PSR-4

自动加载器是否搜索文件夹并在每个页面生命周期加载适当的定义(或者是否缓存它们)?

每个请求都会调用自动加载器,但仅在需要自动加载类时才会调用。

预加载:有没有办法使用自动加载器或其他替代方法将所有类定义预加载到内存中,并使其在所有会话中可用?

我不相信,但是随着班级数量的增加,这变得越来越浪费。

欢迎来到遗留 PHP 的精彩[需要引用] 世界,我强烈建议您查看Modernizing Legacy Applications In PHP。这就像从魔多返回夏尔的战略指南。

【讨论】:

    【解决方案2】:

    我想你可能误解了自动加载的目的。它只是关于当您的代码调用 PHP 无法识别的类时应该做什么的说明。就是这样。自动加载器只调用requires /path/to/classfile 以便 PHP 可以看到该类。

    自动加载器是否搜索文件夹并加载适当的定义 在每个页面生命周期中(或者是否缓存它们)?

    请求之间没有缓存,因此如果您对文件进行更改,下一个 http 请求将包含这些更改。就像您更改了脚本中的任何其他指令一样,例如将 echo 1 更改为 echo 2

    预加载:有没有办法使用自动加载器或其他替代方法 将所有类定义预加载到内存中并使其可用 跨所有会话?

    没有这个必要。一个写得很好的自动加载器有说明在哪里可以找到任何类,所以提前加载所有可能的类是浪费的。如果您仍然遇到undefined classes 错误,您需要改进自动加载器或按照当前的自动加载器说明放置类文件。

    如果您真的想预加载所有类,请使用php.ini 中的auto_prepend_file 设置。 The docs say

    指定在 主文件

    将其设置为初始化脚本。在那个脚本中有类似的东西:

    //put all your class files in this folder
    $dir = '/path/to/classes/folder';
    $handle = opendir($dir);
    
    //require all PHP files from classes folder
    while (false !== ($item = readdir($handle))){
        $path = $dir.'/'.$item;
        if(is_file($path) && pathinfo($path,PATHINFO_EXTENSION)==='php')
            require_once $path;
    }
    

    这是简化的。仅将任何目录中的所有文件都包含到脚本中存在很大风险,因此我不会这样做。如果您想在子目录中包含文件,您还需要对此进行调整。

    基本上,不要这样做。只要有一个好的自动加载器。

    【讨论】:

      【解决方案3】:

      没有人发布我正在寻找的内容,但似乎最好的途径是预建在 php 5.5 及更高版本中的 OptCache(我的客户端使用的是 5.3,所以我不知道)。

      https://github.com/zendtech/ZendOptimizerPlus

      Zend OPcache

      Zend OPcache 通过操作码缓存提供更快的 PHP 执行 和优化。它通过存储预编译来提高 PHP 性能 共享内存中的脚本字节码。这消除了阶段 从磁盘读取代码并在将来访问时对其进行编译。在 此外,它应用了一些字节码优化模式,使 代码执行速度更快。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多