分享一个便捷、通用的 laravel 模型属性转换器

分享一个便捷、通用的 laravel 模型属性转换器

分享一下自己编写的一个便捷、通用 的 laravel 模型属性转换器类。可便捷的通过调用 回调类型的字符串 对属性进行转换。

使用示例

<?php

namespace App\Models;

use App\Casts\CallbackGetCast;
use App\Casts\CallbackSetCast;

class Foo extends Model
{
    protected $casts = [
        'foo' => CallbackSetCast::class.':strtoupper', // 属性 foo 通过调用 strtoupper 函数转换为大写
        'bar' => CallbackGetCast::class.':Illuminate\Support\Str::ucfirst', // 属性 bar 通过调用 \Illuminate\Support\Str::ucfirst 方法转换为首字符大写
        'phone' => CallbackGetCast::class.'Illuminate\Support\Str@substrReplace,0,****,3,4', // 属性 phone 通过调用 \Illuminate\Support\Str::substrReplace 方法替换手机号中间 4 个字符为 *
    ];
}

通用访问器

CallbackGetCast

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Support\Str;
use InvalidArgumentException;
use Throwable;

class CallbackGetCast implements CastsAttributes
{
    protected $callback;
    protected $mainArgIndex;
    protected $secondaryArgs;

    public function __construct(string $callback, int $mainArgIndex = 0, ...$secondaryArgs)
    {
        $this->callback = $this->resolveCallback($callback);
        $this->mainArgIndex = $mainArgIndex;
        $this->secondaryArgs = $secondaryArgs;
    }

    public function set($model, string $key, $value, array $attributes)
    {
        return $value;
    }

    public function get($model, string $key, $value, array $attributes)
    {
        array_splice($this->secondaryArgs, $this->mainArgIndex, 0, $value);

        return call_user_func($this->callback, ...$this->secondaryArgs);
    }

    protected function resolveCallback(string $callback): callable
    {
        if (is_callable($callback)) {
            return $callback;
        }

        if (! Str::contains($callback, '@')) {
            throw new InvalidArgumentException("Invalid callback: $callback");
        }

        $segments = explode('@', $callback);
        if (is_callable($segments)) {
            return $segments;
        }

        if (count($segments) !== 2 || ! method_exists($segments[0], $segments[1])) {
            throw new InvalidArgumentException("Invalid callback: $callback");
        }

        try {
            return [resolve($segments[0]), $segments[1]];
        } catch (Throwable $e) {
            throw new InvalidArgumentException("Invalid callback: $callback");
        }
    }
}

通用修改器

CallbackSetCast

<?php

namespace App\Casts;

class CallbackSetCast extends CallbackGetCast
{
    public function set($model, string $key, $value, array $attributes)
    {
        return parent::get($model, $key, $value, $attributes);
    }

    public function get($model, string $key, $value, array $attributes)
    {
        return $value;
    }
}

原文链接

github.com/guanguans/guanguans.git...

本作品采用《CC 协议》,转载必须注明作者和本文链接
No practice, no gain in one's wit. 我的 Gitub
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 2

有点像Yii 的行为

1个月前 评论
guanguans (楼主) 1个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
42
粉丝
107
喜欢
884
收藏
1252
排名:46
访问:14.4 万
私信
所有博文