guanguans / guanguans.github.io

guanguans 博客
https://www.guanguans.cn
Other
54 stars 6 forks source link

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

Open guanguans opened 2 years ago

guanguans commented 2 years ago

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

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

通用访问器

CallbackGetCast ```php callback = $this->resolveCallback($callback); $this->mainArgIndex = $mainArgIndex; $this->secondaryArgs = $secondaryArgs; } /** * Prepare the given value for storage. * * @param \Illuminate\Database\Eloquent\Model $model * @param string $key * @param mixed $value * @param array $attributes * @return mixed */ public function set($model, string $key, $value, array $attributes) { return $value; } /** * Transform the attribute to its underlying model values. * * @param \Illuminate\Database\Eloquent\Model $model * @param string $key * @param mixed $value * @param array $attributes * @return mixed */ 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); } /** * @param string $callback * * @return callable * @throws \InvalidArgumentException */ 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

使用示例

<?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 个字符为 *
    ];
}

原文链接

forecho commented 2 years ago

正好需要 🙏

guanguans commented 2 years ago

@forecho 欢迎海哥,拿去用😄。