jeremeamia / xstatic
Requires
- php: >=5.3.3
- container-interop/container-interop: ~1.0
Requires (Dev)
- phpunit/phpunit: 3.7.*
This package is auto-updated.
Last update: 2020-07-06 18:27:49 UTC
README
请考虑使用 ReStatic。
XStatic
XStatic 是一个 PHP 库,用于启用 静态代理接口——类似于 Laravel 4+ 的 "Facades",但适用于任何 PHP 项目。XStatic 由 Jeremy Lindblom 创建。
注意:请考虑使用 ReStatic,这是该库的维护分支。XStatic 已不再积极支持。
介绍(问答)
Facades?静态代理?使用静态方法不是一种坏习惯吗?
使用静态方法和类使您的代码更难测试。这是因为您的代码变得与静态引用的类紧密耦合,并且对单元测试中的静态方法进行模拟是困难的。出于这个和其他原因,面向对象编程(OOP)专家通常不鼓励使用静态方法。通常,涉及如 服务定位器 和 依赖注入(DI)的设计模式的技巧被首选用于管理对象依赖和组合。
但是...使用静态方法真的很简单。
是的,喜欢使用 CodeIgniter、Laravel、Kohana 和 FuelPHP 等框架的 PHP 开发者非常习惯在应用程序开发中使用静态方法。在这些社区中,这是一种鼓励的做法,他们认为这使代码更易于阅读,并有助于 快速应用开发(RAD)。
那么,有什么妥协的方法吗?
是的!Laravel 4 有一个名为 "facades" 的概念(注意:这不同于 外观设计模式)。这些充当存储在服务容器中的实际对象实例的静态接口或代理。静态代理通过一些技巧与容器链接,包括通过 PHP 的 class_alias()
函数定义类别名,以及使用魔法 __callStatic()
方法。我们应该感谢 Taylor Otwell 开发这项技术。
那么 XStatic 的目的是什么?
XStatic 使用与 Laravel 的 "facades" 系统相同的技巧,但提供了两个额外的、但重要的特性
- 它与任何框架的服务容器兼容 - XStatic 依赖于 container-interop 项目的
ContainerInterface
。您可以使用 Acclimate 库将任何第三方容器适配到 XStatic 所依赖的标准化容器接口。 - 它在任何命名空间中工作 - XStatic 在堆栈中注入了一个自动加载器,因此无论您尝试从什么命名空间或作用域引用您别名的静态代理,它都会通过 XStatic 自动加载器。您可以配置 XStatic 以在全局命名空间、当前命名空间或特定命名空间中创建别名。
那么,为什么叫 XStatic 呢?
有两个原因
- 它消除了静态方法调用的静态性,因为方法调用被代理到实际对象实例。潜在的标语:"没有静态陷阱的静态接口"。
- 它的发音像单词"ecstatic",因为它的目的是给开发者(至少是其中一些人)带来快乐。
使用方法
为了向您展示如何使用XStatic,我将向您展示一个简单的Silex应用程序。
您的应用程序引导程序
<?php // Include the Composer autoloader, of course require 'vendor/autoload.php'; use Acclimate\Container\ContainerAcclimator; use XStatic\ProxyManager; use Silex\Application; use Silex\Provider\TwigServiceProvider; // Setup your Silex app/container $app = new Application; $app->register(new TwigServiceProvider, array( 'twig.path' => __DIR__ . '/templates', )); $app['db'] = function () { return new PDO('mysql:dbname=testdb;host=127.0.0.1', 'dbuser', 'dbpass'); }; $app->get('/', 'MyApp\Controller\Home::index'); // Routes "/" to a controller object // Setup and enable XStatic $acclimator = new ContainerAcclimator(); $proxyManager = new ProxyManager($acclimator->acclimate($app)); $proxyManager->addProxy('View', 'MyApp\Proxy\Twig'); $proxyManager->addProxy('DB', 'MyApp\Proxy\Pdo'); $proxyManager->enable(ProxyManager::ROOT_NAMESPACE_ANY); // Run the app $app->run();
您的静态代理类
namespace MyApp\Proxy { use XStatic\StaticProxy; class Pdo extends StaticProxy { public static function getInstanceIdentifier() { return 'db'; } } class Twig extends StaticProxy { public static function getInstanceIdentifier() { return 'twig'; } } }
您的控制器类
namespace MyApp\Controller; class Home { public function index() { // It just works! View::render('home.index', array( 'articles' => DB::query('SELECT * FROM articles') ); } }
非常酷,对吧?关于这个例子的一些有趣的事情是,我们实际上隐藏了我们在控制器中使用PDO和Twig的事实。我们可以轻松地替换使用相同接口的其他东西,而控制器代码则不需要更改。我们唯一需要做的是将不同的对象放入应用程序容器中。实际上,测试控制器就是这样工作的。测试可以使用放入容器的模拟或存根对象进行引导。
没有静态陷阱的静态接口。
XStatic 概念
- 静态代理 – 将静态方法调用代理到其 代理主题 实例方法上的静态类。
- 代理主题(实例) – 存储在 容器 中并与 静态代理 链接的对象实例。
- 代理管理器 – 用于将 静态代理 与 别名加载器 和 容器 关联的中介对象。
- 别名 – 用作 静态代理 类完全限定类名的别名的可记忆的类名。
- 别名加载器 – 维护 别名 和 静态代理 之间的关联。它被注入到自动加载堆栈中,以处理引用时出现的别名。
- 容器 – 提供 代理主题 实例的 IoC 容器(例如,服务定位器或 DIC)。它必须实现 container-interop 项目中的
ContainerInterface
。 - 实例标识符 – 用于从 容器 中获取 代理主题 的标识符。每个 静态代理 必须指定获取其代理主题所需的实例标识符。
- 根命名空间 – 可以引用 别名 的命名空间。这可以配置为全局命名空间(默认)、特定命名空间或 任何 命名空间(即,别名可以在任何命名空间中工作)。
工作原理
以下图表显示了当引用静态代理时会发生什么,假设它之前已添加到代理管理器中。
灵感
这个库深受 Facades 系统的启发,该系统在 Laravel 4 框架 中。
免责声明
我不会把自己定位为支持或反对使用静态代理接口(或Laravel的“门面”),但我确实认为这是一个有趣且独特的想法,而且非常酷的是,你可以这样编写代码,同时它仍然能够正常工作并且可测试。我很想看看开发者,尤其是库和框架的开发者,是否能够找到方法来使用,但不强制要求,这些静态代理接口,以便让他们的项目吸引更广泛的PHP开发者。