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 를 막고 프로그램에서 각 접근에 대한 제어가 가능해진다.
분류 : 개발