Laravelの初歩の部分MVCの概念について勉強中です。
最新のLaravelのversionは8系。参考書のversionは5なのでいろいろ無理がありますが、早速はまりました。
<?php
use Illuminate\Support\Facades\Route;
/* 中略 */
Route::get('hello', 'HelloController@Index');
何のことはない、コントーローラを呼び出すだけのコードです。
しかし…
スペルミスじゃないしなぁと思いながら、いろいろ調べてみるとどうやらLaravel8xからwebルーティングに関する仕様変更があり、新規にプロジェクトを作成した際に起こるようです。
解決策
下記を参考にさせていただきました。ありがとうございます。
web.phpで完全な名前空間を使用する
<?php
use Illuminate\Support\Facades\Route;
/* 中略 */
Route::get('hello', 'App\Http\Controllers\HelloController@Index');
完全パスで書くってことですね。でも面倒だなぁ。
RouteServiceProvider.phpで名前空間を手動で追加する
RouteServiceProvider.phpをちょっといじる
/* 中略 */
protected $namespace = 'App\Http\Controllers'; //追加
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
});
}
protected $namespace = ‘App\Http\Controllers’; //追加
これで万事解決と思いきや問題が…、パラメータを付けたときにうまく動作しないのです。
例えばこんな感じ。
//web.php
<?php
use Illuminate\Support\Facades\Route;
/* 中略 */
//完全パスでも相対パスでも結果は同じ
//Route::get('hello/{id?}/{pass?}', 'App\Http\Controllers\HelloController@Index');
Route::get('hello/{id?}/{pass?}', 'App\Http\Controllers\HelloController@Index');
//コントローラ HelloController.php
public function index($id='nameless',$pass='unknown')
{
$html = "";
//中略
return $html;
}
web.phpでアクション構文を使用する
ということで、もうLaravel8から書き方を変えましょうということになりそうです。
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\HelloController; //追加
/* 中略 */
Route::get('hello', [HelloController::class,'index']);
//パラメータありバージョン
//Route::get('hello/{id?}/{pass?}', [HelloController::class,'index']);
割とスマート、でもコントローラ増やすたびにuse句が増えるのですが、まあしょうがないです。
根幹部分はあまり変えないでほしいです。