CodeIgniter is executing database queries in the wrong order (possibly in parallel?)
I am using the current version of CodeIgniter (2.1.3). I have three MySQL tables:
MySQL tables
Operator
id name
========
1 ACME
tag
id tag
=======
1 bar
2 foo
operator_tag
id operator_id tag_id
=======================
1 1 1
2 1 2
So the ACME statement is tagged with (bar and foo) tags.
CodeIgniter files
I am getting an error when I try to remove a tag like this:
//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));
}
Error
If I call a function to remove the "foo" tag (id: 2) from the statement, I open the url http://example.com/tag/remove/2 (which successfully calls the controller "tag" -> "remove" with the parameter "2." However, most of the time I get the following error
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;`)
It seems that the DELETE query is being executed before the SELECT query. (I tried to add an INSERT query in the (second) remove_tag_from_operator
function, and iterated all the results of that table in the function (first) get_operator_for_tag_id
, which mysteriously included the row (previously generated) in the delete function.
Does CodeIgniter execute requests in parallel or in any special order? If so, is there an option to disable this? Thanks in advance!
Edit 1: @luc echo values
@luc I changed the code to the following (added echo lines) for debugging:
//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>';
}
which outputs something like the following when calling 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
This way, the $ id is being transmitted correctly and the echoes are in the correct order. Database queries are executed mysteriously.
Edit 2: Check @itachi lines
@itachi I modified the following code for debugging (outputting the entire operator_tag table if no value is found)
//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());
}
}
which outputs something like the following when calling 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
I tried to reproduce a working example, but I failed. If I comment out the line $this->db->delete('operator_tag',array('id' => $id));
it works (redirects me to the / edit / $ id statement).
source to share
I always got the same error (trying to get a property of a non-object) and was unable to create a script where the code runs .
So, I tried to clear the table. The first lines were removed as expected. On deleting (about id = 9 or so) I was getting the same error incl. And incl. (There is no way to start it again).
I dropped the table again and now I was unable to reproduce the error again. I've tried this procedure about 5 times with about 40 inserts / deletes.
I have never experienced this kind of error. Maybe the database / table was corrupted? Perhaps there are settings for MySQL-Server to "improve performance", for example for multiple threads? It might be a host error (for a while I got a lot of HTTP 500 errors that were redirected to the / 404 page of the host itself when I forgot the semicolon or something). Anyway, since my client wants to keep his odd host, I have no choice.
Thank you all for your great and quick support!
source to share