###(はじめに、注)
この記事は 2009 年 1 月 22 日に自分のブログに書いていた記事を拾ってきて転載したものであります。
元記事
###差し込みたければ include
、利用したければ require_once
PHP には、外部のファイルを読み込む組込みの関数が複数個ある。使いわけがわからない、という声を聞くが、さほど難しくないよ、というのがここで私が主張したいこと。
結論から言えば、外部のファイルをそこに差し込みたい場合は include
を使い、外部のファイルに定義されたものを使いたい場合は require_once
を使えばよい。include_once
や require
もあるって? それらは使わなくていい。
なぜかって? それを知るためには、しばし、おっさんの無駄話を聞いてもらわねばなるまい。
###スクリプトはまさに台本 - セリフとト書き
本当はウェブアプリに限らない話なんだが、とりあえず、ウェブアプリをスクリプト言語で書くことを考えよう。スクリプト言語っていうのは、script すなわち台本を書くための言語だね。台本には「セリフ」と「ト書き」があるのはいいよね。「セリフ」ってのは役者が喋る言葉で、そのまま台本に書かれたものが観客の耳に届く。「ト書き」ってのは、状況を説明したり、役者の動作を説明したりする文章のこと。役者や裏方さんはそれを読んで解釈して、表現する。観客に届くのは台本に書かれたものじゃなくて、役者や裏方さんが解釈・表現したもの。
で、(PHP じゃない) たいていのスクリプト言語ってのは、ト書きベースなんだね。台本に書いてあるのは、「ああせい」「こうせい」というト書き。観客への表現は「『~』と言う」みたいに、『』でセリフを示した動作として書かれる。 print
とか echo
とか、そういう名前の動作命令なわけ。ト書きの中にセリフが散りばめられるからト書きベース。
それに対して、PHP ってのはセリフベースなんだ。台本には直接セリフが書いてある。台本に「こんにちは」と書いてあったら役者は「こんにちは」と言い、「こんにちは、と言う」と書いてあったら役者は「こんにちは、と言う」と言う。ト書きベースだとやるべき動作が書いてあったのに比べて、喋るべきセリフが直接書かれているのが違う。print
だの echo
だのを使わなくても、直接セリフを書けばいいんだから楽だよね。こういうセリフベースの言語には PHP の他にも、JSP や ASP やなんかがあるよ。テンプレートエンジンがどうとかっていうのも仲間と考えていいけど、まあ、それは置いとこう。
ウェブアプリで言うと観客に届く表現というのは、まあ HTML だと言ってもいいから「セリフ」は「HTML」って言ってもいい。「ト書き」は「プログラム」って言ってもいい。
###セリフベース言語でト書きを書くには
もし、セリフベースの言語で一切ト書きが書けなかったら、それはいつ、どこで上演してもまったく内容が同じ台本しか書けないことになる。でも、客層や時間帯、上演場所、役者の個性なんかによってアレンジされるのも楽しいよね。
ということで、セリフベースの言語は「こっからここまでト書きです」というふうに明示してト書きが書けるようになっている。PHP で言えば、<?php
と ?>
で囲んだところがト書きになる。<?php
があると、そこからト書きベースモードに入り、?>
があるとセリフベースモードに戻る、って考えてもいい。ともかく、ト書きベースになっているところは、元からト書きベースの言語と同じで、そこに書くべきは「ああせい」「こうせい」という動作であって、表現される内容そのものじゃない。
セリフベース言語でト書きベースモードになっているとき、print
だの echo
だのの発言命令を使って「セリフを書く」ことができたりする。ここを混乱する人がたまにいるみたいだけど、違いはわかったかな。ここ重要ね。
###さて include
, require
ここまで書いたら察しのいい人はもうわかったかもしれないね。include
ってのは「セリフベース」の命令で、require
ってのは「ト書きベース」の命令なんだ。
include
は HTML 的に考えて、「ここにこのファイルに書いておいた別の HTML を差し込む」ってことを示すものなわけ。include = 差込み、だもんね。使いどころとしては、いろんなページの HTML で共通のヘッダ部分とかフッタ部分とか、メニュー部分とか、そういうものを別ファイルにしておいて、それぞれのページから include
で差し込むようにしておく。そうすると、共通部分に変更があった場合に一つのファイルを変更するだけでいいから楽だよね。
一方、require
はプログラム的な発想で、これからやることに必要なファイルを require、要求するわけだ。で、要求される側ってのは、要求する側で使う部品とか道具についての定義が書いてあるわけだ。しょっちゅう使う部品とか道具をあちこちのファイルから使えると便利だよね。
これで、おのずと include
と require
の使いわけができるようになると思うけど、どう? include
で差し込まれるファイルは、セリフが書いてあることが想定されるよね。喋ることが求められているんだもん。一方で、require
で読み込まれるファイルは部品として使われるものが定義されているんだから、勝手に喋っちゃいけないよね。喋るってのは HTML を出力するってことね。
###さて include_once
, require_once
include_once
や require_once
ってのは、何回 include
, require
されても、最初の一回しか有効にならないよってこと。
でもさ、考えてみてよ。差込み表示したくて何回か include
するのに、最初の一回しか表示されないって変じゃない? include_once
があっても、そこに差し込まれるかどうかわからないってことだよ。変なの。なので、include_once
ってのは使いどころがないって思うわけ。include
があったら、そこに差し込まれる HTML があるんだな、って理解したほうがあとから台本を読み返したときもわかりやすいじゃない。
require
の方は、部品や道具の読込みなわけだ。これは一回どこかで require
して取り込んであれば、別のところで require
して再度取り込む必要はないわけだ。require
してあるところで毎回取り込んでいると無駄ってこと。require_once
ってのは言い換えると、「ほかのどなたがすでに取り込んでいるならそれを使わせていただきますが、そうでなければここで自分で取り込んでから使います」で、require
ってのは「ほかのだれかが取り込んでいようがいまいが、俺はこれを使うからここで取り込んで使うぜ」なのね。てことは、常に require_once
使ってたほうが無駄がないじゃない。ってことで、require
を使う積極的な理由はほとんどないんじゃないって思うわけさ。
###そこが PHP の PHP らしいところ
私の考えとしては、include_once
、require
は不要。どうせだったら、PHP の require_once
の機能を require
という名前にしちゃえばよかったのにと思う。require
したら、「ほかのどなたがすでに取り込んでいるならそれを使わせていただきますが、そうでなければここで自分で取り込んでから使います」と理解すればいいってことね。
ま、それがそうなっていないのが PHP らしいところなんだけどね。