HTTP_RequestでPOSTするには - PHPプロ!Q&A掲示板

1160

  • 0P

HTTP_RequestでPOSTするには

質問日時 / 2008年5月7日 19:49    回答数 / 14件

Questioner:  318is  このエントリーをはてなブックマークに追加 

キーワード / PEAR    HTTP_Request    POST   

こんにちは。初めて質問させていただきます。

今回初めてPEARを使用しています。HTTP_Requestを使用して、自動でPOSTするプログラムを作成中です。
下記フォームの内容を自動でPOSTしたいと考えています。
  1. <form action="./hoge.php" method="POST" enctype="multipart/form-data">
  2. <div>
  3. <div>名前 <input type="text" name="name"></div>
  4. <div>コメント <textarea cols="50" rows="6" name="cmt"></textarea></div>
  5. <div>画像 <input type="file" name="pic"></div>
  6. <div><input type="submit" value="送る"></div>
  7. </div>
  8. </form>

上記フォームを自動で送信するためのプログラムです。
  1. ini_set('include_path','/usr/***/***/***/public_html/PEAR/'. PATH_SEPARATOR . ini_get('include_path') ); 
  2. require_once "HTTP/Request.php";
  3.  
  4. $post_url = "./hoge.php";
  5.  
  6. // POST パラメータ
  7. $post_data = array(
  8.   "name" => "名前",
  9.   "cmt" => "コメント",
  10. );
  11.  
  12. // アップロードパラメータ
  13. $pic = array(
  14.     "name" => "file",
  15.     "path" => "C:\uploadtest\hogehoge.jpg",
  16. );
  17.  
  18. // アップロード
  19. $rs = http_send($post_url, $post_data, $pic);
  20.  
  21. function http_send($url, $params, $pic=null) {
  22.     $req = new HTTP_Request();
  23.     $req->setMethod(HTTP_REQUEST_METHOD_POST);
  24.  
  25.     foreach ($params as $key => $val) {
  26.         $req->addPostData($key, $val);
  27.     }
  28.  
  29.     $req->setURL($url);
  30.     if ($pic) {
  31.         $res = $req->addFile($pic["name"], $pic["path"]);
  32.         if (PEAR::isError($res)) {
  33.             echo $res->getMessage();
  34.            exit;
  35.         }
  36.     }
  37.  
  38.     if (!PEAR::isError($req->sendRequest())) {
  39.         return $req->getResponseBody();
  40.     } else {
  41.       return false;
  42.     }
  43. }


上記プログラムでは、33行目のgetMessage()で

File 'C:\uploadtest\hogehoge.jpg' is not readable

と返ってきます。
34行目のexitを消すとテキストデータ($post_data)は送ることができるのですが、画像($pic)を送ることができません。
上記フォームから送信すると、受信側phpは正常に動作しますので、問題は送信側かと思います。


お分かりになる方いらっしゃいましたら、よろしくお願いします。

[補足]
なお、HTTP_Clientでの類似質問がありましたので試してみましたが、そちらもテキストは送れましたが、画像は送れませんでした。

この質問への意見の募集は締め切られ、ポイントは既に配分されました。
意見を投稿することはできますが、ポイントを受け取ることはできません。



ツリー一覧

┣A01signal>>CODE <?php $pic = array( "name" => "file"
┃┗A01-1318issignalさんご回答ありがとうございます。 >>CODE
┃ ┗A01-1-1kaitau> > > $post_url = "./hoge.php"; の記述と、 >
┃  ┗A01-1-1-1318iskaitauさん返信ありがとうございます。 >このプロ
┃   ┗A01-1-1-1-1signal画像はどこにあって PHPはどこにあって 画像をどこ
┃    ┗A01-1-1-1-1-1318issignalさん再び返信ありがとうございます。 「ロー
┃     ┗A01-1-1-1-1-1-1kaitauお疲れ様です。 > 「通常のフォームで入力」→「サ
┃      ┗A01-1-1-1-1-1-1-1318iskaitauさん 返信ありがとうございます。 まず、ご
┗A02weekendphpエラーの内容が、ファイルが読み込めない、というもの
 ┗A02-1318isweekendphpさん返信ありがとうございます。 上記プ
  ┗A02-1-1weekendphpfile_existsのマニュアルを見ると、 >この関数は
   ┗A02-1-1-1318isweekendphpさん再びありがとうございます。 >file_
    ┗A02-1-1-1-1weekendphpちなみに、open_basedirの設定も問題ないでしょうか?
     ┗A02-1-1-1-1-1318isweekendphpさん またまた返信ありがとうございます。

回答一覧

並び替え:

A01
answerersignal [5月8日 00:25]

  1. <?php
  2. $pic = array(
  3.     "name" => "file",
  4. #    "path" => "C:\uploadtest\hogehoge.jpg",
  5.     "path" => "C:\\uploadtest\\hogehoge.jpg",
  6. # もしくは
  7.     "path" => "C:/uploadtest/hogehoge.jpg",
  8. );
  9. ?>
でできませんか?

この意見に回答する

ツリーへ TOPへ

A01-1
replyer318is [5月8日 09:32] (最終編集:5月8日 11:21)

signalさんご回答ありがとうございます。

  1. #¥マークが勝手にバックスラッシュになるので大文字にしました
  2.     "path" => "C:¥¥uploadtest¥¥hogehoge.jpg", 
  3.     "path" => "C:/uploadtest/hogehoge.jpg",

上記どちらも試してみましたが、残念ながらそれぞれ
  1. File 'C:¥uploadtest¥hogehoge.jpg' is not readable
  2. File 'C:/uploadtest/hogehoge.jpg' is not readable
とでてしまいます。

読み込み不可能との英語表記だと思う(エキサイト調べ)のですが、
パスは通常のフォームの参照ボタンで選択したものをコピペしていますので、
間違いはないと思います。

関係ないかもしれませんが、この画像をサーバにアップして、
  1. #URL指定
  2.     "path" => "http://www.hogehoge.jp/hogehoge.jpg"
  3. #絶対パス指定
  4.     "path" => "/usr/***/***/***/public_html/hogehoge.jpg",
としたところ、絶対パス指定ではこのエラーはでませんでした。
そして34行目のexitを消さなくてもテキストデータは送信できましたが、
やはり画像は送信できませんでした。。

この意見に回答する

ツリーへ TOPへ

A01-1-1
replyerkaitau [5月9日 13:48] (最終編集:5月9日 13:51)

> > > $post_url = "./hoge.php";
の記述と、

> 関係ないかもしれませんが、この画像をサーバにアップして、
> としたところ、絶対パス指定ではこのエラーはでませんでした。
のくだりに怪しさを感じずにはいられません。

失礼かもしれませんが、確認のため質問させてください。
このプログラムはどの環境に設置され、誰かいつ駆動することを
想定したものですか?
重ねて聞くなら、それはWindows環境ですか?

この意見に回答する

ツリーへ TOPへ

A01-1-1-1
replyer318is [5月9日 15:51] (最終編集:5月9日 15:52)

kaitauさん返信ありがとうございます。

>このプログラムはどの環境に設置され、誰かいつ駆動することを想定したものですか?

私が管理している中古車サイトAがあり、今度中古車サイトBとABの総合サイトCを作成予定です。
(中古車サイトAとBはメーカーで分かれています)
例えばAに登録しているお店が中古車情報を登録した場合、AとCに登録されるように、
Bに登録しているお店が中古車情報を登録した場合、BとCに登録されるようにしたいのです。
(正確にはAとC(もしくはBとC)それぞれの更新情報にも)

設置するのはAB両サイトで、使用するのはABそれぞれに登録しているお店(+私)です。
環境はお店それぞれですが、とりあえずwindowsを考えています(私はwindowsXPです)。
ちなみにAは現在LINUXサーバにあり、BとCはwindowsサーバになる予定です。

ですので実際には「$post_url = "./hoge.php";」はテスト環境です。
今は同一ディレクトリに、POST送信ファイルと受信ファイル、イメージ保存用フォルダを置いてテストしています。
URL指定と絶対パス指定については、「エラーの表記から画像の指定の仕方がおかしいのではないかと
思い、色々試していたときにこうなった」ということを、表記せずにもしそれが重要だったらいけないと考えたからです。(ローカルの画像をUPしたいのに、サーバにUPした画像を指定するというのもおかしいかなとは思いましたが、エラーがでなくなったので一応記載しました)

>怪しさを感じずにはいられません。

独学なので当たり前の事が分かってないかもしれません。
後学のため、どのように怪しいのか教えていただければ助かります。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1
replyersignal [5月10日 11:19]

画像はどこにあって
PHPはどこにあって
画像をどこに置きたい

のか教えてもらえませんか?


私は
「サーバAにある画像をサーバAのPHPを使ってサーバBに置きたい」
という認識だったのですが。

「ローカルPCにある画像をサーバAのPHPを使ってサーバBに置きたい」
という話であれば、実現できません。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1-1
replyer318is [5月10日 19:20] (最終編集:5月10日 19:32)

signalさん再び返信ありがとうございます。

「ローカルPCにある画像をサーバAのPHPを使ってサーバBに置きたい」
「サーバAにある画像をサーバAのPHPを使ってサーバBに置きたい」

上記どちらでも構いません。

今までは
「通常のフォームで入力」→「サーバAにPOST」→
「そのデータサーバAで保存し、サーバBにそのままのデータ(画像がローカルPCの画像)をPOST」
と考えていましたが、
「通常のフォームで入力」→「サーバAにPOST」→「サーバAで処理し画像をサーバAに保存」→
「サーバAのデータ(サーバAの画像)をサーバBに自動でPOST」

という流れでもできると思いますので。
ですから
「ローカルPCにある画像をサーバAのPHPを使ってサーバBに置きたい」
が実現できないのならば、

画像はサーバAにあって
PHPはサーバAにあって
画像をサーバBに置きたい

となります。

ですが、画像がサーバにUPされている状態でも、ローカルPCにある状態でも
POSTできずに悩んでおります。

さらに、
「サーバAにある画像をサーバAのPHPを使ってサーバBに置きたい」の場合、
サーバAにある画像をPOSTする場合、受信側は

  1. extract($_POST);
  2. if (is_uploaded_file($_FILES['pic']['tmp_name'])){
  3. $pic_name = "./img/".date("YmdHis").".jpg";
  4. move_uploaded_file($_FILES['pic']['tmp_name'], $pic_name);
  5. }

のようにis_uploaded_fileで受けていいのでしょうか??
  1. if(!empty($_FILES)){
も試しましたが、どちらも画像は保存されませんでした。
現在同一ディレクトリに置いている通常のフォームから受信ファイルにPOSTした場合は
画像は正常に保存されますので、パーミッション等は問題ないかと思います。

現在のテスト状態
------------------------------------------
test/
     sousin.php #自動POST用PHP
     form.html  #通常のフォームHTML
     jusin.php  #受信用PHP
     img/    #画像保存用フォルダ
------------------------------------------

何かアドバイスありましたらよろしくお願いいたします。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1-1-1 満足
replyerkaitau [5月12日 14:28] (最終編集:5月12日 14:36)

お疲れ様です。

> 「通常のフォームで入力」→「サーバAにPOST」→
> 「そのデータサーバAで保存し、サーバBにそのままのデータ(画像がローカルPCの画像)をPOST」
> と考えていましたが、

まさしくそこを疑っていたため、怪しい、という表現になりました。

とにかく、「自動でPOSTするプログラム」から読み取れる場所にアップする
ファイルが無いと、アップが成功するはずもありません。

独学(*)ということで補足しておきますが、
ブラウザからWebサーバ(受け側のプログラムがPHPでも、それ以外でもなんでも)に
画像をPOSTメソッドでアップするという処理は、サーバ側に、「ここ
(例えば C:\uploadtest\hogehoge.jpg)にファイルがあるので取っていって」とやっている訳では
ありません。
「ファイルをアップする」という手続きに従って、ブラウザが自分で指定されたファイルの
データを読み取り、元のファイルの場所に関わらずHTTPリクエストデータの中に
丸ごと送っているだけです。

HTTP_Requestクラスを使ってファイルをPOSTするという事は、このブラウザの
処理を肩代わりしているような物でしか無いので、HTTP_Requestクラスから
画像データを読み取る必要がある訳です。
そして、webサーバであるサイトAからクライアントであるお店上のファイル
C:\uploadtest\hogehoge.jpg なんて、読み取れるはずが無いのです。

と、まとめたところで。

> 「サーバAにある画像をサーバAのPHPを使ってサーバBに置きたい」の場合、
> サーバAにある画像をPOSTする場合、受信側は
(略)
> のようにis_uploaded_fileで受けていいのでしょうか??

受信側というのはサーバB上の受信スクリプトですよね。そこは改修しなくて良いはずです。

問題なのは、サーバA上の、ファイル送信プログラムを稼動しているプログラムで、
サーバA上の画像を正しく指定出来れば問題ないはずです。

> 「通常のフォームで入力」→「サーバAにPOST」→「サーバAで処理し画像をサーバAに保存」→
> 「サーバAのデータ(サーバAの画像)をサーバBに自動でPOST」
の流れで作るならば、
このプログラムを稼動する前に、「サーバAで処理し画像をサーバAに保存」の段階で、
サーバAのどこかに画像が置かれているはずですから、まずそこのファイルを
$req->addFile(,)
の第二引数に入れて試すべきでしょう。

もう一点、受信側(B)で
if (is_uploaded_file($_FILES['pic']['tmp_name'])){
としているのが気になるのですが、
もしフォームフィールドとして指定しているnameが pic であるならば、
Aで駆動させる
$req->addFile(,)
の第一引数は 'file' ではなく、 'pic' であるべきでしょう。


* … よくよく考えたらそもそも技術を習得するにあたって独学かどうかなんて意味が無い気がしますが。
  自分一人しか扱ってないから正しい仕様の把握に自信がない、位の認識にしておきます。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1-1-1-1
replyer318is [5月13日 15:05]

kaitauさん 返信ありがとうございます。

まず、ご指摘の箇所を修正し、無事画像のPOSTに成功しました!
ありがとうございます。

それから補足の説明も大変勉強になりました。
「独学」で言いたかったのはまさしく
「自分一人しか扱ってないから正しい仕様の把握に自信がない」ということです。


返信いただいたsignalさん、weekendphpさん ありがとうございました。
これにて終了とさせていただきます。

この意見に回答する

ツリーへ TOPへ

A02
answererweekendphp [5月9日 00:07]

エラーの内容が、ファイルが読み込めない、というものなので、
まずは下記のような簡単なスクリプトを実行して、
PHPから読み込みが可能かどうかをチェックされてはいかがでしょうか。

  1. $filename = "C:\\uploadtest\\hogehoge.jpg";
  2.  
  3. if (file_exists($filename)) {
  4.     if (is_readable($filename)) {
  5.         echo 'このファイルは読み込み可能です';
  6.     } else {
  7.         echo 'このファイルは読み込み可能ではありません';
  8.     }
  9. } else {
  10.     echo 'ファイルが存在しません';
  11. }

参考まで。

この意見に回答する

ツリーへ TOPへ

A02-1
replyer318is [5月9日 15:22]

weekendphpさん返信ありがとうございます。

上記プログラムを実行すると、
「ファイルが存在しません」となります。
実際のフォームの参照ボタンで選択したのをコピペしていますし、
  1. $filename = "C:¥¥uploadtest¥¥hogehoge.jpg"; 
  2. echo $filename;
として、表示された物をIEのアドレスバーに入力しても、正常に画像が表示されます。ので、
パスは間違ってはいないと思うのですが。。

またなにかアドバイスがありましたら、よろしくお願いします。

この意見に回答する

ツリーへ TOPへ

A02-1-1
replyerweekendphp [5月9日 17:00]

file_existsのマニュアルを見ると、

>この関数は セーフモード  の制限のためファイルにアクセスできない場合 FALSE を返します。

という表記がありますが、これは大丈夫でしょうか?

この意見に回答する

ツリーへ TOPへ

A02-1-1-1
replyer318is [5月9日 21:01]

weekendphpさん再びありがとうございます。

>file_existsのマニュアルを見ると、
>この関数は セーフモード  の制限のためファイルにアクセスできない場合 FALSE を返します。
>という表記がありますが、これは大丈夫でしょうか? 

はい。phpinfo()にて確認していますが、safe_modeはoffになっています。
PHPのバージョンはPHP5.1.6とPHP4.3.9どちらも試しました(バージョンを切り替える機能がついている
=Xサーバー)がどちらでも結果は同じで、
  1. File 'C:¥uploadtest¥hogehoge.jpg' is not readable
↑コレになります。

現在は
-------------------------------------------------------------------------
私のPC windows XP SP1
サーバ  LINUX
PHP  4.3.9(セキュリティパッチ適応済み)←今はコッチにしてます
     5.1.6(セキュリティパッチ適応済み)
PEAR go-pear.phpからインストールし、
     「HTTP_Request 1.4.2」「HTTP_Client 1.1.1 」 をインストール。
-------------------------------------------------------------------------
という状況です。
(もうしわけありません、最初に書くべきでした)

なにかお気づきの点がありましたら、よろしくお願いします。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1
replyerweekendphp [5月10日 09:53]

ちなみに、open_basedirの設定も問題ないでしょうか?

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1
replyer318is [5月10日 19:26]

weekendphpさん またまた返信ありがとうございます。

>ちなみに、open_basedirの設定も問題ないでしょうか? 

ご指摘ありがとうございます。
open_basedirの項目はno valueとなっていて、おそらくオフのことだと思いますが、
念のためサーバ管理会社に確認中です。
返答があり次第、また書き込みさせていただきます。

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
セッションがいいのか、それともデータベースがいいのか教えて下さい。
 このエントリーをはてなブックマークに追加 
A
>ボタンをクリックしたら選んだ商品情報を持っておきたいと思っています。 そのくらいのことならセッションもしくはCookie(期限短め:場合によってはブラウザ閉じるまで)でいいんじゃないですかね。 #わ...

>>続きを読む

一つの目安として、ECサイトの購入情報など絶対に消えてはいけないものはDBに、カートなどの一時的に使用する情報や、ユーザに任意のタイミングで消去されても構わないものはセッションにと使い分けるといいでしょう。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)