- ベストアンサー
includeとinclude_onceの使い分け
- includeとinclude_onceの違いについて説明します。
- includeとinclude_onceの機能や使い方について詳しく解説します。
- 何度も同じファイルを読み込む場合や、一度だけ読み込ませたい場合には、includeとinclude_onceの使い分けが重要です。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
以下のコードは問題なく動作します。 但し、require_once を require に書き換えると動作しません。 このようなシーンでは once つきの呼び出しが必須であると言えるでしょう。 【A.php】 <?php class A { } 【B.php】 <?php require_once "A.php"; class B extends A { } 【C.php】 <?php require_once "A.php"; class C extends A { } 【main.php】 <?php require "B.php"; require "C.php"; $b = new B; $c = new C; 一応以下のように書き換えれば動作するようになりますが、 使用する側で依存関係を把握するのは大変なので出来れば避けたいですよね。 【A.php】 <?php class A { } 【B.php】 <?php class B extends A { } 【C.php】 <?php class C extends A { } 【main.php】 <?php require "A.php"; require "B.php"; require "C.php"; $b = new B; $c = new C; オートロードを使えばこの問題は鮮やかに解決します。 【A.php】 <?php class A { } 【B.php】 <?php class B extends A { } 【C.php】 <?php class C extends A { } 【main.php】 <?php spl_autoload_register(function ($class) { require "{$class}.php"; }); $b = new B; $c = new C;
その他の回答 (3)
- notnot
- ベストアンサー率47% (4900/10358)
シンプルに回答します。 定数やクラスの定義ファイルなどは一度しか読み込んで欲しくない。 しかしincludeやrequireの絡み合っている場合に、_once機能がないと一度だけ読み込むように自分でif文などで制御しないといけない(Cをご存じであれば、システム系のincludeライブラリが内部でこういうif文による制御をやっているのをご存じと思います)。 include_onceを使うとこれが1回目だとかを気にせずに書ける。 >・あえて何度も記述しながら 意図的にinclude_onceを複数回書くケースはないでしょう。あくまで、複雑な依存関係の中で一度だけincludeしたい場合の話。 Cの例: #ifndef _STDIO_H #define _STDIO_H 1 一度だけしかよんで欲しくない中身 #endif 「定義ファイルとかならinclude_onceでなく、require_onceを使うだろう。ファイルがなくてもエラーにならないincludeをあえて使うケースでのonce有り無しの使い分けを聞いているんだ」ということであれば上記回答は的外れです。 私見では、そもそもinclude/include_onceなどという機能があることを忘れて、require/require_onceだけを使えば良いと思いますよ。
お礼
>意図的にinclude_onceを複数回書くケースはないでしょう。 >あくまで、複雑な依存関係の中で一度だけincludeしたい場合の話。 なるほど。やはりNo.3の方のコードのようなケースという事ですかね。 ありがとうございました
補足
実は元は「requireとrequire_once」の違いが疑問でした。 しかし「requireとrequire_once」の違いを知ろうとrequire_onceのページを読むと PHP: require_once - Manual http://www.php.net/manual/ja/function.require-once.php # _once の振る舞い、およびそれが _once なし版とどのように異なるのか # についての情報は、 include_once のドキュメントを参照ください。 とあるので、質問をinclude/include_onceをベースにしました。 なので >ということであれば上記回答は的外れです。 ということはないです。むしろ意図をよく汲み取っていただいています。 >「定義ファイルとかならinclude_onceでなく、require_onceを使うだろう。 >ファイルがなくてもエラーにならないincludeをあえて >使うケースでのonce有り無しの使い分けを聞いているんだ」 とまでは考えていなかったのですが、考えてみると例えばページの上下に同一のメニューバーのようなものを表示したい時にはincludeですね。そう考えるとinclude_onceってどういうときに使うんだと、言われて今疑問に思って来ました。 >私見では、そもそもinclude/include_onceなどという機能があることを忘れて、 >require/require_onceだけを使えば良いと思いますよ。 と書いてあることから、require, require_once, include, include_onceの4つを考えると、include_onceは特に役割が不明な関数という事ですかね。 なるほど。ありがとうございました
【once 有りと無しの違い】 前者は同名のファイルをスクリプト実行中1回しか読み込もうとせず、2回目以降は無視される。後者は何回でも読み込まれる。前者は少し記憶コストがかかる。 【include と require の違い】 前者は読み込みに失敗したとき Warning を発生して処理を継続する。後者は Fatal Error を発生して処理を停止する。 使い分けは以下のような感じでどうぞ。 【クラスや関数のみを定義しているファイル】 require_once が最もオススメ。規模が膨大でコストを気にする場合は require でもOK、但しこの場合は spl_autoload_register 関数などを使ってオートロードで読み込むことを推奨。 【HTMLの一部分を表示させたりするファイル】 include が最もオススメ。但しPHPコードを含まない場合は readfile 関数という選択肢も考えられる。
お礼
>【クラスや関数のみを定義しているファイル】 >require_once が最もオススメ。 >spl_autoload_register 関数などを使ってオートロードで読み込むことを推奨。 > >【HTMLの一部分を表示させたりするファイル】 >include が最もオススメ。 この辺はあまり考えていませんでした。参考になりました。 ありがとうございました
補足
質問は「includeとinclude_onceの使い分け」です。 パターンでいうとこういうことだと思うのですよ。 (0)1度だけ必要なので、1度だけincludeする (1)必要なのは1度だけだが、あえて複数回includeする。このときエラーを防ぐため2度目以降の呼び出しではinclude_onceと書く。 (2)複数回必要だから、複数回includeする。 (0)は普通のことですよね。本来こうすべきだと思います。でもincludeとinclude_onceの両方が用意されているということはその意味を考えると、(1)(2)ともにありうるのではないかと思います。 でも、それってどういうときか分からない、実際どういう場合なの?という疑問が今回の質問です。 しかし、それは考えすぎでもしかすると >前者は少し記憶コストがかかる。 本当にここだけなんですかね。once付はコストがかかるので基本的にはonce無しを使うべき。しかし「よくわかんないからいろんなところにincludeを書いちゃった。けど、本当は使うの1回でいいんだよね、消すのもめんどくさいんだよね」、みたいなときにonce付を使うということなのでしょうか。once付の存在意義は簡単に言うと面倒くさがり屋さんのためにあるという感じなのでしょうか? この辺について、もしよろしければ教えてください。 よろしくお願いします。
- kosukejlampnet
- ベストアンサー率44% (126/282)
function や class , 定数などは同じ名前で定義できませんね。 例えば、 -- includedfile.php <?php class Test { private $_strTest = ''; } -- includedfile2.php <?php include('includefile.php'); class TestExt extends Test { private $_strTest2 = ''; } -- index.php <?php include('includedfile.php'); include('includedfile2.php'); 実際に動かしてみてください。 こんな風にインクルードが多重に読み込まれていた場合、クラスが同名で定義されてしまっても include_once を使っているとエラーになりません。
お礼
ありがとうございました
補足
>こんな風にインクルードが多重に読み込まれていた場合、 >クラスが同名で定義されてしまっても >include_once を使っているとエラーになりません。 おっしゃっていることは一応分かります…。 私は他の言語の経験はありますがPHPは全く経験がありません。その範囲での常識感覚では、以下のように書くべきだと思うのですが。 -- index.php <?php include('includefile2.php'); 特に無駄な記述を排除するために・重複を検知するためにもincludeと書いた方がいいようにも思えます。 違うのですかね。私には「include('includefile.php');」をあえて複数回書く理由が分かりませんでした。PHPでは実際には読み込んでほしくないincludeでも何度も書く伝統があるのでしょうか? もしかして、大規模開発になると何が何を呼んでいるのかわからなくなって、必要か不用か分からないけどとりあえずいろいろincludeしとけみたいなソースになることがあたりまえという感じだからなのですかね? この辺について、もしよろしければ教えてください。 よろしくお願いします。
お礼
あーなるほど。 メインからはrequireで、 メインから呼ばれるファイルではrequire_onceで というポリシーで書き分ければきれいですね。 あとTo_aru_Userさんのコードをみると ・極力requireで書く。 ・複数回読み込んでしまう可能性がある部分について、 意識してrequire_onceで書く。 という一貫したポリシーが伝わってきて参考になりました。 ありがとうございました
補足
実はこの質問のきっかけはSmartyのドキュメントのサンプルコードで 基本的なインストール | Smarty http://www.smarty.net/docs/ja/installing.smarty.basic.tpl 拡張セットアップ | Smarty http://www.smarty.net/docs/ja/installing.smarty.extended.tpl 「基本的なインストール」のページでは、すべてのサンプルで一貫してrequire_onceを使用し 【main.php】 <?php require_once('Smarty.class.php'); などとしているのに対し、 「拡張セットアップ」のページでは、一貫してrequireを使用しており 【main.php】 <?php require('guestbook/setup.php'); 【setup.php】 <?php require('Smarty.class.php'); class Smarty_GuestBook extends Smarty { 「この差は何なんだ、意味があるのか?」と思ったのがきっかけでした。 また、Smartyのドキュメント以外のサイトで見かけるサンプルコードでも、特に意味なくとりあえずrequire_onceを書きまくっているように見えるコードもあって、使い方がよく分からない状態でした。 しかしこの質問で、かなり把握できました。またおそらくこの世のPHPのコードでは、あまり考えずに使ってしまっているものも少なくないのかなとも思いました。 ありがとうございました