質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

cURL

cURLはHTTP, FTPやTelnetなど複数のプロトコルを用いてデータを転送するライブラリとコマンドラインツールを提供します。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

16314閲覧

PHPでフォームを使わずにCSVファイルをPOST送信する方法

chapter

総合スコア36

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

cURL

cURLはHTTP, FTPやTelnetなど複数のプロトコルを用いてデータを転送するライブラリとコマンドラインツールを提供します。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2016/01/10 17:32

いつもお世話になっております。

標記の件について、HTMLで記述したフォームを利用してPOST送信することはできるのですが、
フォームを介さずに指定したURLでダウンロードできるCSVファイルを別のアップロード用URLに
POST送信したく、いろいろと調べてみたのですが、自己解決できなかったので、
こちらに聞きこみさせていただきました。

POST送信にはcURLを利用しています。

ちなみに、指定したURLからCSVファイルの情報を取得する部分までは、
以下のコードで特に問題なくできています。

php

1$download_url = 'http://sample.com/download/'; 2 3$ch = curl_init($download_url); 4curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 5$content = curl_exec($ch); 6curl_close($ch); 7

$contentの中身を出力して、CSV形式のデータが表示されることは確認済みです。

そして、問題なのがPOST送信の方になります。

php

1$upload_url = 'http://sample.com/upload/'; 2$header = array( 3 'Content-Type: multipart/form-data', 4 'Content-Length: ' . strlen($content), // ここは自信ないです。 5); 6$post_data = array( 7 'file' => $file, // ここに何を入れていいのかがよく分かっていません 8); 9 10$ch = curl_init($upload_url); 11curl_setopt($ch, CURLOPT_POST, true); 12curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 13curl_setopt($ch, CURLOPT_HTTPHEADER, $header); 14curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); 15$response = curl_exec($ch); 16curl_close($ch);

上記のコメントのところに書きましたように、アップロード側の受け入れ先の変数名である
「file」に何を入れたらよいのか分からなかったので、
試しにHTMLのフォームでファイルをPOSTした時の$_FILEを参考に以下のように書いてみましたが、

php

1$file = array( 2 'name' => 'upload.csv', 3 'type' => 'text/csv', 4 'tmp_name' => $content, // ここに何を入れていいのかがよく分かっていません 5 'error' => 0, 6 'size' => strlen($content), // ここも自信ないです。 7);

「tmp_name」のところは、フォームからアップロードした際の一時ファイルの
保存先のため、自分でもまず間違いだと思っています。

ただ、フォームを介さない場合のファイルデータの場合は、
何を入れるべきか見当がつかない状況です。

php

1$post_data = array( 2 'file' => '@./upload.csv;filename=upload.csv;type=text/csv', 3);

また、いろいろと検索している際、「file」の部分は上記のような記述方法を
見かけましたが、こちらも最初のファイル名は一時ファイルの保存先と思われるため、
結局何を入れるべきか分かりませんでした。

つきましては、フォームを介さずにCSVファイルをPOST送信する方法について、
ご教授いただければ幸いです。

「file」部分にこだわっていましたが、全く見当違いのことを調べているかも
知れませんし、他にもっとスマートな実装方法があれば、
PHPであれば特にcURLでのPOST送信にはこだわりません。

それでは、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

私自身は試していませんが、事例を見つけましたので参考にどうぞ。

seijimomoto.blogspot.com: PHP cURL関数でPOSTフィールドに配列データとファイルを同時に指定する
http://seijimomoto.blogspot.jp/2012/02/php-curlpost.html
[PHP] cURLのPOSTでファイルアップロードする方法 – 零弐壱蜂
http://b.0218.jp/20140117004504.html

投稿2016/01/11 02:48

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chapter

2016/01/11 06:37

m6uさん、ご回答ありがとうございます。 ご提示していただいたURLを参考にして、改めて取得したCSVデータを ファイルに格納して、そちらのパスを指定するようにして、 以下のように修正してみました。 ※前回、省略した箇所も含めて追記しています。 ```php $download_url = 'http://sample.com/download/'; $ch = curl_init($download_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $content = curl_exec($ch); curl_close($ch); $filename = 'upload.csv'; $file_path = '/tmp/upload.csv'; file_put_contents($file_path, $content); // CSVファイルが生成されることは確認済みです。 $file_size = filesize($file_path); // テストしたファイルのサイズは8KBくらいです。 $upload_url = 'http://sample.com/upload/'; $header = array( 'Content-Type: multipart/form-data', 'Content-Length: ' . file_size, 'Authorization: Bearer <アクセストークン>', // こちらの認証については他の処理で成功しているので、特に問題ないと思います。 ); $post_data = array( 'type' => 1, // アップロード側で必要なリクエストパラメータ 'file' => "@{$file_path};filename={$filename};type=text/csv;size={$file_size}", ); $ch = curl_init($upload_url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $response = curl_exec($ch); curl_close($ch); ``` 上記のように修正したことにより、ひとまずPOST送信するところまでは できたようですが、送信先でエラーが発生している状態です。 > 413 Request Entity Too Large > > The requested resource does not allow request data with POST requests, > or the amount of data provided in the request exceeds the capacity limit. 上記のようなエラーメッセージが表示されてしまうのですが、 ファイルサイズ的には許可されている容量である100MBよりもはるかに軽い 8KBのファイルなので、何が原因なのか判別できずにいます。 つきましては、上記のソースとエラーメッセージから、 何か問題点や確認事項などが分かる方がいらっしゃれば、 ご教授をお願いいたします。
chapter

2016/01/11 06:47

なお、アップロード先で返ってきているエラーメッセージなので、 送信元のサーバの設定とは無関係かもしれませんが、 ウェブサーバとして利用しているNginxの設定ファイルに client_max_body_size 20M; を追記して、更新しても状況は変わりませんでした。
chapter

2016/01/11 09:01

m6uさん、ご返信ありがとうございます。 service nginx reload  と nginx -s reload の両方で更新しましたが、状況は変わりませんでした。 記述場所がご提示いただいた場所と若干違ったので、 そちらも変えて試してみましたが、変わりませんでした。 ただ、このメッセージが出ているサーバは外部のものなので、 送信している自前のサーバの設定を変えても関係ないのかなとも 思っております。 送信先はYahoo!ストアのショッピング用APIで公開されている URLなので、そちらのサーバの設定でサイズが絞られているとは 考え難い状況です。。。
chapter

2016/01/12 09:17

何とか解決しました! コマンドラインのcURLでいろいろとテストしてみたところ、 ヘッダーの「Content-Length」を入れない時に成功したので、 スクリプトの方も削除したところ、無事にアップロードができました。 なぜサイズを入れないと受け付けてくれないのかは、 アップロード側の仕様なのか謎のままなのですが。 あと、CSVファイルのMIME TYPEが間違っていたので修正しました。 (誤) text/csv (正) text/comma-separated-values ただ、こちらは下記の他、間違っている状態のままでも アップロード自体は成功しました。 text/plain application/vnd.ms-excel 最初はあまり重要視していなかったのですが、ファイル送信の時に 他のリクエストパラメータを含める場合は、 cURLでのオプションの指定も特殊なものになって、 スクリプトの書き方も工夫が必要だったのですが、 最初にm6uさんにご紹介していただいた1つ目の参考サイトを見て、 記述方法が分かったので、そちらでハマることがなかったのが 非常に助かりました。 この度はアドバイスいただき、ありがとうございました。
kihada

2017/05/18 09:02

chapterさん 同様の事を行いたくて、ぐぐったらこちらが引っかかったので参考にさせていただきました。 とても助かりました。ありがとうございました。 chapterさんがまとめてなかったら何時間もかかったと思います。。。 ヘッダーの「Content-Length」について報告ですが、 私の方では、ヘッダーの持ち方をポストデータと同じ持ち型にした所 うまく動きました。 $header = array( 'Content-Type'=>'multipart/form-data', 'Content-Length'=> $file_size, ); ちゃんと追う余裕もなくて申し訳ないですが、、、
chapter

2017/06/09 10:04

kihadaさん、こんばんは。 お返事が遅くなってしまい、失礼しました。 ご参考になったようでよかったです。 また、フィードバックの方もありがとうございます。 先ほど、私が挙げたソースコードを見たところ、 $header = array( 'Content-Type: multipart/form-data', 'Content-Length: ' . file_size, 【以下省略】 のようになっており、「file_size」が変数として「$file_size」 と記述されていないのに気づきました。(汗) 単純な転記ミスだったかも知れませんが、実際にこの記述だったら ファイルサイズでエラーが出るのは当然ですね。。。 時間に余裕ができたら、kihadaさんの記述の形も含めて、 ファイルサイズをちゃんと渡す方式でも試してみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問