34

モデルと検証に関する例とチュートリアルを見つけます。そして、検証 (または少なくともそのほとんど) をモデルに含める必要があると述べていますが、これには同意します。しかし、それをどのように行うべきかを示す例やチュートリアルはありません。

それがどのように行われるかについての簡単な例で誰かが私を助けてくれますか? モデルのどこにルールを配置しますか? 検証はどこで行われますか? コントローラーは、検証が成功したか失敗したかをどのように認識しますか? コントローラーはどのようにしてエラー メッセージなどを受け取るのでしょうか?

誰かが助けてくれることを願って、ここで少し迷ってしまいます:p

4

4 に答える 4

36

私も Kohana3 の例を見つけるのに苦労しました。bestattendance の例は Kohana2 です。

私自身のテストで一緒に投げた例を次に示します。

アプリケーション / クラス / モデル / news.php

<?php defined('SYSPATH') OR die('No Direct Script Access');

Class Model_News extends Model
{
    /*
       CREATE TABLE `news_example` (
       `id` INT PRIMARY KEY AUTO_INCREMENT,
       `title` VARCHAR(30) NOT NULL,
       `post` TEXT NOT NULL);
     */

    public function get_latest_news() {
        $sql = 'SELECT * FROM `news_example` ORDER BY `id` DESC LIMIT  0, 10';
        return $this->_db->query(Database::SELECT, $sql, FALSE)
                         ->as_array();
    }

    public function validate_news($arr) {
        return Validate::factory($arr)
            ->filter(TRUE, 'trim')
            ->rule('title', 'not_empty')
            ->rule('post', 'not_empty');
    }
    public function add_news($d) {
        // Create a new user record in the database
        $insert_id = DB::insert('news_example', array('title','post'))
            ->values(array($d['title'],$d['post']))
            ->execute();

        return $insert_id;
    }
}

アプリケーション/メッセージ/errors.php

<?php
return array(
    'title' => array(
        'not_empty' => 'Title can\'t be blank.',
    ),
    'post' => array(
        'not_empty' => 'Post can\'t be blank.',
    ),
);

アプリケーション / クラス / コントローラー / news.php

<?php defined('SYSPATH') OR die('No Direct Script Access');

Class Controller_News extends Controller
{
    public function action_index() {
        //setup the model and view
        $news = Model::factory('news');
        $view = View::factory('news')
            ->bind('validator', $validator)
            ->bind('errors', $errors)
            ->bind('recent_posts', $recent_posts);

        if (Request::$method == "POST") {
            //added the arr::extract() method here to pull the keys that we want
            //to stop the user from adding their own post data
            $validator = $news->validate_news(arr::extract($_POST,array('title','post')));
            if ($validator->check()) {
                //validation passed, add to the db
                $news->add_news($validator);
                //clearing so it won't populate the form
                $validator = null;
            } else {
                //validation failed, get errors
                $errors = $validator->errors('errors');
            }
        }
        $recent_posts = $news->get_latest_news();
        $this->request->response = $view;
    }
}

アプリケーション / ビュー / news.php

<?php if ($errors): ?>
<p>Errors:</p>
<ul>
<?php foreach ($errors as $error): ?>
    <li><?php echo $error ?></li>
<?php endforeach ?>
</ul>
<?php endif ?>

<?php echo Form::open() ?>
<dl>
    <dt><?php echo Form::label('title', 'title') ?></dt>
    <dd><?php echo Form::input('title', $validator['title']) ?></dd>
    <dt><?php echo Form::label('post', 'post') ?></dt>
    <dd><?php echo Form::input('post', $validator['post']) ?></dd>
</dl>
<?php echo Form::submit(NULL, 'Post') ?>
<?php echo Form::close() ?>
<?php if ($recent_posts): ?>
<ul>
<?php foreach ($recent_posts as $post): ?>
    <li><?php echo $post['title'] . ' - ' . $post['post'];?></li>
<?php endforeach ?>
</ul>
<?php endif ?>

このコードをデフォルトのインストールで機能させるには、データベース モジュールを有効にして認証用に構成する必要があります。次に、デフォルト設定を使用して index.php/news からアクセスできます。

これは Kohana 3.0.7 でテストされており、コードをどのようにレイアウトするかの良い出発点となるはずです。他のフレームワークとは異なり、Kohana はロジックをどこに配置するかに関して非常にオープンエンドであるように見えるので、これは私にとって理にかなっています。独自のデータベース インタラクションをローリングする代わりに ORM を使用する場合は、ここで見つけることができる検証用の独自の構文があります。

于 2010-09-08T12:12:34.433 に答える
6

ORM モデルで使用される KO3 検証の例。例は a1986 (blaa) の許可を得て #kohana (freenode) に投稿されました。

<?php defined('SYSPATH') or die('No direct script access.');

class Model_Contract extends ORM {

  protected $_belongs_to = array('user' => array());

  protected $_rules = array(
    'document' => array(
      'Upload::valid'     => NULL,
      'Upload::not_empty' => NULL,
      'Upload::type'      => array(array('pdf', 'doc', 'odt')),
      'Upload::size'      => array('10M')
    )
  );

  protected $_ignored_columns = array('document');


  /**
   * Overwriting the ORM::save() method
   * 
   * Move the uploaded file and save it to the database in the case of success
   * A Log message will be writed if the Upload::save fails to move the uploaded file
   * 
   */
  public function save()
  {
    $user_id = Auth::instance()->get_user()->id;
    $file = Upload::save($this->document, NULL, 'upload/contracts/');

    if (FALSE !== $file)
    {
      $this->sent_on = date('Y-m-d H:i:s');
      $this->filename = $this->document['name'];
      $this->stored_filename = $file;
      $this->user_id = $user_id;
    } 
    else 
    {
      Kohana::$log->add('error', 'Não foi possível salvar o arquivo. A gravação da linha no banco de dados foi abortada.');
    }

    return parent::save();

  }

  /**
   * Overwriting the ORM::delete() method
   * 
   * Delete the database register if the file was deleted 
   * 
   * If not, record a Log message and return FALSE
   * 
   */
  public function delete($id = NULL)
  {

    if (unlink($this->stored_filename))
    {
      return parent::delete($id);
    }

    Kohana::$log->add('error', 'Não foi possível deletar o arquivo do sistema. O registro foi mantido no banco de dados.');
    return FALSE;
  }
}
于 2010-09-30T16:09:07.837 に答える
4

これは私にとってうまくいく簡単な例です。

私のモデル(client.php)では:

<?php defined('SYSPATH') or die('No direct script access.');

class Client_Model extends Model {

public $validation;

// This array is needed for validation
public $fields = array(
    'clientName'    =>  ''
);

public function __construct() {
    // load database library into $this->db (can be omitted if not required)
    parent::__construct();

    $this->validation = new Validation($_POST);
    $this->validation->pre_filter('trim','clientName');
    $this->validation->add_rules('clientName','required');
}

public function create() {
    return $this->validation->validate();
}

// This might go in base Model class
public function getFormValues() {
    return arr::overwrite($this->fields, $this->validation->as_array());
}

// This might go in base Model class
public function getValidationErrors() {
    return arr::overwrite($this->fields, $this->validation->errors('form_errors'));
}
}

?>

私のコントローラー(clients.php)で:

<?php defined('SYSPATH') OR die('No direct access allowed.');

class Clients_Controller extends Base_Controller {

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

public function index() {

    $content = new View('clients/read');
    $content->foobar = 'bob.';

    $this->template->content = $content;
    $this->template->render(TRUE);

}

/* A new user signs up for an account. */
public function signup() {

    $content = new View('clients/create');
    $post = $this->input->post();
    $client = new Client_Model;

    if (!empty($post) && $this->isPostRequest()) {
        $content->message = 'You submitted the form, '.$this->input->post('clientName');
        $content->message .= '<br />Performing Validation<br />';

        if ($client->create()) {
            // Validation passed
            $content->message .= 'Validation passed';
        } else {
            // Validation failed
            $content->message .= 'Validation failed';
        }

    } else {
        $content->message = 'You did not submit the form.';
    }

    $contnet->message .= '<br />';
    print_r ($client->getFormValues());
    print_r ($client->getValidationErrors());


    $this->template->content = $content;
    $this->template->render(TRUE);
}

   }
?>

私の i18n ファイル (form_errors.php) では:

$lang = Array (
'clientName' => Array (
'required' => 'The Client Name field is required.'
)
);
于 2010-03-17T19:50:38.063 に答える
0

理解するのに時間がかかり、良い例が1つも見つからなかったため、以下のリンクでこれを処理する方法について簡単に説明しています。

http://www.matt-toigo.com/dev/orm_with_validation_in_kohana_3

于 2011-10-25T18:47:26.370 に答える