include、requireのパス指定をdirname(__FILE__)、__DIR__と書く理由
2017/03/07
include、requireの一番いいパス指定の仕方の解説
include、requireの一番いいパス指定の仕方
PHPのプログラムで、外部ファイルを読み込む際には、require、include、require_once、include_onceを利用します。
その際、読み込むファイルのパスの記述の仕方によっては不具合の原因となりますので、不具合を生まない記述をしておく必要があります。
具体的には下記の様に指定します。
1 2 |
require ( dirname ( __FILE__ ) . '/path/file.php'); require ( __DIR__ . '/path/file.php'); |
なぜこのような指定をするかの解説を行います。
requireの他、include、require_once、include_onceとありますが、いずれもファイルのパス指定方法は同じですので、ここでは「require」で話を進めていきます。
require ( dirname ( __FILE__ ) . '/path/file.php')
と指定する理由
1 2 |
require ( dirname ( __FILE__ ) . '/path/file.php'); require ( __DIR__ . '/path/file.php'); |
requireのパス指定を上記のようにする理由
他のファイルから呼び出された場合でも正確にパスの位置を指示できるようにするため
です。
下記のような相対パスでの書き方をすることもできますが、この書き方では不具合が発生する場合があるからです。
require ( './path/file.php');
include、requireで相対パスが問題を発生させる場合の例
/file_1.php
/lib.php
/dir/file_2.php
という構造のファイルがあるとします。
file_1.php の中身は下記のような内容です。
1 2 3 |
<?php require ( './lib.php' ); ?> |
file_2.php の中身は下記のような内容です。
1 2 3 |
<?php require ( '../file_1.php' ); ?> |
この場合、file_1.phpを実行した場合は何の問題もなく実行されます。
ですが、file_2.phpを実行した場合は、下記のエラーが表示され処理が止まります。
————-
Warning: require(./lib.php): failed to open stream: No such file or directory in C:\xampp\htdocs\test3.php on line 3
Fatal error: require(): Failed opening required ‘./lib.php’ (include_path=’.;C:\xampp\php\PEAR’) in C:\xampp\htdocs\test3.php on line 3
————-
エラーになる理由は、requireで呼び込まれる際のパスは、「file_1.php」からのパスではなく、処理が実行されている「file_2.php」からのパスとして処理されるからです。
そのため、「file_1.php」の時のパスは「./lib.php」でいいのですが「file_2.php」の時は「../lib.php」となる必要があるためにエラーとなってしまいます。
include、requireのパス指定で問題を解消する方法
相対パスで指定した場合に発生する問題を解消するための書き方として、下記のいずれかの方法で絶対パスでファイルを指定する必要があるのです。
1 2 3 4 5 |
// プログラムファイルの場所から指定する場合 require ( dirname ( __FILE__ ) . '/path/file.php'); require ( __DIR__ . '/path/file_name.php'); // サーバのドキュメントルートから指定する場合 require ( $_SERVER['DOCUMENT_ROOT'] . '/path/file.php'); |
こうすることで、どこにあるファイルから読み込まれても「dirname ( __FILE__ )」によって「file_1.php」の場所が絶対パスで指定されることになりますので、エラーになることがなくなるのです。
また、「__FILE__」などの定数や、「$_SERVER[‘DOCUMENT_ROOT’]」の環境変数を使って絶対パスを指定することで、サーバが変わった場合でも不具合の原因になることを防いでくれます
「dirname ( __FILE__ )
と __DIR__
の違い」については後述しています。
ちなみに、ファイルがあるフォルダより親のフォルダを経由して指定する場合は、下記のような指定も可能です。
1 2 |
// プログラムファイルの場所から指定する場合 require ( dirname ( __FILE__ ) . '/../path/file.php'); |
include、requireでその他のパス指定方法の問題点の解説
絶対パスで指定する場合
require ( ‘/root/path/file.php’ );
もうすでに先に書いてしまいましたが、このように直接絶対パスで書くことで、相対パスで記述した時のような他のファイルから呼び出された場合の不具合は発生しません。
ですが、サーバが変った場合は、サーバの構成の違いによっては絶対パスが変わってしまう場合がありますので、不具合の原因になります。
絶対にサーバが変わらないという場合はこの書き方でも問題ありませんが、わざわざこの方法を採用するメリットがありませんね。
パスを指定しない指定方法
require ( ‘path/file.php’ );
相対パスの指定の仕方とあまり変わらないように見えますが、「path」の前の「/」「./」などを書かずに指定する方法も設定できます。
実は、この方法では、相対パスの際に発生したような「file_2.php」から読み込むときのエラーも発生しません。
理由は、パスを指定しないことで PHPが勝手にファイルを探してくれるためです。
ですが、この方法は PHPがファイルを探す時間がかかってしまいます。
この方法の指定では、php.iniの include_pathに設定してあるディレクトリの中にある「path」ディレクトリから「file.php」を探す処理が実行されます。
そのため、php.iniの include_pathに複数のディレクトリが指定してあるとそれらのディレクトリが検索されますので、その分余計な処理が増えることになります。
requireの記述が数ヶ所程度であれば気にする必要がない差だとは思いますが、requireの記述が多いと下記の様に 3倍も処理スピードが変わる場合もあるようです。
http://dqn.sakusakutto.jp/2013/05/php_require_once_include_once_include_path.html
パスを指定するだけで処理が早くなるわけですので、これまた指定しないメリットがありませんね。
dirname ( __FILE__ )
と __DIR__
の違い
dirname ( __FILE__ )
と
__DIR__
の実行結果は同じです。
どちらを使っても問題ありませんが「__DIR__
」を使っておきましょう。
「__DIR__
」の方は PHP 5.3から追加されたものです。
そのため、今後は「__DIR__
」の書き方が主流になっていくと思いますが、以前に書かれたプログラム、もしくは、それを元にして書かれたプログラムは、今でも「dirname ( __FILE__ )
」が使われているということになるのでしょう。
ただ、PHP 5.2以前のサーバでも使われるような汎用的なプログラムを作成する場合は「dirname ( __FILE__ )
」を使っておくという判断もあるでしょう。
include や require で読み込んだ値をバッファリングする方法
include や requireで読み込むファイルの中に標準出力命令(echoや print)がある場合や HTMLファイルである場合は、include や requireが記述されている場所にそのまま標準出力されてしまいます。
そのため、include や requireは記述する場所が固定されてしまいます。
これを自由な場所に編集する方法の一つとして、標準出力をバッファリングする関数 ob_start()が用意されています。
このバッファリング関数 ob_start()については「PHP関数ob_start、ob_get_contentsで標準出力をバッファリング・変数に代入」に記事を書いていますので参考にしてください。
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
-
PHPで特定の日間の日付を for、strtotimeで表示する
ある特定の間の日付の情報を for文、strtotimeを使って作成し、その解説をしています。
-
-
ECCUBEの注文完了画面注文番号と商品情報を編集するCRITEO(クリテオ)タグを編集
ECCUBEの注文完了画面にクリテオのタグを編集する方法を紹介。標準機能では完了画面に注文IDや購入商品の情報を渡さないため改修が必要です。
-
-
ECCUBEでカード決済NGの受注情報をマイページ購入履歴に表示しない方法解説
ECCUBEでカード決済に失敗しても購入履歴一覧に注文情報(受注情報)が表示される問題への対処方法を解説。受注情報レコードの作成の流れとステイタスについても解説。
-
-
ファイル変更だけ!ECCUBEの本番から開発環境をコピーする手順を解説
ECCUBEを本番から開発環境をコピーする際の手順を解説。PGMメンテに必要な開発環境を構築する手順を解説。ECCUBEの仕組みは簡単なので作業は5分ほど。
-
-
Smartyの Syntax Errorの原因はスペースかも
Smartyのなかなか原因がつかめない Syntax Errorの原因はスペースかもしれません。
-
-
路線・駅検索をPHPで実装する方法解説。GoogleMapsの緯度経度から計算し検索
路線・駅検索の仕組みの構築は大変。登録する側も最寄り駅が多い場合は大変。なので簡易に実装するため緯度経度に基づき直線距離を計算する処理を考案して実装して、その処理を解説。
-
-
リダイレクトループが原因で「ERR_TOO_MANY_REDIRECTS」「このページを表示できません」が出たときの対策12事例+α
リダイレクトループ、自動転送設定ループの原因の解説とその対応方法を含め事例 12例を挙げて説明。
-
-
Smartyの修飾子regex_replaceで正規表現の後方参照・PHPではpreg_replace
ECCUBEで使われているSmartyで文字列を正規表現で置換し後方参照で値を利用する装飾子regex_replaceの解説です。細かな条件がありますので注意が必要です。
-
-
PHP range関数を使って階乗と重複組み合わせを計算
PHPの range関数を使って階乗と重複組み合わせを計算し、それを元に乱数発生器を作成しました。
-
-
PHPでスクレイピング。phpQueryとphp-simple-html-dom-parserの比較と設置方法
「PHP スクレイピング」で検索すると「phpQuery」ばかりヒットするが、10年以上も放置されている。なので今も開発が続いている「PHP Simple HTML DOM Parser」をオススメする。