分享一个便捷、通用的 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。
未填写
文章
58
粉丝
130
喜欢
991
收藏
1349
排名:45
访问:15.5 万
私信
所有博文
社区赞助商