タイトル: 外部ファイルを呼び出す方法
SEOタイトル: PHP 外部ファイル呼び出し (include/require/autoload) 完全ガイド(Composer / PSR-4)
| この記事の要点 |
|
古典的: include / require
<?php
// 単純な読み込み
include 'config.php'; // ファイル無いと Warning、継続
require 'config.php'; // ファイル無いと Fatal Error、停止
// 重複読み込み防止 (グローバル変数や関数定義に重要)
include_once 'helpers.php'; // 既に読込済ならスキップ
require_once 'helpers.php';
| 関数 | 失敗時 | 重複防止 | 典型用途 |
|---|---|---|---|
include | Warning + 継続 | × | オプショナルな読み込み |
require | Fatal Error + 停止 | × | 必須ファイル |
include_once | Warning + 継続 | ○ | 関数 / クラス定義ファイル |
require_once | Fatal Error + 停止 | ○ | 必須かつ重複防止 |
パスの罠: 相対パス vs 絶対パス
相対パスは呼び出し元のスクリプトではなく現在のワーキングディレクトリを基準とします。CLI / cron / Web で挙動が変わるので注意:
<?php
// ❌ 危険: 呼び出し方次第で見つからない
include 'lib/util.php';
// ❌ ハードコードした絶対パスもサーバ移転で死ぬ
include '/var/www/html/lib/util.php';
// ✅ __DIR__ で自ファイルの場所を基準にする
include __DIR__ . '/lib/util.php';
// ✅ 親ディレクトリ参照
require __DIR__ . '/../config/database.php';
// PHP 5.3 未満では dirname(__FILE__) を使う
require dirname(__FILE__) . '/../config/db.php';
戻り値: ファイルから値を返す
<?php
// config.php
return [
'db_host' => 'localhost',
'db_user' => 'root',
'db_pass' => 'secret',
];
// app.php
$config = require __DIR__ . '/config.php';
echo $config['db_host'];
// Laravel 等もこの形式の設定ファイルを多用
include_path と PHP の探索順
<?php
// 現在の include_path 確認
echo get_include_path(); // .:/usr/share/php
// 追加
set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ . '/lib');
// この設定下では:
include 'util.php';
// → 1. カレント ./util.php
// → 2. /usr/share/php/util.php
// → 3. __DIR__/lib/util.php (追加分)
// を順に探す
古典的 autoload: spl_autoload_register
PHP 5 + のクラス名から自動でファイルを読み込む仕組み。Composer 以前の手動 autoload:
<?php
// 自前 autoloader
spl_autoload_register(function (string $class) {
// App\Models\User → /var/www/html/src/App/Models/User.php
$base = __DIR__ . '/src/';
$path = $base . str_replace('\\', '/', $class) . '.php';
if (file_exists($path)) {
require $path;
}
});
// 以降、未読込クラスを使うと自動で require される
$user = new App\Models\User();
現代の正解: Composer + PSR-4
PHP コミュニティの事実上の標準。プロジェクトに composer.json を置き、依存パッケージとオートロード設定を宣言します。
{
"name": "myorg/myapp",
"require": {
"php": "^8.2",
"guzzlehttp/guzzle": "^7.0"
},
"autoload": {
"psr-4": {
"App\\": "src/"
},
"files": [
"src/helpers.php"
]
}
}# 初回 / 依存追加時
composer install
composer require guzzlehttp/guzzle
# autoload を再生成 (新規クラス追加時)
composer dump-autoload
# 最適化 (本番デプロイ時)
composer dump-autoload -o<?php
// アプリのエントリポイント (index.php / artisan 等)
require __DIR__ . '/vendor/autoload.php';
// これ 1 行で:
// - composer.json で宣言した PSR-4 マッピングが有効
// - 全ベンダーパッケージのクラスが自動読込可能
// - src/helpers.php 等の files も読込済
use App\Services\UserService;
use GuzzleHttp\Client;
$service = new UserService();
$http = new Client();
// → どれも require していないのに使える
PSR-4 マッピングの仕組み
名前空間とディレクトリの対応規約。composer.json の psr-4 セクションで宣言:
| クラス | ファイル |
|---|---|
App\Models\User | src/Models/User.php |
App\Services\Mailer | src/Services/Mailer.php |
App\Http\Controllers\HomeController | src/Http/Controllers/HomeController.php |
「App\\ → src/」のマッピングを宣言しておくと、Composer のオートローダが名前空間からパスを機械的に導出します。
名前空間 (namespace) と use
<?php
// src/Models/User.php
namespace App\Models;
class User
{
public function __construct(public string $name) {}
}
// 別ファイルから利用
namespace App\Http\Controllers;
use App\Models\User; // フルパス → 短い名前
use App\Models\User as UserModel; // 別名
class UserController
{
public function show()
{
$u = new User('Alice'); // OK
$u = new \App\Models\User('B'); // FQN (Fully Qualified Name) でも可
}
}
// グルーピング import (PHP 7.0+)
use App\Models\{User, Post, Comment};
// 関数 / 定数も use できる (PHP 5.6+)
use function App\Helpers\format_date;
use const App\Config\APP_VERSION;
Laravel / Symfony での実態
モダンフレームワークでは、ユーザーコードで require / include を直接使うことはほぼありません。代わりにService Container (DI コンテナ) が依存解決します:
<?php
// Laravel コントローラ
namespace App\Http\Controllers;
use App\Services\UserService;
use Illuminate\Http\Request;
class UserController extends Controller
{
// コンストラクタで依存を宣言
// → Service Container が自動で UserService インスタンスを注入
public function __construct(
private UserService $userService
) {}
public function index(Request $request)
{
return $this->userService->all();
}
}
// require / new UserService() を書く必要がない
// → テスト時はモックを bind すれば差し替えられる
パフォーマンス: OPCache と autoload 最適化
; php.ini で OPCache 有効化 (PHP 7+ デフォルト)
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0 ; 本番は 0 (再起動でクリア)
opcache.revalidate_freq=0
opcache.fast_shutdown=1
opcache.enable_file_override=1# 本番デプロイ時の最適化
composer install --no-dev --optimize-autoloader --classmap-authoritative
# Laravel の場合さらに
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache
選び方フローチャート
| 状況 | 使うもの |
|---|---|
| 新規プロジェクト | ★ Composer + PSR-4 (一択) |
| 古いシステムの保守 | require_once __DIR__ . '/..' パターン |
| 設定値ファイル | $cfg = require __DIR__ . '/config.php'; |
| 必須でない拡張モジュール | if (file_exists()) include; |
| 関数のグローバルヘルパー | Composer autoload.files に登録 |
| Laravel / Symfony / Slim | DI コンテナに任せる、ユーザーコードで require しない |
FAQ
Q: include と require の使い分け基準は?
A: 無くてもアプリが動く → include、無いと致命的 → require。実務では大半 require_once または Composer。
Q: Composer 入れないと autoload は無理?
A: spl_autoload_register() で自作可能ですが、依存管理 + 名前空間規約 + 速度面で Composer に勝てません。
Q: 設定ファイルが .env と config.php どちらが良い?
A: 環境ごとに変わる値 (DB パスワード、API キー) は .env → getenv()。コードに含めて良い構造的設定は config.php。Laravel / Symfony もこの分け方。