Easily create stunning presentations
Takes a few minutes to start

More Prezis

By Katsuhiro Ogawa

Popular prezis

See more popular prezis

もっと知りたい名前空間

もっと知りたい名前空間
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/namespace

Created by Katsuhiro Ogawa

2009.12.15 モダンPHP勉強会

Share this prezi

Embed this prezi

Copy the code below

  • Copy to clipboard