質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

3回答

256閲覧

このコードの引数はエラーにならない?

kyoppyy

総合スコア6

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

1グッド

2クリップ

投稿2017/11/07 14:29

https://qiita.com/ritukiii/items/de30b2d944109521298f#%E3%81%9D%E3%81%93%E3%81%A7%E3%82%88%E3%81%86%E3%82%84%E3%81%8Fdi%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A

このサイトのcontainer.phpに質問があります。

$container['file.logger'] = $container->protect(function($logFileName) { return new FileLogger($logFileName); }); $container['twitter.manager'] = function ($c) { $logger = $c['file.logger']('twitter_manager.log'); return new TwitterManager($logger); }; $container['database.authenticator'] = function ($c) { return new DatabaseUserAuthenticator(); }; $container['sample'] = function ($c) { return new Sample($c['file.loggger']('sample.log'), $c['twitter.manager'], $c['database.authenticator']); };

こんな風にプログラムを書いてますが、その下で

$sample = $container['sample'];

としています。

これだと

$container['sample'] = function ($c) { return new Sample($c['file.loggger']('sample.log'), $c['twitter.manager'], $c['database.authenticator']); };

$cに何も入らないんじゃないかと思うんですが、なぜこんな風になっているんでしょうか?

ためしに

<?php $container['sample'] = function ($c) { var_dump("test" . $c); return "Hello" . $c; }; $test = $container['sample']; var_dump($test); ?>

と書いて実行しましたが、

object(Closure)[1] public 'parameter' => array (size=1) '$c' => string '<required>' (length=10)

となりました。
クロージャが返されたのはわかるんですが、**なんで$cに<required>という文字が入ってるんでしょうか?**普通nullとかになると思ったんですが....
あと、**sampleの関数の中のvar_dumpが実行されていないようで、何も出力されませんでした。**これもなぜなのかわからないです。

そして、引数をあげるとどっちもちゃんと動いていました

<?php $container['sample'] = function ($c) { var_dump("test" . $c); return "Hello" . $c; }; $test = $container['sample']("Hello"); var_dump($test); ?>
string 'testHello' (length=9) string 'HelloHello' (length=10)

質問のところを太字にしました
初心者ですが、よろしくお願いします

namimon👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

参考にされている記事は一見、インスタンスの生成を配列で取り回しているように見えるかもしれません。
ですが実際にはDIコンテナとしてPimpleというライブラリが使用されています。
おそらく質問者さんのコードではPimpleを使用せずに配列を使っているのではないでしょうか。

php

1use Pimple\Container; 2 3// Pimple\Containerのインスタンスを生成 4$container = new Container(); 5 6() 7 8// キー(添え字)を指定して代入 9$container['sample'] = function ($c) { 10 return new Sample($c['file.loggger']('sample.log'), $c['twitter.manager'], $c['database.authenticator']); 11}; 12 13() 14 15// キー(添え字)を指定して取り出し 16$sample = $container['sample'];

元記事の$containerは配列ではなく、Pimple\Containerクラスのインスタンス(オブジェクト)になります。
本来オブジェクトは配列のようにキーを指定して、値を出し入れすることはできませんが、
Pimple\ContainerクラスはArrayAccessというインターフェイスを実装しているためこれが可能になっています。

ArrayAccessが実装されたオブジェクトに配列として代入を行うとoffsetSetというメソッドが呼び出されます。
Pimpleでは代入された無名関数をprivate変数の配列に格納しています。
逆に配列として値が取り出される際にはメソッドoffsetGetが呼び出されます。
格納しておいた関数を取り出して、コンテナ自身を引数に実行しています。

php

1$raw = $this->values[$id]; // 無名関数を取り出して、 2$val = $this->values[$id] = $raw($this); // コンテナ自身を引数に実行

値を取り出すだけで処理が実行されるのはコンテナがArrayAccessを実装したクラスだから。
引数$cが渡って来るのはメソッドoffsetGet内でそう書かれているためというのが回答になります。

参考

PHP: ArrayAccess - Manual
http://php.net/manual/ja/class.arrayaccess.php

Pimple\Container::offsetSet
https://github.com/silexphp/Pimple/blob/master/src/Pimple/Container.php#L79

Pimple\Container::offsetGet
https://github.com/silexphp/Pimple/blob/master/src/Pimple/Container.php#L98

投稿2017/11/07 18:49

nnssn

総合スコア1221

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

文章で説明するのちょい難しいですが、

本来の振る舞いと違うかもしれませんがニュアンス的には、Closureクラスの__debugInfoがそのような出力をしているっていうだけのはずです。

<required>って入ってる理由は必要な引数ですよって言うことを出力で分かるようにしているだけになり、
そしてClosureを実行したわけではないのでsampleの関数の中のvar_dumpが実行されません。

投稿2017/11/07 16:24

rururu3

総合スコア5545

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

php

1var_dump($test('wow'));

としてみると理解しやすいかもしれません。
あしからず。

投稿2017/11/07 16:42

ooeok

総合スコア469

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問