前回は単純なファイルアップローダを作成しました。
今回はアップロードされたファイルを別のサーバへ送信します。
ここでは、別サーバをローカルの別領域として実装します。
前回のアップロードファイルの流れは以下です。
クライアント ⇒ ローカルホスト(“TestFileMove”)
今回のアップロードファイルの流れは以下です。
クライアント ⇒ ローカルホスト(“TestFileMove”) ⇒ ローカルホスト(“TestFileGet”)
今回はボリュームが多いです。
Contents
送信側の作成 (“TestFileMove”)
自分でHTTPリクエストの内容を作成し、他のサーバへ送信します。
要するにHTTPのヘッダやボディを作成します。
ヘッダと言っても文字列を自分で作成するだけです。
ボディにはファイルの内容を詰め込みます。ファイルの内容はバイナリデータですが、PHPの “file_get_contents” でファイルの内容を取得出来ます。
前回 作成した test.php を以下のように記載します。
番号の順で説明します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<?php //①アップロードされたファイルのパスとファイル名を取得する。 $filePath = $_FILES['upfile']['tmp_name']; $fileName = basename($filePath); //②アップロードされたファイルの内容を取得する。 $file = file_get_contents($filePath); //③送信先URLを指定する。 $url = 'http://localhost/TestFileGet/test.php'; //④バウンダリを作成する。 $boundary = '--------------------------'.microtime(true); //⑤ヘッダーを作成する。 $headers = [ 'Accept-language: ja', 'Cookie: hash=12345abcde', 'Content-Type: multipart/form-data; boundary='.$boundary ]; //⑥ボディにファイル名とファイルの内容を詰め込む。 $content = '--'.$boundary."\r\n". 'Content-Disposition: form-data; name="userfile"; filename="'. $fileName . '"' . "\r\n" . 'Content-Type: text/plain'."\r\n\r\n". $file ."\r\n". '--'.$boundary.'--'."\r\n"; //⑦送信先への送信データ(ヘッダ、ボディ)を作成する。 $opts['http'] = [ 'method' => 'POST', 'header' => implode("\r\n", $headers), 'content' => $content, ]; $context = stream_context_create($opts); //⑧送信先へデータを送信する。 $contents = file_get_contents($url, false, $context); |
① アップロードされたファイルのパスとファイル名を取得する。
クライアントから送信されたファイルはクライアントからのリクエストとして “$_FILES” 変数に格納されます。
“$_FILES[‘upfile’][‘tmp_name’]” でアップロードされたファイルのフルパスを取得出来ます。
‘upfile’にはファイルアップロード画面にあるinputタグのname属性値を記載します。分からない場合は前回のindex.phpを確認して下さい。
‘tmp_name’は、’tmp_name’と指定することで、アップロードファイル一時格納領域に格納されたファイル名(フルパス)を取得します。
アップロードファイル一時格納領域は、ファイルがアップロードされたら決まって一時的に格納される場所です。これは、php.iniの “upload_tmp_dir” に記載されています。
basename() はファイルのフルパスからファイル名を抜き出します。
② アップロードされたファイルの内容を取得する。
file_get_contents(“ファイルのフルパス”) でファイルのバイナリデータを取得出来ます。
③ 送信先URLを指定する。
送信先のURLを記載します。例として送信先をローカルホストのドキュメントルート以下の”TestFileGet”以下、test.phpを指定します。
test.php は後の “受信側の作成 (“TestFileGet”)” にて説明します。
④ バウンダリを作成する。
バウンダリはデータの区切りです。
バウンダリは複数のデータを送信する際の境界として使用します。HTTP送信時の決まりです。
microtime(true) でバウンダリにマクロ時間を記載しています。
⑤ ヘッダーを作成する。
HTTPヘッダには色々設定出来ます。ここではHTTPヘッダに設定出来るパラメータについては記載しませんが、内容としては以下です。
送信は日本語で、クッキーは適当に指定する。
肝心なのは④で作成したバウンダリです。
ヘッダにバウンダリを設定します。
⑥ ボディにファイル名とファイルの内容を詰め込む。
詳細は別に譲りますが、ボディには ①で作成したファイル名と ②で取得したファイルの内容を設定しています。
⑦ 送信先への送信データ(ヘッダ、ボディ)を作成する。
送信するデータを配列 (“$opts”) に格納し、stream_context_create($opts) で送信データ(コンテキストストリーム)を作成します。
⑧ 送信先へデータを送信する。
file_get_contents()で他へファイルを送信します。第一引数に送信先URL、第二引数はfalse、第三引数は送信データを指定します。
受信側の作成 (“TestFileGet”)
受信側も送信されたファイルの内容はリクエストとして “$_FILES” 変数に格納されます。
ここでは単純な処理として送信されたファイルをカレント(Test.php)と同階層にコピーしています。
以下、受信側 “C:\xampp\htdocs\TestFileGet\test.php” を作成します。
1 2 3 4 5 |
//ファイル名を取得する。 $fileName = basename($_FILES['userfile']['name']); //ファイルをコピーする。 copy($_FILES['userfile']['tmp_name'], dirname(__FILE__) . "/". $fileName); |
結果は受信側 “C:\xampp\htdocs\TestFileGet” 以下に.tmpファイルが作成されているはずです。
最後に
少々分かりづらいかもですが、この内容は他のサイトでも記載がありますのでそちらを参考するのも良いでしょう。
以上です。