SlideShare ist ein Scribd-Unternehmen logo
1 von 22
Downloaden Sie, um offline zu lesen
5分で分かるかもしれない
名前空間とオートロード

 第1回 関西PHP初心者勉強会

  2011年8月27日(土)

  スーパーグローバル世代のPHPer
        k-holy
名前空間とは
「ソースコード上で冗長な命名規則を用いなくても名前の衝突が
起こらないようにし、しかもそれを容易に記述できるようにす
る」(Wikipediaより引用)ための概念

PHP的には、名前の衝突を避けるために使われてきたPEAR命名規
則、「HTTP_Request2_Adapter_Socket」のような、アン
ダースコア区切りの長いクラス名を整理し、適切に階層管理する
ための機能

PHP5.3.0から利用可能
名前空間を宣言する
namespace宣言は必ずコードの先頭に記述すること。
(コメント、改行、スペースは宣言の前に書いてもよい)
名前空間は「」(バックスラッシュ)区切りで階層を構成できる。
<?php
namespace HolyExample; //名前空間 ”HolyExample” を宣言


※1ファイル内では1つの名前空間で完結させることを推奨
名前空間を宣言する
namespace宣言は必ずコードの先頭に記述すること。
(コメント、改行、スペースは宣言の前に書いてもよい)
名前空間は「」(バックスラッシュ)区切りで階層を構成できる。
<?php
namespace HolyExample; //名前空間 ”HolyExample” を宣言

ちなみに、誤っていわゆるBOM付UTF-8でファイルを保存したところ、
こんなエラーで怒られてしまいました。

Fatal error:    Namespace declaration statement has to
be the very first statement in the script

※BOM付きUTF-8には気をつけて!
名前空間でのクラス定義
名前空間で定義されるクラス/関数/定数は、先頭に名前空間を
付加したものとして解釈される。

namespace HolyExample;//名前空間”HolyExample”を宣言

class Foo { //Fooクラスを定義
    public static function getClass() {
        return __CLASS__;//クラス名を返す
    }
}
echo Foo::getClass();//HolyExampleFoo
名前空間とグローバル空間
PHPの定義済みクラス/関数/定数は、グローバル空間に配置さ
れる。名前空間でグローバル空間のクラスを使用する場合は、先
頭に名前空間セパレータを付ける必要がある。
関数や定数は、名前が被らない場合に限り従来通りの記述で構わ
ない。逆に言うと、実は同名で定義すれば上書き可能(一部の定数を除く)

namespace HolyExample;

class Exception extends Exception{}
$ns_ex = new Exception();//HolyExampleException
$global_ex = new Exception();//Exception
PHP_VERSION;//付けても
PHP_VERSION;//付けなくても同じ
別の名前空間のクラスを使う
別の名前空間に定義されたクラスを利用する場合、以下いずれか
の方法で記述する。

●   完全修飾名で記述
●   use 文でインポートしたクラス名で記述
●   use 文 + as キーワードで定義したエイリアスで記述
完全修飾名
名前空間セパレータを含む識別子のうち、先頭に名前空間セパ
レータを付けて指定したものを 完全修飾名 と呼ぶ。

HolyExample名前空間で、ZendFramework2の
ZendOAuthConsumer クラスを使う場合の例

●   完全修飾名
    namespace HolyExample;
    //ZendOAuthConsumerクラスを完全修飾名で指定
    $consumer = new ZendOAuthConsumer();

※ファイルシステムでにおける絶対パスのようなもの
インポートとエイリアス
●   インポート
    namespace HolyExample;
    use ZendOAuthConsumer;
    //インポートしたクラス名 Consumer でアクセスできる
    $consumer = new Consumer();

●   エイリアス
    namespace HolyExample;
    use ZendOAuthConsumer as OAuthConsumer;
    //定義したエイリアス OAuthConsumer でアクセスできる
    $consumer = new OAuthConsumer();

※適切なクラス名を付けていれば基本的にはインポートのみで良いはず
更に詳しく知りたい方は
  PHP Manualで
    FAQもあります
オートロードとは
クラスを利用する際、自動的にそのクラスが定義されているファ
イルを読み込む機能。(require_onceが不要に)
spl_autoload_register()関数で、オートローダのコール
バックを登録することで実装できる。

spl_autoload_register(function ($className) {
    //「_」をディレクトリ区切り文字に置換してinclude
    return (bool)@include str_replace('_',
        DIRECTORY_SEPARATOR, $className) . '.php';
}, true, true);

無名関数のこんな実装でも一応動くけど、これでは名前空間に対応でき
ていないので…
PSR-0という規格
オートローダの相互運用性を確保するために、クラスの完全修飾
名とファイル名の命名規則として提案されている規格

PSR-0 Final Proposal
 - PHP Standards Working Group – 2009-11-14
http://bit.ly/8UPl4A

※Symfony, Doctrine, ZendFramework, Lithium等の主要
なPHP5.3以降専用フレームワークが対応

この仕様に従って作成しておけば、おおむね問題なし
PSR-0の仕様
重要なのはこの3点
1.必ずトップレベルに「ベンダー名」を持たせ、完全修飾名を
  「<ベンダー名>(<名前空間>)*<クラス名>」とする
2.名前空間セパレータは DIRECTORY_SEPARATOR に変換される
3.クラス名に含まれるアンダースコアは
  DIRECTORY_SEPARATOR に変換される

ZendOAuthConsumer クラス(ベンダー名:Zend)
→/project/lib/vendor/Zend/OAuth/Consumer.php

※実装例の SplClassLoader はgistに掲載されている
https://gist.github.com/221634
+αのオートローダ仕様
PSR-0準拠は最低条件として、こんな仕様も追加しました。
ベンダー名ごとに検索対象ディレクトリおよびファイル拡張子を
指定可能とする

●   架空のクラス Smorty の例
    HolyLoader::getInstance()
    ->set('Smorty',//ベンダー名
        '/project/lib/vendor/Smorty/libs',//ディレクトリ
        '.class.php')//拡張子
    ->enableAutoload();
    $smorty = new Smorty();//Smorty
    →/project/lib/vendor/Smorty/libs/Smorty.class.php
stream_resolve_include_path
             オートロードが呼ばれると、
             コールバックオートローダの引
             数にクラス名が完全修飾名で渡
             されるので、PSR-0の仕様に
             従ってファイルパスに変換し、
             インクルードパスを考慮しつつ
             ファイルを検索する必要があり
             ます。
             そこで役に立ったのが、この関
             数
             これ使えば、もう @include とか
             書かなくてもいい
             ※PHP5.3.2以降
オートロード                 こんな時に呼ばれる
namespace HolyExample;

//クラスのインスタンスを生成
$foo = new Foo(); //HolyExampleFoo

//スタティックメソッドをコール
$foo = Foo::getClass();

//クラス定数を記述
Foo::CONSTANT;

//クラス/インタフェース定義で extends, implements
class RuntimeException
  extends RuntimeException //RuntimeException
  implements Exception {} //HolyExampleException
オートロード                 こんな時に呼ばれる
namespace HolyExample;

//スタティックメソッドのコールバックを呼ぶ
call_user_func(array('HolyExampleFoo',
    'getClass'));

//class_exists(), interface_exists()で第2引数を指定しな
い、またはtrueを指定
if (class_exists('HolyExampleFoo'))

※動的にクラス名を指定する際は完全修飾名で書かないとダメ
オートロード                  こんな時には呼ばれない
namespace HolyExample;

//タイプヒンティング
public function setFoo(Foo $foo)//HolyExampleFoo

//instanceof演算子
if ($foo instanceof Foo)//HolyExampleFoo

//try-catch節
try {
} catch (Exception $e) {//HolyExampleException
}
オートロード                  こんな時には呼ばれない
namespace HolyExample;

//is_a(), is_subclass_of()
if (is_a($foo, 'HolyExampleFoo'))

//スタティックメソッドのコールバックをis_callable()
if (is_callable(array('HolyExampleFoo',
    'getClass'))//普通にis_callable()のエラーにはなる

//class_exists(), interface_exists()で第2引数にfalseを指
定
if (class_exists('HolyExampleFoo', false))

※動的にクラス名を指定する際は完全修飾名で書かないとダメ
オートロードが呼ばれないと…
try {
    //UnknownExceptionがスローされるかもしれない処理
} catch (UnkomanException $e) {//タイプミスしてる
    mail('dev@example.com', 'Unknown error',
        $e->getMessage());
}

例外がスローされた時にメールで通知するつもりが…


Fatal error:    Uncaught exception
'HolyExampleUnknownException' with message...

※そもそもこういう場当たり的な例外処理は避けた方が無難ですが
オートロードスタック
spl_autoload_register()で複数のオートローダを登録した
場合、オートロードが呼ばれたら、対象のクラスが定義された
ファイルを読み込むまで、登録された順番で実行される。
spl_autoload_register()の第3引数にTRUEを指定すると、
スタックの末尾ではなく先頭に追加できるので、複数のオート
ローダを利用する場合は優先順位で使い分けが可能。


spl_autoload_functions()でオートロードスタックの配列を
取得できるので、オートロードの処理で何かがおかしい時はこれ
で確認してみてください。
まとめ
●   名前空間は普通に使うだけなら難しくない
●   BOM付きUTF-8の罠には要注意
●   名前空間/クラス名とファイルパスの対応はPSR-0を参考に
●   try-catchやinstanceofで例外を扱う時はオートロードが
    呼ばれないのでtypoに気をつけて



拙作オートローダのコードはgistに掲載しています。
https://gist.github.com/1127033

ありがとうございました。

Weitere ähnliche Inhalte

Was ist angesagt?

initとプロセス再起動
initとプロセス再起動initとプロセス再起動
initとプロセス再起動
Takashi Takizawa
 
基幹業務もHadoopで!! -ローソンにおける店舗発注業務への Hadoop + Hive導入と その取り組みについて-
基幹業務もHadoopで!! -ローソンにおける店舗発注業務へのHadoop + Hive導入と その取り組みについて-基幹業務もHadoopで!! -ローソンにおける店舗発注業務へのHadoop + Hive導入と その取り組みについて-
基幹業務もHadoopで!! -ローソンにおける店舗発注業務への Hadoop + Hive導入と その取り組みについて-
Keigo Suda
 

Was ist angesagt? (20)

initとプロセス再起動
initとプロセス再起動initとプロセス再起動
initとプロセス再起動
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform
 
基幹業務もHadoopで!! -ローソンにおける店舗発注業務への Hadoop + Hive導入と その取り組みについて-
基幹業務もHadoopで!! -ローソンにおける店舗発注業務へのHadoop + Hive導入と その取り組みについて-基幹業務もHadoopで!! -ローソンにおける店舗発注業務へのHadoop + Hive導入と その取り組みについて-
基幹業務もHadoopで!! -ローソンにおける店舗発注業務への Hadoop + Hive導入と その取り組みについて-
 
クラウドネイティブトランスフォーメーションのススメ
クラウドネイティブトランスフォーメーションのススメクラウドネイティブトランスフォーメーションのススメ
クラウドネイティブトランスフォーメーションのススメ
 
AI x OpenCV x WebAR: Selfie Segmentationを使ってみよう
AI x OpenCV x WebAR: Selfie Segmentationを使ってみようAI x OpenCV x WebAR: Selfie Segmentationを使ってみよう
AI x OpenCV x WebAR: Selfie Segmentationを使ってみよう
 
Dep005 azure ネットワーク設計
Dep005 azure ネットワーク設計Dep005 azure ネットワーク設計
Dep005 azure ネットワーク設計
 
[GKE & Spanner 勉強会] GKE 入門
[GKE & Spanner 勉強会] GKE 入門[GKE & Spanner 勉強会] GKE 入門
[GKE & Spanner 勉強会] GKE 入門
 
Azure Monitor Logで実現するモダンな管理手法
Azure Monitor Logで実現するモダンな管理手法Azure Monitor Logで実現するモダンな管理手法
Azure Monitor Logで実現するモダンな管理手法
 
GraalVMを3つの主機能から眺めてみよう(Oracle Groundbreakers APAC Virtual Tour 2020 講演資料)
GraalVMを3つの主機能から眺めてみよう(Oracle Groundbreakers APAC Virtual Tour 2020 講演資料)GraalVMを3つの主機能から眺めてみよう(Oracle Groundbreakers APAC Virtual Tour 2020 講演資料)
GraalVMを3つの主機能から眺めてみよう(Oracle Groundbreakers APAC Virtual Tour 2020 講演資料)
 
脱RESTful API設計の提案
脱RESTful API設計の提案脱RESTful API設計の提案
脱RESTful API設計の提案
 
現実的な「WordPress on Azure App Service」 クイックスタート
現実的な「WordPress on Azure App Service」 クイックスタート現実的な「WordPress on Azure App Service」 クイックスタート
現実的な「WordPress on Azure App Service」 クイックスタート
 
Ruby on Rails の特徴とそのエコシステム
Ruby on Rails の特徴とそのエコシステムRuby on Rails の特徴とそのエコシステム
Ruby on Rails の特徴とそのエコシステム
 
Mule Runtime のアーキテクチャコンセプト紹介
Mule Runtime のアーキテクチャコンセプト紹介Mule Runtime のアーキテクチャコンセプト紹介
Mule Runtime のアーキテクチャコンセプト紹介
 
食べログのフロントエンドエンジニアってめっちゃ大変やねん・・・
食べログのフロントエンドエンジニアってめっちゃ大変やねん・・・食べログのフロントエンドエンジニアってめっちゃ大変やねん・・・
食べログのフロントエンドエンジニアってめっちゃ大変やねん・・・
 
Powershell勉強会 v5 (こちらが最新です。)
Powershell勉強会 v5 (こちらが最新です。)Powershell勉強会 v5 (こちらが最新です。)
Powershell勉強会 v5 (こちらが最新です。)
 
AWS Systems manager 入門
AWS Systems manager 入門AWS Systems manager 入門
AWS Systems manager 入門
 
世界最強のソフトウェアアーキテクト
世界最強のソフトウェアアーキテクト世界最強のソフトウェアアーキテクト
世界最強のソフトウェアアーキテクト
 
NGSI によるデータ・モデリング - FIWARE WednesdayWebinars
NGSI によるデータ・モデリング - FIWARE WednesdayWebinarsNGSI によるデータ・モデリング - FIWARE WednesdayWebinars
NGSI によるデータ・モデリング - FIWARE WednesdayWebinars
 
Spring AOP in Nutshell
Spring AOP in Nutshell Spring AOP in Nutshell
Spring AOP in Nutshell
 
ドメイン駆動設計 失敗したことと成功したこと
ドメイン駆動設計 失敗したことと成功したことドメイン駆動設計 失敗したことと成功したこと
ドメイン駆動設計 失敗したことと成功したこと
 

Ähnlich wie 5分で分かる名前空間とオートロード

10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
kenjis
 
WebAPIではじめるphp入門
WebAPIではじめるphp入門WebAPIではじめるphp入門
WebAPIではじめるphp入門
Hiroaki Murayama
 
はじめての FuelPHP
はじめての FuelPHPはじめての FuelPHP
はじめての FuelPHP
Sho A
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」
yoshiaki iwanaga
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
Hiroshi Ono
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
Hiroshi Ono
 

Ähnlich wie 5分で分かる名前空間とオートロード (20)

10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
 
10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya
 10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya 10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya
10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya
 
10分でわかるFuelPHP @ 2011/12
10分でわかるFuelPHP @ 2011/1210分でわかるFuelPHP @ 2011/12
10分でわかるFuelPHP @ 2011/12
 
あらためてPHP5.3
あらためてPHP5.3あらためてPHP5.3
あらためてPHP5.3
 
最新PHP事情 (2000年7月22日,PHPカンファレンス)
最新PHP事情 (2000年7月22日,PHPカンファレンス)最新PHP事情 (2000年7月22日,PHPカンファレンス)
最新PHP事情 (2000年7月22日,PHPカンファレンス)
 
Best practice laravel
Best practice laravelBest practice laravel
Best practice laravel
 
PHP基礎勉強会
PHP基礎勉強会PHP基礎勉強会
PHP基礎勉強会
 
ECMAScript 6 Features(PDF 版)
ECMAScript 6 Features(PDF 版)ECMAScript 6 Features(PDF 版)
ECMAScript 6 Features(PDF 版)
 
WebAPIではじめるphp入門
WebAPIではじめるphp入門WebAPIではじめるphp入門
WebAPIではじめるphp入門
 
はじめての FuelPHP
はじめての FuelPHPはじめての FuelPHP
はじめての FuelPHP
 
JavaScript (ECMAScript) 2013
JavaScript (ECMAScript) 2013JavaScript (ECMAScript) 2013
JavaScript (ECMAScript) 2013
 
大人のお型付け
大人のお型付け大人のお型付け
大人のお型付け
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」
 
リーダブルコード勉強会
リーダブルコード勉強会リーダブルコード勉強会
リーダブルコード勉強会
 
pecl-AOPの紹介
pecl-AOPの紹介pecl-AOPの紹介
pecl-AOPの紹介
 
JavaのGenericsとは?
JavaのGenericsとは?JavaのGenericsとは?
JavaのGenericsとは?
 
Task
TaskTask
Task
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 

5分で分かる名前空間とオートロード