3

現在のバージョンの 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 にリダイレクトされます)。

4

2 に答える 2

0

私はいつも同じエラー(非オブジェクトのプロパティを取得しようとしています)を受け取り、コードが機能するシナリオを作成することができませんでした

だから私はテーブルをフラッシュしようとしました。最初の行は期待どおりに削除されました。削除すると(約id = 9程度)、同じエラーが何度も発生しました(再び機能する機会はありません)。

テーブルを再度フラッシュしましたが、エラーを再現することができませんでした。この手順を約5回試し、それぞれ約40回の挿入/削除を行いました。

私はこのようなバグを経験したことはありません。データベース/テーブルが破損している可能性がありますか?たぶん、複数のスレッドのような「パフォーマンスの向上」のためのMySQL-Serverの設定がありますか?おそらくそれはホストのせいです(しばらくの間、多くのHTTP 500エラーが発生し、セミコロンなどを忘れたときにホスト自身の/ 404ページにリダイレクトされました)。とにかく、私のクライアントは彼の奇妙なホストを維持したいので、私には選択肢がありません。

素晴らしく迅速なサポートをありがとうございました!

于 2013-01-23T10:33:00.490 に答える
0

このエラーは、主にクエリ文字列が不完全なために発生します。$id を取得する $this->uri->segment(3) をどこかに持っていますか? あなたのコードには表示されません。$id はどこで定義されていますか?

その価値を反映するようにしてください。それが問題だと思います。

于 2013-01-22T14:31:48.030 に答える