0

0

Laravel模型Casts?Casts如何使用定义?

小老鼠

小老鼠

发布时间:2025-09-05 09:05:02

|

335人浏览过

|

来源于php中文网

原创

Laravel模型Casts通过$casts属性自动转换数据库与PHP类型,解决数据类型不一致、减少重复代码、提升可读性与安全性,支持内置类型如boolean、array、datetime及自定义Casts处理复杂场景如Value Object。

laravel模型casts?casts如何使用定义?

Laravel模型Casts是一种相当精妙的机制,它允许我们在模型属性从数据库读取出来,或者在存入数据库之前,自动进行类型转换。简单来说,它就是给你的模型属性套上了一层“翻译器”,确保你拿到的数据是你期望的类型,并且在存回去时也能正确地适配数据库字段。这极大地简化了数据处理的逻辑,让代码更干净、更易读。

Laravel模型Casts的核心在于模型类中的

$casts
属性。它是一个关联数组,键是模型属性名,值是你希望转换成的类型。比如,如果你有一个数据库字段存储的是JSON字符串,但你希望在PHP代码中直接操作数组或对象,Casts就能帮你搞定。

 'boolean', // 数据库可能是tinyint(1),这里直接转成true/false
        'options' => 'array',       // 数据库存的是JSON字符串,这里直接转成PHP数组
        'published_at' => 'datetime', // 数据库是datetime/timestamp,这里转成Carbon日期对象
        'price' => 'float',         // 确保价格字段始终是浮点数
        'settings' => 'json',       // 也可以用'json',行为与'array'类似,但更明确
    ];

    // ...
}

当你从数据库中获取一个

Post
模型实例时,比如
$post = Post::find(1);
$post->is_published
就会是一个布尔值,
$post->options
会是一个PHP数组,而
$post->published_at
则是一个Carbon日期对象。当你修改这些属性并保存时,Laravel也会自动将它们转换回数据库所需的格式(例如,布尔值转为0或1,数组转为JSON字符串)。这种自动化处理,在我看来,是Laravel在开发者体验上做得非常出色的一点。

为什么我们需要Laravel模型Casts?它解决了哪些常见痛点?

说实话,刚开始接触Laravel的时候,我可能没有立刻意识到Casts的重要性。但随着项目复杂度的增加,尤其是在处理一些非标准数据类型时,Casts的价值就凸显出来了。最直接的痛点就是数据类型不一致

想想看,数据库里存日期通常是

DATETIME
TIMESTAMP
,PHP里我们习惯用
DATETIME
对象或者Laravel的
Carbon
。没有Casts,每次从数据库取出来,你都得手动
new Carbon($post->published_at)
,或者在保存前
$post->published_at->format('Y-m-d H:i:s')
。这不仅麻烦,还容易出错,而且代码里会充斥着大量的类型转换逻辑,变得非常臃肿。Casts直接帮你抹平了这种差异,你只管操作
Carbon
对象就行。

另一个常见场景是JSON数据。很多时候,我们会在数据库的一个文本字段里存储配置信息、用户偏好等JSON字符串。手动

json_decode()
json_encode()
的循环简直是噩梦。Casts的
array
json
类型直接让你可以像操作普通PHP数组一样操作这些数据,极大地提升了开发效率和代码的可读性。

此外,布尔值的表示也是个小麻烦。数据库的

TINYINT(1)
字段,取出来可能是
0
1
的字符串或整数。在PHP逻辑中,我们更喜欢直接用
true
false
。Casts的
boolean
类型完美解决了这个问题。

总结来说,Casts解决了以下几个核心痛点:

  • 减少重复代码: 避免了手动进行大量的类型转换。
  • 提高代码可读性 模型属性的类型在代码层面更明确,一目了然。
  • 降低出错率: 自动化处理减少了人为转换的错误。
  • 简化复杂数据类型处理: 比如日期、JSON、集合等,让它们在PHP中更自然地被使用。

Laravel内置了哪些Casts类型?我们该如何选择合适的Casts?

Laravel内置的Casts类型已经相当丰富了,几乎覆盖了我们日常开发中会遇到的所有基础数据类型转换。了解它们,并知道何时使用,是高效开发的关键。

这里列举一些常用的内置Casts类型:

  • string
    : 确保属性是字符串。
  • integer
    ,
    real
    ,
    float
    ,
    double
    : 确保属性是对应的数值类型。
    float
    double
    在PHP中基本等价,
    real
    是它们的别名。
  • decimal:
    : 将字符串转换为浮点数,并指定小数点后的位数。例如
    'price' => 'decimal:2'
    会将
    123.456
    转换为
    123.46
    。这在处理货数据时非常有用。
  • boolean
    : 将数据库的
    0
    /
    1
    false
    /
    true
    转换为PHP的布尔值。
  • object
    : 将JSON字符串转换为PHP的
    stdClass
    对象。
  • array
    : 将JSON字符串转换为PHP数组。
  • json
    : 行为与
    array
    类似,但更明确地表示存储的是JSON。
  • collection
    : 将JSON字符串转换为
    Illuminate\Support\Collection
    实例。这个非常强大,可以直接使用集合的所有方法。
  • date
    : 将数据库日期字符串转换为
    Carbon
    日期对象,通常只包含日期部分(年-月-日)。
  • DATETIME
    : 将数据库日期时间字符串转换为
    Carbon
    日期对象,包含日期和时间。
  • TIMESTAMP
    : 将Unix时间戳(整数)转换为
    Carbon
    日期对象。
  • immutable_date
    ,
    immutable_datetime
    ,
    immutable_timestamp
    : 与上述对应,但返回的是
    ImmutableDateTime
    对象,这意味着对日期对象的修改会返回新实例,而不是修改原实例。这在某些场景下可以避免意外的副作用。

如何选择合适的Casts?

我的经验是,首先看数据库字段的实际存储类型和你的业务需求

唱鸭
唱鸭

音乐创作全流程的AI自动作曲工具,集 AI 辅助作词、AI 自动作曲、编曲、混音于一体

下载
  • 数字类型: 如果数据库是
    INT
    ,用
    integer
    ;如果需要精确到小数点后几位,
    decimal:X
    是首选,避免浮点数精度问题。
  • 布尔值: 数据库是
    TINYINT(1)
    ,毫无疑问用
    boolean
  • JSON数据: 如果你只是需要一个简单的PHP数组,用
    array
    。如果你想更明确地表达这是JSON数据,或者希望利用
    collection
    的强大功能,
    json
    collection
    会更合适。
  • 日期时间: 这是最常见的。如果数据库只存日期,用
    date
    ;如果包含时间,用
    DATETIME
    。如果数据库存的是Unix时间戳,用
    TIMESTAMP
    。如果你特别在意日期对象的不可变性,
    immutable_
    系列是你的朋友。

一个小建议是,尽量让Casts的类型与你的业务逻辑中最常使用的类型保持一致。比如,如果你经常需要对一个JSON字段进行链式操作,

collection
会比
array
更方便。如果一个日期字段你几乎只用来显示,而很少进行日期计算,那么
date
DATETIME
就足够了。

如何实现自定义Casts?何时应该考虑自定义Casts?

有时候,内置的Casts类型无法满足我们的复杂需求,比如处理一个自定义的Value Object,或者在存取数据时进行一些特殊的加密/解密操作。这时候,自定义Casts就派上用场了。它提供了一个强大的扩展点,让你可以完全控制属性的序列化和反序列化过程。

实现自定义Casts需要创建一个类,并实现

Illuminate\Contracts\Database\Eloquent\CastsAttributes
接口。这个接口要求你实现两个方法:

  1. get($model, $key, $value, $attributes)
    : 当属性从数据库中读取出来时,这个方法会被调用。你可以在这里将原始的数据库值
    $value
    转换成你想要的PHP类型。
  2. set($model, $key, $value, $attributes)
    : 当属性被赋值并准备保存到数据库时,这个方法会被调用。你在这里将PHP类型的值
    $value
    转换回数据库可以存储的原始类型。

让我们看一个简单的例子,假设我们有一个

Money
Value Object,它内部以分为单位存储金额,但在应用中我们希望以元为单位操作。

1. 定义

Money
Value Object (可选,但通常自定义Casts会配合Value Object使用):

// app/ValueObjects/Money.php
cents = (int) round($amount * 100);
    }

    public function toDollars(): float
    {
        return $this->cents / 100;
    }

    public function __toString(): string
    {
        return (string) $this->toDollars();
    }
}

2. 创建自定义Cast类:

// app/Casts/MoneyCast.php
toDollars() * 100);
        }

        if (is_numeric($value)) {
            return (int) round($value * 100);
        }

        throw new InvalidArgumentException('The given value is not a Money instance or a numeric value.');
    }
}

3. 在模型中使用自定义Cast:

// app/Models/Product.php
 MoneyCast::class, // 假设数据库中 price 字段存储的是以分为单位的整数
    ];

    // ...
}

现在,当你获取

$product->price
时,你会得到一个
Money
对象。当你设置
$product->price = new Money(19.99);
或者
$product->price = 25.50;
时,它会自动转换为整数(分)存入数据库。

何时应该考虑自定义Casts?

自定义Casts是一个非常强大的工具,但也不是万能药。我认为以下几种情况是考虑自定义Casts的良好时机:

  • Value Objects: 当你的领域模型中存在Value Objects(例如
    Money
    Address
    Email
    等),并且你希望它们在模型属性中被自然地使用时。
  • 复杂的数据结构: 如果数据库字段存储的是一些需要特殊解析或序列化的复杂数据(例如,一个加密的字符串,一个需要特定格式化的地理坐标),自定义Casts可以帮你封装这些逻辑。
  • 第三方API数据格式化 如果你的应用需要与外部API交互,并且API的数据格式与数据库或PHP模型不完全匹配,自定义Casts可以在存取时进行适配。
  • 数据清洗/转换: 在某些情况下,你可能需要在数据从数据库出来时进行一些轻量级的数据清洗或格式转换,自定义Casts提供了一个集中的地方来处理这些。

总之,自定义Casts的引入,通常是为了让你的模型属性在PHP层面更符合领域模型,更易于理解和操作,同时将底层的数据库存储细节隔离开来。这有助于提升代码的内聚性和可维护性。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
laravel组件介绍
laravel组件介绍

laravel 提供了丰富的组件,包括身份验证、模板引擎、缓存、命令行工具、数据库交互、对象关系映射器、事件处理、文件操作、电子邮件发送、队列管理和数据验证。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

319

2024.04.09

laravel中间件介绍
laravel中间件介绍

laravel 中间件分为五种类型:全局、路由、组、终止和自定。想了解更多laravel中间件的相关内容,可以阅读本专题下面的文章。

277

2024.04.09

laravel使用的设计模式有哪些
laravel使用的设计模式有哪些

laravel使用的设计模式有:1、单例模式;2、工厂方法模式;3、建造者模式;4、适配器模式;5、装饰器模式;6、策略模式;7、观察者模式。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

371

2024.04.09

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

374

2024.04.10

laravel入门教程
laravel入门教程

本专题整合了laravel入门教程,想了解更多详细内容,请阅读专题下面的文章。

85

2025.08.05

laravel实战教程
laravel实战教程

本专题整合了laravel实战教程,阅读专题下面的文章了解更多详细内容。

65

2025.08.05

laravel面试题
laravel面试题

本专题整合了laravel面试题相关内容,阅读专题下面的文章了解更多详细内容。

68

2025.08.05

json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

418

2023.08.07

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

9

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 9.6万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.2万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号