Nginx에서 PATH_INFO 미동작 문제 해결하기

프리터코더·2025년 6월 4일
0

php 문제 해결

목록 보기
62/79

Nginx는 Apache와 달리 PATH_INFO를 자동으로 처리하지 않아서 PHP 애플리케이션에서 URL 라우팅이 제대로 작동하지 않는 경우가 많습니다. 이 문제를 해결하는 다양한 방법들을 알아보겠습니다.

1. 기본 PATH_INFO 설정

가장 기본적인 PATH_INFO 설정 방법입니다.

location ~ ^(.+\.php)(.*)$ {
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
    fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    include fastcgi_params;
}

2. try_files를 활용한 설정

존재하지 않는 파일에 대해 index.php로 라우팅하는 방법입니다.

server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        include fastcgi_params;
    }
}

3. 정규식을 이용한 정확한 PATH_INFO 처리

더 정확한 PATH_INFO 분리를 위한 설정입니다.

location ~ ^/api/(.+\.php)(/.*)?$ {
    alias /var/www/api;
    fastcgi_split_path_info ^(.+\.php)(/.*)?$;
    fastcgi_param SCRIPT_FILENAME $request_filename;
    fastcgi_param PATH_INFO $fastcgi_path_info if_not_empty;
    fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
    fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    include fastcgi_params;
}

4. PHP에서 PATH_INFO 확인 및 처리

PHP 코드에서 PATH_INFO를 올바르게 처리하는 방법입니다.

<?php
// PATH_INFO 확인 및 설정
function getPathInfo() {
    if (isset($_SERVER['PATH_INFO'])) {
        return $_SERVER['PATH_INFO'];
    }
    
    // Nginx에서 PATH_INFO가 설정되지 않은 경우 대안
    $requestUri = $_SERVER['REQUEST_URI'];
    $scriptName = $_SERVER['SCRIPT_NAME'];
    
    if (strpos($requestUri, $scriptName) === 0) {
        return substr($requestUri, strlen($scriptName));
    }
    
    return '/';
}

$pathInfo = getPathInfo();
echo "PATH_INFO: " . $pathInfo;

5. 프레임워크별 라우팅 설정

Laravel, Symfony 등 프레임워크를 위한 설정입니다.

server {
    listen 80;
    server_name laravel.local;
    root /var/www/laravel/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

6. API 엔드포인트를 위한 설정

RESTful API를 위한 PATH_INFO 설정입니다.

location /api {
    rewrite ^/api/(.*)$ /api/index.php/$1 last;
}

location ~ ^/api/index\.php(/.*)?$ {
    fastcgi_split_path_info ^(/api/index\.php)(/.*)?$;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    include fastcgi_params;
}

7. 디버깅을 위한 헤더 추가

PATH_INFO 문제를 디버깅하기 위한 설정입니다.

location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    
    # 디버깅 헤더 추가
    add_header X-Script-Name $fastcgi_script_name;
    add_header X-Path-Info $fastcgi_path_info;
    
    fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    include fastcgi_params;
}

8. PATH_INFO 테스트 스크립트

설정이 올바른지 확인하는 PHP 스크립트입니다.

<?php
header('Content-Type: text/plain');

echo "=== PATH_INFO Debug Information ===\n";
echo "REQUEST_URI: " . ($_SERVER['REQUEST_URI'] ?? 'Not set') . "\n";
echo "SCRIPT_NAME: " . ($_SERVER['SCRIPT_NAME'] ?? 'Not set') . "\n";
echo "PATH_INFO: " . ($_SERVER['PATH_INFO'] ?? 'Not set') . "\n";
echo "QUERY_STRING: " . ($_SERVER['QUERY_STRING'] ?? 'Not set') . "\n";
echo "PHP_SELF: " . ($_SERVER['PHP_SELF'] ?? 'Not set') . "\n";

echo "\n=== All $_SERVER variables ===\n";
foreach ($_SERVER as $key => $value) {
    if (strpos($key, 'PATH') !== false || strpos($key, 'SCRIPT') !== false) {
        echo "$key: $value\n";
    }
}

9. 조건부 PATH_INFO 처리

특정 조건에서만 PATH_INFO를 처리하는 설정입니다.

location ~ \.php$ {
    # PHP 파일이 실제로 존재하는지 확인
    try_files $uri =404;
    
    # PATH_INFO가 있는 경우에만 분리
    if ($uri ~ "^(.+\.php)(.*)$") {
        set $script $1;
        set $path_info $2;
    }
    
    fastcgi_param SCRIPT_FILENAME $document_root$script;
    fastcgi_param PATH_INFO $path_info;
    fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    include fastcgi_params;
}

이러한 설정들을 상황에 맞게 적용하면 Nginx에서 PATH_INFO 관련 문제를 해결할 수 있습니다. 설정 후에는 반드시 테스트 스크립트로 확인하고, 애플리케이션의 라우팅이 정상적으로 작동하는지 검증해야 합니다.

profile
일용직 개발자. freetercoder@gmail.com

0개의 댓글