単純なうちはいいんですが、ルーティングも凝りだすと複雑になり、デバッグが大変です。ですから、一日かけて、ルーティングの設定/テストプログラムを作成しました。
FuelPHP上のコントローラーとして動作する、1クラスプログラムです。開発者向けで、自分の開発中のスクラッチにポンと放り込んで使用するイメージで作りました。
そのため、UIは古臭く、エラーチェックはまともにやっていません。しかし、自分で使っていて、便利なプログラムです。
クラス1つだけですから、Githubにはのせません。ご自身でコピペしてご利用ください。
なお、FuelPHPでは404を簡単に表示するために、例外のHttpNotFoundExceptionが用意されています。これを投げると通常は_404_で指定されたルートへ移行するのですが、そのルート自身が一度ルーティングの仕組みを通るため、思い通りに404が表示されないことがあります。
例:
'_404_' => 'error/index',
':name1/:name2' => 'named/index',
'(:any)' => 'every/index',
上記のroute.phpで、HttpNotFoundExceptionを投げると、'error/index'がURIのセグメントとして指定されたものとして、ルーティングが行われる。結果、名前付きパラメーター2つの:name1/:name2に一致してしまう。もしくは、名前付き2セグメントが無くても、(:any)に一致してしまう。
これを防ぐにはFuelPHPのドキュメントルートである、publicの中のindex.php中で:
$response = Request::forge($route)->execute()->response();
の一行を
$response = Request::forge($route,false)->execute()->response();
に変更する、もしくは未テストですが、
'error/index' => 'error/index'と定義する方法があります。
では、肝心のコードです。
<?phpclass Controller_Routingsetter extends Controller
{
const NEW_ROUTE = 5;public function action_index()
{
if (Input::method() == 'POST')
{
// 既存のルーティングの取得
$total_line = Input::post('total_line');
$route_array = array();
for ($i = 0; $i < $total_line; $i++)
{
if (!(Input::post('line'.$i, false) === false) and Input::post('pattern'.$i) and Input::post('class_action'.$i) and !Input::post('delete_radio'.$i))
{
$route_array[Input::post('line'.$i)] = array('pattern' => Input::post('pattern'.$i), 'class_action' => Input::post('class_action'.$i));
}
}// 追加ルーティングの取得
for ($i = 0; $i < self::NEW_ROUTE; $i++)
{
if (Input::post('new_line'.$i) and Input::post('new_pattern'.$i) and Input::post('new_class_action'.$i))
{
$route_array[Input::post('new_line'.$i)] = array('pattern' => Input::post('new_pattern'.$i), 'class_action' => Input::post('new_class_action'.$i));
}
}ksort($route_array);// コンフィグのroutesを一度削除し、生成し直す
Config::delete('routes');
foreach ($route_array as $item)
{
Config::set('routes.'.$item['pattern'], $item['class_action']);
}// コンフィグファイルに保存するConfig::save('routes', 'routes');
} // End of POST handing// グループ名指定で、ルーティングの全設定取得
$routes = Config::get('routes', array());$rt = array();
foreach ($routes as $key => $item)
{
// 正規表現に変換
$replace = str_replace(array(
':any',
':alnum',
':num',
':alpha',
':segment',
),
array(
'.+',
'[[:alnum:]]+',
'[[:digit:]]+',
'[[:alpha:]]+',
'[^/]*',
), '/'.$key.'/');
$replace = preg_replace('%:([[:alpha:]]+)/%', '(?P<$1>.+?)/', $replace);$rt[] = array(
'exp' => trim($replace, '/'),
'pattern' => trim($key, '/'),
'class_action' => trim($item, '/')
);
}// ルーティングのシミュレーション
$matched = false;
$p404 = false;
$test_uri = trim(Input::post('test_uri'), '/');foreach ($rt as $key => $item)
{
if ($test_uri == '' and $item['exp'] == '_root_')
{
$matched = $key;
break;
}
elseif (preg_match('{^'.$item['exp'].'$}', $test_uri, $matches))
{
$matched = $key;
break;
}
elseif ($item['pattern'] == '_404_')
{
$p404 = $key;
}
}
if (!$matched)
$matched = $p404;// 出力
// ビューやテンプレート使わない時の、文字化け対策にヘッダー出力
echo Html::doctype('html5');
echo '<head><meta charset="UTF-8"></head><body>';echo Form::open(Uri::current());
echo 'ルーティングテストURI:'.Form::input('test_uri', Input::post('test_uri') ? : '',
array('size' => 60)).'<hr />';$last_key = -1;
foreach ($rt as $key => $item)
{
$last_key = $key;
echo Form::input('line'.$key, $key * 10, array('size' => 3)).' : ';
echo Form::input('pattern'.$key, $item['pattern'], array('size' => 50)).' ';
echo Form::input('class_action'.$key, $item['class_action'],
array('size' => 50)).' ';
echo Form::label('削除', 'delete_radio'.$key);
echo Form::radio('delete_radio'.$key, 'de.ete_radio'.$key).'<br />';if ($key == $matched)
{
echo '<div>';
$match = true;
}
else
{
echo '<div>';
}// 正規表現をそのまま表示すると正しく表示されないため、エスケープ
echo '比較される正規表現:'.Security::htmlentities($item['exp']).'<br />';if ($key === $p404)
{
echo '404で_404_と一致';
}
elseif ($key == $matched)
{
if ($key == '_root_')
{
echo 'デフォルトとして_root_と一致';
}
else
{
ksort($matches, SORT_LOCALE_STRING);
foreach ($matches as $k => $m)
{
if (is_numeric($k))
{
echo '$'.$k.' => '.'"'.$m.'"<br />';
}
else
{
echo '$this->param("'.$k.'") => "'.$m.'"<br />';
}
}
}
}
echo '</div><hr />';
}// 出力行数をhiddenで保存しておく
echo Form::hidden('total_line', $last_key + 1);// ルーティング追加行表示
echo '<p>ルーティング追加</p>';
for ($i = 0; $i < self::NEW_ROUTE; $i++)
{
echo Form::input('new_line'.$i, ($last_key + $i + 1) * 10, array('size' => 3)).' : ';
echo Form::input('new_pattern'.$i, '', array('size' => 50)).' ';
echo Form::input('new_class_action'.$i, '', array('size' => 50)).'<br />';
}
echo '<hr />';echo Form::submit('submit', '更新');
echo Form::close();echo '</body>';
}}
| HTMLpurifierがFuelPHPで使えました< 前 | 次 >FuelPHP、固定ページ編集パッケージ |
|---|
| < 前 | 次 > |
|---|