もっと知りたい名前空間
2009.12.15 モダンPHP勉強会
presented by
fivestar
with nequal
名前空間概要
名前空間の注意点
名前空間とフレームワーク
名前空間とオートロード
もしLinuxのファイルシステムに
ディレクトリがなかったら?
/
|- hoge.txt
|- bin_ls
|- usr_bin_php
|- usr_bin_mysql
|- usr_local_bin_sl
|- usr_local_bin_php-5.3.1
|- home_fivestar_bin_php-5.3.1
|- var_www_index.php
|- var_www_css_style.css
|- var_www_scripts_phpinfo.php
...
hoge.txtを追加しよう!
名前がかぶるから
my_hoge.txt
とかにしておくか...
それって今のPHPと同じ?
ダウンロードしたzipを展開したら
my_hoge.txtが上書きされた...
(´・ω:;.:...
フレームワークを
使って開発しよう!
File っていうモデル
クラスを作りました
フレームワークの中に
Fileクラスがあった...
\(^o^)/
PHPと名前空間
ファイルシステムには
ディレクトリがあるから、
ディレクトリさえ分けてしまえば
名前は被らないのに...
そんな殺伐としたPHPの世界に救世主が!!
.__
ヽ|・∀・|ノ
|__|
| |
名前空間とは、PHP 5.3.0 から実装された
クラス名や関数名の衝突を避けるための仕組み
PHPと名前空間
<?php
namespace foo\bar;
class MyObject {} // foo\bar\MyObject
function myfunc() {} // foo\bar\myfunc()
const MY_CONST = 1; // foo\bar\MY_CONST
// foo\bar\MyObject の作成
$obj = new MyObject();
// framework\Controller の作成
$controller = new \framework\Controller();
// foo\bar\myfunc() の呼び出し
namespace\myfunc();
// foo\bar\MY_CONST の出力
echo constant(__NAMESPACE__.'\MY_CONST');
名前空間は で宣言
名前空間の区切り文字は (バックスラッシュ)
\
namespace
名前空間が適応されるのは:
クラス
関数
定数
__NAMESPACE__
namespace
定数や 演算子で
現在の名前空間の指定が行える
名前空間名の定義
非修飾名(Unqualified Name)
修飾名(Qualified Name)
完全修飾名(Fully Qualified Name)
先頭に \ をつけて指定すると、
グローバル空間からの絶対指定になる
Foo, Bar
名前空間区切り文字を含まない識別子
名前空間区切り文字を含む識別子
foo\Bar, hoge\fuga\Piyo
名前空間区切り文字を含む識別子のうち、先頭が名前空間セパレータ、
もしくは namespace 演算子で始まるもの
\foo\bar\Baz, namespace\Hoge
インポート / エイリアス
同一ファイル内での名前空間の複数指定
* TIPS *
グローバル空間 = ルートディレクトリ
現在の名前空間 = カレントディレクトリ
に置き換えると理解しやすいです
(ただし、../ のような表現は使えません)
namespace usr\local;
$obj = new bin\Command();
上記の場合はカレントディレクトリからの
相対指定と同じなので、
usr\local\bin\Command クラスが
生成されます
<?php
use foo\Foo;
// foo\Foo
$obj = new Foo();
use MyApplication_MyObject as MyObj;
// MyApplication_MyObject
$obj = new MyObj();
use bar\baz as baz;
// bar\baz\Baz
$obj = new baz\Baz();
// baz\Baz
$obj = new \baz\Baz();
use
を使うことでクラスのインポートや
でクラス/名前空間にエイリアスを作成することができる
インポート/エイリアスの注意点:
use \foo\Foo;
// 既にFooがimportされているので定義できない
class Foo {}
class Bar {}
// 同名のオブジェクトがすでに宣言されているので
// インポートできない
use bar\Bar;
複数指定するならブレスを使う方が推奨される:
<?php
namespace foo;
class MyObject {}
namespace bar;
class MyObject {}
<?php
namespace foo {
class MyObject {}
}
namespace bar {
class MyObject {}
}
<?php
namespace foo {
class MyObject() {}
}
// グローバル空間
namespace {
$obj = new foo\MyObject();
}
名前空間とグローバル空間を同時に指定する:
ネストはできない:
<?php
namespace foo {
namespace bar {
class MyObject {}
}
}
# => Fatal error: Namespace
declarations cannot be nested
同じ名前空間を複数回指定可能:
<?php
namespace {
class MyObject {}
}
namespace foo {
class MyObject {}
}
namespace {
new MyObject();
}
namespace foo {
new MyObject();
}
ただし
ただ、複数の名前空間をひとつのファイルに記述するようなコーディングはできるだけ避けるべきです。 主な使い道としては、複数の PHP スクリプトをひとつのファイルにまとめるときくらいでしょう。
PHPマニュアルより
とのことです
名前解決のルール
文字列によるクラスの指定
クラスは常に現在の名前空間
関数と定数は現在の名前空間
-> 存在しなければグローバル空間
<?php
namespace foo;
#$array = new ArrayObject();
# => Fatal error: Class 'foo\ArrayObject' not found
$array = new \ArrayObject(array(0, 'a', 'b', 'c', 'b'));
$unique = array_unique((array)$array, SORT_STRING);
// 次と同等: \array_unique((array)$array, \SORT_STRING)
fivestar
小川 雄大 / OGAWA Katsuhiro
アシアル株式会社
symfony/Doctrine evangelist
id:Fivestar / twitter:fivestr
symfonyのアドベントカレンダーの翻訳しました
http://www.symfony-project.org/advent_calendar/
ぜひ見てくださいね!
<?php
namepace foo\bar {
class MyObject {}
}
namespace {
$class = 'foo\bar\MyObject';
$object = new $class;
}
ただし次は失敗:
namespace foo\bar;
$class = 'MyObject';
$obj = new $class();
# => Fatal error: Class 'MyObject' not found
use foo\bar\MyObject;
$class = 'MyObject';
$obj = new $class();
# => Fatal error: Class 'MyObject' not found
use foo\bar as fb;
$class = 'fb\MyObject';
$obj = new $class();
# => Fatal error: Class 'fb\MyObject' not found
文字列で指定した場合は必ずグローバル空間から探される
名前解決はコンパイル時に行われるため、
実行時には名前解決は行われない
.....たぶん
<?php
spl_autoload_register(function ($className)
{
echo $className;
}
)
namespace {
new foo\bar\MyObject();
# => 'foo\bar\MyObject'
}
namespace foo {
new bar\MyObject();
# => 'foo\bar\MyObject'
new \MyObject();
# => 'MyObject'
}
名前解決されたクラス名が渡される
useをしただけではクラスはロードされない
use foo\bar\MyObject;
new MyObject();
# => 'foo\bar\MyObject'
class_exists()
namespace foo {
class_exists('bar\MyObject');
# => 'bar\MyObject'
}
namespace {
use foo\bar\MyObject;
class_exists('MyObject');
# => 'MyObject'
}
PHP Standards Working Group
フレームワークやライブラリの開発者やコミュニティのメンバーらがPHPのコーディング規約について議論している
http://groups.google.com/group/php-standards
主なメンバー:
Jonathan H. Wage: Doctrine, symfony
Nate Abele: Lithium(CakePHP)
Matthew Weier O'Phinney: Zend Framework
Paul M. Jones: Solar
David Coallier: PEAR
2009.12.15 現在: 22名
Coding standard for PHP 5.3 and above
名前空間に関するルール
クラス名に関するルール
例外に関するルール
<vendor>\(<package_or_component>\)*<ClassName>
名前空間は常に小文字 + アンダースコア
トップレベル名前空間にはベンダー名が入る
サブ名前空間はいくつ使ってもよい
名前空間セパレータはディレクトリセパレータを表す
名前空間中のアンダースコアに特別な意味はない
ベンダー名は最短のもの(zend, cake, ...)
クラス名はアッパーキャメル
クラス名にはアンダースコアを含めてもよい
インターフェースにはInterfaceサフィックスをつける
抽象クラスにはAbstractサフィックスをつける
クラス名中のアンダースコアはディレクトリセパレータを表す
全てのパッケージはパッケージレベルのExceptionを定義する
全てのパッケージは可能な限りSPL例外を使う
パッケージレベルの例外はクラスでもインターフェースでもよい
パッケージからスローされる例外は可能な限りパッケージレベルの例外を継承もしくは実装する
パッケージからスローされる例外は可能な限り以下のルールに従う:
SPL例外がつかる場合はSPL例外
それ以外はパッケージレベルの例外を継承もしくは実装した例外
主要フレームワークの対応
Lithium
Zend Framework, PEAR2
symfony / Doctrine
命名規則は準拠
lithium\core\Object
lithium\data\Model
不明
準拠する?
zend\controller\FrontController
pear2\http\Request
PEAR2は pear2\HTTP\Request のようになるかも?
名前空間もアッパーキャメル
Symfony\Components\DependencyInjection\Container
Doctrine\ORM\Query
現状のPEARの命名規則における _ を \ に置き換えたものと同じ
Cakeは一切調べていません
SplClassLoader
Jonathanがつくったオートローダー
http://gist.github.com/221634
$classLoader = new SplClassLoader('Doctrine\Common', '/path/to/doctrine');
$classLoader->register();
$parser = new Doctrine\Common\Annotations\Parser();
# /path/to/doctrine/Doctrine/Common/Annotations/Parser.php
as
http://jp2.php.net/namespaceMore presentations by
Popular presentations
Resumen explicativo del Proyecto de Ley de Resguardo del Orden Público (Ley Hinzpeter) en el marco de la protesta social
Sebastián Aylwin on
Resumen explicativo del Proyecto de Ley de Resguardo del Orden Público
More popular prezis in Explore>