Introducing 

Prezi AI.

Your new presentation assistant.

Refine, enhance, and tailor your content, source relevant images, and edit visuals quicker than ever before.

Loading…
Transcript

id:Fivestar / twitter:fivestr

名前空間概要

名前空間の注意点

名前空間とオートロード

名前空間とフレームワーク

もしLinuxのファイルシステムに

ディレクトリがなかったら?

それって今のPHPと同じ?

名前空間は      で宣言

名前空間の区切り文字は  (バックスラッシュ)

  

  • クラス
  • 関数
  • 定数

先頭に \ をつけて指定すると、

グローバル空間からの絶対指定になる

         定数や      演算子で

現在の名前空間の指定が行える

インポート / エイリアス

  を使うことでクラスのインポートや

  でクラス/名前空間にエイリアスを作成することができる

同一ファイル内での名前空間の複数指定

ただし次は失敗:

use foo\bar\MyObject;

$class = 'MyObject';

$obj = new $class();

# => Fatal error: Class 'MyObject' not found

Coding standard for PHP 5.3 and above

PHPと名前空間

名前空間とは、PHP 5.3.0 から実装された

クラス名や関数名の衝突を避けるための仕組み

<?php

namespace foo;

class MyObject {}

namespace bar;

class MyObject {}

http://jp2.php.net/namespace

複数指定するならブレスを使う方が推奨される:

名前解決のルール

<?php

namespace foo {

class MyObject {}

}

namespace bar {

class MyObject {}

}

  • クラスは常に現在の名前空間

名前空間とグローバル空間を同時に指定する:

  • 関数と定数は現在の名前空間

-> 存在しなければグローバル空間

use

as

<?php

namespace foo {

class MyObject() {}

}

// グローバル空間

namespace {

$obj = new foo\MyObject();

}

ただし

ただ、複数の名前空間をひとつのファイルに記述するようなコーディングはできるだけ避けるべきです。 主な使い道としては、複数の PHP スクリプトをひとつのファイルにまとめるときくらいでしょう。

同じ名前空間を複数回指定可能:

PHPマニュアルより

<?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();

とのことです

<?php

namespace {

class MyObject {}

}

namespace foo {

class MyObject {}

}

namespace {

new MyObject();

}

namespace foo {

new MyObject();

}

ネストはできない:

\

namespace

<?php

namespace foo {

namespace bar {

class MyObject {}

}

}

# => Fatal error: Namespace

declarations cannot be nested

<?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)

名前空間が適応されるのは:

PHPと名前空間

namespace

* TIPS *

グローバル空間 = ルートディレクトリ

現在の名前空間 = カレントディレクトリ

に置き換えると理解しやすいです

namespace usr\local;

$obj = new bin\Command();

上記の場合はカレントディレクトリからの

相対指定と同じなので、

usr\local\bin\Command クラスが

生成されます

(ただし、../ のような表現は使えません)

__NAMESPACE__

<?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');

インポート/エイリアスの注意点:

use \foo\Foo;

// 既にFooがimportされているので定義できない

class Foo {}

class Bar {}

// 同名のオブジェクトがすでに宣言されているので

// インポートできない

use bar\Bar;

hoge.txtを追加しよう!

/

|- 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

...

名前空間名の定義

非修飾名(Unqualified Name)

名前空間区切り文字を含まない識別子

Foo, Bar

修飾名(Qualified Name)

名前空間区切り文字を含む識別子

ダウンロードしたzipを展開したら

my_hoge.txtが上書きされた...

(´・ω:;.:...

foo\Bar, hoge\fuga\Piyo

名前空間区切り文字を含む識別子のうち、先頭が名前空間セパレータ、

もしくは namespace 演算子で始まるもの

完全修飾名(Fully Qualified Name)

名前がかぶるから

my_hoge.txt

とかにしておくか...

\foo\bar\Baz, namespace\Hoge

文字列によるクラスの指定

文字列で指定した場合は必ずグローバル空間から探される

namespace foo\bar;

$class = 'MyObject';

$obj = new $class();

# => Fatal error: Class 'MyObject' not found

名前解決はコンパイル時に行われるため、

実行時には名前解決は行われない

.....たぶん

<?php

namepace foo\bar {

class MyObject {}

}

namespace {

$class = 'foo\bar\MyObject';

$object = new $class;

}

フレームワークの中に

Fileクラスがあった...

\(^o^)/

File っていうモデル

クラスを作りました

use foo\bar as fb;

$class = 'fb\MyObject';

$obj = new $class();

# => Fatal error: Class 'fb\MyObject' not found

フレームワークを

使って開発しよう!

ファイルシステムには

ディレクトリがあるから、

ディレクトリさえ分けてしまえば

名前は被らないのに...

そんな殺伐としたPHPの世界に救世主が!!

 .__

ヽ|・∀・|ノ

 |__|

  | |

fivestar

もっと知りたい名前空間

presented by

with nequal

2009.12.15 モダンPHP勉強会

fivestar

  • 小川 雄大 / OGAWA Katsuhiro
  • アシアル株式会社
  • symfony/Doctrine evangelist

symfonyのアドベントカレンダーの翻訳しました

http://www.symfony-project.org/advent_calendar/

ぜひ見てくださいね!

class_exists()

PHP Standards Working Group

namespace foo {

class_exists('bar\MyObject');

# => 'bar\MyObject'

}

namespace {

use foo\bar\MyObject;

class_exists('MyObject');

# => 'MyObject'

}

<vendor>\(<package_or_component>\)*<ClassName>

名前空間に関するルール

  • 名前空間は常に小文字 + アンダースコア
  • トップレベル名前空間にはベンダー名が入る

  • サブ名前空間はいくつ使ってもよい
  • 名前空間セパレータはディレクトリセパレータを表す
  • 名前空間中のアンダースコアに特別な意味はない
  • ベンダー名は最短のもの(zend, cake, ...)

useをしただけではクラスはロードされない

  • クラス名中のアンダースコアはディレクトリセパレータを表す

クラス名に関するルール

フレームワークやライブラリの開発者やコミュニティのメンバーらがPHPのコーディング規約について議論している

use foo\bar\MyObject;

new MyObject();

# => 'foo\bar\MyObject'

  • クラス名はアッパーキャメル
  • クラス名にはアンダースコアを含めてもよい

  • インターフェースにはInterfaceサフィックスをつける
  • 抽象クラスにはAbstractサフィックスをつける

http://groups.google.com/group/php-standards

$classLoader = new SplClassLoader('Doctrine\Common', '/path/to/doctrine');

$classLoader->register();

$parser = new Doctrine\Common\Annotations\Parser();

# /path/to/doctrine/Doctrine/Common/Annotations/Parser.php

http://gist.github.com/221634

Jonathanがつくったオートローダー

SplClassLoader

  • 全てのパッケージはパッケージレベルのExceptionを定義する
  • 全てのパッケージは可能な限りSPL例外を使う
  • パッケージレベルの例外はクラスでもインターフェースでもよい
  • パッケージからスローされる例外は可能な限りパッケージレベルの例外を継承もしくは実装する
  • パッケージからスローされる例外は可能な限り以下のルールに従う:

例外に関するルール

  • SPL例外がつかる場合はSPL例外
  • それ以外はパッケージレベルの例外を継承もしくは実装した例外

主なメンバー:

  • 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名

<?php

spl_autoload_register(function ($className)

{

echo $className;

}

)

Zend Framework, PEAR2

不明

準拠する?

名前解決されたクラス名が渡される

  • zend\controller\FrontController
  • pear2\http\Request

主要フレームワークの対応

namespace {

new foo\bar\MyObject();

# => 'foo\bar\MyObject'

}

namespace foo {

new bar\MyObject();

# => 'foo\bar\MyObject'

new \MyObject();

# => 'MyObject'

}

PEAR2は pear2\HTTP\Request のようになるかも?

Lithium

命名規則は準拠

  • lithium\core\Object
  • lithium\data\Model

Cakeは一切調べていません

symfony / Doctrine

名前空間もアッパーキャメル

  • Symfony\Components\DependencyInjection\Container
  • Doctrine\ORM\Query

現状のPEARの命名規則における _ を \ に置き換えたものと同じ

Learn more about creating dynamic, engaging presentations with Prezi