Php Laravel 5.3自定义模型铸造类型

Php Laravel 5.3自定义模型铸造类型,php,laravel,casting,laravel-5.3,Php,Laravel,Casting,Laravel 5.3,我正在开发一个以金钱为基础的系统,现在,为了显示我在模型中使用的访问者的价格: public function getFormattedPriceAttribute() { return '$' . number_format($this->attributes['price'], 2); // TODO: implement currencies } 但很快我将开始实施多币种,我想让价格显示尽可能简单: protected $casts = [ 'price' => 'c

我正在开发一个以金钱为基础的系统,现在,为了显示我在模型中使用的访问者的价格:

public function getFormattedPriceAttribute()
{
    return '$' . number_format($this->attributes['price'], 2); // TODO: implement currencies
}
但很快我将开始实施多币种,我想让价格显示尽可能简单:

protected $casts = [
'price' => 'currency',
];
货币的自定义转换将按照配置中的设置对其进行格式化


如果不使用手鼓跳舞,这可能吗?

扩展我的评论:

我将创建一个货币类,如下所示:

class Currency {
    $value;

    public function __construct($value) 
    {
        $this->value = $value;
    }

    public function formatted()
    {
        return '$' . number_format($this->value, 2);
    }

    // more methods

}
然后覆盖
模型
铸造属性
方法,以包括新的铸造类:

protected function castAttribute($key, $value)
{
    if (is_null($value)) {
        return $value;
    }

    switch ($this->getCastType($key)) {
        case 'int':
        case 'integer':
            return (int) $value;
        case 'real':
        case 'float':
        case 'double':
            return (float) $value;
        case 'string':
            return (string) $value;
        case 'bool':
        case 'boolean':
            return (bool) $value;
        case 'object':
            return $this->fromJson($value, true);
        case 'array':
        case 'json':
            return $this->fromJson($value);
        case 'collection':
            return new BaseCollection($this->fromJson($value));
        case 'date':
        case 'datetime':
            return $this->asDateTime($value);
        case 'timestamp':
            return $this->asTimeStamp($value);

        case 'currency': // Look here
            return Currency($value);
        default:
            return $value;
    }
}
简单

当然,您可以使事情变得更简单,只需在
casttribute
方法中执行此操作:

// ...
case 'dollar':
    return  '$' . number_format($value, 2);
// ...

关于我的评论:

我将创建一个货币类,如下所示:

class Currency {
    $value;

    public function __construct($value) 
    {
        $this->value = $value;
    }

    public function formatted()
    {
        return '$' . number_format($this->value, 2);
    }

    // more methods

}
然后覆盖
模型
铸造属性
方法,以包括新的铸造类:

protected function castAttribute($key, $value)
{
    if (is_null($value)) {
        return $value;
    }

    switch ($this->getCastType($key)) {
        case 'int':
        case 'integer':
            return (int) $value;
        case 'real':
        case 'float':
        case 'double':
            return (float) $value;
        case 'string':
            return (string) $value;
        case 'bool':
        case 'boolean':
            return (bool) $value;
        case 'object':
            return $this->fromJson($value, true);
        case 'array':
        case 'json':
            return $this->fromJson($value);
        case 'collection':
            return new BaseCollection($this->fromJson($value));
        case 'date':
        case 'datetime':
            return $this->asDateTime($value);
        case 'timestamp':
            return $this->asTimeStamp($value);

        case 'currency': // Look here
            return Currency($value);
        default:
            return $value;
    }
}
简单

当然,您可以使事情变得更简单,只需在
casttribute
方法中执行此操作:

// ...
case 'dollar':
    return  '$' . number_format($value, 2);
// ...

我想从长远来看,和手鼓跳舞会让你的生活更轻松。我将创建一个单独的用于管理货币的类(使用诸如“eur”、“dollar”、“formatted”…之类的方法,不管您需要什么),并将所有
price
属性强制转换到此类(将value作为构造函数)。然后你可以做一些事情,比如
$model->price->eur
或者
$model->price->formatted
。我将创建一个单独的用于管理货币的类(使用诸如“eur”、“dollar”、“formatted”…之类的方法,不管您需要什么),并将所有
price
属性强制转换到此类(将value作为构造函数)。然后你可以做一些事情,比如
$model->price->eur
或者
$model->price->formatted
。唯一的问题是,您必须在模型中使用这种臃肿的方法,这并不好。也许你可以把它变成一种特质。我想,我会在我有空闲时间的时候,尝试用叉子把铸造封装起来。所以,现在没有办法将自定义铸造类型“注入”到铸造列表中?是的,简单易行。唯一的问题是,您必须在模型中使用这种臃肿的方法,这并不好。也许你可以把它变成一种特质。我想,我会尝试用叉子把铸件做成胶囊,等我有空的时候。