• ベストアンサー

ユーザ関数function の扱いについて。

おそらくは、初歩的な質問なのだろうとは思いますが、どうぞよろしくお願い致します。 早速ですが、質問に入ります。(PHP4または5での話です。) //関数を定義 function test($a){   $b = $a*100;   print $b;   return $b; } //テキトーに値を用意して変数に格納 $c = 5; //------------------------ 作った関数を使ってみる //------------------------ //(その1)関数内の処理結果をprintしてくれるものと思って使っている。 test($c); //------------------------- //(その2)関数内の処理結果の戻り値を変数$dで受け、それをprint。 //「その1」との違いを調べたくて、こんなことをしている。 $d = test($c); print $d; //------------------------------- さて、何が言いたいかと言いますと(笑)、 まず、上記(その2)に着目して頂いて、 関数定義の中でprint()を使用している関数に対し、 その定義の中にreturnがあるからと、 $dでその戻り値を受けているわけですが、 この場合、print()で出力した値は、一体、どこへ行ってしまったのでしょうか。 このような質問のしかたをしていますが、 分からないのは、この辺りの処理の流れ全体なんです。 つまり、print()したものがどうなったのかだけが知りたいわけではなく、 ユーザ関数内のprintとreturnの関係とか、そのあたりです。(笑) return; が来たら関数内の処理を抜ける、 ということは分かっています。 以上、1つずつ順を追って説明して頂けると助かります。 //-------------------補足------------ //新たに関数を定義 function test2($a){   $b = $a*100;   print $b; } $e = 5; $f = test2($e); //returnのない関数から戻り値を受け取ろうとしてもダメ //ということは、こんな私にでも分かっています。 //---------------------------- 以上、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.3

質問の意味を正確に把握できていないのですが・・・ <? function test($a){ $b = $a*100; print $b; return $b; } $c = 5; $d = test($c); print $d; ?> ってすれば、画面には 500500 って表示されますよね?なので >疑問点は、「★」の部分です。 に関しては、「普通に出力され、戻り値もある」 ということで回答になりませんか?

march4
質問者

お礼

ありがとうございました(^^) また何かありましたら、教えて下さいね。

march4
質問者

補足

こちらでもお世話になっております。 挙げて頂いた例を使って補足させて頂きます。 $d = test($c); この時点で、関数内のprint機能が働いて、文字が出力されてしまうのでしょうか? 私の頭の中のイメージ的な話になりますが、 私のイメージでは、test($c);で出されたものすべてが、$dに入ってしまうため、$d = test($c);の時点では、外の世界(つまり、$dの外)では、何もまだ起こっていない(つまり、printされるものはない)、という風に思っているのですが、これは考え方として間違っているのでしょうか。 こんな話をすると、「では、print機能はどうなった?」と問われそうですが、それは、$dの中で行われた($dの値として出力された)のでは?というように私は答えるわけです。(笑) 薄々、何が正解で、何が間違っているか、気付いてはいるのですが、 それをバシッと、どなたかに明解にまとめて頂きたくて、こんなことを話しています。(苦笑) それと、私が迷い込みそうになっている概念について、誰かに理解してもらいたい、みたいな気持ちもあります。(笑) >500500 って表示されますよね? --------考え方、その1-------------- 最初の500は、 $d = test($c); の、test($c)の中のprint機能によって生成されたものでしょうか?? 次の500は、 print $d; の中の$dの中にreturnとして返された値をprintで出力することで生成されたものでしょうか?? ------------------------------------ それとも、 ---------考え方、その2------------- 最初の500は、 print $d; の中の、$dに含まれているprint機能によって返された値を外の世界でprintされることで生成されたものでしょうか?? そして、次の500は、 print $d; の中の、returnによって返された値を外の世界でprintして生成されたものでしょうか?? ------------------------------------- この、概念、分かりますか・・・。(涙) 定義の中にprint機能があるユーザ関数(ここで言うtest();)を、 発動させて変数 $d に入れるというのがどういうことなのか理解できずにいるということです。 returnのみであれば、そのまま、test();は「値」として捉えることができ、それを変数に格納することは、私にも簡単に理解できるのですが、 returnだけでなく、print機能も含む関数を変数に格納するとは、なんぞや!!! と思えてしまうわけです。 変数に格納する式、つまり代入式を書いたら、 print機能が、$dの外の世界で発動されて、文字を出力してしまうようだが、それはなんでだぁ!!! test();で発生したものは、まずは全部 $d の箱の中に入ってくれないのかぁあああ。return,print問わず!! という、モヤモヤの叫びをなんとか、どなたか、一刀両断して下さい。(笑) もはや、回答を得たいというより、私の疑問を理解してもらいたい。 そっちの方が強いかもしれません。(笑) どうぞ、よろしくですw

その他の回答 (4)

回答No.5

print(とecho)は呼び出されたら呼び出しを行われた時点で値を出力するというPHPの制御構造になるので、それがユーザ関数内だろうが、class内のメソッドであろうが、呼び出しを行われた時点で出力されます・・・・ というのがyambejpさんが仰っている 「printはいわゆる標準出力です。 printが実行された時点で出力になります。」 を補足した内容になります。

march4
質問者

お礼

ありがとうございました(^^) また何かありましたら、教えて下さいね。

march4
質問者

補足

hogehoge78さん、またしても、ありがとうございます。 私のもだえ苦しむ様子があまりにも酷かったので、 見るに見かねて助けてくれたのでしょうね。苦笑 おかげさまで、多少救われた気がします。 「制御構造」このキーワードは何度か本などで見たことがあるのですが、それが何を意味するのか、まだ自分にはよく分かっていないのだな、そして、それは放置しておいてはいけないんだな、ということに今回気付かされたように思います。 今回の疑問は、私にはまだ、手を出すには早かったかなー、なんて思いました。笑 (質問する前に、そんな感じは既にしていたのですが、飛び込んでみたのです。その結果がこれです。玉砕。キラーン。) しかし、このままでは悔しいので、近いうちにもちろんリベンジします! 今回も、皆さん、ありがとうございました。 また迷路に迷い込みましたら、こちらに質問をさせて頂きますので、 その時には、どうかお力をお貸し下さい。

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.4

すでに概念の世界なので、納得してくれとは言い難いですが。 ある程度スキルのある方のようにお見受けできるので以下ヒントを。 printはいわゆる標準出力です。 printが実行された時点で出力になります。 バッファの関数をつかうとイメージしやすくなります。 <? function test($a){ $b = $a*100; print $b; return $b; } $c = 5; ob_start(); $d = test($c); ob_end_clean(); print $d; ?> test($c)が実行された時点で吐き出されるprintされた500は バッファでクリーンされるので $dに戻された500のみが有効で、「500」としか表示されません。 応用で、ユーザー関数の中ですべて完結しろ!というので あれば、ユーザー関数の出力をバッファしてしまえばよいので <? function test(){ ob_start(); print "hogehoge"; $x = ob_get_contents(); print "fugafuga"; ob_end_clean(); return $x; } print test(); ?> のようなやりかたになります。 この場合、バッファが有効なhogehogeは戻り値になりますが ob_get_contents後に出力されたfugafugaはバッファを破棄されて 表示対象になりません。 厳密にはhttpではバッファされながら出力するので リアルタイムで出力されるわけではないです (a) <? print "hogehoge"; sleep(5); print "fugafuga"; ?> (b) <? print "hogehoge"; flush(); sleep(5); print "fugafuga"; ?> (a)と(b)が挙動が違うことである程度イメージできると思います

march4
質問者

お礼

ありがとうございました(^^) また何かありましたら、教えて下さいね。

march4
質問者

補足

お返事が遅くなり、申し訳ありません。 急にハードルが上がったため、何度か読ませて頂きました。 が、何度読んでも、まだ私には難しい内容のようでした。苦笑 近い将来、書かれている内容をすらすら理解できるようになっていたいと思います。 ということで、これは宿題ということにしておきます。笑 回答番号NO.5のhogehoge78さんが、要点をまとめて下さったので、そちらによって、yambe.jpさんの言わんとすることを理解することができたと思っています。 私が分からなかったのは、yambe.jpさんの挙げて頂いた具体例(ob_start()などを含むコード)であって、伝えようとして下さっている内容については、恐らく理解できているように思います。(本当かw) ということなので、ひとまず、長いものに巻かれる気持ちで、 ぼんやりと分かった気になろうかと思います。笑 もう少し明確に自分の中で何が分からないか分かるようになったら、そして、それを伝えるだけの技量を身につけられたら、再度リベンジするかもしれませんが、その前に、この宿題を解いてから、にするつもりです。 では、また何かありましたら、よろしくお願い致します。 (たぶん、別の話題で、coming soon. 苦笑)

  • x_jouet_x
  • ベストアンサー率68% (162/236)
回答No.2

変数のスコープというものをご存知ですか? 変数のスコープとは変数が参照される(できる)範囲のことを言い、通常ユーザ定義関数内で定義された変数のスコープはその関数内部のみです。 ---------- //関数を定義 function test($a){   $b = $a*100;   print $b;   return $b; } ---------- 上記にある変数 $b は関数 test() 内で定義された変数なので、変数 $b のスコープはこの関数のみに限定されます。この変数のように、ある関数内に範囲が限定されているスコープを「ローカルスコープ」と言います。 つまり、関数 test() が呼び出される度にローカルスコープ変数 $b が初期値 $a*100 で作られます。 "print $b;" の命令文は変数 $b のスコープ内なので当然参照可能で、"return $b;" の命令文も同様にスコープ内なので関数 test() の返り値になります。 ---------- $d = test($c); print $d; ---------- 次に上記の処理についてです。 変数 $d はグローバルスコープと呼ばれ、PHPプログラム全体から参照可能です。 "$d = test($c);" の命令文は関数 test() の返り値を変数 $d に「代入」していることになります。 > この場合、print()で出力した値は、一体、どこへ行ってしまったのでしょうか。 上記をふまえてこの質問への回答ですが、関数 test() 内に記述された print() で出力した値はその変数のスコープがローカルであるため関数の処理が終了した時にその値は失われます。 一方、 $d = test($c); print $d; のようにグローバルスコープの変数に代入した値はプログラムが終了するまでその値は失われません。

参考URL:
http://www.php.net/manual/ja/language.variables.scope.php
march4
質問者

お礼

ありがとうございました(^^) また何かありましたら、教えて下さいね。

march4
質問者

補足

さて、どう補足しましょう。 スコープの意味については、恐らく私は理解できていると思います。 説明頂いた内容をすらすらと問題なく頷きながら読むことができたからです。 ただ、スコープの説明が全く無駄だったかと言うとそうではなく、 おかげさまで、自分が何が分かっていないかを絞り込むことができたという意味で、大変有益であったと思っています。 今回頂いた回答を読み、私が疑問に思っているモヤモヤした部分が多少ではありますが明確化してきたので、その辺りについて書き加えてみます。 更なる回答をもし頂けるのであれば、参考にして頂けると嬉しいです。 functionの種類をここで3つに大別してみます。 大別の基準は、私の疑問と関係のありそうな視点で行っています。 (多少、説明文の中に不適切な言い方があるかもしれませんが、想像力で補完して理解して下さい。涙) //----------------------------------------------- タイプ1:func1(); function定義の中に、printやechoなどの、文字を出力する要素のみあり、returnなどの値を返す要素のない関数 タイプ2:func2(); function定義の中にreturnのみあり、値を返すだけの関数 タイプ3:func3(); タイプ1とタイプ2の両方を含む関数(ただし、returnは一番最後に記述) //----------------------------------------------- //========タイプ1-1=========== //printやecho等が働き、何かしら、文字を出力します。(と私は思っています。) func1(); //--------タイプ1-2----------- //returnがないので、値は渡しません。(と私は思っています。) //★この場合、printやechoの処理はどう扱われるのでしょうか?? $x = func1(); //========タイプ2-1=========== //これだけでは、何も起こりません。(と私は思っています。) func2(); //--------タイプ2-2----------- //returnの部分が、$xに値を渡す働きをします。(と私は思っています。) $x = func2(); //========タイプ3-1=========== //printやecho等が働き、何かしら、文字を出力します。(と私は思っています。) //return;によって返された値は、ここでは活かされることはありません。(と私は思っています。) func3(); //--------タイプ3-2----------- //★この場合、printやechoの処理はどう扱われるのでしょうか?? //returnの部分が、$xに値を渡す働きをします。(と私は思っています。) $x = func3(); //============END=============== 疑問点は、「★」の部分です。 そして、その背景にある仕組みなのだと思います。 ※(と私は思っています。)という所で、もし、間違いがありましたらご指摘下さい。 以上で、多少モヤモヤしていたものが、カクカクしてきたかなと思いますが、 どうでしょう?(苦笑) それでは、引き続き、どうぞよろしくお願い致します。

  • mizutaki
  • ベストアンサー率33% (111/333)
回答No.1

printの引数というのはApacheから出力するデータになります。 例えfunctionだろうとclassだろうと何だろうとprintを実行したらApacheから出力して、結果はブラウザなどに表示されます。 こういう意味の話でしょうか?

march4
質問者

お礼

ありがとうございました(^^) また何かありましたら、教えて下さいね。

march4
質問者

補足

ん~、ちょっと、物足りない感じです。 どこがどう、と言われましても難しいんですけどもね。。^^; 上の回答に対して補足をさせて頂きますので、そちらも参考にして下さい。 わざわざ、ご意見下さりありがとうございました。

関連するQ&A