foothing/laravel-repository
Composer 安装命令:
composer require foothing/laravel-repository
包简介
This package provides an implementation of the repository pattern for Laravel 5.
关键字:
README 文档
README
This package provides an implementation of the repository pattern for Laravel 5.
Composer installation
composer require foothing/laravel-repository
Basic usage
This package ships with a repository interface definition and
an Eloquent implementation.
The EloquentRepository is ready to use.
// Make a repository instance manually $repository = new EloquentRepository(new Post());
You are now ready to go:
// Find first occurrence with matching field 'email' $repository->findOneBy('email', 'test@example.com'); // Find first occurrence where id > 1 $repository->findOneBy('id', '1', '>'); // Find where title starts with 'foo' $repository->findAllBy('title', 'foo%', 'like'); // Find all occurrences where id > 1 $repository->findAllBy('id', '1', '>'); // Returns all posts $repository->all(); // Returns all post with Laravel pagination format $repository->paginate(); // Return record count $repository->filter('name', 'Homer')->count(); // Create, update and delete instances. $model = new Post(Input::all()); $freshMoel = $repository->create($model); $updatedModel = $repository->update($model); $repository->delete($model);
If you want to extend the base implementation with
your custom methods all you need to do is extend the
base class and define a constructor with the Eloquent
model as the first argument.
class PostsRepository extends EloquentRepository { function __construct(Post $post) { // Call superclass constructor. parent::construct($post); } function customFancyMethod() { } }
Don't forget to call the superclass constructor in order to enable all the features that are delivered out of the box. You can also add additional dependencies while overriding the base constructor.
class PostsRepository extends AbstractEloquentRepository { function __construct(Post $post, AnotherDependency $dependency) { parent::construct($post); // Do whatever you like with your $dependency } }
and you are all set. Examples:
// Use with a dependency injector class PostsController { protected $posts; function __construct(PostsRepository $posts) { $this->posts = $posts; } function getIndex($id = null) { // Return one post by primary key return $this->posts->find($id); } }
Eager load relations
You can eager load relations using the with method:
$posts = $repository->with(['author', 'comments'])->all(); Output: [ { "id": 1, "title": "Post title", "author": { "id": 1, "email": "test@example.com" }, "comments": [ {"id": 1, "text": "a comment"}, {"id": 2, "text": "another comment"}, ], } ]
You can chain the with method to all available methods:
$posts = $repository->with(['author', 'comments'])->findOneBy('name', 'foo'); $posts = $repository->with(['author', 'comments'])->all(); // And so on.
You'll often want to eager load some relations by default. Let's assume you have an User model with a many-to-many relation with its Role models, and you want to fetch both the user info and the roles.
The Foothing\Resources\Resource interface has three methods
which define the default Model behaviour:
- which relations to eager load by default for a findOne operation
- which relations to eager load by default for a findMany operation
- which fields to skip upon save
class User extends Model implements Foothing\Resources\Resource { /** * Array of relations we want to eager-load when * a single entity is being fetched. * * @return array */ function unitRelations() { return ['roles', 'posts']; } /** * Array of relations we want to eager-load when * a list of entities is being fetched. * * @return array */ function listRelations() { return ['roles']; } /** * When the resource is sent in a json-encoded * format it may happen to have relations fields * populated. Since they would be set as stdClass * objects we need to unset them before save. * * This method should return an array with all relations * we want to be unset when processing the updates. * * @return array */ function skipOnSave() { return ['roles', 'posts']; } }
In this way, each time you will use your UserRepository the following would be the default behaviour:
$users->find($id); // will eager load *roles* and *posts* $users->findOneBy($id); // will eager load *roles* and *posts* $users->create(); // will eager load *roles* and *posts* $users->update(); // will eager load *roles* and *posts* $users->all(); // will eager load *roles* $users->paginate(); // will eager load *roles*
This default behaviour will be ignored if you use the with method explicitly.
The skipOnSave method comes handy when dealing with JSON object, since
when you read a resource, then process it on the client side, then
send it back to the server, it will contain the relation properties.
This properties will be converted to stdClass PHP object breaking the
Eloquent save method.
Criteria
You can apply filters and order constraints using the CriteriaInterface,
which also ships with an Eloquent implementation.
Usage:
$criteria = new \Foothing\Repository\Eloquent\EloquentCriteria(); $criteria->filter('name', 'Homer'); $criteria->filter('lastName', 'Simpson'); // Chain methods $criteria->order('name')->sort('asc'); $repository->criteria($criteria)->paginate();
The repository provides shortcut methods you can use in your chains. The following example produces the same effect as the previous one.
$repository ->filter('name', 'Homer') ->filter('lastName', 'Simpson') ->order('name') ->sort('asc') ->paginate();
Available filters:
// Defaults to '=' $criteria->filter('name', 'Homer'); $criteria->filter('name', 'Home%', 'like'); $criteria->filter('id', 1, '>'); $criteria->filter('id', 1', '>='); $criteria->filter('id', 1, '<'); $criteria->filter('id', 1, '<='); $criteria->filter('id', 1, '!='); $criteria->filter('lastName', 'Simpson,Nahasapeemapetilon', 'in');
You can use the in operator with a comma separated list of values or with an array of values.
$criteria->filter('lastName', 'Simpson,Nahasapeemapetilon', 'in'); $criteria->filter('lastName', ['Simpson', 'Nahasapeemapetilon'], 'in');
Nested filters
It's also possible to query a Model relation. Assume your
Eloquent Model defines a children relation like so:
class Foo extends Model { protected $table = 'foo'; public function children() { return $this->hasMany('Bar'); } }
In this case you'll be allowed to query children values:
$criteria->filter('children.name', 'Bar');
Keep in mind that the methods subject to criteria restrictions are all those fetching more than one record.
Attach and detach many-to-many
Given the following Model:
class Homer extends Model { public function roles() { return $this->hasMany('Role'); } }
you can use the attach() and detach() methods to attach and detach to / from relation.
$homer = Homer::find(1); $foodCritic = Role::find(1); $repository->attach($homer, 'roles', $foodCritic); $repository->detach($homer, 'roles', $foodCritic);
Scopes
You can plug-in your Model scopes using the scope() method.
// Model class Person extends Model { public function scopeMale($query) { return $query->where('sex', 'male'); } } // Usage in Repository $malePeople = $repository->scope('male')->all(); $malePeople = $repository->scope('male')->filter('name', 'Bart')->all(); $malePeople = $repository->scope('male')->paginate(); $malePeople = $repository->scope('male')->findAllBy('name', 'John');
Scopes only apply on read methods.
Global Scopes
You can define a global scope for each repository implementation, which might come handy to restrict records access globally.
Just set
protected $globalScope = 'whatever';
in your repository. The global scope must match an Eloquent scope.
Note that if you use explicit scopes, i.e. $repository->scope('male'),
your global scope will be ignored.
Repository API
<?php namespace Foothing\Repository; interface RepositoryInterface { // // // Crud. // // public function find($id); public function findOneBy($field, $arg1, $arg2 = null); public function findAllBy($field, $arg1, $arg2 = null); public function all(); public function paginate($limit = null, $offset = null); public function count(); public function create($entity); public function update($entity); public function delete($entity); // // // Eager loading. // // public function with(array $relations); // // // Relations. // // /** * Attach $relatedEntity and $entity in a many-to-many relation. * * @param Model $entity * @param string $relation * @param Model $relatedEntity * * @return Model the updated $entity */ public function attach($entity, $relation, $relatedEntity); /** * Detach $entity and $relatedEntity in a many-to-many relation. * * @param Model $entity * @param string $relation * @param Model $relatedEntity * * @return Model the updated $entity */ public function detach($entity, $relation, $relatedEntity); // // // Criteria shortcuts. // // public function criteria(CriteriaInterface $criteria); public function filter($field, $value, $operator = '='); public function order($field, $sort = null); public function sort($direction); // // // Scopes. // // public function scope($scope); // // // Helpers. // // /** * Forces the next read query to skip cached values. * @return self */ public function refresh(); /** * Reset the refresh flag. * @return self */ public function reset(); }
RemoteQuery
More info coming soon.
License
foothing/laravel-repository 适用场景与选型建议
foothing/laravel-repository 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 2.3k 次下载、GitHub Stars 达 4, 最近一次更新时间为 2015 年 10 月 29 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「repository」 「laravel」 「eloquent」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 foothing/laravel-repository 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 foothing/laravel-repository 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 foothing/laravel-repository 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
repository php library
A Laravel Eloquent model trait for translatable resource
A package for automatically encrypting and decrypting Eloquent attributes in Laravel 5.5+, based on configuration settings.
Help to manage meta data on Laravel Eloquent model
A package to cast json fields, each sub-keys is castable
Laravel 5 - Repositories to the database layer
统计信息
- 总下载量: 2.3k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 4
- 点击次数: 12
- 依赖项目数: 6
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2015-10-29