farafiri / class-generator-for-php
用于创建和自动加载常见模式(如装饰者、空对象、组合、延迟加载、代理对象)的类的库
Requires
- php: >=5.4.0
Requires (Dev)
- phpunit/phpunit: >=3.5
This package is not auto-updated.
Last update: 2024-09-22 04:28:14 UTC
README
用于创建和自动加载常见模式(如装饰者、空对象、组合、延迟加载、代理对象)的类的库。所有生成的类都可以进行缓存,因此不会对性能产生相关影响。
示例
假设你有一个以下实体类。请注意,为了可读性,该类不完整(没有属性声明等)
class Book implements PriceInterface { public function __construct($id) { $this->id = $id; $this->loadPropertiesFromDb($id); } /** * @return \Author */ public function getAuthor() { return new Author($this->authorId); } /** * @return int */ public function getPrice() { return $this->price; } /** * @return \Tag[] */ public function getTags() { return array_map(function($id) {return new Tag($id);}, $this->tagsIds); } }
装饰
class DiscountDecorator extends ClassGenerator\BaseDecorator { const CG_DECORATED = 'PriceInterface'; //by default you can decorate any class. This const will restrict to given interface or class protected $discount; public function __construct($discount = 0.8) { $this->discount = $discount; } public function getPrice() { return ceil($this->cgDecorated->getPrice() * $this->discount); } } $book = new DecorableBook($id); $book->getPrice(); // 100 $book->cgDecorate(new DiscountDecorator(0.9)); $book->getPrice(); // 90 $book instanceof Book //return true
空对象
$book = new NullBook($id); //null object gets expected result type from phpDoc and returns proper empty value $book->getPrice(); // 0 $book->getTags(); // array() $book->getAuthor(); // NullAuthor
延迟构造函数
$book = new LazyConstructorBook($id); //no DB query performed yet $book->getPrice(); //retrieved data from DB and proper price returned
延迟
$book = new LazyBook($id); //OR $book = new LazyBook::cgGet(function() { return new Book($id); }); //no DB query performed yet $book->getPrice(); //retrieved data from DB and proper price returned
延迟与延迟构造函数的区别
$lazyConstructorBook = new LazyConstructorBook($id); //no DB query performed yet $lazyBook = new LazyBook($id); //no DB query performed yet $author1 = $lazyConstructorBook->getAuthor(); // 2 queries performed (book and author) $author2 = $lazyBook->getAuthor(); // still no queries performed (LazyAuthor returned) $author2->getFirstName(); //retrieve book and author data
组合
$book1 = new Book(1); $book2 = new Book(2); $composite = new CompositeBook(array($book1, $book2)); $composite->getAuthor(); //will return composite of book authors (new CompositeAuthor(array($book1->getAuthor(), $book2->getAuthor()))) $composite->getTags(); //will return all tags (array_merge($book1->getTags(), $book2->getTags())) $composite->getPrice(); // will return first value which evaluate to true
我们可以通过添加 @composite 注解来自定义行为。例如:如果我们向 price 方法添加 @composite sum,则 $composite->getPrice() 将返回所有价格的总和
设置
首先,在您的 composer.json 中添加以下内容:"farafiri/class-generator-for-php": "dev-master"
然后在您的代码中调用 \ClassGenerator\Autoloader::register
\ClassGenerator\Autoloader::getInstance()->register(); //this is not a Singleton (you can create instance with new ..., also method setInstance is available) //but i need instance getter and I don't want make this code DI container dependent
如果您使用的是 Symfony 2,请检查 Doctrine\README.md
此自动加载器不是独立的 - 它不会从您的 PHP 文件中加载任何类,您需要另一个加载器来完成此任务。它应注册为最后一个加载器 - 否则,它将创建新类而不是从您的项目文件中加载它。(例如:如果您有类 \Item 和 \NullItem,则在尝试使用 \NullItem 时,它将生成新类而不是加载您的实现)确保在开发模式下关闭缓存,在生产模式下打开缓存(在代码更改时清除缓存)。要打开缓存
\ClassGenerator\Autoloader::getInstance()->setCachePath($cacheDirectoryPath)->setEnabledCache(true);
即使缓存未启用,也最好设置 $cachePath - 创建的类将保存并从文件系统加载,而不是简单的代码 eval。感谢这一点,在出现错误时,错误消息将类似于 "Error in cacheFile.php on line X" 而不是 "Error in eval code" + 您的 IDE 应该在它们在文件中时识别这些类。