エス技研

WordPress、CakePHP、PHP、baserCMSなどの Web系システムを中心に情報を提供します!


include、requireのパス指定をdirname(__FILE__)、__DIR__と書く理由

      2017/03/07

include、requireの一番いいパス指定の仕方の解説

 

include、requireの一番いいパス指定の仕方

 
PHPのプログラムで、外部ファイルを読み込む際には、require、include、require_once、include_onceを利用します。
 
その際、読み込むファイルのパスの記述の仕方によっては不具合の原因となりますので、不具合を生まない記述をしておく必要があります。
 
具体的には下記の様に指定します。
 

require ( dirname ( __FILE__ ) . '/path/file.php');
require ( __DIR__ . '/path/file.php');

 
なぜこのような指定をするかの解説を行います。
 
 
requireの他、include、require_once、include_onceとありますが、いずれもファイルのパス指定方法は同じですので、ここでは「require」で話を進めていきます。
 
 
[amazonjs asin=”4873117933″ locale=”JP” title=”初めてのPHP”]
 

require ( dirname ( __FILE__ ) . '/path/file.php')と指定する理由

 

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 の中身は下記のような内容です。

<?php
require ( './lib.php' );
?>

 
file_2.php の中身は下記のような内容です。

<?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のパス指定で問題を解消する方法

 
相対パスで指定した場合に発生する問題を解消するための書き方として、下記のいずれかの方法で絶対パスでファイルを指定する必要があるのです。
 

// プログラムファイルの場所から指定する場合
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__の違い」については後述しています。
 
 
ちなみに、ファイルがあるフォルダより親のフォルダを経由して指定する場合は、下記のような指定も可能です。

// プログラムファイルの場所から指定する場合
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
 
パスを指定するだけで処理が早くなるわけですので、これまた指定しないメリットがありませんね。
 
 
[amazonjs asin=”479813547X” locale=”JP” title=”独習PHP 第3版”]
 
 

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で標準出力をバッファリング・変数に代入」に記事を書いていますので参考にしてください。

 - PHP・Smarty・ECCUBE

最後までお読みいただきましてありがとうございます。
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!

Message

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

下記の空欄を埋めてください。 * Time limit is exhausted. Please reload CAPTCHA.

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

※入力いただいたコメントは管理者の承認後に掲載されます。

  関連記事

乱数発生器(パスワード生成サービス)がバージョンアップで高速化!
乱数発生器(パスワード生成サービス)がバージョンアップで高速化!

乱数やパスワードを生成する乱数発生器を高速化!重複しない10桁、20桁の文字列を10万件、20万件と生成することも可能!イベントのキャンペーンのシリアルコードなどにも利用可能!

ECCUBEでアップロードできない。upload_max_filesizeを設定する場所

テンプレートをアップロードする際に発生するエラー「テンプレートファイルがアップロードされていません」の対処方法。これはファイル容量の制限に引っかかっています。

サーバ移転、PHPバージョンアップでPHPのソースコードが表示される・ショートタグのPHPが動かない

PHPでショートタグを使うのは危険。サーバ移転やバージョンアップで動かなくなる!ソースが丸見え、設定情報流出のリスクが!php.iniのshort_open_tagの設定を再確認。

ECCUBEの管理画面のSSL設定をインストール後に変更する方法

ECCUBEをインストールした後から管理画面のSSL設定を変更する方法を解説します。config.phpファイルのHTTPS_URLとADMIN_FORCE_SSLの値を変更すればOK。

JSON形式の値を配列形式に変換・PHPでは json_decode()、json_encode()
JSON形式の値を配列形式に変換・PHPでは json_decode()、json_encode()

JSONとは「JavaScript Object Notation」の略でテキストベースのデータフォーマット。JSONの値をPHPで配列に変換するWebツールの紹介とその処理「json_encode()」「json_decode()」関数の解説。

PHPで特定の日間の日付を for、strtotimeで表示する

ある特定の間の日付の情報を for文、strtotimeを使って作成し、その解説をしています。

PHPで1ヵ月前、先月、今月1日、来月末の日付などの算出はDateTimeImmutableを使う
PHPで1ヵ月前、先月、今月1日、来月末の日付などの算出はDateTimeImmutableを使う

PHPには日時をオブジェクトとして生成する関数「DateTimeImmutable」「DateTime」が用意されている。これを利用して1ヶ月後、月初日、月末日、5日後などを指定して日付を取得できる。

PHP画面が真っ白 header(“Location: $url”);

PHPの開発で header(“Location: $url”);を使うと画面が真っ白になる不具合が出る場合もあります。

QRコード作成ライブラリ「cakePHP-QR-Code-Helper」をPHPで使うカスタマイズ
QRコード作成ライブラリ「cakePHP-QR-Code-Helper」をPHPで使うカスタマイズ

CakePHP2用のQRコード作成ライブラリ「cakePHP-QR-Code-Helper」をプレーンのPHPでも使うためのカスタマイズ方法を解説。1ファイルを設置するだけでQRコードが作れるため使い勝手がいい。

SEO対策用タイトル、ディスクリプションの文字数カウントツール

SEO対策に使える文字数カウントツールで文字数の条件の説明も行っています。