--> -->

skimemo


Laravel のバックアップ差分(No.4)


  • 追加された行はこの色です。
  • 削除された行はこの色です。
* 今日のLaravel [#ta529ca4]
これは、Laravel(5.4)を使った開発の中で気づいた事を毎日一つメモしていくものです。
これは、2018アドベントカレンダー記事で、Laravel(5.4)を使った開発の中で気づいた事を毎日一つメモしていくものです。
#contents
----
** 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でも動作するコードになりました。
~
----
** 2018/12/8 WYSWYGエディタには要注意 [#j53c17f7]
WYSWYGはWhat You See What You Getの略で、直訳すると見たままの物が得られる、という意味です。~
そんなの当たり前じゃん、と言っているそこの若者! [[これが誕生した頃は画期的:https://ja.wikipedia.org/wiki/WYSIWYG#%E6%84%8F%E5%91%B3]]だったのですよ(Appleが広めた)。~
~
まあそんなことはいいとして、フリーで使えるWYSWYGエディタは各種あります。((https://engineer.blog.lancers.jp/2017/12/wysiwyg_editor_best_7/))~
私が試したのは[[Trumbowyg:https://alex-d.github.io/Trumbowyg/]]。簡単にこんなTEXTAREAが得られます。~
#ref(trumbowyg1.png)~
~
使い方はこんな感じ。~
#code(php){{{
{{Form::textarea('description')}}
 {{Html::style(asset('trumbowyg/dist/ui/trumbowyg.min.css'))}}
 {{Html::script(asset('trumbowyg/dist/trumbowyg.min.js'))}}
 {{Html::script(asset('trumbowyg/dist/langs/ja.min.js'))}}
 <script language="JavaScript">
	$('textarea').trumbowyg({
		lang: 'ja',
	});
 </script>
}}}
&size(10){(スクショはプラグインを幾つか入れてます)};~
~
このエディタ、画面上に得るべき物を表示しているということは、HTMLタグをレンダリングしているということになります。このTrumbowygは生HTMLも書けるので、試しにJavascriptタグを埋めてみます。~
#ref(trumbowyg2.png)~
~
そして生HTMLモードを解除してみると・・・~
#ref(trumbowyg3.png)~
~
うーん、ダメだこりゃ。これではユーザーが自由にこのサーバー上でJavascriptを動かせちゃうということです。~
生HTMLは書けないモードにして使う必要がありそうです。~
Trumbowygはボタンのカスタマイズができますので、例えばこんな感じです。~
#code(php){{
<script language="JavaScript">
	$('textarea').trumbowyg({
		lang: 'ja',
		btns: [
			['undo', 'redo'], // Only supported in Blink browsers
			['formatting'],
			['strong', 'em', 'del'],
			['superscript', 'subscript'],
			['link'],
			['insertImage'],
			['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],
			['unorderedList', 'orderedList'],
			['horizontalRule'],
			['removeformat'],
			['fullscreen'],
		]
	});
</script>
}}