18
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Laravelでmultipart/form-dataのPUT,PATCH,DELETEのパラメタが取れない

Last updated at Posted at 2018-03-15

問題

RESTFulなAPIサーバを作るとき、パラメタのあるPUTやPATCHメソッドを定義することがよくあります。しかしLaravelで普通に実装すると、パラメタをapplication/x-www-form-urlencodedで渡したときはうまく動きますが、multipart/form-dataだとパラメタが取れません。これはかなり以前からある問題(Input from PUT requests sent as multipart/form-data is unavailable #13457)でこのissueはcloseされているのですが問題は解決していません。(なぜ問題が残っているのにcloseされたのかはよくわかりません)

これはPHPがPOSTメソッド以外ではapplication/x-www-form-urlencodedやmultipart/form-dataで渡されたパラメタの処理をしてくれない仕様だからで、application/x-www-form-urlencodedについてはSynfonyのSymfony\Component\HttpFoundation\Requestクラスがなんとかしてくれますが、multipart/form-dataについては誰も何もしてくれないからです。

対処方法

いくつかの対処方法を紹介します

apiを呼ぶ側で_methodパラメタに本来呼びたいメソッドを設定してPOSTする。

proxyがPUT,PATCHに対応してないときなんかに使う代替手段を利用するやり方です。サーバ側は何もしなくていいですが、使う側には負担になります。

multipart/form-dataを解釈するプログラムを用意する

先ほどのissueの議論の中でもこの方向でプログラムを書いた人がいて、https://gist.github.com/devmycloud/df28012101fbc55d8de1737762b70348 が紹介されています。

ただしいったんphp://inputの内容を変数に受ける実装なので、大きなファイルを扱うAPIなどではこのままでは使えないと思います。

pecl/apfdを使う

apfdはPHPがPOST以外のメソッドでもパラメタの処理をするようになる機能拡張です。PHP本体がデフォルトでこちらの動作になっててもいいと思うのですが、やはり過去との互換性とかいろいろ事情があるのでしょうか。

まとめ

もしextensionの追加ができるならapfdを使うのが一番楽だと思います。

18
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?