名前空間

FuelPHP は PHP 5.3+ フレームワークであり、 可能な限りコードをポータブルに、また、アプリケーションの一部をあちこち移動した場合にクラス名の衝突を回避するために、 さまざまなフレームワークのコンポーネントとアプリケーションを分離するために、名前空間に大きく依存しています。

これに対する例外は、デフォルトでは、APPPATH/classes 内のメインアプリケーションです。 すべてのメインアプリケーションクラスはグローバル名前空間 (名前空間なし) に定義され、 ユニークなクラス名を付与するためにカスケーディングファイルシステムを使います。

これは初心者が FuelPHP フレームワークを使い始めるのを簡単にしますが、より複雑なクラス名を付与し、 それらのクラスをよりポータブルでないものや取り換え可能でないものにします。

コントローラの名前空間

はじめに で述べたように、デフォルトではコントローラは APPPATH/classes/controller フォルダに作成され、 Controller_ という接頭辞を付けます。この接頭辞は APPPATH/config/config.php 設定ファイルで定義されています (定義されていない場合はそれがデフォルトです)。 しかし、これはコントローラを希望する名前空間に変更し、異なるフォルダ構成にコントローラを移動することができます。

Controller 名前空間の例に移りましょう。FuelPHP のアプリケーションの config.php ファイルで controller_prefix の設定を 'Controller_' から 'Controller\\' に変更します。

namespace Controller;

class Example extends \Controller
{
	public function action_index()
	{
		// 何かコード
	}
}

一旦、コントローラで名前空間を有効にすると、すべての コントローラクラスで名前空間が必要になります! これは、Mymodule モジュール内のコントローラは、このようになることを意味します:

namespace Mymodule\Controller;

class Example extends \Controller
{
	public function action_index()
	{
		// 何かコード
	}
}

コントローラの名前空間はアプリケーションに完全に透過的で、他の変更なしに実装できます。 名前空間とカスケーディングファイルシステムを組み合わせ、\Controller\Admin\User_Groups のようなコントローラを作成することもでき、 その場合、APPPATH/classes/controller/admin/user/groups.php に定義します。

コントローラを名前空間内にした場合、すべてのグローバルなクラス (例での "Controller" のような) にバックスラッシュを先頭に付ける必要があることに注意してください。 グローバル名前空間からロードされる必要があるためです。 あるいは、'use' キーワードを使い、現在の名前空間にインポートしてください。

モデルの名前空間

追加の設定は必要なく、すぐにモデルに名前空間を付けることができます。

namespace Model;

class Example extends \Orm\Model
{
	// 何らかのコード
}

モジュール内では:

namespace Mymodule\Model;

class Example extends \Model_Crud
{
	// 何らかのコード
}

コントローラではモデルにこのようにアクセスします:

// 上で作成された ORM モデル
$orm = \Model\Example::forge();

// 上で作成されたモジュールの Crud モデル
$crud = \Mymodule\Model\Example::forge();

プレゼンタの名前空間

プレゼンタには接頭辞の設定がないため、名前空間を使うのは少し複雑になります。 アプリケーションで Presenter クラスを拡張する必要があります。次のようなクラスを作成します:

// ファイル APPPATH/classes/presenter.php
class Presenter extends \Fuel\Core\Presenter
{
	// 名前空間の接頭辞
	protected static $ns_prefix = 'Presenter\\';
}

そして、APPPATH/bootstrap.php に追加して、フレームワークに Presenter クラスを拡張したことを知らせます:

// プレゼンタのオーバーライドを追加
Autoloader::add_classes(array(
	'Presenter' => APPPATH.'classes/presenter.php',
));

オートローダが登録される前に追加したことを確認してください!

一旦、この変更をすれば、プレゼンタをこのように定義できます:

// ファイル APPPATH/classes/presenter/users/group.php
namespace Presenter\Admin\Users;

class Group
{
	public function view()
	{
		// プレゼンタのコード
	}
}

その他のクラスの名前空間

classes フォルダにある他のどのクラスも、完全修飾名がクラスを定義しているファイルに マッピングできる限り、問題なく名前空間を付与できます:

// ファイル APPPATH/classes/admin/users/group.php
namespace Admin\Users;

class Group
{
	// 何らかのコード
}

// 同じファイルとクラスで別の選択肢
namespace Admin;

class Users_Group
{
	// 何らかのコード
}

// あるいは、名前空間なしの古いスタイル
class Admin_Users_Group
{
	// 何らかのコード
}

警告

異なるネーミングスタイルを同じクラスでミックスしないでください

クラス名には名前空間とアンダースコアを組み合わすことができますが、クラスを使用する際は組み合わせることはできません。 もし \Admin\Users\Group とクラスを定義したら、\Admin\Users_Group::method(); は正しいファイルをロードします (正しいファイルにマップされるからです) が、オートローラは例外をスローします。なぜなら、期待される \Admin\Users_Group クラスが そのファイルに定義されていないからです。

そのため、アプリケーションでは名前の規約を決め、それを忠実に守ることがベストです!

クラス名の衝突

リクエスト実行に際し、モジュールはメインアプリより優先されます。これはモジュールに関して、 アプリの中で使える名前と名前空間に密接に関連します。

例えば、Admin というモジュールがあった場合、そのモジュールのすべてのクラスは \Admin で始まる名前空間内に定義されます。 この時、同時に APPPATH/classes/admin 内にクラスがあれば、上の例のように
- それらのアプリのクラスは、そのモジュールがロードされない限り機能します。
- もしモジュールがロードされれば、同じ名前のモジュールのクラスが優先権を持つため、アプリのクラスはロードされません。

同じように、もしアプリのコントローラ Controller_Admin_Users があった場合、モジュール Admin があると、 フレームワークは admin という接頭辞に基づきモジュール内のコントローラを探すため、 URL リクエストからアプリのコントローラがロードされることはありません。