nxtlvlsoftware / static-constructors
为PHP带来静态类构造函数!
Requires
- php: ^8.2.0
Requires (Dev)
- brianium/paratest: ^7.2
- phpstan/phpstan: ^1.10
- phpstan/phpstan-phpunit: ^1.3
- phpstan/phpstan-strict-rules: ^1.5
- phpunit/php-code-coverage: ^10.1
- phpunit/phpunit: ^10.3.3
This package is auto-updated.
Last update: 2024-09-03 22:29:02 UTC
README
PHP静态构造函数
将静态类初始化带到PHP!
关于
本包将其他流行编程语言中普遍存在的功能引入PHP,即静态构造函数。这是通过搜索类以查找合适的静态方法来实现的。默认策略查找与类名相同的私有方法(区分大小写)或PHP风格的魔法__constructStatic()
。接下来的步骤是确保该方法不接受任何参数,不是抽象的,并且是用户定义的(不希望意外调用扩展中的内容!)
以下是一个简单的单例示例
// src/Example.php class Example { private static self $instance = null; public static function get(): self { return self::$instance; } private static function Example(): void { self::$instance = new self(); } public function echo(): void { echo "Hello World!" . PHP_EOL; } } // src/bootstrap.php require_once __DIR__ . '/../vendor/autoload.php'; Example::get()->echo();
您可能已经可以猜到这段代码的输出,控制台将输出Hello World!
。当您的代码中首次引用类或任何子类时,静态构造函数将被调用。由于PHP加载类的方式,父构造函数将始终先被调用。
abstract class Parent { private static function __constuctStatic() { echo "Called first" . PHP_EOL; } } class Child extends Parent { private static function __constructStatic() { echo "Not called" . PHP_EOL; } private static function Child() { echo "Called second" . PHP_EOL; } } // src/bootstrap.php require_once __DIR__ . '/../vendor/autoload.php'; $object = new Child;
可以通过策略自定义方法名和可见性要求。不建议对包这样做,因为这会在其他代码依赖于默认行为时引入不兼容性问题。这个功能最好在框架中使用,其中一个项目目标是提供一个自定义的、文档齐全的环境。
安装
使用命令行上的composer安装
$ composer require nxtlvlsoftware/static-constructors
或直接将依赖项添加到您的composer.json清单中
{ "require": { "nxtlvlsoftware/static-constructors": "^1.0.0" } }
当您需要vendor/autoload.php
文件时,composer会自动处理“挂钩”库。如果您在项目中使用其他自动加载器,您可以通过在包含composer自动加载文件之前添加define('DISABLE_STATIC_CONSTRUCTOR_HOOK', true)
来禁用自动挂钩。然后,您必须自己使用\NxtLvLSoftware\StaticConstructors\Loader::init()
来挂钩库。同时也会检查全局变量$_SERVER['DISABLE_STATIC_CONSTRUCTOR_HOOK']
和$_ENV['DISABLE_STATIC_CONSTRUCTOR_HOOK']
是否存在true
值。
在手动初始化加载器时,您可以选择为方法名解析和方法要求启用哪些策略。也可以控制加载器是否应搜索已声明的运行时类。
use \NxtlvlSoftware\StaticConstructors\Loader; Loader::init( // same as default classPolicies: Loader::DEFAULT_CLASS_POLICIES, // don't check if method is public/protected/private methodPolicies: [], // only check classes that the runtime loads after init call checkLoadedClasses: false );
内部原理
所有这些都是通过注册我们自己的类加载器并注销任何先前注册的加载器来实现的。当我们的加载器被调用时,我们执行PHP通常执行的任务,遍历所有实际类加载器以尝试加载类,但在这里我们执行允许我们使用静态构造函数的魔法。如果一个类被其中一个真正的加载器加载,我们将使用反射在该加载的类上查找合适的静态构造函数方法。如果我们找到构造函数,我们只需调用它!PHP为我们做了大部分脏活。如果一个类继承自另一个类,则父类将在PHP加载子类之前自动加载,所以我们甚至不需要自己遍历继承链。由于PHP只使用自动加载器将类加载到运行时一次,构造函数只会被调用第一次引用类时。
更多信息
关于为什么要使用静态构造函数的良好总结可以在这篇博客文章中找到,作者为@ImLiam。这篇文章基于另一个较老的包,该包启发了这个包中的__constructStatic()
魔法方法。
贡献
问题
如果你发现这个项目有问题,请确保在问题跟踪器上提交一个问题,我们将尽力解决问题!
许可证信息
nxtlvlsoftware/php-static-constructors
是开源软件,可以在MIT许可证的条款下自由使用。
许可证的完整副本可在此处找到。
本软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于对适销性、针对特定目的的适用性和非侵权的保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论是基于合同、侵权或其他原因,无论是从软件产生、产生于软件或与软件的使用或其他交易有关。
NxtLvL Software Solutions产品。