ActiveRecordをサイトに固定します

はじめに


多少複雑なサイトを作成するプロセスでは、データベース(データベース)へのアクセスを整理することを考慮する必要があります。 既存のフレームワークまたはCMSに基づいてサイトを作成する場合、通常は組み込みのORMメカニズムがあります(英語-オブジェクトリレーショナルマッピング、詳細はwikiから )。 この記事では、人気のあるシンプルなORM ActiveRecordシステムを独自のフレームワークにアタッチする方法を説明します。



ActiveRecordはどのように機能しますか?


コンポーネントは、作業に必要な基本クラスのセット(Model、Config、ConnectionManagerなど)、特定のDBMSおよびエントリポイントに接続するためのアダプターのセット、プロジェクトモデルのクラスのオートロード機能を含むActiveRecord.php初期化ファイルです。 すべてのクラスはActiveRecord名前空間で定義されているため、プロジェクトは別のスペースまたはグローバルスペースにある可能性が高いため、extends \ ActiveRecord \ Modelなどのクラスの構築やuse ActiveRecordディレクティブの使用を避けるために、独自のラッパーを作成することは理にかなっていますActiveRecord また、ARコンポーネントに影響を与えることなくORMの機能を拡張します。



したがって、すべてのARメソッドを使用するには、ActiveRecord.php初期化ファイルをプロジェクトに接続し、データベース内の各テーブルのモデルクラスを作成し、\ ActiveRecord \ Modelから継承する必要があります(たとえば、クラスBook extends \ ActiveRecord \ Model {})、初期化デザインを使用したデータベースへの接続:



$connections = array( 'development' => 'mysql://invalid', 'production' => 'mysql://test:test@127.0.0.1/test' ); ActiveRecord\Config::initialize(function($cfg) use ($connections) { $cfg->set_model_directory('.'); $cfg->set_connections($connections); });
      
      







その後、モデルにアクセスして必要なメソッドを呼び出すことができます。たとえば、Book :: first()-Bookモデルで定義されたテーブルの最初の行を返します。



ARラッパーの作成


プロジェクトでは、異なるファイルからデータベースにアクセスする必要がある場合があり、通常、構成は別のファイルに保存されます。標準のAR機能は必ずしも十分ではなく、\ ActiveRecord名前空間を使用した書き込みの形式はあまり美しくありません。 このトピックはいくつかの記事に基づいているので、ここで問題の本質を述べようとします。



単純な場合、2つのクラスのみを作成する必要があります。1つは\ ActiveRecord \ Modelから継承し、もう1つはARを初期化および構成するメインクラスです。 2つのクラスファイルを作成します。



 //Orm.php class Orm { /** * array $models_    ,          ,     *     [ ]=>array('path'=>       , 'namespace'=>       ) */ public $models_ = array(); /** *    PHP,   ,    ,   * * @param null $name */ function __construct($name = null) { if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) die('PHP ActiveRecord requires PHP 5.3 or higher'); define('PHP_ACTIVERECORD_VERSION_ID', '1.0'); include_once 'lib/Singleton.php'; include_once 'lib/Config.php'; include_once 'lib/Utils.php'; include_once 'lib/DateTime.php'; include_once 'lib/Model.php'; include_once 'lib/Table.php'; include_once 'lib/ConnectionManager.php'; include_once 'lib/Connection.php'; include_once 'lib/SQLBuilder.php'; include_once 'lib/Reflections.php'; include_once 'lib/Inflector.php'; include_once 'lib/CallBack.php'; include_once 'lib/Exceptions.php'; spl_autoload_register(__NAMESPACE__ . '\ActiveRecord::activerecord_autoload'); Config::initialize(function ($cfg) { $cfg->set_connections(array( 'development' => Configuration::$dbtype . "://" . Configuration::$db_user . ":" . Configuration::$db_password . "@" . Configuration::$db_host . "/" . Configuration::$db_name )); /*     ,       AR,    "Ymd H:i:s T"      ,         datetime  MySQL */ $cfg->set_date_format("Ymd H:i:s"); }); } /**      ,     ,      FALSE */ public function getModel($model) { $config = Config::instance(); if (array_key_exists($model, $this->models_)) { $config->set_model_directory($this->models_[$model]['path']); if( $this->models_[$model]['namespace'] ) $class = "\\" . $this->models_[$model]['namespace'] . "\\" . $model; else $class = $model; return new $class; } else { return false; } } /**   ,       getModel() $class_name   ,      NEW   getModel() */ public static function activerecord_autoload($class_name) { $root = Config::instance()->get_model_directory(); $class_name = explode('\\', $class_name); $class_name = end($class_name); $file = $root . $class_name . ".php"; if (file_exists($file)) require $file; } } //Model.php class Model extends \ActiveRecord\Model { /*    ,      ,         */ static $table_name = 'simple_name'; //      static $primary_key = 'id'; //      static $connection = 'production'; //    ,   SQL    - db.table_name static $db = 'test'; /* *            */ }
      
      







Modelクラスから、既存のテーブルのすべてのモデルを継承します。 また、アプリケーション構成全体が別のConfiguration.phpファイルに保存されているとします。



 class Configuration{ /*.....*/ /** * $db_host       */ static $db_host = 'localhost'; /** * $db_user    */ static $db_user = 'root'; /** * $db_password    */ static $db_password = 'root'; /** * $db_name    */ static $db_name = 'db_name'; /** * $dbtype     */ static $dbtype = 'mysql'; /*.....*/ }
      
      







Ormクラスのコンストラクター(このコードはActiveRecord.phpから取得されます)で必要なクラスを接続してオートローダーを登録し、最後にデータベースへの接続を初期化します。



時間形式に特に注意する必要があります。デフォルトのままにすると、データベースにデータを書き込む操作中に、datetime型のフィールドでエラーが生成されます。 ARは、2000-02-03 16:23:27 MSKの形式で文字列を生成します。 タイムゾーンインデックスを示します。 構成を変更するだけでは十分ではありません。理由はわかりませんが、他のクラスのAR開発者は構成からではなく日付と時刻の形式を使用しますが、必要なメソッドで明示的に指定するため、次のファイルをさらに変更する必要があります。

/lib/Column.phpキャストメソッド

 return new DateTime($value->format('Ymd H:i:s T'))
      
      







 return new DateTime($value->format(Config::instance()->get_date_format()))
      
      





同様に、/ lib / Connection.phpファイルでは、datetime_to_string()メソッドstring_to_datetime()および/lib/Model.php assign_attribute()メソッド。



ここで、これらすべての使用方法の例を示します。 まず、Ormクラスのオブジェクトを格納する変数を作成する必要があります。この変数は、スクリプトで必要な場所で使用できる必要があるため、静的メインコントローラーまたはグローバルとして宣言することをお勧めします。 オブジェクトを作成した後、プロジェクトで使用されるすべてのモデルの配列を_models配列に配置する必要があります。配列の形式は、コードのコメントに記載されています。 上記のすべてを実装する可能な例を次に示します。



 <?php class Controller{ public static $ORM; function __construct(){ $this->loadOrm(); } function loadOrm(){ include 'Orm.php' self::$ORM = new Orm(); self::_models = array('Book'=>array('path'=>'models', 'namespace'=>__NAMESPACE__)); } } new Controller; ?> //            <?php $model = Controller::$ORM ->getModel('Book'); $books = $model->all(); foreach($books as $book) echo $book->author;
      
      







もちろん、このメソッドにはまだ改良が必要です。たとえば、Ormクラスの静的メソッドを作成し、プロジェクトを開始するときに初期化する必要があります。次に、Orm :: getModel( 'Model Name')のような構造を使用します。

ARはかなり強力で柔軟なツールです。標準のCRUD操作に加えて、テーブルの関係(複雑なスルースルーの関係を含む)、SQLクエリを構築するためのSQLBuilder、検証、変換などもサポートします。



英語の公式ドキュメントであり、基本的な質問をカバーしています.ARでの作業に関する回答のほとんどを見つけることができるフォーラムもありますが、自分のフレームワークまたは単純なWebサイトエンジンでのARの実装に関する情報を通常のソースよりも多くすることはできませんでした。



私の仕事の過程で、私はこのライブラリに出くわす必要がありました。このトピックが興味深い場合は、ActiveRecordの記事でこのシリーズを続けます。



All Articles