3

Codeigniter の学習を開始し、MVC をより適切に扱えるようになった後、私は何か疑問に思い始めました。

データベースに格納されているユーザーを制御するモデルがあるとします。コントロールで検証されるフォームを介して簡単な登録が行われ、データがモデルに渡されてデータベースに保存されます。現在、投稿されたデータを取得し、格納するためにデータベースに渡す配列を設定するプロセスは、次のようにモデルで組み立てられます。

function add_user() {
        $new_user_data = array(
            'etunimi' => $this->input->post('etunimi'),
            'sukunimi' => $this->input->post('sukunimi'),
            'osoite' => $this->input->post('osoite'),
            'postinro' => $this->input->post('postinro'),
            'toimipaikka' => $this->input->post('toimipaikka'),
            'puhelin' => $this->input->post('puhelin'),
            'email' => $this->input->post('email'),
            'tunnus' => $this->input->post('tunnus'),
            'salasana' => $this->input->post('salasana')
        );

        $insert = $this->db->insert('kayttajat', $new_user_data);

        return $insert;
    }

私が考えているのは、データのアセンブリをコントローラーに転送して、モデルをもう少し独立して再利用可能にすることです。最終的なデータは、次のようにメソッド パラメータとして渡されます。

function add_user ($new_user_data) {

        $insert = $this->db->insert('kayttajat', $new_user_data);

        return $insert;
    }

モデルは最終的な情報を取得して渡すだけであり、証明とアセンブリの負担はコントローラにあり、ビューはそれをすべて出力してUIを提供するだけなので、これは私の理解ではレイヤー間をより区別します。

どの概念が MVC の原則に似ていて、単純に理にかなっているのかについて、より経験豊富な意見を求めています。

4

5 に答える 5

1

2番目のアプローチは、かなり無意味なモデル関数を作成します。を呼び出すだけで同じことができます$this->db->insert()

最初のケースが「良好」である理由は、指定された列のみを送信するためです。たとえば、ずさんな場合、$this->input->post()パラメータとして関数に送信すると、余分な投稿フィールドでmyselエラーが発生するリスクが高くなります。

私のアプローチはこれに似ているでしょう:

function add_user() {

    $arr = array('etunimi', 'sukunimi', 'osoite', 'postinro', 'toimipaikka', 'puhelin', 'email', 'tunnus', 'salasana');

    $new_user_data = array();
    foreach($arr as $h)
        $new_user_data[$h] = $this->input->post($h);

    $insert = $this->db->insert('kayttajat', $new_user_data);

    return $insert;

}

データを渡したい場合は、少なくとも指定されたフィールドのみが使用されていることを確認してください。

function add_user($data) {

    $arr = array('etunimi', 'sukunimi', 'osoite', 'postinro', 'toimipaikka', 'puhelin', 'email', 'tunnus', 'salasana');

    $new_user_data = array();
    foreach($arr as $h)
        if (isset($data[$h]))
            $new_user_data[$h] = $data[$h];

    $insert = $this->db->insert('kayttajat', $new_user_data);

    return $insert;

}
于 2012-07-27T12:07:58.717 に答える
1

コントローラーで検証を行い、データをモデルに送信できます。

コントローラ:

if ($this->form_validation->run()) {
    $this->my_model->add_user($this->input->post());
}

モデル:

function add_user($input) {
    $this->db->insert('kayttajat', $input);
}
于 2012-07-27T12:02:46.823 に答える
0

別のオプション...

コントローラ

public function validate()
{
    //apply the rules
    $this->form_validation->set_rules('email', 'Email', 'required');

    if ($this->form_validation->run() == FALSE)
    {
        $this->load->view('form_incompleted');
    }
    else
    {

        $email = $this->input->post('email');

        //create the model and store it
        $user = new User($email);
        $user->add_user();

        $this->load->view('form_completed');
    }
}

モデル

class User extends CI_Model {

    var $email = '';

    function __construct()
    {
        parent::__construct();
    }

    function __construct($email)
    {
        parent::__construct();
        $this->email = $email;
    }

    /**
     * Add the current user
     */
    function add_user()
    {
        $this->db->insert('kayttajat', $this);
    }

}

属性だけを使用しましたemailが、すべて問題なく追加できます

于 2012-07-27T12:14:49.220 に答える
0

私は CI の経験が少しありますが、あなたのロジックは優れていると言えます。モデルをより再利用可能にするために、コントローラーに挿入値を含む配列を設定できます。実際、より一般的なモデルが必要な場合は、次を使用できます。

function general_insert($table,$data){
   return $this->db->insert($table,$data);
}

したがって、テーブルの名前と挿入するデータを渡すだけです。

于 2012-07-28T05:51:24.613 に答える
0

これが、 MVC
を実行するための例として CodeIgniter を使用することが非常に恐ろしい考えである理由です。

適切な MVC では、モデルはレイヤーであり、複数の異なるクラスから作成され、それぞれがいくつかの責任の 1 つを処理します。名前に「モデル」という単語が含まれるクラスを含むまたは拡張するモデル層には、クラスがあってはなりません。それはあなたが間違ったことをしているという最初の兆候です。

実際に何が間違っていたのですか?

CI_Modelクラス自体には何も含まれていません。何もないので、ドメインのビジネスロジックを収めるための構造とは言えません。しかし、ドキュメントでは ActiveRecord パターンを使用するように勧めています。パターン自体がストレージとビジネス ルールを組み合わせているため、これは問題です。

そして、なぜか「モデル」と呼ばれています。

クラスのグループを取得します (PR 上の理由から「モデル」と呼ばれます)。また、各クラスは、1 つのテーブルのストレージとロジックのみを扱います。複数のテーブルのデータ間の相互作用に基づくロジックの場所はありません。

なぜそれが重要なのですか?

このアーキテクチャ上の欠陥により、ドメイン ビジネス ロジックの一部 (検証など) がコントローラーにリークします。エンティティが相互作用するための場所が「モデル」にない構造を作成することになります。

どうすればそれをより少なくすることができますか?

「モデル」をテーブルに直接マップしようとするのをやめてください。CI_Model代わりに、コントローラーのドメイン ビジネス ロジックの高レベル インターフェイスを提供する、サービスのようなもので拡張するクラスを変更するようにしてください。このようなサービスレベル構造には、エンティティ間の相互作用が含まれる場合があります。

これらのサービスは、ドメイン オブジェクト(特定のエンティティのビジネス ロジックを含み、それ自体を検証できます) とデータ マッパーのようなものを使用して、エンティティの情報を簡単に保存および取得できます。

于 2012-07-28T20:36:16.007 に答える