質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

解決済

4回答

3778閲覧

laravel5の2階層の一括ルーティング

SeijiroKomatsu

総合スコア18

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

0グッド

0クリップ

投稿2017/07/06 10:02

###前提・実現したいこと
全てアクセスに関して1つ1つルーティングしていくのはすごく面倒なので
https://ドメイン/ディレクトリ/コントローラファイル名/アクション名/id/
っていうふうにしたいです。
ルーティングの設定をどのようにすればいいのでしょうか?

###発生している問題・エラーメッセージ

他のサイトをいくらぐぐっても無理でした。

エラーメッセージ

###該当のソースコード
php

Route::any('{one?}/{two?}/{three?}/{four?}/{five?}/{six?}/{seven?}/{eight?}/{nine?}/{ten?}/'
, function($one='top',$two=null,$three=null,$four=null) {
$app = app();

$two = ucfirst($two); $app_path = app_path(); if (file_exists($app_path.'/Http/Controllers/'.$one.'/'.$two.'Controller.php')) { $controller = "App\Http\Controllers\".$one."\".$two."Controller"; $foo = new $controller; $foo->$three($four); } else { header("HTTP/1.0 404 Not Found"); die(View::make('common/404')); }

});

###試したこと と書くとViewが動かなくなりました。 laravel4なら動いてたのに、5になって動かなくなりました。 ###補足情報(言語/FW/ツール等のバージョンなど) laravel5

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

https://ドメイン/ディレクトリ/コントローラファイル名/アクション名/id/

このように決めているのであれば、以下のようにしてはどうでしょう。
(Laravelのバージョンは5.4)

ルーティング(汎用的なものに修正)

PHP

1// その他ルーティング 2Route::any('a/b/c', 'AbcsController@abc'); 3 4// [ 規定 ] 5// https://ドメイン/ディレクトリ/コントローラファイル名/アクション名/id/ 6$paths = explode('/', Request::path()); 7if (!empty($paths) && count($paths) >= 3) { 8 // 規定にマッチするが、別にルーティングをしたい場合 9 // 規定と同じURLのものがある場合は、先に書いた方が優先して表示される 10 Route::any('aa/bb/cc', 'FugasController@aaa'); 11 12 // 規定通りにルーティングをする場合 13 $paths[0] = \Doctrine\Common\Inflector\Inflector::classify($paths[0]); 14 $paths[1] = \Doctrine\Common\Inflector\Inflector::classify($paths[1]); 15 Route::group(['namespace' => $paths[0]], function () use ($paths) { 16 Route::any('{directory}/{controller}/{action}/{id?}/', $paths[1].'Controller@'.$paths[2]); 17 }); 18}

コントローラーの例

PHP

1namespace App\Http\Controllers\Hoge; 2 3class HogesController extends \App\Http\Controllers\Controller 4{ 5 public function show($directory, $controller, $action, $id=null) 6 { 7 dd([$directory, $controller, $action, $id]); 8 } 9}

例:
https://example.com/hoge/hoges/show/123/
(ドメイン:example.comを利用)
(ディレクトリー:App\Http\Controllers\Hogeにコントローラーがある)
(コントローラー:HogesController)
(アクション:showアクションにアクセス)
(ID:idは123)

上記ルーティングのコードの\Doctrine\Common\Inflector\Inflector::classify()は以下を使っています。

PHP

1/** 2 * Converts a word into the format for a Doctrine class name. Converts 'table_name' to 'TableName'. 3 * 4 * @param string $word The word to classify. 5 * 6 * @return string The classified word. 7 */ 8public static function classify($word) 9{ 10 return str_replace(" ", "", ucwords(strtr($word, "_-", " "))); 11} 12

投稿2017/07/06 14:12

編集2017/07/08 07:15
coba-coba

総合スコア1409

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SeijiroKomatsu

2017/07/07 01:07

回答ありがとうございます。 ディレクトリはView内ではなくコントローラ内にディレクトリがほしいです。
coba-coba

2017/07/07 17:02 編集

修正しました。 Route::group()の'namespace'でコントローラー内のディレクトリを指定します。 ディレクトリが変わるので、コントローラーではnamespaceをApp\Http\Controllers\Hogeとして、Controllerについてもextends \App\Http\Controllers\Controllerのように指定します。
SeijiroKomatsu

2017/07/08 05:40

ありがとうございました。解決しました。namespaceを考慮する必要があったんですね。
guest

0

もうちょっと修正を加えました。 参考までに

$paths = explode('/', Request::path());
$paths[0] = isset($paths[0]) ? ucfirst($paths[0]) : '';
$paths[1] = isset($paths[1]) ? ucfirst($paths[1]) : '';
$paths[2] = isset($paths[2]) ? $paths[2] : 'default';
if (file_exists(app_path().'/Http/Controllers/'.$paths[0].'/'.$paths[1].'Controller.php')) {
$controller = 'App\Http\Controllers'.$paths[0].''.$paths[1].'Controller';
$instance = new $controller;
if (method_exists($instance,$paths[2])) {
Route::group(['namespace' => $paths[0]], function () use ($paths) {
Route::any('{directory}/{controller}/{action?}/{id?}/{five?}/{six?}/{seven?}/', $paths[1] . 'Controller@' . $paths[2]);
});
}
}

投稿2017/12/29 06:01

SeijiroKomatsu

総合スコア18

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

if文をついかすれば安全ですね。ありがとうございました。

投稿2017/08/25 02:48

SeijiroKomatsu

総合スコア18

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自己解決

$paths = explode('/', Request::path()); $paths[0] = isset($paths[0]) ? ucfirst($paths[0]) : ''; $paths[1] = isset($paths[1]) ? ucfirst($paths[1]) : ''; $paths[2] = isset($paths[2]) ? $paths[2] : ''; if (file_exists(app_path().'/Http/Controllers/'.$paths[0].'/'.$paths[1].'Controller.php')) { Route::group(['namespace' => $paths[0]], function () use ($paths) { Route::any('{directory}/{controller}/{action}/{id?}/', $paths[1].'Controller@'.$paths[2]); }); }

ありがとうございました。解決しました。

投稿2017/07/08 05:39

SeijiroKomatsu

総合スコア18

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coba-coba

2017/07/08 07:39

解決してよかったです! でも「解決した方法」は細かいところを除いてまんま私のコードですよね… 下記の回答では回答用にポイントを絞って書いており変なところがあったので、汎用的なものに書き換えました。 ルーティングではファイルの有無をチェックする必要は基本的にはありません。 ルーティングで拾えないものは404となるだけです。 ただ、自分の規定通りのアクセスがきた場合のみ、500エラーにならないように気を付ける必要はあります。 あと、以下は好みの話ですが…… コントローラーの名前などは自分で好きにつければいいと思いますが、私はNamesControllerやTableNamesControllerとしたいです。 また、\Doctrine\Common\Inflector\Inflector::classify()を使ってURLを変換したいです。 なぜなら、URLを/table_names/…のように指定した場合、簡単に"TableNames"に変換することができるためです。 ucfirst()を使う場合は"TableNames"に一発で変換するためには、URLを/tableNames/…のように一部大文字を使ってあらわす必要があるためです。 URLに大文字は不格好なイメージがあります。 すみません好みの問題ですが。
SeijiroKomatsu

2017/07/08 12:11

>ルーティングで拾えないものは404となるだけです。 これは試してみたいと思います。 \Doctrine\Common\Inflector\Inflector::classify()でそういう使い方ができるんですね。 回答ありがとうございました。助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問