別のphpファイルに記述されたソースコードを読み込む(requireなど)
Bitbucketのアカウントをとってみました。
そして、ソースコードの表示が……あまり見やすくならなかった(あれ?)ので、また方式を考えたほうがいいんでしょうか……。
それでは、本題。
require_onceは次から使うというより今度作ることがあったら、これを基にした設計をちゃんとしたいなと思ったので少し気合入れて調べてました。
今回参考にしたのはこちらです。
パーフェクトPHP
- 作者: 小川雄大,柄沢聡太郎,橋口誠
- 出版社/メーカー: 技術評論社
- 発売日: 2010/11/12
- メディア: 大型本
- 購入: 32人 クリック: 1,065回
- この商品を含むブログ (59件) を見る
PHPマニュアル
requireについて
http://www.php.net/manual/ja/function.require.php
includeについて
http://php.net/manual/ja/function.include.php
さて、単体の機能試しているうちはいいのですが、少し大きなものを書こうとした場合、色んなページで共通に行う処理や定数が出てきます。そういった共通部分が含まれている処理を表示するページごとに別のphpで管理していたりすると、無駄に全体のコードの分量増やしたり、修正するときに面倒くさかったりしてよろしくありません。
そういうときに、複数のページから共通して使われる関数をまとめて一つのphpに書いておいて、
require "読み込まれるphpのアドレス"
ないし、
require_once "読み込まれるphpのアドレス"
のようにrequire/require_onceの構文を使って、いま開いているphpから使いたい関数のあるphpファイルの内容を読み込むようにすることで共通機能と個別の機能が分離できて便利です。
この二つの構文は、読み込みたいphpのアドレスが間違っていたり、そのphpファイルが存在しない場合はエラーが出てその時点で実行が終了します。
_onceをつけている場合は、多数のファイルをrequireで読み込んでくるときに、一度しか同名のファイルを読み込まないようにします。
たとえば、php3からphp1とphp2を読み込むのだけれど、
php1の処理のために、php2の処理が必要なのでphp1でもphp2を読み込んでいる場合。
この場合、都合二回php2が呼び出されます。
すると、php2中の関数やclassが2回宣言されました、という旨のエラーが出て実行がとまってしまいます。
たとえば下記のような場合です。
php1.php
php2.php
php3.php
このままの状態で実行するとコメントにあるようなエラーが出ます。
php3.phpの3行目をコメントアウトしてphp3.phpからphp2.phpを読み込むのをやめるとエラーは出ません。
しかし、こんな具合にいちいち何を読み込んだか、記録したり管理するのは面倒です。
一度一つのファイルを読み込んだら、他のファイルを読み込むときにそのファイルを読み込まないようにしてくれるとありがたいです。それができるのがrequire_onceで、上のコードでrequireをrequire_onceに変更するとエラーは出なくなります。
また、別のphpファイルに記述されたコードを読む構文には、include/include_onceがあり、こちらは、ファイルがなくても処理を進めてくれます(ただし警告は出ますし、ファイルがない場合の処理も記述しておくべきだと思います)。
また、このあいだ書いてみるまで気づかなかったのですが、読み込まれるphpにおいて関数の外に命令を書いていると、読み込んだタイミングで順次実行されていきます。
たとえば、php1.phpを以下のようにかいていた場合、
冒頭にやっほー!と出力されてから上記の場合と同じようにphp3.phpの関数の出力が出てきます。
これはつまり、
require "読み込まれるphp"
と書いた場合、この部分に読み込まれるphpファイルのコードをコピーペーストした結果できる
読み込まれるphpファイルのコード
+そのphpファイルに書いてあったコード
のようになっているphpを開くのと同じ、と解釈したらいいのでしょうかね。
読み込まれたphpファイルの途中にreturnの命令を記述していても、それより後に記述した関数を利用できる(関数の外に書いた命令についてはreturnより後に記述した分はは実行されません)、ということからもそんな気がします。
なんだか秋ごろにパーフェクトphpで勉強していた頃は、関数を二回読み込んだらエラーになる、ということだけ覚えていたもので、関数だけ読み込むというふうに誤解していた節があり結構驚きました。
いまは、requireの類を使って読み込みたいようなファイルは、関数集ないし定数集みたいな感じなのだと考えています。