php에서 fancy url을 구현하는 방법

이 방법은 어떤 프레임워크 없이 단순히 php에서 fancy url을 구현하고자 하는 사람들을 위한 내용입니다.

참조

.htaccess

서버에 .htaccess 파일을 만들고 아래 내용 복사.
fancy url 을 구현하기 위해서 rewrite engine 을 켜는 내용임.

<IfModule mod_rewrite.c>  
    RewriteEngine On  
 RewriteBase /  
 RewriteCond $1 !^(index\.php|images|captcha|data|include|uploads|robots\.txt)  
 RewriteCond %{REQUEST_FILENAME} !-f  
 RewriteCond %{REQUEST_FILENAME} !-d  
 RewriteRule ^(.*)$ /index.php/$1 [L]  
</IfModule>  

함수를 호출하는 방식.

index.php

아래 내용을 index.php 로 저장.

function startsWith($haystack, $needle)  
{  
    return $needle === "" || strpos($haystack, $needle) === 0;  
}  

function endsWith($haystack, $needle)  
{  
    return $needle === "" || substr($haystack, -strlen($needle)) === $needle;  
}  

function contains($haystack, $needle)  
{  
    return strrpos($haystack, $needle) !== false;  
}  

function show_404(){  
    echo "this page is not allow";  
}  

function parse_path() {  
  $path = array();  
  if (isset($_SERVER["REQUEST_URI"])) {  
    $request_path = explode("?", $_SERVER["REQUEST_URI"]);  
    if (endsWith($request_path[0], "/") == false){ // 만약 http://도메인으로만 끝나면 call_parts가 빈 배열이 들어오는 문제 수정  
        $request_path = array($request_path[0] . "/", $request_path[1]);  
    }  

    $path["base"] = rtrim(dirname($_SERVER["SCRIPT_NAME"]), "\/");  
    $path["call_utf8"] = substr(urldecode($request_path[0]), strlen($path["base"]) + 1);  
    $path["call"] = utf8_decode($path["call_utf8"]);  
    if ($path["call"] == basename($_SERVER["PHP_SELF"])) {  
      $path["call"] = "";  
    }  
    $path["call_parts"] = explode("/", $path["call"]);  

    $path["query_utf8"] = urldecode($request_path[1]);  
    $path["query"] = utf8_decode(urldecode($request_path[1]));  
    $vars = explode("&", $path["query"]);  
    foreach ($vars as $var) {  
      $t = explode("=", $var);  
      $path["query_vars"][$t[0]] = $t[1];  
    }  
  }  
  return $path;  
}  

function path_match(){  
    $path = parse_path();  
    $call_parts = $path["call_parts"];  
    if (count($call_parts) == 0){  
        index();  
        exit();  
    }  

    $funcname = $call_parts[0];  
    if ($funcname == ""){  
        index();  
        exit();  
    }  
    else if (function_exists($funcname) == false){  
        show_404();  
        exit();  
    }  

    $arg_length = new ReflectionFunction($funcname);  
    $arg_length = $arg_length->getParameters();  
    $arg_length = count($arg_length);  
    if ((count($call_parts) - 2) != $arg_length){  
        show_404();  
        exit();  
    }  

    $funcparam = array_slice($call_parts, 1);  
    call_user_func_array($funcname, $funcparam);  

}  

// 여기에 메서드만 정의하면 자동 바인딩.  
// http://도메인/ 으로만 들어올 경우 index 함수 호출.  
function index(){  
    echo "simple redirect engine";  
}  

// http://도메인/test/1st/2nd  
// 형식일 경우 아래 test 함수 호출됨.  
function test($a,$b){  
    echo "$a $b";  
}  

// 주의. 이 함수는 반드시 이 파일 가장 마지막에 있어야 함.  
path_match();  

사용법은 단순함.
// 여기에 메서드만 정의하면 자동 바인딩.
이부분 아래에 필요한 함수를 기술하면 됨.

예를 들어서
http://도메인/test/1st/2nd
형식일 경우 function test($a,$b) 가 호출됨.

http://도메인/run/
형식일 경우 function run() 이 호출됨.

즉 무조건 첫번째 인자는 메서드 이름. 두번째 부터는 파라미터로 바인딩됨.

만약 메서드 시그니쳐가 달라서 인수 갯수가 다르다거나 하면 show_404() 함수가 호출되므로 필요하면 show_404() 함수를 수정할 것.

단순히 http://도메인 이나 http://도메인/ 으로 접속했을 경우에는 index() 함수가 호출되므로 필요하면 index() 함수를 수정할 것.

단순 문서를 호출하는 방식.

아래 내용을 index.php 로 저장.

<?php  
<?php  

function startsWith($haystack, $needle)  
{  
    return $needle === "" || strpos($haystack, $needle) === 0;  
}  

function endsWith($haystack, $needle)  
{  
    return $needle === "" || substr($haystack, -strlen($needle)) === $needle;  
}  

function contains($haystack, $needle)  
{  
    return strrpos($haystack, $needle) !== false;  
}  

function index(){  
    echo "simple redirect engine";  
}  

function show_404(){  
    echo "this page is not allow";  
}  

// 파일 경로로 호출함.  
// 개별 페이지.  
function path_file_match(){  
    $requri = $_SERVER["REQUEST_URI"];  
    $requri = urldecode($requri);  

    if ($requri =="" || $requri == "/"){  
        index();  
        exit();  
    }  

    $relpath = realpath(dirname(__FILE__));  
    $filepath = $relpath . "/content" . $requri . ".md";  
    if (file_exists($filepath)){  
        $content = file_get_contents($filepath);  
        echo $content;  
    }else{  
        show_404();  
    }  
}  

path_file_match();  

 ?>  
 ?>  

위와같은 방식을 쓰면 파일에 직접 access 를 막고 프로그램에서 각 접근에 대한 제어가 가능해진다.

분류 : 개발


이 문서가 가리키는 다른 문서 목록