忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2024/11/22 07:15 |
ZF1.10 :Zend_Http_ClientとZend_Http_Cookie
HTTPリクエストを送受信するクラスです。
送受信ならfile_get_contents()curl_exec()で十分だろ、と思いきやこいつらには重大な問題があります。

何処かにPOST送信を行った際、ステータスコード302が返ってくるとそっちにGETで送り直しちゃうんだよね。
http://www.studyinghttp.net/status_code#Code302

本来POSTで302が返ってきたらユーザに一旦確認したうえで移動先にPOST送信する、というのが本来の動きなのですが、上記関数やブラウザを含む大抵の実装が確認せずにGET送信してしまうようになっています。
この挙動を変更することができないのか探してみましたがよくわかりませんでした。

Zend_Httpもデフォルトでは上記のような挙動を取るようになっていますが、オプションで正しい動作を行うように設定することができます。

また、Zend_Http_Cookieを使うことでCookieを簡単に使い回すことができ、セッションを利用しているサイトへのリクエストも楽に行うことができます。
言葉で言っても意味がわかんないので書いてみましょう。

zend_http1.php
<?php
	session_set_cookie_params(0,'/','localhost');
	session_start();
	
	$_SESSION['a']='aaa';
	$_SESSION['b']='bbb';

zend_http2.php
<?php
	session_start();
	var_dump($_SESSION);

zend_http1.phpでセッションに値を代入し、zend_http2.phpでその値を表示します。
ブラウザで順にアクセスすると、正しくセッションの値

array(2) {
  ["a"]=>
  string(3) "aaa"
  ["b"]=>
  string(3) "bbb"
}

が表示されます。


ではPHPで順に取得してみましょう。
zend_http3.php
<?php
	file_get_contents('http://localhost/zend_http1.php');
	$ret=file_get_contents('http://localhost/zend_http2.php');
	
	var_dump($ret);

$bodyは、

array(0) {
}


何も取得できませんでした。
file_get_contentsはcookieとか特に考えないので、zend_http1.phpをfile_get_contentsした時点で発行されたcookieをzend_http2.phpに送信していないからです。
zend_http2.phpにcookieを送信する手段もなくはないですが、stream_context_create()なんかで自作する必要があり少々面倒です。
Zend_Httpでやってみましょう。

zend_http4.php
<?php
	
	$zend_http1='http://localhost/zend_http1.php';
	$zend_http2='http://localhost/zend_http2.php';
	
	//Zend_Http
		require_once('Zend/Http/Client.php');
		require_once('Zend/Http/Cookie.php');
		$http = new Zend_Http_Client();
	
	// 厳格なリダイレクト
		$http->setConfig(array('strictredirects' => true));
	
	//リクエスト送信先
		$http->setUri($zend_http1); 
	
	//リクエスト送信
		$http->request('POST');
	
	//返り値を取得
		$res=$http->getLastResponse();
		$header=$res->getHeaders();
	
	//Cookieを取得
		$cookie=Zend_Http_Cookie::fromString($header['Set-cookie']);
	
	//新たなリクエスト
		$http = new Zend_Http_Client();
		
	//リクエスト送信先
		$http->setUri($zend_http2); 
	
	//Cookieをセット
		$http->setCookie($cookie);
	
	//リクエスト送信
		$res=$http->request('POST');
	
	//レスポンスボディ
		$body=$res->getBody();
		
		var_dump($body);

リクエスト送信先はスキームからの入力が必須です。
相対リンクやホスト名からの表記などはできません。

レスポンスボディ$bodyは、

array(2) {
  ["a"]=>
  string(3) "aaa"
  ["b"]=>
  string(3) "bbb"
}


見事にセッション情報が表示されました。
$cookie=Zend_Http_Cookie::fromString($header['Set-cookie']);
$http->setCookie($cookie);

の部分において、一回目のリクエストで発行されたセッションキーを取得し、二回目のリクエストに付加しています。
これにより、簡単にセッションの継続を行うことができます。


前公開したしたらば削除スクリプトはZend_Httpのcookie制御とstrictredirectsを使用しています。
旧管理画面は画面遷移のたびに毎回パスワードをフォームで送るというどうなんだ仕様だったのですが、リニューアルを経てセッションを利用したログイン管理になりました。
セキュリティ上は正しいのですがスクリプト的にはcookieを使い回さないといけないため少々面倒になりました。
また、したらばの管理画面はフォーム送信のたびに毎回302でリダイレクトされる仕様のため、リダイレクト先にも正しくPOSTを送信するためにstrictredirectsを使用しました。
ただこれ、ブラウザは普通にGETで送信し直しているにも関わらず正しく動いてるのにPHPからだとGETでリダイレクトしても動かず、たまたまPOSTで再送信したところ動いたという状態で、原因がよくわからないのが困ったものなのですが。
PR


2010/10/05 22:07 | Comments(0) | TrackBack() | PHP

トラックバック

トラックバックURL:

コメント

コメントを投稿する






Vodafone絵文字 i-mode絵文字 Ezweb絵文字 (絵文字)



<<XAMPP1.7.3 設定ファイルに定義されている管理ユーザ(controluser)での接続に失敗しました | HOME | 買ったものリスト 2010/10/03>>
忍者ブログ[PR]