我尝试使用CakePHP(2.4.6)将数据保存到更多表中。
我有帖子/ add.tcp文件:
<?php
echo $this->Form->create('Post');
echo $this->Form->input('title');
echo $this->Form->input('body', array('rows' => '3'));
echo $this->Form->end('Save Post');
?>
并在PostsController文件中添加方法:
public function add() {
if ($this->request->is('post')) {
$this->request->data['Post']['user_id'] = $this->Auth->user('id');
$titulek = $this->request->data['Post']['title'];
$uid=$this->request->data['Post']['user_id'];
$body=$this->request->data['Post']['body'];
$sqla = "INSERT INTO posts (title,created,user_id) VALUES ('$titulek', NOW(),'$uid')";
$sqlb = "INSERT INTO forums (user_id,post_id,text,created) VALUES ('$uid',NULL,'$body', NOW())";
if ($this->Post->query($sqla)) {
if ($this->Post->query($sqlb)) {
$this->Session->setFlash(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
}
}
}
}
但它没有按预期工作。实际上只有$sqla
查询保存到数据库中。 $sqlb
查询根本没有被执行,最后我没有被重定向到另一个页面。有趣的是,如果我颠倒查询的顺序(例如,当前$sqlb
查询变为$sqla
查询,$sqlb
查询变为$sqla
查询INSERT INTO forums
查询执行正确,但INSERT INTO posts
不是,所以似乎两个查询都是正确编写的,并且由于某种原因只有第一个查询执行)。我究竟做错了什么?我只想在一个操作中将自定义查询插入到更多表中。提前感谢您的帮助。
答案 0 :(得分:1)
所以让我清楚这一点,除了你在那里遇到明显的SQL注入问题(执行原始查询时,总是使用prepared statements以便以安全的方式绑定数据),你不是在评估正确的Model::query()
的返回值。
不幸的是,文档对此有点误导/混淆/不正确,INSERT
查询将在成功时始终返回一个空数组,因此您必须检查以下内容:
is_array($this->Post->query($sqla))
但是,如果你问我,那就太难看了。
对于INSERT
查询,我总是使用DboSource::execute()
,它也支持绑定参数:
$db = ConnectionManager::getDataSource('default');
$options = array();
$params = array(
':title' => $titulek,
':uid' => $uid,
);
$result = $db->execute(
'INSERT INTO posts (title,created,user_id) VALUES (:title, NOW(), :uid)',
$options,
$params
);
现在$result
成功时可以是PDOStatement
的实例,或者失败时false
,所以简单地测试值是真的是安全的:
if($result)
如果您使用框架,使用框架!
正如评论中已经提到的,如果可能的话,你应该避免手动执行查询,ORM层提供了极大的舒适性和安全性,并且使用起来非常简单:
$this->Post->save($this->request->data)
您所要做的就是设置模型关联,并确保视图正确格式化数据。
然而,您的数据库架构似乎很奇怪,我真的不明白为什么您为每个帖子创建一个论坛,论坛中包含帖子内容,与帖子没有任何关联o_O也许您应该重新考虑。
更多信息:
答案 1 :(得分:1)
[这是]一个学校项目,我必须使用PHP框架
如果您要使用PHP框架 - 您应该使用它,而不仅仅是将普通的php代码插入控制器。如果使用框架是任务的一部分,那么您的代码不使用框架设计时不会对您有利;除了不使用ORM之外 - 控制器代码不应该包含sql,这是不正确使用模型(或根本不使用)的指示。
您需要的等效控制器代码不超过:
public function add() {
if ($this->request->is('post')) {
$this->request->data['Post']['user_id'] = $this->Auth->user('id');
if ($this->Post->saveAssociated($this->request->data)) {
$this->Session->setFlash(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
}
}
}
上面显示的代码(与问题中的代码形成对比):
Post和Forum模型是如何相关的并不明显(帖子模型在表单中使用,但是数据被插入到不同的表中,并且看起来像post-body被插入到论坛表中 - &# 39;令人困惑),使用适当的请求数据调用saveAssociated(或saveAll)将插入具有所需数据的帖子和论坛。
请注意,此代码为very similar to the blog tutorial - 新开发人员通常需要15分钟才能完成。