はじめに
PHPの設定を調べる時、「メインのphp.ini以外にどんな設定ファイルが読み込まれているの?」と疑問に思ったことはありませんか?
実は、PHPはメインのphp.iniファイル以外にも、複数の追加設定ファイル(.iniファイル)を読み込むことができます。特にLinux環境では、拡張機能ごとに個別の.iniファイルが用意されていることが一般的です。
そんな追加設定ファイルを確認するのが**php_ini_scanned_files関数**です。この関数を使えば、どの設定ファイルが読み込まれているかを正確に把握できます。
この記事では、php_ini_scanned_filesの基本から実践的な活用方法まで、詳しく解説します。
php_ini_scanned_filesとは?
php_ini_scanned_filesは、追加で読み込まれた.iniファイルのリストをカンマ区切りの文字列として返す関数です。
基本構文
php_ini_scanned_files(): string|false
パラメータ
この関数はパラメータを取りません。
戻り値
- 成功時: カンマ区切りの.iniファイルパスの文字列
- 失敗時: 追加の.iniファイルが読み込まれていない場合は
false
対応バージョン
- PHP 4.3.0 以降で使用可能
基本的な使い方
シンプルな確認方法
<?php
$scanned_files = php_ini_scanned_files();
if ($scanned_files) {
echo "追加で読み込まれた.iniファイル:\n";
echo $scanned_files;
} else {
echo "追加の.iniファイルはありません";
}
// 出力例(Linux):
// /etc/php/8.2/cli/conf.d/10-opcache.ini,
// /etc/php/8.2/cli/conf.d/10-pdo.ini,
// /etc/php/8.2/cli/conf.d/20-mysqli.ini
?>
配列に変換して扱いやすく
<?php
$scanned = php_ini_scanned_files();
if ($scanned) {
// カンマ区切りを配列に変換
$files = explode(',', $scanned);
// 前後の空白を削除
$files = array_map('trim', $files);
echo "読み込まれている.iniファイル数: " . count($files) . "\n\n";
foreach ($files as $index => $file) {
echo ($index + 1) . ". {$file}\n";
}
} else {
echo "追加の.iniファイルはありません\n";
}
?>
実践的な使用例
例1: すべての設定ファイルを一覧表示
<?php
function getAllConfigFiles() {
$config_files = [
'main' => php_ini_loaded_file(),
'additional' => []
];
$scanned = php_ini_scanned_files();
if ($scanned) {
$files = explode(',', $scanned);
$config_files['additional'] = array_map('trim', $files);
}
return $config_files;
}
$configs = getAllConfigFiles();
echo "=== PHP設定ファイル一覧 ===\n\n";
echo "【メイン設定ファイル】\n";
echo $configs['main'] ?: '(なし)';
echo "\n\n";
echo "【追加設定ファイル】\n";
if (!empty($configs['additional'])) {
foreach ($configs['additional'] as $i => $file) {
echo sprintf("%2d. %s\n", $i + 1, $file);
}
} else {
echo "(なし)\n";
}
?>
例2: 特定の拡張機能の設定ファイルを検索
<?php
function findExtensionIni($extension_name) {
$scanned = php_ini_scanned_files();
if (!$scanned) {
return null;
}
$files = array_map('trim', explode(',', $scanned));
foreach ($files as $file) {
$basename = basename($file);
// ファイル名に拡張機能名が含まれているか確認
if (stripos($basename, $extension_name) !== false) {
return $file;
}
}
return null;
}
// 使用例
$extensions = ['opcache', 'mysqli', 'pdo', 'redis'];
echo "=== 拡張機能の設定ファイル検索 ===\n\n";
foreach ($extensions as $ext) {
$ini_file = findExtensionIni($ext);
if ($ini_file) {
echo "✓ {$ext}: {$ini_file}\n";
} else {
echo "✗ {$ext}: 設定ファイルが見つかりません\n";
}
}
?>
例3: 設定ファイルの詳細情報を取得
<?php
function getIniFilesDetails() {
$details = [];
// メインファイル
$main_ini = php_ini_loaded_file();
if ($main_ini && file_exists($main_ini)) {
$details['main'] = [
'path' => $main_ini,
'size' => filesize($main_ini),
'modified' => date('Y-m-d H:i:s', filemtime($main_ini)),
'readable' => is_readable($main_ini),
'writable' => is_writable($main_ini)
];
}
// 追加ファイル
$scanned = php_ini_scanned_files();
if ($scanned) {
$files = array_map('trim', explode(',', $scanned));
foreach ($files as $file) {
if (file_exists($file)) {
$details['additional'][] = [
'path' => $file,
'name' => basename($file),
'size' => filesize($file),
'modified' => date('Y-m-d H:i:s', filemtime($file)),
'readable' => is_readable($file)
];
}
}
}
return $details;
}
$details = getIniFilesDetails();
echo "=== 設定ファイル詳細 ===\n\n";
if (isset($details['main'])) {
echo "【メインファイル】\n";
echo "パス: {$details['main']['path']}\n";
echo "サイズ: " . number_format($details['main']['size']) . " bytes\n";
echo "更新日時: {$details['main']['modified']}\n";
echo "\n";
}
if (isset($details['additional'])) {
echo "【追加ファイル】\n";
foreach ($details['additional'] as $i => $info) {
echo ($i + 1) . ". {$info['name']}\n";
echo " パス: {$info['path']}\n";
echo " サイズ: " . number_format($info['size']) . " bytes\n";
echo " 更新: {$info['modified']}\n\n";
}
}
?>
例4: 設定ファイルの内容を検索
<?php
function searchInIniFiles($search_term) {
$results = [];
// メインファイルを検索
$main_ini = php_ini_loaded_file();
if ($main_ini && file_exists($main_ini)) {
$content = file_get_contents($main_ini);
if (stripos($content, $search_term) !== false) {
$results[] = [
'file' => $main_ini,
'type' => 'main'
];
}
}
// 追加ファイルを検索
$scanned = php_ini_scanned_files();
if ($scanned) {
$files = array_map('trim', explode(',', $scanned));
foreach ($files as $file) {
if (file_exists($file)) {
$content = file_get_contents($file);
if (stripos($content, $search_term) !== false) {
$results[] = [
'file' => $file,
'type' => 'additional',
'name' => basename($file)
];
}
}
}
}
return $results;
}
// 使用例
$term = 'memory_limit';
$found = searchInIniFiles($term);
echo "「{$term}」を含む設定ファイル:\n\n";
if (empty($found)) {
echo "見つかりませんでした\n";
} else {
foreach ($found as $result) {
echo "[{$result['type']}] {$result['file']}\n";
}
}
?>
例5: 拡張機能のロード順序を確認
<?php
function getExtensionLoadOrder() {
$order = [];
$scanned = php_ini_scanned_files();
if (!$scanned) {
return $order;
}
$files = array_map('trim', explode(',', $scanned));
foreach ($files as $index => $file) {
$basename = basename($file);
// 数字のプレフィックスを抽出(例: 10-opcache.ini → 10)
if (preg_match('/^(\d+)-/', $basename, $matches)) {
$priority = (int)$matches[1];
$name = preg_replace('/^\d+-/', '', $basename);
} else {
$priority = 999;
$name = $basename;
}
$order[] = [
'priority' => $priority,
'name' => $name,
'path' => $file,
'load_order' => $index + 1
];
}
return $order;
}
$extensions = getExtensionLoadOrder();
echo "=== 拡張機能のロード順序 ===\n\n";
echo sprintf("%-5s %-10s %-30s\n", "順序", "優先度", "ファイル名");
echo str_repeat("-", 60) . "\n";
foreach ($extensions as $ext) {
echo sprintf(
"%-5d %-10d %-30s\n",
$ext['load_order'],
$ext['priority'],
$ext['name']
);
}
?>
conf.dディレクトリの仕組み
多くのLinuxディストリビューションでは、追加の.iniファイルはconf.dディレクトリに配置されます。
典型的なディレクトリ構造
/etc/php/8.2/
├── cli/
│ ├── php.ini ← メイン設定
│ └── conf.d/ ← 追加設定
│ ├── 10-opcache.ini
│ ├── 10-pdo.ini
│ ├── 20-mysqli.ini
│ ├── 20-pdo_mysql.ini
│ └── 30-xdebug.ini
├── apache2/
│ ├── php.ini
│ └── conf.d/
└── fpm/
├── php.ini
└── conf.d/
conf.dディレクトリの確認
<?php
function getConfDDirectory() {
$main_ini = php_ini_loaded_file();
if (!$main_ini) {
return null;
}
// php.iniのディレクトリからconf.dディレクトリを推測
$ini_dir = dirname($main_ini);
$conf_d = $ini_dir . '/conf.d';
if (is_dir($conf_d)) {
return $conf_d;
}
return null;
}
$conf_d = getConfDDirectory();
if ($conf_d) {
echo "conf.dディレクトリ: {$conf_d}\n\n";
// ディレクトリ内のファイル一覧
$files = glob($conf_d . '/*.ini');
echo "利用可能な.iniファイル:\n";
foreach ($files as $file) {
$basename = basename($file);
$scanned = php_ini_scanned_files();
$is_loaded = $scanned && strpos($scanned, $file) !== false;
$status = $is_loaded ? '✓ 読込済' : '✗ 未読込';
echo " {$status} {$basename}\n";
}
} else {
echo "conf.dディレクトリが見つかりません\n";
}
?>
環境別の設定確認
CLI、Apache、FPMの比較
<?php
function compareEnvironments() {
$current_sapi = PHP_SAPI;
$current_ini = php_ini_loaded_file();
$current_scanned = php_ini_scanned_files();
echo "=== 現在の環境 ===\n";
echo "SAPI: {$current_sapi}\n";
echo "メインini: {$current_ini}\n\n";
if ($current_scanned) {
$count = count(explode(',', $current_scanned));
echo "追加iniファイル数: {$count}\n";
} else {
echo "追加iniファイル: なし\n";
}
// よくある環境のパス
$environments = [
'CLI' => '/etc/php/8.2/cli/conf.d',
'Apache' => '/etc/php/8.2/apache2/conf.d',
'FPM' => '/etc/php/8.2/fpm/conf.d'
];
echo "\n=== 各環境のconf.dディレクトリ ===\n";
foreach ($environments as $env => $path) {
if (is_dir($path)) {
$count = count(glob($path . '/*.ini'));
echo "{$env}: {$path} ({$count}ファイル)\n";
} else {
echo "{$env}: {$path} (存在しません)\n";
}
}
}
compareEnvironments();
?>
Docker環境での確認
<?php
function checkDockerIniFiles() {
$is_docker = file_exists('/.dockerenv');
echo "Docker環境: " . ($is_docker ? 'はい' : 'いいえ') . "\n\n";
$main_ini = php_ini_loaded_file();
$scanned = php_ini_scanned_files();
echo "メイン設定: " . ($main_ini ?: 'なし') . "\n";
if ($scanned) {
$files = array_map('trim', explode(',', $scanned));
echo "\n追加設定ファイル (" . count($files) . "個):\n";
foreach ($files as $file) {
// Dockerボリュームマウントの確認
$is_mounted = strpos($file, '/usr/local/etc/php/conf.d') !== false;
$marker = $is_mounted ? ' [ボリューム]' : '';
echo " - " . basename($file) . $marker . "\n";
}
} else {
echo "追加設定: なし\n";
}
}
checkDockerIniFiles();
?>
トラブルシューティング
ケース1: 拡張機能が有効にならない
<?php
function diagnoseExtension($extension_name) {
echo "=== {$extension_name} 拡張機能の診断 ===\n\n";
// 拡張機能がロードされているか確認
$is_loaded = extension_loaded($extension_name);
echo "1. 拡張機能の状態: " . ($is_loaded ? '✓ ロード済み' : '✗ 未ロード') . "\n";
if (!$is_loaded) {
echo " → 拡張機能がロードされていません\n\n";
// 設定ファイルを確認
echo "2. 設定ファイルの確認:\n";
$scanned = php_ini_scanned_files();
if ($scanned) {
$files = array_map('trim', explode(',', $scanned));
$found = false;
foreach ($files as $file) {
if (stripos(basename($file), $extension_name) !== false) {
echo " ✓ 設定ファイルが見つかりました: {$file}\n";
// ファイルの内容を確認
if (file_exists($file)) {
$content = file_get_contents($file);
if (preg_match('/^extension\s*=\s*' . $extension_name . '/m', $content)) {
echo " ✓ extension={$extension_name} の記述あり\n";
} else {
echo " ✗ extension={$extension_name} の記述なし\n";
}
// コメントアウトされていないか確認
if (preg_match('/^;\s*extension\s*=\s*' . $extension_name . '/m', $content)) {
echo " ⚠ 設定がコメントアウトされています\n";
}
}
$found = true;
break;
}
}
if (!$found) {
echo " ✗ {$extension_name} 用の設定ファイルが見つかりません\n";
echo "\n対処法:\n";
echo " - パッケージマネージャーで拡張機能をインストール\n";
echo " - conf.dディレクトリに .ini ファイルを作成\n";
}
} else {
echo " 追加の設定ファイルがありません\n";
}
} else {
echo " → 拡張機能は正常にロードされています\n";
// 設定値を表示
if (function_exists($extension_name . '_get_config')) {
echo "\n設定値:\n";
$config = call_user_func($extension_name . '_get_config');
print_r($config);
}
}
}
// 使用例
diagnoseExtension('mysqli');
?>
ケース2: 設定が重複している
<?php
function findDuplicateSettings($setting_name) {
$occurrences = [];
// メインファイルを確認
$main_ini = php_ini_loaded_file();
if ($main_ini && file_exists($main_ini)) {
$content = file($main_ini, FILE_IGNORE_NEW_LINES);
foreach ($content as $line_num => $line) {
if (preg_match('/^\s*' . preg_quote($setting_name) . '\s*=/', $line)) {
$occurrences[] = [
'file' => $main_ini,
'line' => $line_num + 1,
'content' => trim($line),
'type' => 'main'
];
}
}
}
// 追加ファイルを確認
$scanned = php_ini_scanned_files();
if ($scanned) {
$files = array_map('trim', explode(',', $scanned));
foreach ($files as $file) {
if (file_exists($file)) {
$content = file($file, FILE_IGNORE_NEW_LINES);
foreach ($content as $line_num => $line) {
if (preg_match('/^\s*' . preg_quote($setting_name) . '\s*=/', $line)) {
$occurrences[] = [
'file' => $file,
'line' => $line_num + 1,
'content' => trim($line),
'type' => 'additional'
];
}
}
}
}
}
return $occurrences;
}
// 使用例
$setting = 'memory_limit';
$dupes = findDuplicateSettings($setting);
echo "=== {$setting} の設定箇所 ===\n\n";
if (empty($dupes)) {
echo "設定が見つかりません\n";
} else {
echo "現在の値: " . ini_get($setting) . "\n\n";
echo "設定箇所 (" . count($dupes) . "個):\n";
foreach ($dupes as $i => $item) {
echo ($i + 1) . ". [{$item['type']}] " . basename($item['file']) . ":{$item['line']}\n";
echo " {$item['content']}\n\n";
}
if (count($dupes) > 1) {
echo "⚠ 警告: 複数の箇所で設定されています\n";
echo " → 最後に読み込まれた設定が有効になります\n";
}
}
?>
ケース3: ファイルの読み込み順序の問題
<?php
function analyzeLoadOrder() {
$scanned = php_ini_scanned_files();
if (!$scanned) {
echo "追加の設定ファイルはありません\n";
return;
}
$files = array_map('trim', explode(',', $scanned));
echo "=== .iniファイルの読み込み順序 ===\n\n";
echo "重要: 後から読み込まれた設定が優先されます\n\n";
foreach ($files as $index => $file) {
$basename = basename($file);
$order = $index + 1;
// プレフィックス番号を抽出
if (preg_match('/^(\d+)-/', $basename, $matches)) {
$prefix = $matches[1];
echo "{$order}. [{$prefix}] {$basename}\n";
} else {
echo "{$order}. [--] {$basename}\n";
}
}
echo "\nヒント:\n";
echo "- 番号の小さいファイルから順に読み込まれます\n";
echo "- 依存関係のある拡張機能は番号で順序を制御できます\n";
echo " 例: 10-pdo.ini → 20-pdo_mysql.ini\n";
}
analyzeLoadOrder();
?>
実用的なツール作成
設定ファイル管理ツール
<?php
class IniFileManager {
private $mainIni;
private $scannedFiles;
public function __construct() {
$this->mainIni = php_ini_loaded_file();
$this->scannedFiles = $this->parseScannedFiles();
}
private function parseScannedFiles() {
$scanned = php_ini_scanned_files();
if (!$scanned) {
return [];
}
return array_map('trim', explode(',', $scanned));
}
public function getAllFiles() {
$files = [];
if ($this->mainIni) {
$files[] = [
'type' => 'main',
'path' => $this->mainIni,
'name' => basename($this->mainIni)
];
}
foreach ($this->scannedFiles as $file) {
$files[] = [
'type' => 'additional',
'path' => $file,
'name' => basename($file)
];
}
return $files;
}
public function searchSetting($setting_name) {
$results = [];
foreach ($this->getAllFiles() as $file) {
if (!file_exists($file['path'])) {
continue;
}
$content = file_get_contents($file['path']);
$lines = explode("\n", $content);
foreach ($lines as $num => $line) {
if (preg_match('/^\s*' . preg_quote($setting_name) . '\s*=\s*(.+)/', $line, $matches)) {
$results[] = [
'file' => $file['name'],
'path' => $file['path'],
'line' => $num + 1,
'value' => trim($matches[1])
];
}
}
}
return $results;
}
public function getStatistics() {
$stats = [
'total_files' => count($this->getAllFiles()),
'main_file' => $this->mainIni ? 1 : 0,
'additional_files' => count($this->scannedFiles),
'total_size' => 0
];
foreach ($this->getAllFiles() as $file) {
if (file_exists($file['path'])) {
$stats['total_size'] += filesize($file['path']);
}
}
return $stats;
}
public function generateReport() {
$report = "=== PHP設定ファイルレポート ===\n\n";
$report .= "生成日時: " . date('Y-m-d H:i:s') . "\n";
$report .= "PHPバージョン: " . PHP_VERSION . "\n";
$report .= "SAPI: " . PHP_SAPI . "\n\n";
$stats = $this->getStatistics();
$report .= "統計情報:\n";
$report .= " 設定ファイル総数: {$stats['total_files']}\n";
$report .= " 追加ファイル数: {$stats['additional_files']}\n";
$report .= " 合計サイズ: " . number_format($stats['total_size']) . " bytes\n\n";
$report .= "設定ファイル一覧:\n";
foreach ($this->getAllFiles() as $i => $file) {
$report .= sprintf(
"%2d. [%s] %s\n %s\n",
$i + 1,
$file['type'],
$file['name'],
$file['path']
);
}
return $report;
}
}
// 使用例
$manager = new IniFileManager();
// レポートを生成
echo $manager->generateReport();
// 特定の設定を検索
echo "\n=== memory_limit の設定箇所 ===\n";
$results = $manager->searchSetting('memory_limit');
foreach ($results as $result) {
echo "{$result['file']}:{$result['line']} = {$result['value']}\n";
}
?>
まとめ
php_ini_scanned_filesは、追加で読み込まれた.iniファイルを確認するための重要な関数です。
主な特徴:
- ✅ 追加の.iniファイル一覧を取得
- ✅ カンマ区切りの文字列として返される
- ✅
php_ini_loaded_file()と併用で全設定ファイルを把握 - ✅ 拡張機能の設定管理に便利
重要なポイント:
- Linuxでは
conf.dディレクトリが一般的 - ファイル名のプレフィックス番号で読み込み順序を制御
- CLI/Apache/FPMで異なる設定ファイルが使われる
- 後から読み込まれた設定が優先される
活用シーン:
- 拡張機能のトラブルシューティング
- 設定の重複チェック
- 環境構築の確認
- 設定管理ツールの作成
関連する関数:
php_ini_loaded_file(): メインのphp.iniのパスを取得ini_get(): 現在の設定値を取得get_loaded_extensions(): ロード済み拡張機能一覧
この関数を活用して、PHPの設定管理をより効率的に行いましょう!
