CakePHP - 插入多个表错误

时间:2014-04-11 18:07:56

标签: php cakephp

我尝试使用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不是,所以似乎两个查询都是正确编写的,并且由于某种原因只有第一个查询执行)。我究竟做错了什么?我只想在一个操作中将自定义查询插入到更多表中。提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

所以让我清楚这一点,除了你在那里遇到明显的SQL注入问题(执行原始查询时,总是使用prepared statements以便以安全的方式绑定数据),你不是在评估正确的Model::query()的返回值。

评估Model :: query()结果

不幸的是,文档对此有点误导/混淆/不正确,INSERT查询将在成功时始终返回一个空数组,因此您必须检查以下内容:

is_array($this->Post->query($sqla))

但是,如果你问我,那就太难看了。

用于INSERT的DboSource :: execute()

对于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)

CakePHP ORM救援

如果您使用框架,使用框架!

正如评论中已经提到的,如果可能的话,你应该避免手动执行查询,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'));
        }
    }
}

上面显示的代码(与问题中的代码形成对比):

  • 验证您的用户输入
  • 如果合适,在输入旁边显示错误消息(例如&#34;正文不能为空&#34;)
  • 保护您免受sql注入(因为它使用参数化的sql语句)
  • 实际按预期工作

Post和Forum模型是如何相关的并不明显(帖子模型在表单中使用,但是数据被插入到不同的表中,并且看起来像post-body被插入到论坛表中 - &# 39;令人困惑),使用适当的请求数据调用saveAssociated(或saveAll)将插入具有所需数据的帖子和论坛。

请注意,此代码为very similar to the blog tutorial - 新开发人员通常需要15分钟才能完成。