名前空間を使用すると、モジュールやライブラリの作成者を悩ませる競合の問題を解決できます。 名前空間により、同じ名前の2つのファイルが(異なるディレクトリにある限り)存在でき、エイリアスのおかげでコードが読みやすくなります。 名前空間という単語は、現在のスペースまたは名前空間内の位置のソースを示すために使用されます。
ImageCMS専用のネームスペースの重要性については、サードパーティのモジュール開発者がスタンドアロンモジュールを作成できるようになりました。 結局のところ、モジュールを書くことの利便性の問題は決して完全に閉じられるべきではありません。 しかし、ある程度、これらまたは他のタスクは解決できます。
この決定に至ったきっかけについていくつかの言葉。
ImageCMSスクリプトはCodeIgniterで実行されます。 フレームワークは、ライブラリを「 / application / libraries 」に配置し、Loaderクラスを使用してモジュールに接続することを提案しました。 このような制限により、モジュールの操作性を確保するためにファイルを配置する場所の説明とともに、モジュールのインストールに関するマニュアルを作成する必要がありました。 そして、その名前のファイルが既にある場合はどうなりますか? またはクラス名? これに注意する必要がありました。
IRCに連絡して、 codeigniter.com / irc名前空間のサポートが近い将来に計画されているかどうかを尋ねました。 応答はありませんでした。 変更ログページでも同じ状況が待っていました。この方向ですぐに一歩が踏み出されるというヒントではありません。 フォーラムでのみ、いくつかのベストプラクティスがユーザーによってレイアウトされ、 https://github.comで1つのコミットが行われました。これにより、CI_Controllerを継承できます(何らかの理由でCI_Modelが見つかりませんでした)。
5月25日にPHP 5.3に切り替えたという嬉しい事実により、これらの数行を自分で記述して名前空間のサポートを実装することができました。
ImageCMSで名前空間を実装する例
以下の例は、システムリリースの最後からはほど遠いものです。 何度も書き直され、テストされ、最適化されますが、提示されたプロトタイプは、PHPプロジェクトで名前空間サポートを実装するためのオプションの1つを見る機会を提供します。
pre_controllerフックポイントに初期化を追加します
\application\config\hooks.php: $hook['pre_controller'][] = array( 'class' => '', 'function' => 'modules_namespaces_initialize', 'filename' => 'namespaceses.php', 'filepath' => 'third_party/' );
そして、実際には、初期化自体
\application\third_party\namespaceses.php: <?php if (!defined('BASEPATH')) exit('No direct script access allowed'); function modules_namespaces_initialize() { if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) die('Namespaces requires PHP 5.3 or higher'); spl_autoload_register('modules_namespaces_autoload', false); } function modules_namespaces_autoload($name) { if (strpos($class_name, "\\")) { if (file_exists($file = 'application/modules/' . strtolower(str_replace('\\', DS, $name)) . EXT)) require $file; } }
これで、名前空間を介して接続クラスに応答できるようになりました。
名前空間を操作する原理を示すために、データベースからユーザーのリストを取得する簡単なモジュールの例を示します。
モジュールコントローラー
\application\modules\feedback\feedback.php: <?php use Feedback\Getuserlist as Getuserlist; if (!defined('BASEPATH')) exit('No direct script access allowed'); class Feedback extends \MY_Controller { public function __construct() { parent::__construct(); } public function index() { $users = Getuserlist::getUsers(); $this->template->add_array(array('users', $users)); $this->display_tpl('feedback'); } }
次に、Getuserlistクラスを持つgetuserlist.phpファイルが必要です。
<?php namespace Feedback; if (!defined('BASEPATH')) exit('No direct script access allowed'); class Getuserlist extends \MY_Controller { function __construct() { parent::__construct(); } public function getUsers() { return $this->db->get('users')->result(); } }
クラスを設計するためのこのアプローチは、多くの人が失敗したと考えています。 データベースと作業を分離したい。 そのため、getUsers()メソッドを書き換えて、モデルデータベースとの作業を転送し、情報をプルアップするプロセスから抽象化する必要があります。
新しいメソッドは次のようになります。
public function getUsers() { return Model::getUsers(); }
さて、エイリアス「モデル」を追加します。
use Feedback\Model as Model,
データベースを操作するためのモデルについて説明します。
<?php namespace Feedback; if (!defined('BASEPATH')) exit('No direct script access allowed'); class Model extends \CI_Model { function __construct() { parent::__construct(); } public function getUsers() { return $this->db->get('users')->result(); } }
これで、Getuserlistハンドラーに対してロジックが閉じられたクラスができました。つまり、コードの開発と保守が容易になります。
結果-作成したモジュールは、エンドユーザーからの最小限のインストールコストで簡単に1つのフォルダーにパックし、拡張ストアに配置できます。 クラスとアーキテクチャ構造の階層を正しく構築する可能性が明らかになりました。
この記事が、開発者が同様の問題を解決するのに役立つことを願っています。 コメント、質問、提案がある場合は、コメントをお待ちしています。
関連リンク:
http://www.php.net-名前空間
CodeIgniter
ImageCMS