URLルーティング

PHP でつくってみた。
フレームワーク風です。

.htaccess

アクセスをすべて index.php に。

Options +FollowSymLinks
IndexIgnore */*
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php

common.php

共通部分。いろんな関数を呼びやすくしただけ。

<?php

function redirect($url)
{
  header('Location: '. $url);
  exit;
}

function r($url)
{
  return redirect($url);
}

function h($str)
{
  return htmlspecialchars($str, ENT_QUOTES);
}

function p($str)
{
  print($str);
}

function ph($srt)
{
  p(h($str));
}

function pr($ary)
{
  print_r($ary);
}

function hr()
{
  echo "<hr>";
}

index.php

設定部。

<?php
require "lilium.php";

dispatch("/", "index");
dispatch("/index", "index");
function index()
{
  echo "Hello!";
}

dispatch("/search/:keyword", "search");
function search($args)
{
  echo "SEARCH(". $args['keyword'] .")";
}

run();

lilium.php(本体)

本体。多分バグだらけ。
やらなきゃならないこと多し。

<?php

require 'common.php';

function maps()
{
  static $maps = array();
  if (func_num_args() === 3) {
    list ($uri, $function, $request_method) = func_get_args();
    $pattern = explode('/', trim($uri, "/"));
    $maps[] = array('pattern' => $pattern,
		    'function' => $function,
		    'request_method' => $request_method);
  }
  return $maps;
}

function get_request_pattern()
{
  $req = explode('/', trim($_SERVER['REQUEST_URI'], "/"));
  $scr = explode('/', trim($_SERVER['SCRIPT_NAME'], "/"));
  for ($i = 0; $i < count($req); $i++) {
    if ($req[$i] === $scr[$i]) {
      unset($req[$i]);
    }
  }
  if (count($req) === 0) {
    $req[0] = "";
  }
  return array_values($req);
}

function search_map($pattern)
{
  $maps = maps();
  foreach ($maps as $map) {
    if (match_map($map, $pattern)) {
      return $map;
    }
  }
  return null;
}

function match_map($map, $pattern)
{
  for ($i = 0; $i < count($map); $i++) {
    if (substr($map["pattern"][$i], 0, 1) === ":") {
      continue;
    }
    if ($map["pattern"][$i] !== $pattern[$i]) {
      return false;
    }
  }
  return true;
}

function get_args($map, $pattern)
{
  $args = array();
  for ($i = 0; $i < count($pattern); $i++) {
    if (substr($map["pattern"][$i], 0, 1) === ":") {
      $key = substr($map["pattern"][$i], 1);
      $args[$key] = $pattern[$i];
      #$args["args"][$key] = $pattern[$i];
    } else {
      #$args["args"][$map[$i]] = $pattern[$i];
    }
  }
  return $args;
}

function dispatch($uri, $function, $request_method = 'GET')
{
  maps($uri, $function, $request_method);
}

function run()
{
  $pattern = get_request_pattern();
  $map = search_map($pattern);
  $args = get_args($map, $pattern);
  execute($map["function"], $args);
}

function execute($function, $args)
{
  if (function_exists($function)) {
    $function($args);
  } else {
    not_found();
  }
}

function not_found()
{
  echo "404";
}