--> -->

skimemo


Laravel のバックアップソース(No.3)

* 今日のLaravel [#ta529ca4]
これは、Laravel(5.4)を使った開発の中で気づいた事を毎日一つメモしていくものです。
----
** 2018/12/5 resourceのroute名の変更方法 [#k2619b38]
開発を進めていくと、routeの記述がどうしても長大になりがちな中で、resource定義は一行で複数の挙動が定義できて、しかもroute名も自動で定義してくれてとても助かります。~
しかし、例えば以下のように別々のディレクトリ内で同じ定義名を使いたい場合があります。
#code(php){{
Route::resource('user/regist', 'UserHogeController');
 Route::resource('product/regist', 'ProductHogeController');
}}
この場合、route名はどちらも「regist.index」等となってしまい、別々に識別することができなくなってしまいます。~
~
この問題の解決方法として、[[マニュアル:https://readouble.com/laravel/5.4/ja/controllers.html#restful-naming-resource-routes]]では以下のように再定義できると書かれています。
#code(php){{
Route::resource('photo', 'PhotoController', ['names' => [
    'create' => 'photo.build'
]]);
}}
しかし、アクションがindex,create,store,show,edit,update,destroyと7つもあるのに、いちいち書いていたらroute定義が無駄に長くなってしまいます。
そこで、resource()のソースを確認すると、&inlinecode{Illuminate\Routing\ResourceRegistrar::getResourceRouteName()};で以下のように作成していました。
#code(php){{
if (isset($options['names'])) {
	if (is_string($options['names'])) {
		$name = $options['names'];
	} elseif (isset($options['names'][$method])) {
		return $options['names'][$method];
	}
}
(後略)
}}
stringも許可しています。なので、以下の通り指定すると7つのアクション全てを書き換えてくれます。
#code(php){{
Route::resource('user/regist', 'UserHogeController',['names'=>'user-regist']);
 Route::resource('product/regist', 'ProductHogeController',['names'=>'product-regist']);
}}
便利(^^)~
~
----
** 2018/12/6 apiでセッションを使おうとするとformと両立できない [#o0b28b82]
LaravelではAPIアクセスはapi.phpで定義できますが、ステートレスなアクセスを前提としているため、セッションを使うことができません。((参考ページ: https://qiita.com/pinekta/items/d10c8374b1a3003cd952))~
参考ページの通りに対応すればセッションが有効になりますが、以下の手順で操作した場合にCSRFエラーになります。~

+ フォームの中でボタンを押すとajaxを使用してAPIアクセス
+ フォームからpostでsubmit

#ref(csrf.png)~
~
想像ですが、APIアクセス時にセッション保持しているCSRFトークンが書き換わってしまい、フォームに埋め込まれたトークンと一致しなくなってしまうと考えられます。~
~
私の場合はやむなく無認証にしましたが、どうしても認証したい場合は、アクセストークン方式にする必要があるのではないかと思います。
~
----
** 2018/12/7 php5とphp7での配列を使ったメソッド呼び出しの挙動の違い [#bfdade1e]
以下のコードにおいて、php5とphp7で挙動の違いがありました。
#code(php){{
<?php

class test {

	public function __construct() {
		echo "test!\n";
		$method[0] = "test2";
		$this->$method[0]();
	}

	private function test2() {
		echo "test2\n";
	}

}

new test();
}}
- php5(5.6.30)の場合
 >php test.php
 test!
 test2
- php7(7.1.24)の場合
 >php test.php
 test!
 PHP Notice:  Array to string conversion in F:\test.php on line 8
 PHP Stack trace:
 PHP   1. {main}() F:\test.php:0
 PHP   2. test->__construct() F:\test.php:17
         :
 PHP Fatal error:  Uncaught Error: Function name must be a string in F:\test.php:8
どうやら変数が配列の場合、php7だと「$this->$method」で一旦区切って解釈するようです。~
~
解決方法は以下の通り。
 -	$this->$method[0]();
 +	$this->{$method[0]}();
これでphp5でも7でも動作するコードになりました。