【问题标题】:CodeIgniter executes database queries in the wrong order (maybe parallel?)CodeIgniter 以错误的顺序执行数据库查询(可能是并行的?)
【发布时间】:2013-01-22 14:02:19
【问题描述】:

我正在使用当前版本的 CodeIgniter (2.1.3)。我有三个 MySQL 表:

MySQL 表

运营商

id  name
========
1   ACME

标签

id  tag
=======
1   bar
2   foo

operator_tag

id  operator_id  tag_id
=======================
1   1            1
2   1            2

所以操作符 ACME 被标记了两个标签(bar 和 foo)。

CodeIgniter 文件

我在尝试删除这样的标签时遇到错误:

//file: controllers/tag.php (function contained in class Tag extends CI_Controller)

//this function should remove the tag with the id $id and redirect back to the edit page for the operator
public function remove($id){
    $operator_id = $this->operator_model->get_operator_for_tag_id($id);
    $this->operator_model->remove_tag_from_operator($id);
    redirect('operator/edit/'.$operator_id);
}

..

//file: models/operator_model.php (functions contained in class Operator_model extends CI_Model)

public function get_operator_for_tag_id($id){
    $query = $this->db->select('operator_id')->from('operator_tag')->where('id',$id)->get();
    return $query->row()->operator_id;
}

public function remove_tag_from_operator($id){
    $this->db->delete('operator_tag',array('id' => $id));
}

错误

如果我调用函数从操作员中删除标签“foo”(id:2),我打开 url http://example.com/tag/remove/2(它成功调用控制器“tag”-> 函数“remove”,参数“ 2"。但是大多数时候我收到以下错误

A PHP Error was encountered
Severity: Notice
Message: Trying to get property of non-object
Filename: models/operator_model.php
Line Number: XX (which is line with `return $query->row()->operator_id;`)

似乎 DELETE 查询是在 SELECT 查询之前执行的。 (我尝试在(第二个)remove_tag_from_operator 函数中添加一个 INSERT 查询,并在(第一个)get_operator_for_tag_id 函数中回显该表的所有结果,该函数神秘地将行(先前生成的)包含在删除函数中。

CodeIgniter 是并行执行查询,还是以任何特殊顺序执行查询?如果是这样,是否有可能禁用此功能?提前致谢!

编辑 1:回声值@luc

@luc 我将代码更改为以下(添加了回显行)以进行调试:

//file: controllers/tag.php
public function remove($id){
    echo '-1. CONTROLLER '.$id.'<br>';
    $operator_id = $this->operator_model->get_operator_for_tag_id($id);
    echo '-2. CONTROLLER '.$id.'<br>';
    $this->operator_model->remove_tag_from_operator($id);
    echo '-3. CONTROLLER '.$id.'<br>';
    redirect('operator/edit/'.$operator_id);
}
//file: models/operator_model.php
public function get_operator_for_tag_id($id)
{
    echo '-1.1 GET '.$id.'<br>';
    $query = $this->db->select('operator_id')->from('operator_tag')->where('id',$id)->get();
    echo '-1.2 GET '.$id.'<br>';
    $result = $query->row()->operator_id;
    echo '-1.3 GET '.$id.'<br>';
    return $result;
}

public function remove_tag_from_operator($id){
    echo '-2.1 REMOVE '.$id.'<br>';
    $this->db->delete('operator_tag',array('id' => $id));
    echo '-2.2 REMOVE '.$id.'<br>';
}

在调用http://example.com/tag/remove/41时输出如下内容

-1. CONTROLLER 41  
-1.1 GET 41  
-1.2 GET 41  

**A PHP Error was encountered**  
Severity: Notice  
Message: Trying to get property of non-object  
Filename: models/operator_model.php
Line Number: 236 (which is the row with `$result = $query->row()->operator_id;`)

-1.3 GET 41  
-2. CONTROLLER 41  
-2.1 REMOVE 41  
-2.2 REMOVE 41  
-3. CONTROLLER 41  

**A PHP Error was encountered**  
Severity: Warning  
Message: Cannot modify header information - headers already sent by (output started at .../application/controllers/tag.php:242)  (which is the output generated by `echo '1. CONTROLLER '.$id.'<br>';`)
Filename: helpers/url_helper.php  
Line Number: 542

因此 $id 被正确传递并且回显的顺序正确。只有数据库查询以一种神秘的方式执行。

编辑 2:检查行@itachi

@itachi 我更改了以下代码进行调试(如果找不到值,则输出整个 operator_tag-table)

//file: controllers/tag.php
public function get_operator_for_tag_id($id)
{
    $query = $this->db->select('operator_id')->from('operator_tag')->where('id',$id)->get();
    if ($query->num_rows() > 0){
        return $query->row()->operator_id;
    }else{
        $query = $this->db->get('operator_tag');
        print_r($query->result());
    }
}

在调用http://example.com/tag/remove/44时会输出如下内容

Array ( [0] => stdClass Object ( [id] => 3 [operator_id] => 40 [tag_id] => 1 ) )
A PHP Error was encountered
Severity: Warning
Message: Cannot modify header information - headers already sent by (output started at .../application/models/operator_model.php:236) (which is the line with `print_r($query->result());`)
Filename: helpers/url_helper.php
Line Number: 542

我试图重现工作示例,但失败了。如果我注释掉 $this-&gt;db-&gt;delete('operator_tag',array('id' =&gt; $id)); 行,它会起作用(将我重定向到 operator/edit/$id)。

【问题讨论】:

  • 你说大部分时间这是否意味着上面的代码有时有效?如果是,您是否注意到它起作用时的任何模式? 2、如果你注释掉上面代码中的delete查询,它返回的id是不是没有任何错误信息?
  • operator_tag 中,为什么两行都有id1
  • -itachi 如果我注释掉删除块它总是有效的(将我重定向回操作员/编辑/$id)。是的,该代码有时会起作用。我无法识别模式。我将编辑主要帖子,以发布另一个代码示例。 -RocketHazmat 抱歉,这只是一个错字。当然,第二行的 id 应该是 2(我已经解决了这个问题)。

标签: php mysql database codeigniter activerecord


【解决方案1】:

发生该错误主要是因为查询字符串不完整。你有 $this->uri->segment(3) 在某处获取 $id 吗?我在您的代码中没有看到它。 $id 是在哪里定义的?

尝试呼应它的价值,我认为这就是问题所在。

【讨论】:

  • 感谢您的回答。 AFAIK 段自动作为参数传递,因此 CodeIgniter 将example.com/tag/remove/2 映射到控制器“标签”、函数“删除”并传递参数“2”。以前总是这样。但是我成功地回显了 id。
【解决方案2】:

我总是遇到同样的错误(试图获取非对象的属性)并且无法创建代码工作的场景。

所以我试图冲洗桌子。第一行已按预期删除。删除时(大约 id = 9 左右)我不断收到相同的错误(没有机会让它再次工作)。

我再次刷新表,现在我无法再次重现 错误。我尝试了这个过程大约 5 次,每次插入/删除大约 40 次。

我从未遇到过这样的错误。也许数据库/表已损坏?也许 MySQL-Server 有设置用于“性能改进”,比如多线程?也许是主机的错(有一段时间我遇到了很多 HTTP 500 错误,当我忘记分号或类似的东西时,它重定向到主机自己的 /404 页面)。无论如何,由于我的客户想保留他奇怪的主机,我别无选择。

感谢大家的大力支持!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-11
    • 2017-09-05
    • 2020-06-16
    • 1970-01-01
    • 1970-01-01
    • 2019-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多