문제: 상대경로로 인해 다른 디렉토리에서 실행할 때 파일을 찾지 못함
<?php
// 데이터베이스 설정
return [
'host' => 'localhost',
'username' => 'root',
'password' => 'password',
'database' => 'myapp'
];
?>
<?php
function connectDatabase() {
// 프로젝트 루트 기준으로 절대경로 사용
$config = require __DIR__ . '/../config/database.php';
try {
$pdo = new PDO(
"mysql:host={$config['host']};dbname={$config['database']}",
$config['username'],
$config['password']
);
return $pdo;
} catch (PDOException $e) {
die('데이터베이스 연결 실패: ' . $e->getMessage());
}
}
function loadTemplate($template_name) {
$template_path = __DIR__ . '/../templates/' . $template_name . '.php';
if (!file_exists($template_path)) {
throw new Exception("템플릿 파일을 찾을 수 없습니다: $template_name");
}
return $template_path;
}
?>
<?php
// 프로젝트 루트 디렉토리 정의
define('ROOT_DIR', dirname(__DIR__));
// 절대경로로 파일 포함
require_once ROOT_DIR . '/includes/functions.php';
require_once ROOT_DIR . '/config/database.php';
// 사용 예시
$db = connectDatabase();
$template = loadTemplate('header');
include $template;
?>
문제: 깊은 디렉토리 구조에서 상위 디렉토리 참조가 복잡함
<?php
// 프로젝트 루트 디렉토리 설정
if (!defined('APP_ROOT')) {
define('APP_ROOT', dirname(__DIR__));
}
// 주요 디렉토리 경로 정의
define('CONFIG_DIR', APP_ROOT . '/config');
define('INCLUDES_DIR', APP_ROOT . '/includes');
define('TEMPLATES_DIR', APP_ROOT . '/templates');
define('UPLOADS_DIR', APP_ROOT . '/uploads');
define('LOGS_DIR', APP_ROOT . '/logs');
// 자동 포함 함수
function includeFile($file_path) {
$full_path = APP_ROOT . '/' . ltrim($file_path, '/');
if (!file_exists($full_path)) {
throw new Exception("파일을 찾을 수 없습니다: $full_path");
}
return require_once $full_path;
}
// 설정 파일 로드 함수
function loadConfig($config_name) {
$config_file = CONFIG_DIR . '/' . $config_name . '.php';
if (!file_exists($config_file)) {
throw new Exception("설정 파일을 찾을 수 없습니다: $config_name");
}
return require $config_file;
}
?>
<?php
// 부트스트랩 파일 포함 (상위 디렉토리 2단계)
require_once __DIR__ . '/../../bootstrap/app.php';
// 이제 간단하게 파일 포함 가능
includeFile('includes/auth.php');
includeFile('includes/user_functions.php');
$db_config = loadConfig('database');
$app_config = loadConfig('app');
// 템플릿 포함
include TEMPLATES_DIR . '/admin/header.php';
?>
문제: 여러 디렉토리에서 공통 파일을 포함해야 하는 경우
<?php
// include_path 설정
$include_paths = [
__DIR__ . '/../includes',
__DIR__ . '/../lib',
__DIR__ . '/../vendor',
get_include_path()
];
set_include_path(implode(PATH_SEPARATOR, $include_paths));
// 안전한 파일 포함 함수
function safeInclude($filename, $required = true) {
$file_found = false;
$include_paths = explode(PATH_SEPARATOR, get_include_path());
foreach ($include_paths as $path) {
$full_path = $path . DIRECTORY_SEPARATOR . $filename;
if (file_exists($full_path)) {
if ($required) {
require_once $full_path;
} else {
include_once $full_path;
}
$file_found = true;
break;
}
}
if (!$file_found && $required) {
throw new Exception("필수 파일을 찾을 수 없습니다: $filename");
}
return $file_found;
}
?>
<?php
require_once __DIR__ . '/../includes/path_manager.php';
// include_path에서 파일 검색
safeInclude('database.php');
safeInclude('product_functions.php');
safeInclude('optional_module.php', false); // 선택적 포함
?>
문제: 파일 존재 여부 확인 없이 포함하여 오류 발생
<?php
class FileLoader {
private static $loaded_files = [];
public static function requireOnce($file_path, $base_dir = null) {
$full_path = self::resolvePath($file_path, $base_dir);
if (in_array($full_path, self::$loaded_files)) {
return true; // 이미 로드됨
}
if (!file_exists($full_path)) {
throw new Exception("파일을 찾을 수 없습니다: $full_path");
}
if (!is_readable($full_path)) {
throw new Exception("파일을 읽을 수 없습니다: $full_path");
}
require_once $full_path;
self::$loaded_files[] = $full_path;
return true;
}
public static function includeIfExists($file_path, $base_dir = null) {
$full_path = self::resolvePath($file_path, $base_dir);
if (file_exists($full_path) && is_readable($full_path)) {
include_once $full_path;
return true;
}
return false;
}
private static function resolvePath($file_path, $base_dir = null) {
if ($base_dir === null) {
$base_dir = defined('APP_ROOT') ? APP_ROOT : __DIR__;
}
// 절대경로인 경우 그대로 반환
if (substr($file_path, 0, 1) === '/' || substr($file_path, 1, 1) === ':') {
return $file_path;
}
return $base_dir . '/' . ltrim($file_path, '/');
}
public static function getLoadedFiles() {
return self::$loaded_files;
}
}
?>
<?php
require_once __DIR__ . '/../../includes/safe_loader.php';
try {
// 필수 파일들
FileLoader::requireOnce('config/app.php', __DIR__ . '/../..');
FileLoader::requireOnce('includes/auth.php', __DIR__ . '/../..');
// 선택적 파일들
FileLoader::includeIfExists('modules/user/custom_fields.php', __DIR__ . '/../..');
FileLoader::includeIfExists('plugins/user_extensions.php', __DIR__ . '/../..');
echo "로드된 파일들:\n";
foreach (FileLoader::getLoadedFiles() as $file) {
echo "- $file\n";
}
} catch (Exception $e) {
error_log("파일 로드 오류: " . $e->getMessage());
die("시스템 오류가 발생했습니다.");
}
?>
문제: 개발/운영 환경에 따라 다른 설정 파일을 로드해야 함
<?php
class ConfigLoader {
private static $configs = [];
private static $environment = null;
public static function init($env = null) {
if ($env === null) {
$env = $_ENV['APP_ENV'] ?? 'development';
}
self::$environment = $env;
}
public static function load($config_name) {
if (isset(self::$configs[$config_name])) {
return self::$configs[$config_name];
}
$config_dir = __DIR__;
$env = self::$environment ?? 'development';
// 환경별 설정 파일 우선 로드
$env_config_file = $config_dir . "/{$config_name}.{$env}.php";
$default_config_file = $config_dir . "/{$config_name}.php";
$config = [];
// 기본 설정 로드
if (file_exists($default_config_file)) {
$config = require $default_config_file;
}
// 환경별 설정으로 덮어쓰기
if (file_exists($env_config_file)) {
$env_config = require $env_config_file;
$config = array_merge($config, $env_config);
}
if (empty($config)) {
throw new Exception("설정 파일을 찾을 수 없습니다: $config_name");
}
self::$configs[$config_name] = $config;
return $config;
}
}
// 초기화
ConfigLoader::init();
?>
<?php
require_once __DIR__ . '/config/config_loader.php';
try {
// 환경별 설정 로드
$db_config = ConfigLoader::load('database');
$app_config = ConfigLoader::load('app');
$mail_config = ConfigLoader::load('mail');
echo "환경: " . ($_ENV['APP_ENV'] ?? 'development') . "\n";
echo "데이터베이스: " . $db_config['host'] . "\n";
} catch (Exception $e) {
error_log("설정 로드 오류: " . $e->getMessage());
die("애플리케이션을 시작할 수 없습니다.");
}
?>
__DIR__
을 기준으로 한 절대경로 권장file_exists()
로 사전 확인require_once
/include_once
로 중복 로드 방지