--> -->
これは、2018アドベントカレンダー記事で、Laravel(5.4)を使った開発の中で気づいた事を毎日一つメモしていくものです。
開発を進めていくと、routeの記述がどうしても長大になりがちな中で、resource定義は一行で複数の挙動が定義できて、しかもroute名も自動で定義してくれてとても助かります。
しかし、例えば以下のように別々のディレクトリ内で同じ定義名を使いたい場合があります。
1 2 |
|
この場合、route名はどちらも「regist.index」等となってしまい、別々に識別することができなくなってしまいます。
この問題の解決方法として、マニュアルでは以下のように再定義できると書かれています。
1 2 3 |
|
しかし、アクションがindex,create,store,show,edit,update,destroyと7つもあるのに、いちいち書いていたらroute定義が無駄に長くなってしまいます。 そこで、resource()のソースを確認すると、Illuminate\Routing\ResourceRegistrar::getResourceRouteName()で以下のように作成していました。
1 2 3 4 5 6 7 8 |
|
stringも許可しています。なので、以下の通り指定すると7つのアクション全てを書き換えてくれます。
1 2 |
|
便利(^^)
LaravelではAPIアクセスはapi.phpで定義できますが、ステートレスなアクセスを前提としているため、セッションを使うことができません。*1
参考ページの通りに対応すればセッションが有効になりますが、以下の手順で操作した場合にCSRFエラーになります。
想像ですが、APIアクセス時にセッション保持しているCSRFトークンが書き換わってしまい、フォームに埋め込まれたトークンと一致しなくなってしまうと考えられます。
私の場合はやむなく無認証にしましたが、どうしても認証したい場合は、アクセストークン方式にする必要があるのではないかと思います。
以下のコードにおいて、php5とphp7で挙動の違いがありました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
>php test.php test! test2
>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でも動作するコードになりました。
WYSWYGはWhat You See What You Getの略で、直訳すると見たままの物が得られる、という意味です。
そんなの当たり前じゃん、と言っているそこの若者! これが誕生した頃は画期的だったのですよ(Appleが広めた)。
まあそんなことはいいとして、フリーで使えるWYSWYGエディタは各種あります。*2
私が試したのはTrumbowyg。簡単にこんなTEXTAREAが得られます。
使い方はこんな感じ。
1 2 3 4 5 6 7 8 9 |
|
(スクショはプラグインを幾つか入れてます)
このエディタ、画面上に得るべき物を表示しているということは、HTMLタグをレンダリングしているということになります。このTrumbowygは生HTMLも書けるので、試しにJavascriptタグを埋めてみます。
そして生HTMLモードを解除してみると・・・
うーん、ダメだこりゃ。これではユーザーが自由にこのサーバー上でJavascriptを動かせちゃうということです。
生HTMLは書けないモードにして使う必要がありそうです。
Trumbowygはボタンのカスタマイズができますので、例えばこんな感じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
ただし、これでもブラウザのJavascriptを無効にして、<script>タグ書いて、再度有効にすればやはり実行できます。うーん悩ましい・・・。
追記: ぬれぎぬでした・・・→#q4ca3ee1
一番ひっかかっのはS3の設定です(^^;)。当初S3の設定が良く分からなかったのですが、こちら*3に非常に詳しく書かれています。感謝!
S3のバケットを作るだけではダメで、S3とは独立した設定でユーザーを作るのが必要でした。AWSの基本?(^^;)
但し、上記の方法はユーザーの認証情報とバケットを結びつけていないため、このユーザーのS3には全てアクセスできてしまうと思われます。実際には当該バケットに限定した権限設定が必要でしょう。
まずはコードの確認でlocalに保存してみます。
1 2 3 4 |
|
1 2 3 |
|
すると、storage/app/hogeの下に、ユニークなファイル名でファイルが保存されます。(Oc4GsSGFIe3NkjnUUttt4mnaRtpKklQhv5ZArdMq.txt みたいな感じ)
従って、元のファイル名はgetClientOriginalName()を使って別途保存しておく必要があります。
次に、S3に保存してみます。
これは簡単で、コードを以下のように変えるだけです。(もちろんS3の設定、.envの設定、league/flysystem-aws-s3-v3の導入は済んでいる前提です)
1 |
|
しかし、ここで問題が起きました(ネタ、来た(笑))
以下のようなエラーが発生しました。
要約すると、ローカルの証明書が無いからSSLアクセスができない、ということです。調べるとWindowsのCURLはデフォルトで証明書が無いためSSLアクセスがエラーになるということが分かりました(S3関係ないやん・・・(笑))。
検索するとCURLにオプションを付ける対策などが出てくるのですが、LaravelFWをいじることになるので却下。
こちら*4のページにある方法で解決しました。
実行後、S3のコンソールでファイルが確認できれば成功です。
ちなみに、localからS3に切り替える場合、いちいちコードを修正しなければいけないのでしょうか? もちろんそんなことはありません。Storage::disk()のソースを見ると、
1 2 3 4 5 6 7 8 9 10 |
|
のようになっています。つまりStorage::disk()と引数無しにしておけば、.envを変更するだけで切り替えられるようになります。(もちろん切り替え時のデータ移行は必要ですけど)
私は複数箇所に開発環境があるのですが、片方は本番と同じphp5.6+MySQL5.7です。もう一方はなるべく新しい環境でも動作することを担保するため、php7+MySQL8にしてみました。そこで分かったことを2つ(3つ?)。
12/8にWYSWYGエディタに生HTMLが書けてしまう危険性について書きました。
その後色々調べてみると、どうやら使い方に問題があることが分かりました。エディタのせいにしてしまってごめんなさいm(_ _)m
前回は{{Form::textarea()}}を使っていたのですが、これだとJavascriptを無効にしてもテキスト入力ができてしまい、脆弱性が生まれます。
Javascriptが無効の時は入力も無効になるよう、以下のようにすればOKです。
1 2 3 4 5 6 7 |
|
サンプルもこのようになっているんですが、一部のドキュメント*9はtextareaを使っちゃってるんですよね。これ危険では・・・(^^;)
ちなみにsubmitの時は、divでは値が飛ばないので一工夫必要です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
今日はディレクトリ内にあるファイルを拾ってSQL文にかけるというコマンドライン処理を書いていました。
サンプル的に書くと以下のような感じです。
1 2 3 4 5 6 7 |
|
2カ所ある環境のうち、1カ所(環境A)では問題無く動いたのですが、もう一方(環境B)では何故かエラーになりました。どちらもWindows10Proです。
SQLSTATE[HY000]: General error: 1267 Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8mb4_unicode_ci,COERCIBLE) for operation '=' (SQL: select count(*) as aggregate from `migration` where `name` = 20181202_instにstatus追加.txt)
DBのcollationはutf8_general_ciです。何故かWindowsのファイル名はutf8mb4_unicode_ciとなっているようです。ちなみにソースはUTF8で書かれています。
環境Aでこのまま動いたのが謎ではあるのですが、普通に考えるとWindowsはSJIS環境ですので、以下の変換を入れてみます。
$filename = mb_convert_encoding($filename,mb_internal_encoding(),(PHP_OS=='WINNT'?'SJIS':'UTF-8'));
すると、エラー無く動作するようになりました*10。(DBへの照会も正しくされていました)
何故同じWindows10でこのような差が出るのかは謎です。思い当たる違いと言えば、環境Aは今年のWindows10クリーンインストールで、環境BはMSDNのWindows10 1151からのアップデートということぐらいですが・・・。なぜ?(笑)
LaravelでセッションIDで認証状態をチェックするステートフルなAPIを使う
https://qiita.com/pinekta/items/d10c8374b1a3003cd952
商用でも利用できる、イケてるWYSIWYGエディタ7選 2017年版
https://engineer.blog.lancers.jp/2017/12/wysiwyg_editor_best_7/
超簡単!LaravelでS3を利用する手順
https://qiita.com/tiwu_official/items/ecb115a92ebfebf6a92f
cURL error 60: SSL certificate in Laravel 5.4
https://stackoverflow.com/questions/42094842/curl-error-60-ssl-certificate-in-laravel-5-4
PHP 5.6.x から PHP 7.0.x への移行
http://php.net/manual/ja/migration70.new-features.php#migration70.new-features.return-type-declarations
PHP7.2のcountにハマった話
https://qiita.com/masaki-ogawa/items/1671d110b2286ececd09
Laravel5 MySQL8.0 NO_AUTO_CREATE_USERのSQL_MODEエラー対策
https://qiita.com/ucan-lab/items/2a482a9537dcc5daeb97
Default laravel's strict mode isn't compatible with MySQL 8.0 (NO_AUTO_CREATE_USERS)
https://github.com/laravel/framework/issues/23970
https://alex-d.github.io/Trumbowyg/documentation/#prefix
この変換処理が環境AやLinux環境で正常に動作するかは未確認です