現在のバージョンの CodeIgniter (2.1.3) を使用しています。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」を正常に呼び出します -> 関数パラメータ「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 クエリの前に実行されるようです。((2番目の)関数にINSERTクエリを追加しようとしましたがremove_tag_from_operator
、このテーブルのすべての結果を(最初の)get_operator_for_tag_id
関数にエコーしましたが、これは不思議なことに(以前に生成された)行をdelete関数に含めていました。
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->db->delete('operator_tag',array('id' => $id));
と機能します (operator/edit/$id にリダイレクトされます)。