jgswift / qtil
PHP 5.5+ 工具库
Requires
- php: >=5.5
- jgswift/restructr: 0.1.*
Requires (Dev)
- phpunit/phpunit: 3.7.*
- satooshi/php-coveralls: dev-master
This package is not auto-updated.
Last update: 2024-09-28 15:13:30 UTC
README
PHP 5.5+ 工具库
描述
此软件包包含各种工具,以帮助开发并减少样板代码。
安装
通过命令行使用 composer 安装
php composer.phar require jgswift/qtil:0.1.*
通过 composer.json 使用 composer 安装
{
"require": {
"jgswift/qtil": "0.1.*"
}
}
依赖
- php 5.5+
- jgswift/restructr 域组件基础
用法
ArrayAccess
以下是一个 ArrayAccess 最小示例
<?php class Foo implements \ArrayAccess, \Countable, \IteratorAggregate { use qtil\ArrayAccess, qtil\Countable, qtil\IteratorAggregate; } $foo = new Foo; $foo['bar'] = 'baz'; var_dump($foo['bar']); // returns "baz"
ObjectAccess
类似于 ArrayAccess,ObjectAccess 也可以用于传统对象魔法。
以下示例看起来是默认对象行为,但所有访问器和修改器都通过魔法和属性在本地数组中处理。
<?php class Foo { use qtil\ObjectAccess; } $foo = new Foo; $foo->bar = 'baz'; var_dump($foo->bar); // returns "baz"
JSONAccess
JSONAccess 特性提供集成 JSON 序列化,可用于 ObjectAccess 和 ArrayAccess 对象。
<?php class Foo { use qtil\ObjectAccess, qtil\JSONAccess; } $foo = new Foo; $foo->bar = 'baz'; $json_string = $foo->toJSON(); $foo2 = new Foo; $foo2->fromJSON($json_string); var_dump($foo2->bar); // returns "baz"
Serializable
使用 Serializable 接口/特性组合也可以进行常规对象序列化。常规序列化也适用于 ArrayAccess 和 ObjectAccess。
<?php class Foo implements \Serializable { use qtil\ObjectAccess, qtil\Serializable; } $foo = new Foo; $foo->bar = 'baz'; $serial_string = serialize($foo); $foo2 = unserialize($serial_string); var_dump($foo2->bar); // returns "baz"
Iterator
Qtil 通过名为 Iterator 和 IteratorAggregate 的特性分别提供标准 Iterator 和 IteratorAggregate 实现。
<?php class Foo { use qtil\ObjectAccess, qtil\Iterator; } $foo = new Foo; $foo->bar = 'baz'; $foo->baz = 'rus'; foreach($foo as $name => $value) { var_dump($name,$value); // returns bar => baz, then baz => rus }
IteratorAggregate
<?php class Foo { use qtil\ObjectAccess, qtil\IteratorAggregate; } $foo = new Foo; $foo->bar = 'baz'; $foo->baz = 'rus'; foreach($foo as $name => $value) { var_dump($name,$value); // returns bar => baz, then baz => rus }
IteratorAggregate 自定义迭代器
迭代器聚合特性提供了一个便利的属性来手动指定迭代器。默认情况下,使用 ArrayIterator。
class Foo { use qtil\ObjectAccess, qtil\IteratorAggregate; public static $ITERATOR_CLASS = 'FooIterator'; } class FooIterator implements \Iterator { function current() { /* ... */ } function key() { /* ... */ } function next() { /* ... */ } function rewind() { /* ... */ } function valid() { /* ... */ } } $foo = new Foo; foreach($foo as $value) { // iterates over foo using fooiterator }
Generator
可以通过指定生成器函数轻松自定义迭代过程,而不需要自定义 Iterator。
class Foo { use qtil\ObjectAccess, qtil\Generator; } $foo = new Foo([ 'bob', 'sam', 'jim' ]); $foo->setGenerator(function($item) { return $item; }); $gen = $foo->getGenerator(); foreach($gen as $item) { // 'bob' , 'sam' , 'jim' }
Identifier
Qtil 包含一个简单的工具,可以轻松自定义对象识别方式。
有一些默认的识别对象方案,确保各个对象实例分别识别。您可以使用此功能代替 spl_object_hash 来确保标识符唯一性。或者,提供一些内置方案。
以下是最小示例,使用默认方案
<?php class Foo { } $foo = new Foo(); $id = qtil\Identifier::identify($foo); // Returns an unique hash
通过轻微的修改,您可以将识别行为封装在您自己的类中
class Foo { function getID() { return qtil\Identifier::identify($this); } } $foo = new Foo(); $id = $foo->getID(); // Returns an unique hash
方案
qtil 还提供了一些内置方案,使用各种方式确定如何识别对象。
class Foo { function getID() { return qtil\Identifier::identify($this); } function getUniqueID() { return 1; } } qtil\Identifier::addScheme( new qtil\Identifier\Scheme\MethodScheme('getUniqueID') ); $foo = new Foo(); $id = $foo->getID(); // Returns 1
您可以为大多数方案提供自定义回调方法
class Foo { function getID() { return qtil\Identifier::identify($this); } } qtil\Identifier::addScheme( new qtil\Identifier\Scheme\ClassScheme('Foo',function() { return 1; }) ); $foo = new Foo(); $id = $foo->getID(); // Returns 1
Factory
通过反射创建对象,并验证构造函数签名中的参数
如果提供的参数与类构造函数不匹配,则抛出 qtil\Exception 异常
class User { /* ... */ } class MyUserFactory { use qtil\Factory; } $factory = new MyUserFactory; $user = $factory->make('User'); var_dump(get_class($user)); // 'User'
Proxy
简单的魔法中介
通过本地作用域的魔法方法(即 __get、__set、__unset、__isset 和 __call)中介对象实例
class MyUserProxy { use qtil\Proxy; } class User { /* ... */ function sayHello() { return 'hello'; } } $user = new User; $proxy = new MyUserProxy(); $proxy->setSubject($user); $message = $proxy->sayHello(); var_dump($message); // 'hello'
可执行(命令)
此简单特性使对象可调用,并通过执行方法公开。执行方法可以有任何参数,不强制执行任何特定方法签名。
class MyBinarySwitch { use qtil\Executable; function execute($start) { if($start) { return false; } return true; } } $switch = new MyBinarySwitch(); $result = $switch(false); // starts off var_dump($result); // ends on $result = $switch(true); // starts on var_dump($result); // ends off
方法链
以下概述的链机制优先考虑约定而非配置。链式方法由一个或多个命名空间的直接子类提供。命名空间是可定制的,但默认值是单个命名空间,与链式类的类签名相匹配
class Query { use qtil\Chain; } // a namespace with the same signature as the class must be created // or alternatively the namespaces may be configured manually namespace Query { class Select { function __construct() { /* Specify relevant fields */ } } class From { function __construct() { /* Choose a source */ } } } namespace OtherQueryTypes { class Within { function __construct() { /* Specify constraints */ } } } // create a query using above chain classes $query = new Query; $query->select()->from(); var_dump(count($query->getLinks())); // 2 // this namespace extension will only extend this individual query instance $query->addNamespace("OtherQueryTypes"); $query->within(); var_dump(count($query->getLinks())); // 3 // add a second namespace globally to extend every instantiated object of this type. qtil\Chain\ClassRegistry::addNamespace('Query','OtherQueryTypes');
注意:使用魔法方法(如 __get, __set 等)的属性如果不提供自定义实现手动路由重复方法,则彼此不兼容。请参阅PHP traits 文档,特别是关于 insteadof 操作符的部分。