このPHPライブラリは、ネットワークを経由したHTTP通信でコンテンツを取得するクラスです。OpenSSLがインストールされている環境では、HTTPSも利用可能です。
他のクラスに依存することなく単体で動作します。オリジナルのクラス名は PxHTTPAccess となっていますが、環境に合わせて任意に変更しても動作します。
ダウンロード
次のボタンをクリックして、PxHTTPAccess をダウンロードしてください。
ファイル構成
- PxHTTPAccess.php
- PxHTTPAccessライブラリの本体です。
インストール
PHPのお使いの環境の任意の場所に設置してください。PHP4系でも動作するように設計されています。
更新履歴
PxHTTPAccess 1.0.3 (2011/05/22)
- すべてのHTTPレスポンスヘッダーを参照できるようにした。
PxHTTPAccess 1.0.2 (2011/03/27)
- ダイジェスト認証に対応した。
- 取得したファイルの更新日を取得する機能を追加。
PxHTTPAccess 1.0.1 (2009/09/20)
- 取得したコンテンツをファイルに保存せず直接返却させる場合に、リダイレクトの処理が正しく動作しないバグを修正。
PxHTTPAccess 1.0.0
- 初版リリース
使い方
基本的な使い方を次に示します。
<?php require_once( './PxHTTPAccess.php' ); $httpaccess = new PxHTTPAccess(); $httpaccess->clear_request_header();//初期化 $httpaccess->set_url( 'http://www.pxt.jp/ja/index.html' );//ダウンロードするURL $httpaccess->set_method( 'GET' );//メソッド $httpaccess->save_http_contents( './download.html' );//ダウンロードを実行する ?>
HTTPレスポンスヘッダーを受け取る
<?php require_once( './PxHTTPAccess.php' ); $httpaccess = new PxHTTPAccess(); $httpaccess->set_url( 'http://www.pxt.jp/ja/index.html' );//ダウンロードするURL $httpaccess->save_http_contents( './download.html' );//ダウンロードを実行する //HTTPレスポンスヘッダーを出力 echo $httpaccess->get_status_cd();//ステータスコード(例:'200') echo $httpaccess->get_status_msg();//ステータスメッセージ(例:'OK') echo $httpaccess->get_content_type();//Content-type echo $httpaccess->get_content_charset();//文字コード(HTTPヘッダ) echo $httpaccess->get_content_length();//コンテンツ容量 echo $httpaccess->get_response_time();//リクエストからダウンロード完了までにかかった時間 echo $httpaccess->get_socket_open_error();//ソケットを開いた際のエラー取得 echo $httpaccess->get_response( 'content-type' );//任意のキーからHTMLレスポンスヘッダの値を取得 ?>
ベーシック認証
<?php require_once( './PxHTTPAccess.php' ); $httpaccess = new PxHTTPAccess(); $httpaccess->set_auth_type( 'basic' );//ベーシック認証(ID) $httpaccess->set_auth_user( 'userid' );//認証ID $httpaccess->set_auth_pw( 'userpasswd' );//認証パスワード $httpaccess->set_url( 'http://www.pxt.jp/ja/index.html' );//ダウンロードするURL $httpaccess->save_http_contents( './download.html' );//ダウンロードを実行する ?>
ダイジェスト認証
<?php require_once( './PxHTTPAccess.php' ); $httpaccess = new PxHTTPAccess(); $httpaccess->set_auth_type( 'digest' );//ダイジェスト認証 $httpaccess->set_auth_user( 'userid' );//認証ID $httpaccess->set_auth_pw( 'userpasswd' );//認証パスワード $httpaccess->set_url( 'http://www.pxt.jp/ja/index.html' );//ダウンロードするURL $httpaccess->save_http_contents( './download.html' );//ダウンロードを実行する ?>
HTTP_USER_AGENTを任意の文字列に指定する
<?php require_once( './PxHTTPAccess.php' ); $httpaccess = new PxHTTPAccess(); $httpaccess->set_user_agent( 'Mozilla/4.01' );//HTTP_USER_AGENT $httpaccess->set_url( 'http://www.pxt.jp/ja/index.html' );//ダウンロードするURL $httpaccess->save_http_contents( './download.html' );//ダウンロードを実行する ?>
HTTP_REFERERを指定して、任意のURLからの遷移に見せかける
<?php require_once( './PxHTTPAccess.php' ); $httpaccess = new PxHTTPAccess(); $httpaccess->set_http_referer( 'http://www.pxt.jp/ja/about/index.html' );//refererを設定 $httpaccess->set_url( 'http://www.pxt.jp/ja/index.html' );//ダウンロードするURL $httpaccess->save_http_contents( './download.html' );//ダウンロードを実行する ?>
リダイレクトとその回数
<?php require_once( './PxHTTPAccess.php' ); $httpaccess = new PxHTTPAccess(); $httpaccess->set_max_redirect_number( 10 );//リダイレクトする回数 $httpaccess->set_auto_redirect_flg( true );//リダイレクトするか否か $httpaccess->set_url( 'http://www.pxt.jp/ja/index.html' );//ダウンロードするURL $httpaccess->save_http_contents( './download.html' );//ダウンロードを実行する ?>
POSTメソッドでデータを送信する
<?php require_once( './PxHTTPAccess.php' ); $httpaccess = new PxHTTPAccess(); $httpaccess->set_method( 'POST' );//メソッド $httpaccess->set_post_data( 'aaa=bbb&ccc=ddd' );//POSTデータ $httpaccess->set_url( 'http://www.pxt.jp/ja/index.html' );//ダウンロードするURL $httpaccess->save_http_contents( './download.html' );//ダウンロードを実行する ?>
ソースコードプレビュー
次のソースコードは、PxHTTPAccess.php のバージョン1.0.2のものです。
<?php
###################################################################################################################
#
# PxHTTPAccess 1.0.3
# (HTTPアクセスオブジェクト)
# Copyright (C)Tomoya Koyanagi, All rights reserved.
# LastUpdate : 12:07 2011/05/22
# --------------------------------------
# このライブラリは、ネットワークを経由したHTTP通信でコンテンツを取得するクラスです。
# OpenSSLがインストールされている環境では、HTTPSも利用可能です。
# 他のクラスに依存することなく単体で動作することができます。
# オリジナルのクラス名は PxHTTPAccess となっていますが、
# 環境に合わせて任意に変更しても動作します。
class PxHTTPAccess{
var $http_connection_resource = null;//コネクションリソース
#--------------------------------------
# 設定
var $auto_redirect_flg = true;//true=>自動的にリダイレクトを追跡; false=>リダイレクト指示を無視してダウンロード
var $max_redirect_number = 5;//リダイレクト回数の上限値
var $redirect_count = 0;//現在のリダイレクト処理回数
var $stream_timeout = 5;//読み込みのタイムアウト
var $fread_length = 5000;//fread()が一回に読み込むバイト数。
# / 設定
#--------------------------------------
#--------------------------------------
# 要求ヘッダ
var $http_url = null;
var $http_method = 'GET';
var $http_post_data = null;//POSTメソッドで送信するデータ
var $http_user_agent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)';//ユーザエージェント文字列
var $http_referer = null;//リファラを送信する
var $http_authorization = array('type'=>null,'user'=>null,'passwd'=>null);//ベーシック認証, PxHTTPAccess 1.0.2 : Digest認証を追加,プロパティ名変更
var $http_request_header_ext = null;//追加するリクエストヘッダ
var $cookies = array();//クッキーの記憶
# / 要求ヘッダ
#--------------------------------------
#--------------------------------------
# 応答ヘッダ:アクセス結果のメモ
var $socket_open_error_num = null;//fsockopen() のエラー番号
var $socket_open_error_msg = null;//fsockopen() のエラーメッセージ
var $http_response_header = null;//レスポンスヘッダ
var $http_response_content = null;//コンテンツ領域の実データ
var $http_response_version = null;//レスポンスのHTTPバージョン
var $http_response_status_cd = null;//レスポンスステータスコード
var $http_response_status_msg = null;//レスポンスステータスメッセージ
var $http_response_content_type = null;//取得したデータのコンテントタイプ
var $http_response_content_charset = null;//取得したデータの文字コード
var $http_response_content_length = null;//取得したデータの容量
var $http_response_redirect_to = null;//リダイレクト先URLのメモ
var $http_response_time = null;//リクエストから受信完了までにかかった時間(microtime)
var $http_response_transfer_encoding = null;//HTTP1.1 Transfer-Encoding の値
var $http_response_last_modified = null;//HTTP1.1 Last-Modified の値 (PxHTTPAccess 1.0.2 追加)
var $http_response_connection = null;//Connection の値
var $http_response_www_authenticate = array();//WWW-Authenticate の値 PxHTTPAccess 1.0.2 追加
var $http_response_all = array();//その他のヘッダー情報を仕舞っておく器 PxHTTPAccess 1.0.3 追加
# / 応答ヘッダ:アクセス結果のメモ
#--------------------------------------
###################################################################################################################
# ユーザインターフェイス
# ★save_http_contents() , get_http_contents()は、実際にリモートホストからデータをダウンロードします。
# ★get_responce() は、実際にソケット接続からデータを読み出し、
# コンテンツ部分とヘッダー部分を解析します。
# リファラURL
function set_http_referer( $url ){
$this->http_referer = $url; return true;
}
# fread() が1回で読み込むバイト数
function set_fread_length( $length ){
$length = intval($length);
if( $length <= 0 ){ return false; }
$this->fread_length = intval( $length );
return true;
}
# 取得するURL
function clear_url(){
$this->http_url = null;
return true;
}
function set_url( $url ){
$this->http_url = $url;
return true;
}
function get_url(){
return $this->http_url;
}
# POSTメソッドで送信するデータ
function set_post_data( $post_data ){
$this->http_post_data = $post_data;
return true;
}
# コンテンツ読み込みのタイムアウト値
function set_stream_timeout( $timeout_sec ){
$this->stream_timeout = intval( $timeout_sec );
return true;
}
# メソッド
function set_method( $value ) { $this->http_method = strtoupper($value); return true; }
function get_method() { return $this->http_method; }
# HTTP_USER_AGENT
function set_user_agent( $value ) { $this->http_user_agent = $value; return true; }
function get_user_agent() { return $this->http_user_agent; }
# 追加で設定する要求ヘッダの操作
function add_request_header( $value ) { $this->http_request_header_ext .= $value; return true; }
function clear_request_header(){
$this->http_url = null;
$this->http_method = 'GET';
$this->http_post_data = null;
$this->http_referer = null;
$this->http_authorization = array('type'=>null,'user'=>null,'passwd'=>null);
$this->http_request_header_ext = null;
return true;
}
# 基本認証情報
function set_auth_type( $type_name ){
//PxHTTPAccess 1.0.2 追加
if( !strlen($type_name) ){
$this->http_authorization['type'] = null;
return true;
}
switch( strtolower( $type_name ) ){
case 'basic':
case 'digest':
break;
default:
return false;
}
$this->http_authorization['type'] = $type_name;
return true;
}
function set_auth_user( $user_name ) { $this->http_authorization['user'] = $user_name; return true; }
function set_auth_pw( $passwd ) { $this->http_authorization['passwd'] = $passwd; return true; }
# リダイレクト関連
function set_auto_redirect_flg( $bool ){
$this->auto_redirect_flg = (bool)$bool;
return true;
}
function set_redirect_count( $num ) { $this->redirect_count = intval($num); return true; }
function set_max_redirect_number( $num ){ $this->max_redirect_number = intval($num); return true; }
#--------------------------------------
# 要求後にする操作系
# リモートホストの応答から得た値を取り出す
# 応答ヘッダを取り出す
function get_response_header(){
return $this->http_response_header;
}
# コンテンツを取り出す
function get_response_content(){
# ただし、save_http_contents() によって、
# その内容をファイルに保存した場合は、
# このメソッドから取り出すことはできません。
return $this->http_response_content;
}
# その他の結果取り出し系インターフェイス
function get_content_type() { return $this->http_response_content_type; }
function get_content_length() { return $this->http_response_content_length; }
function get_content_charset() { return $this->http_response_content_charset; }
function get_status_cd() { return $this->http_response_status_cd; }
function get_status_msg() { return $this->http_response_status_msg; }
function get_redirect_to() { return $this->http_response_redirect_to; }
function get_response_time() { return floatval( $this->http_response_time ); }
function get_transfer_encoding() { return $this->http_response_transfer_encoding; }
function get_last_modified() { return $this->http_response_last_modified; }//PxHTTPAccess 1.0.2 追加
function get_last_modified_timestamp() {//PxHTTPAccess 1.0.2 追加
if( !strlen( $this->http_response_last_modified ) ){ return null; }
return strtotime( $this->http_response_last_modified );
}
function get_response( $key ) { return $this->http_response_all[strtolower($key)]; }//PxHTTPAccess 1.0.3 追加
function get_socket_open_error_num() { return $this->socket_open_error_num; }
function get_socket_open_error_msg() { return $this->socket_open_error_msg; }
function get_socket_open_error(){
$num = $this->get_socket_open_error_num();
$msg = $this->get_socket_open_error_msg();
if( $num || $msg ){
$RTN = $num.':'.$msg;
return $RTN;
}
return null;
}
###################################################################################################################
# アクセス+ダウンロード処理系
#--------------------------------------
# HTTP接続リソースを取り出す
function &get_connection_resource(){
return $this->http_connection_resource;
}
#--------------------------------------
# ホストに接続する
function &http_connect( $host , $port = null , $is_ssl = false ){
if( !strlen( $host ) ){
return false;
}
if( $is_ssl ){
$host = 'ssl://'.$host;
}
if( !strlen( $port ) ){
if( $is_ssl ){
$port = 443;//HTTPSのデフォルトポート
}else{
$port = 80;//HTTPのデフォルトポート
}
}
$port = intval( $port );
$res = @fsockopen( $host , $port , $this->socket_open_error_num , $this->socket_open_error_msg , 10 );
if( !is_resource( $res ) ){
return false;
}
stream_set_timeout( $res , intval( $this->stream_timeout ) );
$this->http_connection_resource = &$res;
return $res;
}
#--------------------------------------
# 接続を解除する
function http_disconnect(){
$res = &$this->get_connection_resource();
if( !is_resource( $res ) ){ return false; }
if( !fclose( $res ) ){ return false; }
return true;
}
#--------------------------------------
# リクエストヘッダーを生成する
function create_http_request_header(){
$URL_INFO = parse_url( $this->get_url() );
$POSTDATA = $this->http_post_data;
$request_path = $URL_INFO['path'];
if( strlen( $URL_INFO['query'] ) ){
$request_path = $URL_INFO['path'].'?'.$URL_INFO['query'];
}
$RTN = '';
$RTN .= $this->get_method().' '.$request_path.' HTTP/1.1'."\r\n";
$RTN .= 'Host: '.$URL_INFO['host']."\r\n";
$RTN .= 'User-Agent: '.$this->get_user_agent()."\r\n";
if( ( $this->http_authorization['type'] == 'digest' || !$this->http_authorization['type'] && $this->http_response_www_authenticate['type'] == 'digest' ) && strlen( $this->http_authorization['user'] ) && strlen( $this->http_authorization['passwd'] ) && strlen( $this->http_response_www_authenticate['nonce'] ) ){
# ダイジェスト認証
$RTN .= 'Authorization: Digest';
$RTN .= ' username="'.$this->http_authorization['user'].'",';
$RTN .= ' realm="'.$this->http_response_www_authenticate['realm'].'",';
$RTN .= ' nonce="'.$this->http_response_www_authenticate['nonce'].'",';
$RTN .= ' uri="'.$request_path.'",';
$RTN .= ' algorithm='.$this->http_response_www_authenticate['algorithm'].',';
$tmp_digest_val_qop = 'auth';//UTODO:←本来は選択式。固定ではダメ。
$RTN .= ' qop='.$tmp_digest_val_qop.',';
$tmp_digest_val_nc = str_pad( dechex( ++ $this->http_authorization[$this->http_response_www_authenticate['nonce']]['nc'] ) , 8 , '0' , STR_PAD_LEFT );
$RTN .= ' nc='.$tmp_digest_val_nc.',';
$tmp_digest_val_cnonce = md5( rand(1,99999) );
$RTN .= ' cnonce="'.$tmp_digest_val_cnonce.'",';
$tmp_a1 =
$this->http_authorization['user'].':'.
$this->http_response_www_authenticate['realm'].':'.
$this->http_authorization['passwd']
;
$tmp_a2 =
$this->http_method.':'.
$request_path
;
$RTN .= ' response="'.md5(
md5($tmp_a1).':'.
$this->http_response_www_authenticate['nonce'].':'.
$tmp_digest_val_nc.':'.
$tmp_digest_val_cnonce.':'.
$tmp_digest_val_qop.':'.
md5($tmp_a2)
).'"';
$RTN .= "\r\n";
unset( $tmp_digest_val_nc , $tmp_digest_val_cnonce , $tmp_digest_val_qop );
}elseif( ( $this->http_authorization['type'] == 'basic' || !$this->http_authorization['type'] && $this->http_response_www_authenticate['type'] == 'basic' ) && strlen( $this->http_authorization['user'] ) && strlen( $this->http_authorization['passwd'] ) ){
# 基本認証
$RTN .= 'Authorization: Basic '.base64_encode( $this->http_authorization['user'].':'.$this->http_authorization['passwd'] )."\r\n";
}
if( strlen( $this->http_referer ) ){
# リファラ
$RTN .= 'Referer: '.$this->http_referer."\r\n";
}
$cookie_string = trim( $this->get_cookies4requestheader( $this->http_url ) );
if( strlen( $cookie_string ) ){
# クッキー
$RTN .= $cookie_string."\r\n";
}
$header_ext = trim( $this->http_request_header_ext );
if( strlen( $header_ext ) ){
$RTN .= trim($header_ext)."\r\n";
}
$RTN .= 'Connection: close'."\r\n";
if( strlen( $POSTDATA ) ){
# POSTの場合にくっつける部分。
$RTN .= 'Content-Type: application/x-www-form-urlencoded'."\r\n";
$RTN .= 'Content-Length: '.strlen( $POSTDATA )."\r\n";
$RTN .= "\r\n";
$RTN .= trim( $POSTDATA )."\r\n";
}
$RTN .= "\r\n";
return $RTN;
}
#--------------------------------------
# リクエストを送信する
function send_request( $request_header = null ){
$res = &$this->get_connection_resource();
if( !is_resource($res) ){ return false; }
if( !strlen( $request_header ) ){
$request_header = $this->create_http_request_header();
}
fputs( $res , $request_header );
return true;
}
#--------------------------------------
# ホストの返答を受け取り、内容を返す
function get_responce( $save_to_path = null ){
# このメソッドは、リモートホストからコンテンツを取得します。
# ヘッダー部分はプロパティに記憶するのみとし、
# コンテンツセクションのみを取り出します。
# $save_to_path に有効なローカルパスがわたった場合、
# そのファイルに保存し、真偽を返す。
# 初期化
$status = 0;
$this->http_response_content = '';
# / 初期化
if( strlen( $save_to_path ) ){
if( is_file( $save_to_path ) ){
if( !is_writable( $save_to_path ) ){ return false; }
unlink( $save_to_path );
}elseif( is_dir( dirname( $save_to_path ) ) ){
if( !is_writable( dirname( $save_to_path ) ) ){ return false; }
}else{
return false;
}
touch( $save_to_path );
chmod( $save_to_path , 0777 );
$save_to_path = realpath( $save_to_path );
if( !is_file($save_to_path) ){ return false; }
}else{
$save_to_path = null;
}
$res = &$this->get_connection_resource();
if( !is_resource($res) ){ return false; }
$this->clear_response_header();//前回のレスポンスヘッダを削除(初期化)
$downloaded_content_size = 0;
$this->http_response_content_length = null;
list( $microtime , $time ) = explode( ' ' , microtime() );
$start_mtime = ( floatval( $time ) + floatval( $microtime ) );
while( !feof( $res ) ){
if( !strlen( $this->http_response_status_cd ) ){
# HTTPステータスコードを受け取ってないのに次へ行こうとしたら
# ここではじく。
$status = 0;
}
if( $status >= 1 && $this->http_response_transfer_encoding != 'chunked' && !preg_match( '/^(?:text|application)\/.*$/i' , $this->get_content_type() ) ){
# バイナリだったらこっちが速い?
$line = fread( $res , $this->fread_length );
}else{
# テキストのデータはこっちが速い?
$line = fgets( $res );
}
if( $status == 1 || $status == 2 ){
#--------------------------------------
# コンテンツ領域
if( $this->http_response_transfer_encoding == 'chunked' && $status == 1 ){
# コンテンツ領域の最初に全体の容量が入っている場合がある。(Transfer-Encoding: chunked の場合)
# このときは 16進数 で表現される模様。
# see: http://www.tohoho-web.com/ex/http.htm
if( preg_match( '/^([0-9a-f]+\s*?(?:\r\n|\r|\n))(.*)$/si' , $line , $matches ) ){
$chunk_length = intval( hexdec( trim($matches[1]) ) );
if( $chunk_length === 0 ){ continue; }
$this->http_response_content_length = $this->http_response_content_length + $chunk_length;
$status = 2;
continue;
}
continue;
}
if( is_int( $this->http_response_content_length ) && $downloaded_content_size + strlen( $line ) > $this->http_response_content_length ){
# もしも、予定容量よりも多くのデータを取り出してしまったら、丸めなければならない。
$sabun = strlen( $line ) - ( $this->http_response_content_length - $downloaded_content_size );
$line = preg_replace( '/^(.{'.intval(strlen($line)-$sabun).'}).*$/si' , "$1" , $line );
}
#--------------------------------------
# コンテンツ取り出し
$downloaded_content_size += strlen( $line );
if( @is_file( $save_to_path ) ){
if( !$this->savefile_push( $save_to_path , $line ) ){
# 保存に失敗したらおしまいにする
break;
}
}else{
$this->http_response_content .= $line;
}
# / コンテンツ取り出し
#--------------------------------------
if( is_int( $this->http_response_content_length ) && $downloaded_content_size >= $this->http_response_content_length ){
if( $this->http_response_transfer_encoding == 'chunked' ){
$status = 1;
}
}
continue;
}elseif( $status == 0 ){
#--------------------------------------
# ヘッダー領域
if( preg_match( '/HTTP\/([0-9]+?\.[0-9]+?) ([0-9]{3}) (.*?)(?:\r\n|\r|\n)?$/si' , $line , $matched ) ){
# HTTP Status
$this->http_response_version = floatval( $matched[1] );
$this->http_response_status_cd = intval( $matched[2] );
$this->http_response_status_msg = $matched[3];
}elseif( preg_match( '/Content-Type:\s*([a-zA-Z\-\_\.]+\/[a-zA-Z\-\_\.]+)(?:;\s*charset\=([a-zA-Z0-9\-\_\.]+))?/si' , $line , $matched ) ){
# Content-type & charset
$this->http_response_content_type = trim( $matched[1] );
$this->http_response_content_charset = trim( $matched[2] );
}elseif( preg_match( '/content-length:\s*?([0-9]+)/si' , $line , $matched ) ){
# Content-Length
$this->http_response_content_length = intval( $matched[1] );
}elseif( preg_match( '/Transfer-Encoding:\s*?([a-z0-9]+)/si' , $line , $matched ) ){
# Transfer-Encoding: chunked
$this->http_response_transfer_encoding = strtolower( $matched[1] );
}elseif( preg_match( '/Last-Modified:\s*?([a-zA-Z0-9\-\_\,\: ]+)/si' , $line , $matched ) ){
# Last-Modified
# PxHTTPAccess 1.0.2 追加
$this->http_response_last_modified = trim( $matched[1] );
}elseif( preg_match( '/Connection:\s*?([a-z0-9]+)/si' , $line , $matched ) ){
# Connection: chunked
$this->http_response_connection = strtolower( $matched[1] );
}elseif( preg_match( '/Location:\s*(.*?)(?:\r\n|\r|\n)?$/si' , $line , $matched ) ){
# リダイレクトの処理
$this->http_response_redirect_to = trim( $matched[1] );
if( $this->auto_redirect_flg ){
# 自動的にリダイレクトを解決する設定だった場合、
# 再帰的にリダイレクト先を巡回する。
if( $this->max_redirect_number <= $this->redirect_count ){
# リダイレクト回数に達していたら、再帰的アクセスをしない。
continue;
}
$this->http_disconnect();//自分の接続を解除する。0:01 2009/09/20
$thisClassName = get_class( $this );
$http4redirect = new $thisClassName();
$http4redirect->set_max_redirect_number( $this->max_redirect_number );
$http4redirect->set_redirect_count( $this->redirect_count + 1 );
$http4redirect->set_user_agent( $this->http_user_agent );
$http4redirect->set_url( $this->http_response_redirect_to );
$http4redirect->set_method( 'GET' );
if( is_file( $save_to_path ) ){
$http4redirect->save_http_contents( $save_to_path );
}else{
$this->http_response_content = $http4redirect->get_http_contents();
}
$this->clear_response_header();//初期化 23:58 2009/09/19
$this->put_response_header( $http4redirect->get_response_header() );
unset( $http4redirect );
return $this->http_response_content;
}
}
if( !strlen( trim( $line ) ) ){
$status = 1;//次へ
}else{
$this->put_response_header( $line );
}
continue;
}
}
list( $microtime , $time ) = explode( ' ' , microtime() );
$end_mtime = ( floatval( $time ) + floatval( $microtime ) );
$this->http_response_time = floatval( $end_mtime - $start_mtime );
#--------------------------------------
# 受け取ったクッキーの処理
$this->parse_cookie( $this->http_url , $this->get_response_header() );
# / 受け取ったクッキーの処理
#--------------------------------------
#--------------------------------------
# 受け取った認証情報の処理
$this->parse_www_authenticate( $this->get_response_header() );
# / 受け取った認証情報の処理
#--------------------------------------
if( is_file( $save_to_path ) ){
return true;
}
return $this->http_response_content;
}//get_responce();
#--------------------------------------
# ★リクエストを送信して結果を取得する
function get_http_contents( $path_save_to = null , $try = 0 ){
$URL_INFO = parse_url( $this->get_url() );
# if( !strlen( $URL_INFO['port'] ) ){ $URL_INFO['port'] = 80; }
$is_ssl = false;
if( strtolower( $URL_INFO['scheme'] ) == 'https' ){
$is_ssl = true;
}
if( !$this->http_connect( $URL_INFO['host'] , $URL_INFO['port'] , $is_ssl ) ){
return false;
}
if( !$this->send_request() ){
$this->http_disconnect();
return false;
}
$reqult = $this->get_responce( $path_save_to );
$this->http_disconnect();
if( !$try && $this->get_status_cd() == '401' &&//←認証に失敗した場合
(
//↓ダイジェスト認証を求められたら
( $this->http_response_www_authenticate['type'] == 'digest' && strlen( $this->http_response_www_authenticate['nonce'] ) )
//↓ベーシック認証を求められたら(ユーザが指定していない場合のみ)
|| ( $this->http_response_www_authenticate['type'] == 'basic' && !strlen( $this->http_authorization['type'] ) )
)
&& strlen( $this->http_authorization['user'] ) && strlen( $this->http_authorization['passwd'] )
){
//ダイジェスト認証で失敗したらもう一度アクセスする//PxHTTPAccess 1.0.2 追加
$reqult = $this->get_http_contents( $path_save_to , 1 );
}
return $reqult;
}
#--------------------------------------
# ★結果をファイルに保存する
function save_http_contents( $path_save_to ){
return $this->get_http_contents( $path_save_to );
}
###################################################################################################################
# アクセス事後処理
# 応答ヘッダを削除する
function clear_response_header(){
$this->http_response_header = null;
$this->http_response_transfer_encoding = null;
$this->http_response_last_modified = null;//PxHTTPAccess 1.0.2 追加
$this->http_response_version = null;
$this->http_response_status_cd = null;
$this->http_response_status_msg = null;
$this->http_response_content_type = null;
$this->http_response_content_charset = null;
$this->http_response_content_length = null;
$this->http_response_redirect_to = null;
$this->http_response_connection = null;
$this->http_response_all = array();
return true;
}
# 応答ヘッダに追記する
function put_response_header( $value ){
$this->http_response_header .= $value;
if( preg_match( '/(.*?):\s*(.*?)(?:\r\n|\r|\n)?$/si' , $value , $matched ) ){
# ヘッダーを記憶
$this->http_response_all[strtolower($matched[1])] = trim( $matched[2] );
}
return true;
}
###################################################################################################################
# 認証関連操作
#--------------------------------------
# WWW-Authenticate を解析する
function parse_www_authenticate( $http_header_string ){
//PxHTTPAccess 1.0.2 追加
if( preg_match( '/WWW\-Authenticate\:\s*(.*?)(?:\r\n|\r|\n|$)/si' , $http_header_string , $matched ) ){
$value = $matched[1];
preg_match( '/^(Basic|Digest)(.*)$/si' , trim($value) , $matched );
$this->http_response_www_authenticate['type'] = strtolower( $matched[1] );
$value = $matched[2];
$tmp = array();
while( 1 ){
if( !preg_match( '/^(?:\,\s*)?([a-zA-Z0-9\-\_]+)\=(\"?)(.*?)\2((?:\s*\,).*)?$/' , trim($value) , $matched ) ){
break;
}
$tmp[$matched[1]] = $matched[3];
$value = $matched[4];
continue;
}
$this->http_response_www_authenticate['realm'] = $tmp['realm'];
if( $this->http_response_www_authenticate['type'] == 'digest' ){
$this->http_response_www_authenticate['nonce'] = $tmp['nonce'];
$this->http_response_www_authenticate['algorithm'] = $tmp['algorithm'];
$this->http_response_www_authenticate['qop'] = $tmp['qop'];
}
}
return true;
}
###################################################################################################################
# クッキー関連操作
#--------------------------------------
# クッキーを削除する
function clear_cookies(){
$this->cookies = array();
return true;
}
#--------------------------------------
# クッキーを解析する
function parse_cookie( $sender_url , $http_header_string ){
$url_info = parse_url( $sender_url );
preg_match_all( '/Set-Cookie:(.*?)(?:\r\n|\r|\n|$)/i' , $http_header_string , $preg_result );//クッキーの行を解析・取得
if( !is_array( $preg_result[1] ) ){ $preg_result[1] = array(); }
foreach( $preg_result[1] as $cookie_line ){
$cookie_elm = explode( ';' , $cookie_line );
$cookie_current_key = null;
$cookie_current_parse_memo = array();
if( !is_array( $cookie_elm ) ){ $cookie_elm = array(); }
foreach( $cookie_elm as $LINE ){
list( $cookie_key , $cookie_value ) = explode('=',$LINE);
switch( $cookie_key ){
case 'expires';
case 'path';
case 'domain';
case 'secure';
break;
default:
if( is_null( $cookie_current_key ) ){
$cookie_current_key = trim($cookie_key);
}
break;
}
$cookie_current_parse_memo[trim($cookie_key)] = trim( $cookie_value );
}
if( !strlen( $cookie_current_parse_memo['path'] ) ){
$cookie_current_parse_memo['path'] = $url_info['path'];
}
if( !strlen( $cookie_current_parse_memo['domain'] ) ){
$cookie_current_parse_memo['domain'] = $url_info['host'];
}
$this->accept_cookie(
$cookie_current_parse_memo['domain'] ,
$cookie_current_key ,
$cookie_current_parse_memo[$cookie_current_key] ,
$cookie_current_parse_memo['path'] ,
$cookie_current_parse_memo['expires'] ,
$cookie_current_parse_memo['secure']
);
unset($cookie_current_parse_memo);
}
return true;
}
#--------------------------------------
# クッキーを受け付ける
function accept_cookie( $domain , $cookie_key , $cookie_value , $path = '/' , $expires = null , $secure = null ){
$this->cookies[$domain][$cookie_key]['value'] = $cookie_value;
$this->cookies[$domain][$cookie_key]['path'] = $path;
$this->cookies[$domain][$cookie_key]['expires'] = $expires;
$this->cookies[$domain][$cookie_key]['secure'] = $secure;
return true;
}
#--------------------------------------
# リクエストHEADERに付け加えるクッキーを取得
function get_cookies4requestheader( $sendto_url ){
$sendto_url_info = parse_url( $sendto_url );
$current_cookies = $this->cookies[$sendto_url_info['host']];
if( !is_array( $current_cookies ) ){ $current_cookies = array(); }
$RTN_ARY = array();
if( !is_array( $current_cookies ) ){ $current_cookies = array(); }
foreach( $current_cookies as $key=>$value ){
array_push( $RTN_ARY , $key.'='.addslashes($value['value']).';' );
}
$RTN = implode( ' ' , $RTN_ARY );
if( !strlen( $RTN ) ){
return null;
}
return 'Cookie: '.$RTN;
}
#--------------------------------------
# ファイルに追記する
function savefile_push( $filepath , $CONTENT , $perm = null ){
if( !strlen( $CONTENT ) ){ return false; }
if( !is_int($perm) ){ $perm = 0777; }
if( is_dir( $filepath ) ){ return false; }
if( is_file( $filepath ) && !is_writable( $filepath ) ){ return false; }
$res = fopen($filepath,'a');
if( !is_resource( $res ) ){ return false; }
fwrite( $res , $CONTENT );
fclose( $res );
chmod( $filepath , $perm );
clearstatcache();
return filesize( $filepath );
}
}
?>
著作権と利用についての規約
- PxHTTPAccess の著作権は、Tomoya Koyanagi に帰属します。
- 商用利用、個人利用を問わず自由に利用できます。
- ただし、これらのソースコードやアプリケーションに起因するいかなる損害やトラブルに関しても、著作者は責任を負うことはできませんので、利用者の自己責任の範囲でご利用ください。