PHPの基礎 - インクルード文

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要

以下に示す関数を総称して、インクルード文またはインクルード系関数と呼ぶ。
これらの関数が共通して外部のPHPファイルを含める (include) という動作を行うことに由来している。

  • require関数
  • require_once関数
  • include関数
  • include_once関数


require関数とinclude関数の基本的な違いとして、require関数は、致命的なエラー (Fatal Error) を発生させて、プログラムの実行を停止する。
一方、include関数は、警告 (Warning) を発生させるだけで、プログラムは続行される。

そのため、必須のファイル (設定ファイルやクラス定義等) にはrequire関数、オプショナルなファイル (テンプレート等) にはinclude関数を使用する。

require_once関数とinclude_once関数は、それぞれrequire関数とinclude関数の機能に加えて、同じファイルが複数回読み込まれることを防ぐ機能がある。
これは、同じクラスや関数を複数回定義しようとするとエラーが発生するため、クラス定義や関数定義を含むファイルで重要となる。

 // 使用例
 
 // データベース接続設定(必須)
 require_once 'config/database.php';
 
 // ユーティリティ関数(必須)
 require 'includes/functions.php';
 
 // サイドバー (オプショナル)
 include 'templates/sidebar.php';
 
 // フッタ (オプショナル)
 include 'templates/footer.php';


また、require_once関数とinclude_once関数では、既に読み込まれたファイルを追跡する必要があるため、処理が重くなる傾向がある。
ただし、この差は現代のPHPエンジンでは最適化されており、多くの場合は無視できる。

セキュリティの観点から、外部から入力されたパスを直接インクルード文に渡すことは避けるべきである。
必ずパスの検証を行う、あるいは、予め定義された安全なパスのみを使用する。

インクルードされるファイルのスコープにおいて、インクルードされたファイル内の変数はインクルードが呼び出された場所のスコープを継承するため、変数名の衝突に注意を払う必要がある。

@ (エラー制御演算子) は、その行で発生するエラーメッセージの表示を抑制する。(基本的な動作に変化なし)
ただし、エラー制御演算子@の使用は一般的に推奨されないため、代わりに、適切なエラーハンドリングを実装するほうがよい。

 // 推奨される方法
 
 try {
    if (!file_exists('config.php')) {
       throw new Exception('設定ファイルが見つからない: config.php');
    }
    require_once 'config.php';    
 }
 catch (Exception $e) {
    // エラーログへの記録
    error_log($e->getMessage());
 
    // 開発環境の場合は詳細なエラー情報を表示
    if (ENVIRONMENT === 'development') {
       echo 'エラーが発生: ' . $e->getMessage();
       echo '<br>スタックトレース: <pre>' . $e->getTraceAsString() . '</pre>';
    }
    else {
       // 本番環境では一般ユーザ向けのエラーページを表示
       require_once 'templates/error_page.php';
    }
 
    // 必要に応じて管理者にメール通知
    if (is_critical_error($e)) {
       notify_admin($e->getMessage());
    }
 }



require関数 / @require関数

require関数は、ファイルの読み込みに失敗すると致命的なエラー (Fatal Error) が発生する。
@require関数は、エラーメッセージは表示されないが処理は停止する。

@require関数を使用する場合、デバッグを困難にする可能性があるため、必須ファイルの@requireは推奨されない。
エラーログの確認や適切なエラーハンドリングの実装することが推奨される。

実務では、@require関数や@require_once関数はあまり推奨されない。
代わりに、以下に示すような例外処理の実装が推奨される。

 // カスタム例外クラスの定義
 class FileNotFoundException extends Exception
 {
    protected $fileName;
 
    public function __construct($fileName)
    {
       $this->fileName = $fileName;
       parent::__construct("ファイル '{$fileName}' が見つかりません");
    }
 
    public function getFileName()
    {
       return $this->fileName;
    }
 }
 
 // エラーハンドリングの実装
 class ErrorHandler
 {
    public static function handleFileInclusion($filePath)
    {
       if (!file_exists($filePath)) {
          throw new FileNotFoundException($filePath);
       }
 
       if (!is_readable($filePath)) {
          throw new Exception("ファイル '{$filePath}' は読み取り可能ではありません");
       }
 
       require_once $filePath;
    }
 
    public static function logError($exception)
    {
       $logMessage = sprintf("[%s] %s in %s on line %d", date('Y-m-d H:i:s'), $exception->getMessage(), $exception->getFile(), $exception->getLine());
       error_log($logMessage);
    }
 }


 // 使用例
 
 try {
    ErrorHandler::handleFileInclusion('config.php');
 }
 catch (FileNotFoundException $e) {
    ErrorHandler::logError($e);
 
    // ファイルが見つからない場合の代替処理
    // ...略
 }
 catch (Exception $e) {
    ErrorHandler::logError($e);
 
    // その他のエラーの処理
    // ...略
 }



include

include関数は、警告 (Warning) を発生させるが、スクリプトの実行は継続する。
@include関数は、ファイルの読み込みに失敗した場合でも警告は表示しない。

  • @include関数のメリット
    • エラーメッセージを非表示にできる。
    • ユーザへのエラー表示を制御できる。


  • @includeのデメリット
    • デバッグが困難になる可能性がある。
    • 重要なエラーを見逃す可能性がある。


一般的には、開発時はinclude関数を使用してエラーを確認して、本番環境での使用時は状況に応じて@includeの使用を検討することが推奨される。
ただし、エラー抑制演算子 (@) の使用は必要最小限に留めるほうがよい。


require_once / include_once

require_once関数およびinclude_once関数は、同じファイルが複数回読み込まれることを防ぐ。

@require_once関数は、エラーメッセージは表示されないが、Fatal Errorで処理は停止する。
@include_once関数は、エラーメッセージは表示されないが、処理は継続する。