定制 kouks/laravel-casters 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

kouks/laravel-casters

Composer 安装命令:

composer require kouks/laravel-casters

包简介

Provides a convenient way to cast and transform your models for API purposes.

README 文档

README

Scrutinizer Code Quality Latest Version on Packagist Build Status StyleCI

Contents

Installation

Composer

Open your console and cd into your Laravel project. Run:

composer require kouks/laravel-casters

Yeah, you are pretty much ready to go right now...

Usage

Creating casters

You can put you casters pretty much anywhere, but I suppose you put them in a app/Casters directory. Now make a new php class, we are gonna be casting a Post model here. Suppose our model has only id, title, body and active database columns, along with timestamps.

namespace App\Casters;

use Koch\Casters\Caster;

class PostCaster extends Caster
{
    //
}

Good! Now we can put in our first casting rule.

namespace App\Casters;

use Koch\Casters\Caster;

class PostCaster extends Caster
{
    public castRules()
    {
        return [
            'title',
        ];
    }
}

This caster is going to cast only the title column, leaving its contents unchanged. More about making rules in the follwing section.

Making your rules

Let's move on how to make your own rules, there are four ways to achieve that at this moment.

Simple casting/renaming columns

There was an example of a simple cast rule in the previous section. Let us reviews it again and att something up.

namespace App\Casters;

use Koch\Casters\Caster;

class PostCaster extends Caster
{
    public castRules()
    {
        return [
            'title',
            'body' => 'long_text',
        ];
    }
}

This rule will remain the title column unchanged completely, and renaming the body column to long_text, however leaving the contents unchanged.

Using cast queries

Similar to Laravel's validation rules, you can use queries to cast.

namespace App\Casters;

use Koch\Casters\Caster;

class PostCaster extends Caster
{
    public castRules()
    {
        return [
            'active' => '!name:is_active|type:bool',
        ];
    }
}

Note the ! before the cast rule. This says that we want to use a query. This simple query renames the active column to is_active and casts its contents to a boolean. All documentation on cast queries can be found in the Cast queries section.

Casting using a closure

As a value of the cast rules, you can speficy a closure, which will determine what data to return.

namespace App\Casters;

use App\Post;
use Koch\Casters\Caster;

class PostCaster extends Caster
{
    public castRules()
    {
        return [
            'text' => function (Post $post) {
                return str_limit($post->body, 100);
            },
        ];
    }
}

This particular query is going to cast a new column body and as its contents it is going to use whatever is returned from the closure. In this case - the post body limited to 100 characters. Note that you are given an instance of the model that is being cast in the closure arguments.

Casting using a method

You can even use other methods on the caster class to determine what is going to be cast.

namespace App\Casters;

use App\Post;
use Koch\Casters\Caster;

class PostCaster extends Caster
{
    public castRules()
    {
        return [
            'draft' => '@isDraft',
        ];
    }
    
    public function isDraft(Post $post)
    {
        return ! $post->active;
    }
}

Notice the @ sign - it is to determine that we want to use a caster class method to do the casting. This cast is (similarly to the closure one) create a new column draft, which is just a negation of the active column in this example. You are given the model instance in this case, too.

Actual casting

The actual casting gets really simple, there are two ways to cast you data at this moment.

Casting a single model

Let us have a controller action show, which is going to cast our model, and retrun it as json.

...

class PostController extends Controller
{
    public function show(Post $post, PostCaster $caster)
    {
        return $caster->cast($post);
    }
}

Note that you can use DI for your casters, as with anything in Laravel. Then you call a single cast method and provide you model instance in the arguments. If we were to combine all the example casters, the returned json could look following:

{
  "id": 1,
  "title": "Some title",
  "long_text": "Some long text...",
  "text": "Some long text...",
  "active": true,
  "draft": false,
  "updated_at": {
    "date": "2016-11-01 00:38:03.000000",
    "timezone_type": 3,
    "timezone": "UTC"
  },
  "created_at": {
    "date": "2016-08-06 17:58:09.000000",
    "timezone_type": 3,
    "timezone": "UTC"
  }
}

Note that in the example above, the text field is going to be limited to 100 characters.

Casting a collection

You cast collections in the same way that you would cast single models. Only difference is that you are given back array of cast models, instead of a single one.

Casting directly from model instance

This package provides the Koch\Casters\Behavior\Castable trait, which lets you do both casting a single model as follows:

$post->cast($caster);

and a collection directly from you query:

Post::cast($caster);

Also note that if you specify a full class path to the caster in you model, you can omit the caster variable completely.

...
class Post extends Model
{
    use Castable;

    protected $caster = App\Casters\PostCaster::class;
}

Lets you do this fancy stuff:

$post->cast();

Post::cast();

If you follow the convention of storing your casters in the app/Casters directory as well as the naming conventions, this package will try to find related caster in that location - this lets you leave out even the caster property.

Casting relationships

There, obviously, is a way to cast relationships. Suppose there is a related model Comments, wich has a many-one relationship with our Post model. Also suppose that there is a CommentCaster set up. Look at the following code:

namespace App\Casters;

use App\Post;
use Koch\Casters\Caster;

class PostCaster extends Caster
{
    protected $commentCaster;
    
    public function __construct(CommentCaster $commentCaster)
    {
        $this->commentCaster = $commentCaster;
    }
    
    public castRules()
    {
        return [
            'comments' => function (Post $post) {
                return $this->commentCaster->cast($post->comments);
            },
        ];
    }
}

Note that even here you can levarage Laravel's DI. You now create a new column comments, which is then populated by the closure. This closure usis the injected caster to cast the comments relationship. You can do the same with casting via methods.

Also beware of cycling your casts. At the moment, there is no check for that. So if you were to cast your comments relationship on the PostCaster and do the same vice versa, you'd end end with a 500. Feel free to submit a PR correcting this issue.

Cast queries

At this moment, there are only two queries. I am open for suggestions to add more.

  • name:new_name
  • type:new_type - accepts int, string, bool and float

Abstracion

There is a Koch\Casters\Contracts\Caster interface, which you could use for example with the repository pattern, where you have a parent Repository class which deals with all the stuff around any model, including casting it. You might want to inject the caster though a PostRepository constructor, in which case, the parent class would require the contract.

FAQ

Nobody has ever asked me anything about this package so I can't determine the frequency of questions.

kouks/laravel-casters 适用场景与选型建议

kouks/laravel-casters 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 152 次下载、GitHub Stars 达 1, 最近一次更新时间为 2016 年 11 月 07 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「api」 「transform」 「laravel」 「casters」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 kouks/laravel-casters 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 kouks/laravel-casters 我们能提供哪些服务?
定制开发 / 二次开发

基于 kouks/laravel-casters 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 152
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 5
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2016-11-07