Yii2框架的几个隐蔽的坑
摘要:Yii2是一款优秀的通用Web后端框架,结构简单优雅、实用功能丰富、扩展性强、性能搞是他最突出的优点。它优秀的地方你在使用过程中总能轻易的发现,无须赘述。而这些隐蔽的小瑕疵,显得更有必要告诉大家。
- 博客: http://www.cnblogs.com/jhzhu
- 邮箱: jhzhuustc@gmail.com
- 作者: 知明所以
- 时间: 2015-08-17
目录
- Yii2框架的几个隐蔽的坑
- 目录
- 说点闲话
- ActiveRecord被莫名写入?
- 准备知识
- 代码现场
- 总结问题
- 解决方法
- 你的Transaction生效了吗?
- 代码现场
- 问题总结
- 解决方法
- 'Y-m-d'不被识别?
- 代码现场
- 问题总结
说点闲话
距离上次写博客,已经有三个月了。在动手写之前,总是带着深深的罪恶感。被它折磨许久,终于,还是,动手了。
值得庆祝的一件事:最近开始,每天早上8:30起来健身了。有两个视频很好用,只需8分钟,照着做一遍保证你(生)爽(不)到(如)爆(死)。(8分钟腹肌锻炼第2级-下载,8分钟胸肌锻炼第2级-下载)
值得反思的一件事:最近看了《叔本华美学随笔》,改变了我一直以来对阅读的看法。我曾经以为阅读是进步的源动力,却被这本书深深的打脸了。来,先给大家分享一段:
我们只管所见的外在环境并不像阅读物那样,把某已确定的见解强加给我们的头脑,而只是为我们提供了素材和机会。去思考与我们的头脑能力相称、与当下的情绪相符的事情。所以,太多的阅读会是我们的精神失去弹性,就像把一重物持续压在一条弹簧上面就会是弹簧失去弹性一样;而让自己没有自己思想的最稳妥的办法就是在空闲的每一分钟马上随手拿起一本书。
思考才是进步的源动力!
好了,扯淡完毕,步入正题。
ActiveRecord被莫名写入?
准备知识
-
ActiveRecord
的基本用法。如果不理解,可参考这里。
代码现场
<span>/**</span><span> * @property integer $id</span><span> * @property string $name</span><span> * @property string $detail</span><span> * @property double $price</span><span> * @property integer $area</span><span> **/</span><span>class OcRoom extends ActivieRecord</span><span>{</span><span> ...</span><span>}</span><span>$room = OcRoom::find() //先取出一个对象。</span><span> ->select(['id']) //只取出'id'列</span><span> ->where(['id'=>20])</span><span> ->one();</span><span>$room->save(); //保存,会发现此行的其它字段都被写成默认值了。</span>
总结问题
这个例子的问题在于:
- 我从数据库中取出了一行,也就是代码中的
$room
,但是只取出了id
字段,而其他字段自然就是默认值。 - 当我
$room->save()
的时候,那些是默认值的字段也被保存到数据库里去了。what!? - 也就是说,当你想节约资源,不取出所有字段的时候,一定要注意不能保存,否则,很多数据会被莫名修改为默认值。
解决方法
然而,我们有什么解决办法呢?提供几种思路:
- 自己时刻注意,避免未完全取出的
ActiveRecord
的保存。 - 修改或继承
ActiveRecord
, 使得,当此对象由find()
新建,且字段没有完全取出,调用save()
方法,抛出异常。 - 修改或继承
ActiveRecord
,使得,当此对象由find()
新建,且字段没有完全取出,调用save()
方法时,只保存取出过的字段,其他字段被忽略。
你的Transaction生效了吗?
代码现场
<span>/**</span><span> * @property integer $id</span><span> * @property string $name</span><span> **/</span><span>class OcRoom extends ActiveRecord</span><span>{</span><span> public function rules()</span><span> {</span><span> return [['name','string','min'=>2,'max'=>10]];</span><span> }</span><span> ...</span><span>}</span><span>class OcHouse extends ActiveRecord</span><span>{</span><span> public function rules()</span><span> {</span><span> return [['name','string','max'=>10]];</span><span> }</span><span> ...</span><span>}</span><span>$a = new OcRoom();</span><span>$a->name = ''; //name为空字符串,不满足rules()条件。</span><span>$b = new OcHouse();</span><span>$b->name = '我的房间'; //name合法,可以保存。</span><span>$transaction = Yii::$app->db->beginTransaction();</span><span>try{</span><span> $a->save(); //name字段不合法,无法验证通过,在validate()阶段已经返回false,不会进行数据库存储的步骤,所以也不会抛出异常。</span><span> $b->save(); //name字段合法,可以正常保存。</span><span> $transaction->commit(); //提交后,发现$a保存失败,而$b保存成功。</span><span>}</span><span>catch (Exception $e) </span><span>{</span><span> Yii::error($e->getTraceAsString(),__METHOD__);</span><span> $transaction->rollBack();</span><span>}</span>
问题总结
这段代码的问题在于:
- 大家知道
$transaction
的存在意义是保证整段数据库存储代码要么全成功,要么全失败。 - 显然,在这个例子中,
transaction
并没有达到我们想要的效果:$a
因为validate()
都没过,所以$transation->commit()
的时候并不会报错。
解决方法
在$transation
块内,所有的save()
都要判断下返回值,如果为false
,则直接抛出异常。
'Y-m-d'不被识别?
代码现场
<span>OcRenterBill extends ActiveRecord</span><span>{</span><span> public function rules()</span><span> {</span><span> return [</span><span> ['start_time','date','format'=>'Y-m-d'],</span><span> ];</span><span> }</span><span>}</span><span>$a = new OcRenterBill();</span><span>$a = '2015-09-12';</span><span>$a->save(); //会报错,说格式不对。</span>
问题总结
如果一开始,Yii框架就报错,这个还不算坑。坑的是我在Mac上开发时,这个可以完全正常的工作,而发布到线上环境(Ubuntu)后,就弹出“属性start_time格式无效”的错误。而参考官方文档,发现这种格式是允许的官方文档。
啊啊啊。各种试错,最后发现如果改成php:Y-m-d
,世界就清净了。所以,如果你遇到这种问题,感激我吧。

Vue实现博客前端,需要实现markdown的解析,如果有代码则需要实现代码的高亮。Vue的markdown解析库有很多,如markdown-it、vue-markdown-loader、marked、vue-markdown等。这些库都大同小异。这里选用的是marked,代码高亮的库选用的是highlight.js。具体实现步骤如下:一、安装依赖库在vue项目下打开命令窗口,并输入以下命令npminstallmarked-save//marked用于将markdown转换成htmlnpmins

首先,请确保您已安装Python3和Tkinter。我们需要的其他东西是tkhtmlview和markdown2。您可以通过运行pipinstalltkhtmlviewmarkdown2或pip3installtkhtmlviewmarkdown2来安装它们(如果您有多个Python版本)。现在启动您喜欢的编辑器或IDE并创建一个新文件(例如www.linuxidc.com.py(我将其命名为linuxidc.com编辑器))。我们将从导入必要的库开始。fromtkinterimport*fro

Pygame的Font文本和字体Pygame通过pygame.font模块来创建一个字体对象,从而实现绘制文本的目的。该模块的常用方法如下所示:名称说明pygame.font.init()初始化字体模块pygame.font.quit()取消初始化字体模块pygame.font.get_init()检查字体模块是否被初始化,返回一个布尔值。pygame.font.get_default_font()获得默认字体的文件名。返回系统中字体的文件名pygame.font.get_fonts()获取所有

VScode中怎么使用markdown?下面本篇文章给大家介绍一下VScode配置Markdown的方法,并聊聊Markdown基础语法,希望对大家有所帮助!

随着人们对于技术的不断追求,越来越多的工具和应用程序被开发出来来帮助人们简化复杂的任务。其中之一就是 Markdown,它是一种轻量级的标记语言,可以将纯文本转换成 HTML 格式的文本。本文将介绍如何使用 PHP 来实现 Markdown 转换。

在现代互联网时代的开发中,文档撰写已经逐渐从繁琐的HTML标签转变为更为简单且便于读写的Markdown语法。ThinkPHP6使用了高度灵活的模板引擎,提供了方便的Markdown扩展,使得在项目中使用Markdown文件编写和显示变得十分容易。什么是MarkdownMarkdown是一种轻量级的标记语言,可快速将纯文本编写的文档转化为HTML,以便进行在

概述在Linux系统中,我们频繁使用命令行来处理文件和目录。Markdown是一种简洁的标记语言,可快速创建和格式化文档。但要阅读和管理Markdown文件可能需要大量命令和参数,对初学者来说可能有些复杂。这时就可以使用glow命令来简化操作。glow是一个旨在简化在Linux终端中渲染Markdown文件的命令行工具。它的主要目标是为用户提供更直观、更易管理的Markdown文件阅读体验。glow带有一个用户友好的图形界面,让您可以更轻松地查看和管理Markdown文件。通过这一界面,您无需记

本篇文章给大家带来了关于Markdown的相关知识,其中主要内容就是总结分享大家一份Markdown备忘单,感兴趣的朋友下面一起来看一下吧,希望对大家有帮助。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

Dreamweaver Mac版
视觉化网页开发工具