2016年6月15日水曜日

PHPのnamespace と useについて






PHPのライブラリなどで
useやnamespaceといった記述を見かけます。
一体何なんだこれ?
理解しておく必要がありそうです。
理解を深めるためにもまとめておきたいと思います。



namespaceの利用が役立つとき

別なファイルのインスタンスに同じ名前のインスタンスが
ある場合の衝突を避けることができます。


use の利用が役立つとき

namespaceが長い場合
記述画面どうなのでエイリアスを作成し参照できるようになります。


実例をと思いましたが。
簡潔にわかりやすく記載してくれているページがありました。

引用

namespaceを使わない場合に起こりえる問題点を示します。

2つのPHPファイル、lib1.phpとlib2.phpがあるとします。この2つのファイルにはそれぞれFooというクラスと、get_fooというメソッドが定義されていたとします。

・lib1.php

<?php
class Foo {
    public function get_foo() {
        return 'lib1.foo';
    }
}

・lib2.php

<?php
class Foo {
    public function get_foo() {
        return 'lib2.foo';
    }
}

ここで、これらの2つのPHPファイルを読み込んで、Fooクラスのインスタンスを生成してget_fooメソッドを実行してみます。

<?php
require_once 'lib1.php';
require_once 'lib2.php';
$foo = new Foo();
echo $foo->get_foo() . "\n";

すると、以下のようにFatal errorが発生します。

Fatal error: Cannot declare class Foo, because the name is already in use in .../lib2.php on line 3

要は、lib1.phpでFooクラスを定義していて、lib2.phpでもFooクラスを定義しているから、クラス名が重複していて怒られているんですね!

解決方法: namespaceを利用

それでは、先ほどのクラス名が衝突した問題点を、namespaceを使って解決してみます。そのために、lib1.phpとlib2.phpに、namespace xxx;という行を追加します。

・lib1.php

<?php
namespace Lib1;  // これを追加
class Foo {
    public function get_foo() {
        return 'lib1.foo';
    }
}

・lib2.php

<?php
namespace Lib2;  // これを追加
class Foo {
    public function get_foo() {
        return 'lib2.foo';
    }
}

そして、これら2つのファイルを読み込んで、先ほどと同様にget_fooメソッドを実行してみます。

先ほどの例だと、Fooクラスのインスタンスを生成するときに、$foo = new Foo();としました。今回は、lib1.phpとlib2.phpにnamespaceを追加したので、lib1.phpのFooクラスのインスタンスを生成は$foo = new Lib1\Foo()と書くことができます。また、lib2.phpのFooクラスのインスタンスは$foo = new Lib2\Foo()で生成できます。

<?php
require_once 'lib1.php';
require_once 'lib2.php';
// $foo = new Foo();
$foo = new Lib1\Foo();
echo $foo->get_foo() . "\n";  // 「lib1.foo」と出力します。

$foo = new Lib2\Foo();
echo $foo->get_foo() . "\n";  // 「lib2.foo」と出力します。

つまり、lib1.phpとlib2.phpにnamespaceを指定したので、同じFooクラスでも、Lib1というnamespace(名前空間)に属するFooクラスと、Lib2というnamespaceに属するFooクラスで、区別できるようになったということです。これで、クラス名の衝突による問題は解決できました!

useでエイリアスを作成

最後にuseを使用してみます。その前に、lib1.phpを修正します。具体的には、namespaceを長くして、Foo2クラスとFoo3クラスを追加してみます。(※これ以降、lib2.phpはでてきません。)

・lib1.php

<?php
namespace Foo\Bar\Baz\Lib1;  // 長い。。。
class Foo {
    public function get_foo() {
        return 'lib1.foo';
    }
}

class Foo2 {
    public function get_foo() {
        return 'lib1.foo2';
    }
}

class Foo3 {
    public function get_foo() {
        return 'lib1.foo3';
    }
}

先ほどのnamespaceの例のように、lib1.phpを読み込むと、FooクラスはFoo\Bar\Baz\Lib1\Foo、Foo2クラスはFoo\Bar\Baz\Lib1\Foo2、Foo3クラスはFoo\Bar\Baz\Lib1\Foo3でアクセスすることができます。

<?php
require_once 'lib1.php';
$foo = new Foo\Bar\Baz\Lib1\Foo();
$foo2 = new Foo\Bar\Baz\Lib1\Foo2();
$foo3 = new Foo\Bar\Baz\Lib1\Foo3();
echo $foo->get_foo() . "\n";  // 「lib1.foo」と出力します。
echo $foo2->get_foo() . "\n";  // 「lib1.foo2」と出力します。
echo $foo3->get_foo() . "\n";  // 「lib1.foo3」と出力します。

なんだか、Foo\Bar\Baz\Lib1\がいっぱい出現して、面倒な感じですよね。。。

ここで登場するのがuseです。useを使うと、Foo\Bar\Baz\Lib1というnamespace(名前空間)のエイリアスを作成し、Lib1で参照できるようになります!先ほどのコードはuseを使って、以下のように修正できます。

<?php
require_once 'lib1.php';
/*
$foo = new Foo\Bar\Baz\Lib1\Foo();
$foo2 = new Foo\Bar\Baz\Lib1\Foo2();
$foo3 = new Foo\Bar\Baz\Lib1\Foo3();
*/
use Foo\Bar\Baz\Lib1 as Lib1;  // Foo\Bar\Baz\Lib1を、Lib1で参照できるようにエイリアスを作成します。
$foo = new Lib1\Foo();
$foo2 = new Lib1\Foo2();
$foo3 = new Lib1\Foo3();
echo $foo->get_foo() . "\n";  // 「lib1.foo」と出力します。
echo $foo2->get_foo() . "\n";  // 「lib1.foo2」と出力します。
echo $foo3->get_foo() . "\n";  // 「lib1.foo3」と出力します。

useを使ってエイリアスを作成したら、コードがすっきりしました!

ちなみに、この例だとuseのas以降を省略することもできます。(※asを使うと、作成するエイリアスの名前をLib1以外にすることができます。)

// use Foo\Bar\Baz\Lib1 as Lib1;
use Foo\Bar\Baz\Lib1;

また、エイリアスでnamespaceだけではなくて、クラスなどのエイリアスも作成することができます。

use Foo\Bar\Baz\Lib1\Foo;
use Foo\Bar\Baz\Lib1\Foo2;
use Foo\Bar\Baz\Lib1\Foo3;
// PHP7以降は以下の記述も使えます。※asの省略も可能です。
// use Foo\Bar\Baz\Lib1\{Foo as Foo, Foo2 as Foo2, Foo3 as Foo3};
$foo = new Foo();
$foo2 = new Foo2();
$foo3 = new Foo3();


引用:https://remotestance.com/blog/3064/

2016年6月7日火曜日

人形町、小伝馬町で500円で食べれるランチのお店



常連として通っていた
さくら水産が日本橋近辺からなくなってしまいました。
残念です。
価格が500円というのは財布に優しいランチでした。

さくら水産に変わる500円以内で食べれるランチのお店は
日本橋界隈にはまだ幾つかあるようなので、
記録として残していきたとおもいます。


カフェクローバー

日替わりのランチが500円です。
ドリンクもサービスしてくれます。
店内の雰囲気がなごめます。
休日も営業してほしいです。
東京都中央区日本橋馬喰町1-5-6 ツカキビル
http://tabelog.com/tokyo/A1302/A130204/13139446/

カフェクローバー2

日替わりのランチが500円です。
ドリンクもサービスしてくれます。
カフェクローバーと同じく店内の雰囲気がなごめるところです。
浜町公園の近くなので静かでゆったりしています。
東京都中央区日本橋浜町2-44-4 2F
http://tabelog.com/tokyo/A1302/A130204/13152931/


とりいちず人形町店

2016年6月3日にオープン!
さくら水産があった場所にできた居酒屋です。唐揚げのランチが500円でたべられます。
とても美味しいです。
ランチメニューは唐揚げばかりなので、
毎日行くのはあきてしまいますが週1では行きたくなる味です。

東京都中央区日本橋人形町3-7-10日本橋DOLL-3 B1
http://tabelog.com/tokyo/A1302/A130204/13195390/


肉い奴

純レバ丼とホルモンの丼が500円でそれぞれたべれました。
野菜や味噌汁は別途支払いがひつようです。
東京都中央区日本橋小伝馬町3-6
http://tabelog.com/tokyo/A1302/A130204/13184395/


あぐらし

500円ランチがあります。
13時くらいに3回いきましたが、3回とも終了していました。
早めに行かないと食べれないことがおおいかもしれません。
東京都日本橋小舟町9-4 イートピア日本橋小舟町ビル 2F
http://tabelog.com/tokyo/A1302/A130204/13158861/

関連時事

人気の投稿