본문 바로가기

php

[함수] $_SERVER['PATH_INFO'] 사용하기.


PHP의 $_SERVER['PATH_INFO'] 는 다음의 주소에서
http://domain.tld/script.php/path/1/2/3
/path/1/2/3 부분을 말하며 이 부분이 없을때는 $_SERVER['PATH_INFO'] 또 한
생성되지 않습니다. 즉
http://domain.tld/script.php 로 호출하면 $_SERVER['PATH_INFO']는 아예
정의 되지 않습니다.


이 PATH_INFO 정보를 이용하여  query string을 조금 친근하게 바꾼다거나
controller 클래스의 메소드와 연결하여 자동으로 호출하게하는 등 다양한
용도와 방식으로 사용됩니다.

1. PATH_INFO를 통한 클래스의 메소드 호출
디버깅용이나 간단한 메소트 테스트용으로 사용할수 있겠습니다.
형식이 꽤 자유로운 편이니 이 글에서는 script,class,method,parameters 로
4개로 구분하고 다음과 같은 path 형식을 쓰겠습니다.
예) http://domain.tld/script.php/script/MyClass/printMethod/apple/orange
위 형식중 printMethod 이후에 오는 모든 / 구분자로된 항목은 메소드의
파라미터로 간주합니다.

----------------------------test.php----------------------------------
function IamGoingTo($path = NULL) {
    //$path 가 NULL 이면 $_SERVER['PATH_INFO']를 사용
    if ($path === NULL) {
        if (isset($_SERVER['PATH_INFO']) === false) {
         
            return '길을 잃어버렸습니다.';
        } 
        $path = $_SERVER['PATH_INFO'];
    } 

    //$path를 / 로 쪼개고 빈 배열 요소는 제거
    $tracks = preg_split('/\//', $path, -1, PREG_SPLIT_NO_EMPTY);
    $length = count($tracks);

    //최소 3개의 요소가 있어야한다. script/class/method
    if ($length < 3) {
        return '길에 구멍이 생겼어요 공사좀해주세요.';
    } 

    //0-3까지 list로 변수에 대입한다.
    list($script, $class, $method) = array_slice($tracks, 0, 3);

    //3이후의 값들을 파라미터로 전달하고 WayToRun을 호출한다.
    return WayToRun($script, $class, $method, array_splice($tracks, 3));
}


function WayToRun($script, $class, $method, $parameters) {
    //$sript에 .php를 붙여서 매우 긴 파일 경로명으로 만듭니다.
    $path = realpath(rtrim($script, '/').'.php');

    if (file_exists($path) === false) {
      return '파일이 없네요? 찾아주세요';
    }

    //현재 require나 include된 파일에 존재하는지 검사 없으면 포함
    if (in_array($path, get_included_files()) === false) {
        require $path;
    } 

  //클래스가 존재하는지 검사
    if (class_exists($class, false) === false) {
        return '클래스 이름이 좀 틀린듯?';
    } 

    if (method_exists($class, $method) === false) {
        return '메소드명 제대로 기억하시나요?';
    } 

    //클래스의 메소드에 파라미터를 넘겨서 최종 호출하고 결과를 리턴합니다.
    return call_user_func_array(array(new $class, $method), $parameters);
}

//테스트용 클래스
class MyClass {
    public function printMethod($a, $b) {
        print('호출당했어요! with'.$a.', '.$b);
    }
    public function printMethod2() {
        print('호출당했어요! with'.$_GET['what']);
    } 
}

// 테스트용 단순히 이 스크립트롤 호출하여 테스트하고 싶을때 주석제거
//print(IamGoingTo('/test/MyClass/printMethod/orange/apple'));

//$_SERVER['PATH_INFO'] 를 사용하기 위해 단순히 호출
IamGoingTo();

--------------------------------test.php end------------------------------

이제 테스트를 위해 다음처럼 호출해봅시다
http://domain.tld/test.php/test/MyClass/printMethod/orange/apple
http://domain.tld/test.php/test/MyClass/printMethod2?what=pink

다양한 방식으로 함수를 만들고 호출해 보실수 있겠습니다.


2. 별명으로 연결하기
처음 알아본 방식대로 사용하면 주소가 너무 길고 사용하기가 상당히 불편합니다.
좀 하나로 줄여줄 필요가 있습니다. 예를들어

class SomeController {
    public function login() {
    .....
    }
}

IamGoingTo('/some_script/SomeController/login');
형식으로 호출하는건 좀 길고 불편하니
IamGoingTo('/login') 처럼 호출하면 훨씬더 편리할것입니다.

이를 위해
$map = array('login'=>'/some_script/SomeController/login',
                    'logout=>'/some_script/SomeController/logout');
처럼 서로를 연결해주는 alias용 map를 하나 만들어주고

IamGoingTo에서 이 $map를 $p[0] 이 참조하도록하여 isset으로 검사를 하면됩니다.
이는 어렵지 않게 할 수 있으므로 소스코드는 생략 하겠습니다.

추가로 IamGoingTo에서 에러가 발생하면 Page Not Found에러로 header를 이용하여
Location를 사용하여 페이지가 없는것처럼 만들수도 있겠습니다.


간단하게 PATH_INFO를 사용하는 법을 정리해보았습니다.
위 같은 방식은 꽤 많은 framework가 채용하고있고 코드는달라도
하는짓은 비슷한 경우도 많이 있습니다.

킁킁. =_=/


http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=63620

'php' 카테고리의 다른 글

파일다운로드 - 이어받기 속도제한 인증 기타  (0) 2010.03.08
UTF8 문자관련  (1) 2009.12.15
php 이메일주소 유효성검사  (0) 2009.11.11
html 제거  (0) 2009.10.07
욕필터링  (0) 2009.10.07