我使用giix创建了一个简单的Yii模型,它继承自ActiveRecord。使用rules函数我定义了某个Value是不安全的,所以它不能被更改,因为它指示它属于哪个用户。当您提交表单时,它会通过表单发送数据的ID,以将更改应用于正确的数据集。如果你改变这个id怎么办?如果这是Yii找到数据的唯一方法,你可以改变随机的东西吗?或者Yii是否使用内置函数自动检查?
顺便说一下。您只获得属于特定用户的结果,因为我使用的是defaultScope,但defaultScope仅适用于SELECT查询,而不适用于INSERT,DELETE或UPDATE。
编辑:
我更改了网址中提交的ID。现在它指向一个不同的记录。此记录不会分配给它的特定用户值。但是,Yii没有检查我猜,所以我仍然可以编辑该记录,只需更改URL中给出的ID?
感谢您提出任何建议和解答:)
答案 0 :(得分:0)
也许我误解了你的问题,但我想你可能不清楚不安全的验证器如何在Yii中工作。
查看reference page进行验证。
基本上,当您从数据库获取记录到ActiveRecord模型时,将从数据库值中填充所有模型的属性。但是,如果在指定记录ID的表单上没有输入(因为它通常不是,因为它通常是该数据库表的主键),那么它将不会在您的模型中更新表格提交时的数据库。
换句话说,假设我有一个具有以下特征的表:
CREATE TABLE `users` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`username` varchar(39) NOT NULL UNIQUE,
`password` varchar(39) NOT NULL,
然后我创建了该表的模型,它将填充所有三列用于它所提取的任何记录。但是,如果我要创建“更新密码”表单,我绝不应该添加ID行。因此,当我拉出记录并将其保留在模型中,然后更新密码的值以节省该模型时,ID属性永远不会暴露给最终用户。
现在,当我提交表单后去保存记录时:
if (isset($_POST['MyForm'])) {
$model->attributes = $_POST['MyForm'];
$model->save();
}
模型首先要在保存之前运行任何验证规则,这是正确的。但我应该设置验证规则的唯一项目是那些可能来自用户的输入不正确或不完整的项目。所以,做这样的事情可能有意义:
public function rules()
{
return array(
array('username', 'match', 'pattern'=>'/^[a-z0-9_-]{6,100}$/i', 'message' => 'Come on now, make a name that makes sense!'),
array('password', 'match', 'pattern'=>'/^[\w\d]{6,18}$/', 'message' => 'Don\'t use special characters in your password!'),
}
这两个人都会使用regular expressions进行检查(请原谅任何正则表达式拼写错误,但乍看之下看起来是正确的),用户名和密码是否符合模式。
但是如果我要将属性声明为unsafe会怎样?所做的就是阻止我使用大量的赋值将表单中发布的值设置为模型。
所以,如果我用以下内容更新我的规则()
public function rules()
{
return array(
array('username', 'unsafe'),
array('password', 'match', 'pattern'=>'/^[\w\d]{6,18}$/', 'message' => 'Don\'t use special characters in your password!'),
}
然后在提交表单时,调用将模型中的所有属性设置为等于表单值:
$model->attributes = $_POST['MyForm'];
将不会设置unsafe属性(在本例中为username)。
但是对于ID来说无关紧要,因为无论如何它都不应该是形式的。要么在执行查询时已从数据库中提取,要么在将新记录插入数据库时自动创建(使用正确的模式定义)。