5

大規模なシステムに配置する監査証跡モジュールを作成しています。証跡エントリを保存するテーブルを作成しました。「監査者」として、現在ログオンしているユーザー、ユーザーがいるページ、ユーザーが行ったアクション、および変更内容を確認したいそしていつ...

これらは基本的に私が見たいものです。私の監査証跡テーブルは次のようになります。

ユーザー| タイムスタンプ| モジュール名| アクション| 古い値| 新しい価値| 説明

私は基本的にユーザーを取得するのに問題はありませんでした

Yii::app()->session['username'];

コントローラーの : を取得することによるページ/モジュールとアクション:

$this->module->getName();
$this->action->id;

私の問題は、古い値から新しい値への変更、ユーザーによる編集にあります。文字通り変数をコピーし、ログを作成する関数に渡すことで、彼/彼女が行った編集/変更を「嗅ぎ分ける」ことができます..これを動的に行うにはどうすればよいですか?

特定のモデルのプロパティまたは属性が変更されたかどうかを検出し、詳細ログを取得できるように、どのような変更が加えられたかを確認したいと考えています...ありがとう ! 申し訳ありませんが、私はこれを説明するのに本当に苦労しています。

4

3 に答える 3

8

観察したい各モデルではafterFind()、現在の DB 属性をプライベート変数 eb に格納するメソッドを記述できます_dbValues。次にbeforeSave()、現在の属性を検証し_dbValues、変更があった場合は監査レコードを作成します。

これを機能させたら、さらに一歩進んでそこから動作を作成できます。プライベート変数、afterFind()およびbeforeSave()メソッドをそこに配置します。その後、その動作を多くのレコードに関連付けることができます。

于 2013-05-22T07:33:44.323 に答える
6

簡単な例:

class Book extends CActiveRecord
{
    private $oldAttrs = array();

    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    public function tableName()
    {
        return 'book';
    }

    protected function afterSave()
    {
        // store history
        if (!$this->isNewRecord) {
            $newAttrs = $this->getAttributes();
            $oldAttrs = $this->getOldAttributes();

            // your code
        }

        return parent::afterSave();
    }

    protected function afterFind()
    {
        // Save old values
        $this->setOldAttributes($this->getAttributes());

        return parent::afterFind();
    }

    public function getOldAttributes()
    {
        return $this->oldAttrs;
    }

    public function setOldAttributes($attrs)
    {
        $this->oldAttrs = $attrs;
    }
}
于 2013-05-22T07:47:09.140 に答える
0

あなたの解決策は良いですが、->save() を同時に呼び出す 2 つのスレッドがある場合はどうでしょうか?

と仮定する:

  1. 最初のスレッド検索レコード、A ステータスを保存します。
  2. 2 番目のスレッド検索レコード、A ステータスを保存します。
  3. 次に、最初のスレッドがレコードを B に変更し、->save() を呼び出します。システムは A->B をログに記録します
  4. 次に、2 番目のスレッドでレコードを C に変更し、->save() を呼び出します。システムは A->C を記録します

要約すると、A->B、A->C の 2 つのログがあります。これが問題にならない場合は、無視して上記の解決策を実行してください。

于 2013-05-23T08:32:41.810 に答える