eftec/autoloadone

AutoloadOne 是一个用于生成 PHP 的自动加载类的程序。

1.28 2023-01-26 21:52 UTC

This package is auto-updated.

Last update: 2024-08-27 01:20:03 UTC


README

AutoloadOne 是一个为 PHP 生成特定项目自动加载类(自动包含)的程序。这个类在代码中使用类时非常有用,无需手动调用每个“包含”。它是 Composer 的自动加载的直接替代品,但工作方式不同。
Composer 的自动加载在运行时扫描文件夹,而此库仅扫描一次文件夹并存储结果。

Packagist Total Downloads Maintenance composer php php CocoaPods

与其他替代方案不同,它支持使用 PHP 以最简单的方式自动加载类,而不会牺牲性能。它是如何工作的?AutoLoadOne 预计算项目中每个类,并生成一个可用的单一生成 autoload.php(或指定的名称)文件。您无需特定文件夹、结构或规则即可使用它。只需生成 classinclude 文件,即可加载任何类(即使是没有任何命名空间的类、不同文件夹中的命名空间内的类、单个文件中定义的多个类...)。

AutoLoadOne 是 Composer 的自动加载的替代品,使得 psr-0 或 psr-4 的使用变得过时。

注意:如果您运行的是 dev-distro,那么您必须排除 example/ 文件夹,因为它包含 @autorun 标签。

最后更新 2023 年 1 月 26 日

"PHP 中的通用自动加载类,任何类,任何时间!"

目录

它是如何工作的?

1️⃣
以 CLI 或 Web 的方式运行 AutoLoadOne.php。
2️⃣
AutoLoadOne 将根据您的项目生成一个名为 autoload.php(或指定的名称)的单个文件。记录一下,扫描 WordPress 仅需 1.5 秒,而且它与 WordPress 兼容。
3️⃣
将生成的文件(例如,autoload.php)包含到您的项目代码中并开始使用它。

我应该何时重新运行 AutoLoadOne?

如果您在相同文件夹中添加具有相同命名空间的新的类,则无需再次运行它。

此外,您还可以手动编辑 autoload.php,添加更多类和命名空间。

或者,您可以再次运行 AutoLoadOne.php 并替换旧的生成文件。

Composer 自动加载功能

🔲 每个文件一个类
🔲 每个文件一个命名空间
🔲 文件必须有一个命名空间
🔲 它需要 composer
🔲 它验证每个用户加载类时的每个文件
🔲 文件夹结构应预先定义
✅ 支持CLI

AutoLoadOne 扩展功能

✅ 每个文件一个或多个类
✅ 每个文件一个或多个命名空间
✅ 文件可以包含可选的命名空间。
✅ 只需要PHP。
✅ 文件夹结构和类只验证一次。
✅ 如果你添加一个与之前文件夹共享且使用之前命名空间的类,那么你不需要运行生成器。
✅ 你可以使用任何文件夹结构。建议使用相同的文件夹来存储相同的命名空间,但这不是必需的。
✅ 支持CLI和Web-UI。
✅ 不需要APCU、锁文件或缓存。
✅ 与几乎所有项目兼容,包括使用Composer自动加载的项目。
✅ 与PSR-0、PSR-4以及几乎所有规范兼容,因为你不需要使用任何特殊配置或标准。
✅ 允许项目文件夹外的库。
例如 /someuser/myproject/ 允许包含来自文件夹 /otheruser/library/ 的库。
✅ 不需要APCU、锁文件或缓存。
✅ 对运行时的影响最小。
✅ 允许压缩而不影响运行时。

入门

你可以直接运行AutoLoadOne.php(通过Web或通过CLI),或者你可以创建一个调用它的文件。

通过 CLI 使用

必须在根目录下执行,它将生成一个名为autoload.php的文件。

php AutoLoadOne.php -generate

如果AutoLoadOne.php不在同一文件夹中,则可以复制它,或设置路径以使用它:php /somefolder/AutoLoadOne.php -generate。还有更多你可以使用的命令,但-generate是基本且即用即得的体验。

通过代码使用

  • 将AutoLoadOne.php复制到项目的根目录(推荐)
  • 直接执行它或
  • 创建下一个PHP文件(在根目录下)并执行它。
<?php
// This code will generate the file autoload.php

use eftec\AutoLoadOne\AutoLoadOne;

define("_AUTOLOAD_SELFRUN",false); // we want to call it manually.
include "AutoLoadOne.php"; // or change the path of the file.
$auto=new AutoLoadOne();
$auto->init();
$auto->process();
$auto->render();

通过 Web 使用(生成代码)

1️⃣
将文件 autoloadone.php 复制到某处。

2️⃣
出于安全考虑,你可以编辑类 autoloadone.php 的前几行。如果需要,更改用户、密码和autoloadenter。

<?php
define("_AUTOLOAD_USER","autoloadone");
define("_AUTOLOAD_PASSWORD","autoloadone");
define("_AUTOLOAD_ENTER",true); // if you want to autoload (no user or password) then set to true
?>

3️⃣
启动浏览器

输入您的用户名和密码。如果 _AUTOLOAD_ENTER 为true,则您将自动登录。

autoloadone login

4️⃣
选择要扫描的文件夹,然后选择要生成的文件,最后点击生成按钮。

autoloadone screen

  • 根文件夹:要扫描的文件夹。
  • 生成文件:autoload.php的完整路径(本地)。即使你不使用文件生成,也必须指定它,因为程序使用它来确定相对路径。
  • 保存文件:如果你勾选它,则将生成文件。如果PHP没有权限保存文件,则可以手动复制代码(屏幕结果)
  • 排除命名空间:排除映射的命名空间。
  • 排除映射:排除扫描的路径(它们不是递归的)

5️⃣
结果应该看起来像这样

autoloadone screen2

通过 CLI 使用

autoloadone cli

在shell中,浏览到你想要生成代码的文件夹,并运行以下命令

可用命令

  • 当前(扫描当前文件夹并生成文件)
  • 文件夹(要扫描的文件夹)
  • filegen(autoload.php将要生成的文件夹)
  • filename(默认生成的文件名,通常是autoload.php)
  • save yes/no(保存要生成的文件)。这是必需的选项。
  • excludens(排除命名空间)
  • excludepath(排除路径)
  • externalpath(包含外部路径)。外部路径是位于项目文件夹之外的库

示例:php autoloadone.php -folder folder\scan -filegen folder\whereautoload\ -save yes

php folder/located/autoloadone.php -current

使用生成的文件(autoload.php)

1️⃣
包含上一步生成的文件。例如:autoload.php

<?php
define("_AUTOLOAD_ONEDEBUG",true); // this line is optional. By default, the DEBUG is off. The debug mode is used for find errors.
include "autoload.php"; // it could be an absolute or relative path.
?>

就是这样!

在/test文件夹中,你可以找到一些示例来尝试。

注意:最后,如果你想,你可以删除文件autoloadone.php。

注意

如果你想排除一个类,你可以将命名空间添加到排除列表中,或者你可以跳过一个文件夹。
此外,如果一个类有以下的注释,它将自动被排除

<?php
// @noautoload
?>

自动运行

如果您想执行(运行)一个PHP文件,可以添加以下注释。

<?php
// @autorun
?>

您也可以通过添加带有@autorun的注释来设置执行优先级。

<?php
// @autorun first
?>

如果您发现错误:语法错误,在第000行。那么一些扫描的PHP文件存在语法错误。解决方案是修复问题或排除整个文件夹。
如何找到有错误的文件?您可以运行带有调试标志的页面:autoloadone.php?debug=1

扩展

您可以通过运行以下命令来更改扩展名(默认为.php)

$auto=new AutoLoadOne();
$auto->extension='.php'; // it's not required. By default it's .php

统计和优化

此库生成以下统计数据。目标很简单,必须(在可能的情况下)减小地图的大小。地图越小,越好。

Number of Classes: 42
Number of Namespaces: 12
Number of Maps: 16
Number of PHP Files: 50
Number of PHP Autorun: 3
Number of conflicts: 0
Ratio map per file: 32% Acceptable (less is better. 100% means one map/one file)<
Ratio map per classes: 38.1% Acceptable (less is better. 100% means one map/one class)
Map size: 3.1 kbytes (less is better, it's an estimate of the memory used by the map)

屏幕示例

autoloadone screen

在日志文件中

  • 白色表示正常操作
  • 黄色表示警告。例如,某些文件已被排除。
  • 绿色表示优化。
  • 蓝色表示成功执行了重要操作。
  • 红色是必须注意的错误。

我如何减少映射?

  • 您可以使用一个类/一个文件,同时,类名必须与文件名相同。命名空间名称无关紧要

    示例 Customer.php 和类 Customer { }

  • 将同一命名空间下的类分组在同一文件夹中。因此,库可以将整个命名空间映射为单个文件夹,而不是映射每个文件/类。
    • 📁 仓库 (repositoryns\)
      • 📃 MyClass.php repositoryns\MyClass
      • 📃 MyClass2.php repositoryns\MyClass2
    • 📁 模型 (namespace_model\)
      • 📃 MyClass.php namespace_model\MyClass
      • 📃 MyClass2.php namespace_model\MyClass2
  • 您可以通过删除(:scissors:)不需要的命名空间和文件夹。但是,某些命名空间和文件夹由系统使用,它们不需要自动加载,因为它们是手动加载的(例如,大多数库都手动加载其自己的包含文件)
    • 📁 somelibrary
      • 📃 MainLibraryClass.php
      • 📃 IncludesLibrary.php ✂️
      • 📁 somelibrary ✂️
        • 📃 MoreIncludesLibrary.php ✂️
        • 📃 MoreIncludesLibrary.php ✂️
  • 您还可以通过添加标签 @noautoload 来排除文件/类/include/结构。
/* @noautoload */
class Someclass {

}
    • 📁 somelibrary
      • 📃 MainLibraryClass.php
      • 📃 IncludesLibrary.php @noautoload ✂️
  • 只有扩展名为 .php(或定义的扩展名)的文件才会被加载。所以,.inc.phpinclude 或类似的文件会被自动排除(:scissors:)。
    • 📁 somelibrary
      • 📃 file.inc.php (inc.php被包含,但.inc)
      • 📃 IncludesLibrary.inc ✂️
      • 📃 MoreIncludesLibrary.inc ✂️
  • 另一种优化是在同一个文件中写入多个类。此库甚至允许在同一个文件中使用多类/多命名空间。因此,可以创建项目的批量版本。
    • 📃 AllClassesOneFile.php
      • namespace repositoryns\
        • class repositoryns\MyClass
        • class repositoryns\MyClass3
      • namespace anotherns\MyClass2
        • class anotherns\MyClass2

测试

我在Laravel上创建了一个空的博客。项目是空的,但有默认库和组件。

文件

7545 files in total. (including files that aren't PHP files)

AutoLoadOne

Number of Classes: 5565
Number of Namespaces: 765
Number of Maps: 2305 (you want to reduce it)
Number of PHP Files: 6302
Number of PHP Autorun: 0
Number of conflicts: 31

生成的文件

autoload.php 231kb.

优化后的 AutoLoadOne

我已将PHPUnit和Mockery从项目中分离出来。为什么?这两个库都是用于单元测试的。

排除的命名空间 = /vendor/phpunit/,/vendor/mockery/

Number of Classes: 5565
Number of Namespaces: 765
Number of Maps: 1535 (you want to reduce it)
Number of PHP Files: 6302
Number of PHP Autorun: 0
Number of conflicts: 13     

生成的文件

autoload.php 159kb.    

Composer 的自动加载(使用优化)

composer dump-autoload -o

Generated optimized autoload files containing 3519 classes
Number of Maps: 3519 (static and not-static)

自动加载使用以下方法之一

  • 静态:(快速方法,它使用更多内存,并且需要手动计算)

    autoload.php 1kb
    autoload_real.php 3kb
    autoload_static.php 468kb
    ClassLoader.php 14kb

  • 非静态:(默认方法)

    autoload.php 1kb autoload_real.php 3kb autoload_namespaces.php 1kb autoload_psr4.php 4kb autoload_classmap.php 426kb

大小为什么很重要?

假设我们调用一个使用自动加载的单页网页。

如果我们使用 Composer 的自动加载(静态加载),我们也会调用一个使用 468kb(加上其他文件)的文件,并且这个内存被加载到内存中。每次调用可能会使用(平均)609kb 的 RAM(大约是 PHP 文件 x 1.3 x 1kb)。

例如,如果我们有 1000 个并发用户。由于自动加载,它将使用 609kb x 1000 = 609mb 的 RAM,同时有 10k 个并发用户,我们仅因为自动加载就会使用 6gb 的 RAM

使用 AutoLoadOne,它被优化到 302mb(1000 个用户)或 3gb(10k 个用户),这是对于未优化的版本。

AutoLoadOne 会标记项目中所有的类,包括在 composer.json 中未定义的类(除非它们被排除在项目之外)。Composer 的自动加载只找到了 3519 个类,而 AutoLoadOne 找到了项目中的所有类(5565 个)。

然而,有些类可能不需要被项目加载(例如单元测试类),因此我们可以排除这些项目中的类。

例如,排除 PHPUnit 和 Mockery 可以将使用量减少到 206mb(1000 个用户)或 2gb(10k 个用户),但我们还可以进一步优化。

查找使用?

假设我们有一个包含不同元素的 "map"。查找 map 中的元素需要多长时间?

所以,map 的大小/查找时间并不重要。一个小 map(100 个元素)与一个大 map(1百万个元素)之间的差异总共是 0.1 秒(每 1 百万个查询)。然而,内存使用很重要,可能会对性能产生重大影响。

调用多少次查找?

假设我们有 10k 个并发用户,每个用户调用 100 个不同的类。这意味着我们同时进行 10k x 100 = 1 百万个查找。

第二次测试(Magento 2.2.3)

Magento 是一个巨大的项目,它有 22k 个 PHP 文件,其中 20k 个是类。

AutoLoadOne

Number of Classes: 21063
Number of Namespaces: 7018
Number of Maps: 9473 (you want to reduce it)
Number of PHP Files: 22862
Number of PHP Autorun: 0
Number of conflicts: 6
Ratio map per file: 41.44% Bad. (less is better. 100% means one map/one file)
Ratio map per classes: 44.97% Bad. (less is better. 100% means one map/one class)
Map size: 1398.7 kbytes (less is better, it's an estimate of the memory used by the map)
Map size Compressed: 1195.1 kbytes (less is better, it's an estimate of the memory used by the map)

生成 autoload.php 需要大约 +/- 200 秒。

相比之下,Composer 的自动加载(优化版)使用

Generated optimized autoload files containing 11582 classes
Number of Maps: 11582 classes (2.6mb of memory will be use per request per user)

然而,它没有进行手动优化。

假设我们有 1000 个并发用户

(*) 然而,Magento 并不是为了并发而创建的。但,然而我们测量的不是并发用户的数量,而是并发调用的数量(例如 rest-json、打开页面等)。

压缩和 Magento。

虽然 AutoLoadOne 能够压缩 map,但它只压缩了路径,而不是命名空间。这是因为压缩的目标是尽量减少对系统的影响。Magento 在大型命名空间上依赖很重,因此压缩无法压缩它们。但仍然,系统能够在 15% 的程度上压缩值。

总的来说,压缩可以将值缩小 40-50%。

代码执行。

AutoLoadOne 和 Composer 的自动加载都在初始化/执行时执行代码。

当 AutoLoadOne 生成 map 时,它由以下两个关系数组组成

    private $_arrautoloadCustom = array(
		'Magento\AdminNotification' => '/app/code/',
		'Magento\Notice' => '/app/code/Developer/',...

而 Composer 的自动加载生成一个需要拼接的数组。

array(
    'Magento\\AdminNotification' => $baseDir . '/app/code/MagentoActions.php',
    'Magento\\Notice' => $baseDir . '/app/code/Developer/Notice.php',

所以它需要拼接每个 map(使用一个名为 $baseDir 的变量)。因此,Composer 的自动加载会稍微影响性能。

基准测试

PHP 7.1.18 + Windows 10 + SSD。

AutoloadOne Benchmark

越多越好。

我通过加载不同的类并读取其性能进行了综合基准测试。由于我的机器有 SSD 硬盘,所以与机械硬盘相比,磁盘的影响最小。此图表比较了与 INCLUDE 的性能。

安全性

您可以阻止对文件的访问

RedirectMatch 403 ^/folder/^/folder/.*$

❗ 虽然程序有内置的安全措施,但我建议添加新的安全层,例如将 AutoLoadOne.php 文件放在 public/web 文件夹之外。

AutoLoadOne.php 不安全(因为它会写入生成文件),它没有访问数据库的权限,也不允许写入任何内容到文件,但它可能会覆盖现有的代码并破坏系统。

然而,生成文件(autoload.php)是安全的,并且可以将其暴露在网络上。

  • 更改用户名和密码,并将 _AUTOLOAD_ENTER 设置为 false。
  • 或者,不要将此文件放在您的公共网站上。
  • 或者,更改文件名。
  • 或者,您可以使用 .htaccess 或类似工具阻止对文件的访问。
RewriteEngine On
RewriteBase /

<Files "AutoLoadOne.php">
Order Allow,Deny
Deny from all
</Files>
  • 或者,您可以限制对 PHP 的访问,Linux 上的默认行为就是这样(通常以 NOBODY 用户身份运行于 Apache 账户下)。

composer.json

通常,这个库不需要 composer.json,并且它直接读取 PHP 源代码,因此会忽略其配置。然而,从 1.19 版本开始,AutoLoadOne(可选地)读取 composer.json 的部分信息,以实现兼容性。例如,guzzlehttp 库就使用了这个功能。

注意:需要将常量 _AUTOLOAD_COMPOSERJSON 设置为 true。默认情况下,此变量为 false

让我们看看下一个文件

composer.json

{
  "autoload": {
    "psr-4": {
      "blahblahblah": "some folder blahblahblah/"
    },
    "files": ["src/functions_include.php"]
  }
}

如果 AUTOLOAD_COMPOSERJSON 为 true,AutoLoadOne 将包含 composer.json 和 'files' 中声明的文件。这些文件或文件夹将按如下方式添加到我们的 autoload.php 中

我们生成 autorun.php 的代码

define("_AUTOLOAD_COMPOSERJSON",true);
include 'vendor/eftec/autoloadone/AutoLoadOne.php';

生成的 autorun.php 文件

@include __DIR__.'/folder/jsontest/src/functions_include.php'; 

由于这个过程只执行一次(在生成 autoload.php 时),因此此功能不会影响性能,因为它只读取一次 composer.json 文件。

版本

  • 1.28 2023-01-26
    • 小清理
  • 1.27 2022-08-27
    • [修复] 修复了双重映射的问题。
  • 1.26 2022-02-21
    • [修复] 兼容 PHP 8.1。
    • 提高与 php 7.1.5 及更高版本的兼容性。如果需要使用旧版本,可以使用 1.25.1。
    • 将 AutoLoadOne 添加为 composer 的二进制文件。
  • 1.25.1 2021-06-09
    • [修复] 在 autoloadone_exception_handler 中,当错误参数不是数组而是字符串时。
  • 1.25 2021-04-17
    • 更好的错误管理。现在,它会在自定义跟踪中显示错误所在的行。
  • 1.24 2021-04-17
    • [cli] 重新着色 CLI。
    • [代码] 代码中的某些清理。
    • [修复] 现在生成的文件显示了正确的小时。
  • 1.23 2021-02-26
    • 更新了生成的文件。
  • 1.22.2 2021-02-26
    • 修复了 composer.json。
  • 1.22.1 2021-02-26
    • 修复了代码中的错误。
  • 1.22 2021-02-26
    • 另一个修复(它未能保存配置文件。未能为多个类使用相同的路径)。
    • 配置现在存储在同一个文件 autoload.php 中。旧文件仍然可以使用,但仅当未设置或使用新配置时。
    • 删除了部分配置,与 json 相关的函数以及与 json 相关的常量。
  • 1.21.2 2021-02-15
    • 删除了错误的 "']" 字符。
  • 1.21.1 2021-02-15
    • 修复了 composer.json(错误的数字)。
  • 1.21 2021-02-15
    • 修复了与 Linux 相关的一个大问题。它使用了 basename(),但在 Linux 和 Windows 中的行为不同。现在,它在 Linux 中正常工作。
  • 1.20 2020-09-02
    • 一些清理。
    • GUI 有一些示例。
    • _AUTOLOAD_COMPOSERJSON 指示了它在何处执行或不执行。
  • 1.19.2 2020-06-05
    • composer.json 功能现在是可选的(默认禁用)。
  • 1.19.1 2020-06-05
    • composer.json 的 autoload-files 现在可以通过 "exclude-path" 排除。
  • 1.19 2020-06-05
    • 添加了 composer.json {'autoload': {'files': []}}
  • 1.18 2020-04-23
    • 一些清理。
    • 生成的文件也进行了清理和优化。
  • 1.17 2020-01-26(可选但默认),映射被压缩。
    • 压缩对运行时的影响最小,它只使用正则表达式替换字符串。
  • 1.16 2019-08-04 删除了 git 引用。它不再使用。将样式格式改为 PSR。
  • 1.15 2019-06-08 再次删除了外部 CSS。现在它将 CSS 生成在文件内。
  • 1.14 2019-06-08 修复了一些错误。重置为全局(const 数组与 php<7.0 不兼容)。
  • 1.12 2019-05-10 添加了一些提交的更改。删除了 CSS。
  • 1.11 2019-03-04 允许指定结果PHP文件。并进行了一些清理。现在,/namespace/nameclass:class 不会被视作一个类
  • 1.10 2018-10-18 解决了从不同URL加载autoload.php时的小错误,并处理了外部和远程文件夹的问题。
  • 1.9 2018-10-14 做了一些小修复和一些颜色调整。
  • 1.8 2018-10-14 添加了外部路径和一些修复。现在您可以在路径中不包含逗号(将自动添加)[WebUI]
  • 1.7 2018-10-12 一些小修复。现在默认情况下,系统使用调用者的路径,而不是AutoLoadOne.php的路径。
  • 1.6 2018-09-28 在排除列表(文件夹)中添加了通配符 (*)。
  • 1.5 2018-09-05 默认情况下,界面会自动打开。如果用于公开用途,则必须删除或限制此文件。
  • 1.4 2018-08-25 一些示例。现在默认情况下,界面不会自动打开。这是出于安全考虑。
  • 1.3 2018-07-05 现在它支持界面,并修复了一些特定文件的问题。还修复了Linux与Windows文件夹的问题。
  • 1.2 2018-07-01 做了许多更改。修改了排除项。Web UI的标题和图标。它还允许禁用Web。
  • 1.1 2018-06-26 一些修复。
  • 1.0 2018-06-24 第一个版本

待办事项

  • 保存配置
  • CLI(更多命令)
  • 清理代码。
  • 转换为单个类。
  • 外部文件夹/库(相对或绝对路径)
  • 如果PHP文件有错误,生成将失败。
  • 指定扩展名。默认情况下,它只扫描.php文件。