CUrl()のサポート用クラス

提供:wiki - PCスキルの小技・忘却防止メモ
移動: 案内, 検索

cUrl()のサポート用クラス - 通信関連で使うcurl()のサポート用クラス

ソース

<?php
/**
 * class_curl_support.php
 * curl()のサポートクラス
 */
class ClassCurlSupport {
	public $_result;
	
	private $_ch;
	private $_able;
	private $_curlOpts;
	
	function __construct() {
		$this->initResult();
		$this->_ch = curl_init();
		$this->chkIniGet();
		$this->setCurlOpt();
	}
	
	function __destruct() {
		curl_close($this->_ch);
	}
	
	/**
	 * initResult()
	 * - status :各種確認用データの格納先
	 *   - code     :httpステータスコードの格納先
	 *   - message  :メッセージの格納先
	 *   - inputUrl :入力されたURLの格納先(http等をつけた状態)
	 *   - redirect :リダイレクト先URLの格納先
	 *   - ua       :指定したユーザーエージェントの格納先
	 * - header :ヘッダ情報の格納先
	 * - source :取得したソースの格納先
	 */
	private function initResult() {
 		$this->_result = array( "status" => array( "code"     => 0,
		                                           "message"  => "",
		                                           "inputUrl" => "",
		                                           "redirect" => "",
		                                           "ua"       => ""
		                                    ),
		                        "header" => "",
		                        "source" => ""
		);
	}
	
	/**
	 * chkIniGet()
	 */
	private function chkIniGet() {
		$this->_able = false;
		if ( ini_get("open_basedir") == "" ){
			if ( ini_get("safe_mode") == "Off" || ini_get("safe_mode") == "" ) {
				$this->_able = true;
			}
		}
	}
	
	/**
	 * setCurlOpt()
	 * - CURLOPT_RETURNTRANSFER : TRUE: curl_exec()の返り値が文字列
	 * - CURLOPT_FAILONERROR    : TRUE: 400以上のコードで処理失敗
	 * - CURLOPT_TIMEOUT        : 5   : curl関数タイムアウト(秒)
	 * - CURLOPT_CONNECTTIMEOUT : 5   : 接続のタイムアウトの設定
	 * - CURLOPT_HEADER         : TRUE: ページの内容にヘッダ情報も含める
	 * 
	 * ▼ini_get()次第で下記
	 * - CURLOPT_FOLLOWLOCATION : TRUE: リダイレクトをたどる
	 * - CURLOPT_MAXREDIRS      : 5   : リダイレクトをたどる最大回数
	 * - CURLOPT_AUTOREFERER    : TRUE: リダイレクトの際にヘッダのRefererを自動的に追加
	 */
	private function setCurlOpt() {
		$this->_curlOpts = array(
			CURLOPT_URL            => "",
			CURLOPT_RETURNTRANSFER => TRUE,
			CURLOPT_FAILONERROR    => TRUE,
			CURLOPT_TIMEOUT        => 5,
			CURLOPT_CONNECTTIMEOUT => 5,
			CURLOPT_HEADER         => TRUE
		);
		
		if ($this->_able) {
			$this->_curlOpts[CURLOPT_FOLLOWLOCATION] = TRUE;
			$this->_curlOpts[CURLOPT_MAXREDIRS]      = 5;
			$this->_curlOpts[CURLOPT_AUTOREFERER]    = TRUE;
		}
	}
	
	/**
	 * fixTrueOrFalse() - true or falseに変換。
	 */
	private function fixTrueOrFalse($arg) {
		if ($arg !== false) {
			$tmp = true;
		}
		else {
			$tmp = false;
		}
		return $tmp;
	}
	
	/**
	 * convertUrl() - http形式に変換
	 */
	private function convertUrl($url) {
		if ( strpos($url, "http://") === 0 || strpos($url, "https://") === 0 ) {
			$tmpUrl = $url;
		}
		else {
			$tmpUrl = "http://" . $url;
		}
		
		return $tmpUrl;
	}
	
	/**
	 * getRedirectUrl() - リダイレクト先のURLの取得
	 */
	private function getRedirectUrl($all, $source) {
		$rUrl = array_key_exists("redirect_url", $all);
		
		if ($this->_able && $rUrl === true) {
			$redirectUrl = $all["redirect_url"];
		}
		else {
			$redirectUrl = "";
			$srcAry = explode("\n", str_replace("\r", "", $source));
			foreach ($srcAry as $src) {
				if ( strpos($src, "Location") === 0){
					$tmpLocation = explode(" ", $src);
					$redirectUrl = $tmpLocation[1];
					break;
				}
			}
		}
		return $redirectUrl;
	}
	
	/**
	 * splitSource() - ヘッダ部とボディ部を分割
	 */
	private function splitSource($all, $source){
		$resultSource = array();
		
		if (array_key_exists("header_size", $all)) {
			$resultSource["header"] = substr($source, 0, $all["header_size"]);
			$resultSource["body"] = substr($source, $all["header_size"]);
		}
		else {
			$resultSource["header"] = "";
			$resultSource["body"] = $source;
		}
		
		return $resultSource;
	}
	
	// ========================================================
	// ▼各オプションの追加・修正
	
	/**
	 * setOptReturnTransfer() - CURLOPT_RETURNTRANSFERの設定変更
	 * TRUE: curl_exec()の返り値が文字列 / FALSE: データを直接出力
	 */
	public function setOptReturnTransfer($arg=true) {
		$bool = $this->fixTrueOrFalse($arg);
		$this->_curlOpts[CURLOPT_RETURNTRANSFER] = boolarg;
	}
	
	/**
	 * setOptFailOnError() - CURLOPT_FAILONERRORの設定変更
	 * TRUE: 400以上のコードで処理失敗 / FALSE: ページの内容を取得
	 */
	public function setOptFailOnError($arg=true) {
		$bool = $this->fixTrueOrFalse($arg);
		$this->_curlOpts[CURLOPT_FAILONERROR] = $bool;
	}
	
	/**
	 * setOptTimeOut() - CURLOPT_TIMEOUTの設定変更
	 * curl関数タイムアウト(秒): cURL 関数の実行にかけられる時間の最大値。 
	 */
	public function setOptTimeOut($time=5) {
		$this->_curlOpts[CURLOPT_TIMEOUT] = (int) $time;
	}
	
	/**
	 * setOptConnectTimeOut() - CURLOPT_CONNECTTIMEOUTの設定変更
	 * タイムアウトの設定:接続の試行を待ち続ける秒数
	 */
	public function setOptConnectTimeOut($arg=5) {
		$this->_curlOpts[CURLOPT_CONNECTTIMEOUT] = (int) $arg;
	}
	
	/**
	 * setOptFollowLocation() - CURLOPT_FOLLOWLOCATIONの設定変更
	 * リダイレクトをたどるか
	 */
	public function setOptFollowLocation($arg=true) {
		if ($this->_able) {
			$bool = $this->fixTrueOrFalse($arg);
			$this->_curlOpts[CURLOPT_FOLLOWLOCATION] = $bool;
		}
	}
	
	/**
	 * setOptMaxRedirs() - CURLOPT_MAXREDIRSの設定変更
	 * 最大何回リダイレクトをたどるか(リダイレクトループの回避)
	 */
	public function setOptMaxRedirs($max=5) {
		if ($this->_able) {
			$this->_curlOpts[CURLOPT_MAXREDIRS] = (int) $max;
		}
	}
	
	/**
	 * setOptAutoReferer() - CURLOPT_AUTOREFERERの設定変更
	 * TRUE: リダイレクトの際にヘッダのRefererを自動的に追加させる
	 */
	public function setOptAutoReferer($arg=true) {
		if ($this->_able) {
			$bool = $this->fixTrueOrFalse($arg);
			$this->_curlOpts[CURLOPT_AUTOREFERER] = $bool;
		}
	}
	
	/**
	 * setOptHeader() - CURLOPT_HEADERの設定変更
	 * TRUE: ページの内容にヘッダ情報も含める
	 */
	public function setOptHeader($arg=true) {
		$bool = $this->fixTrueOrFalse($arg);
		$this->_curlOpts[CURLOPT_HEADER] = $bool;
	}
	
	/**
	 * setOptUserAgent() - CURLOPT_USERAGENTの設定変更
	 * ユーザーエージェントの設定
	 */
	public function setOptUserAgent($arg="") {
		if ( $arg !== "" ) {
			$this->_curlOpts[CURLOPT_USERAGENT] = $arg;
			$this->_result["status"]["ua"] = $arg;
		}
	}
	
	/**
	 * setOptReferer() - CURLOPT_REFERERの設定変更
	 * リファラー(リンク元のページ)の設定
	 */
	public function setOptReferer($arg="") {
		if ( $arg !== "" ) {
			$this->_curlOpts[CURLOPT_REFERER] = $arg;
		}
	}
	
	/**
	 * setOptProxy() - Proxyの設定の設定
	 * (CURLOPT_HTTPPROXYTUNNEL、CURLOPT_PROXY、CURLOPT_PROXYPORT)
	 */
	public function setOptProxy($url="", $port="") {
		if ($url != "") {
			// ▼こいつは使っちゃダメ。罠。
			//$this->_curlOpts[CURLOPT_HTTPPROXYTUNNEL] = TRUE;
			
			$proxyUrl = $url;
			if ($port != "") {
				$proxyUrl .= ":" . $port;
				$this->_curlOpts[CURLOPT_PROXYPORT] = $port;
			} 
			
			$this->_curlOpts[CURLOPT_PROXY] = $proxyUrl;
		}
	}
	
	/**
	 * setOptProxyUserPwd() - CURLOPT_PROXYUSERPWDの設定変更
	 * ProxyのIDとPWの設定
	 */
	public function setOptProxyUserPwd($user="", $pwd="") {
		if ( $user !== "" ) {
			$this->_curlOpts[CURLOPT_PROXYUSERPWD] = $user . ":" . $pwd;
		}
	}
	
	/**
	 * setOptSslConnect() - CURLOPT_SSL_VERIFYPEER、CURLOPT_SSL_VERIFYHOST、CURLOPT_SSLVERSIONの設定変更
	 * ※SSLを利用するなら引数は「false」にしておく。サーバー証明書が分かるなら「true」
	 * CURLOPT_SSL_VERIFYPEER
	 *  TRUE : サーバー証明書の検証を行う。
	 *  FALSE: サーバー証明書の検証を行なわない。
	 * CURLOPT_SSL_VERIFYHOST
	 * CURLOPT_SSLVERSION : SSLのバージョン(2 or 3)。手動設定が必要なとき(デフォルトでは PHP が自動的に判断)
	 * 
	 * ※cUrlのSSLバージョンが「NSS」「OpenSSL」で何か変わることもあるとか…
	 */
	public function setOptSslConnect($arg=true, $version=-1) {
		$bool = $this->fixTrueOrFalse($arg);
		$this->_curlOpts[CURLOPT_SSL_VERIFYPEER] = $bool;
		
		if ($bool === false) {
			$this->_curlOpts[CURLOPT_SSL_VERIFYHOST] = false;
		}
		else {
			// 1 : SSL ピア証明書に一般名が存在するかどうかを調べる
			// 2 : それに加え、その名前がホスト名と一致することを検証(デフォルト)
			// ※cURL 7.28.1以降:「1」は使えないらしい
			$this->_curlOpts[CURLOPT_SSL_VERIFYHOST] = 2;
		}
		
		if ($version !== -1){
			$this->_curlOpts[CURLOPT_SSLVERSION] = (int) $version;
		}
	}
	
	/**
	 * setOptPost() - CURLOPT_POSTの設定変更
	 * TRUE : postでリクエストを投げる
	 * FALSE: getでリクエストを投げる
	 */
	public function setOptPost($arg=true) {
		$bool = $this->fixTrueOrFalse($arg);
		$this->_curlOpts[CURLOPT_POST] = $bool;
	}
	
	/**
	 * setOptPostFields() - CURLOPT_POSTFIELDSの設定変更
	 * POSTで投げるときのパラメータ(POSTするデータを連想配列で格納)
	 */
	public function setOptPostFields($args=false) {
		if ( $args !== false ) {
			$this->setOptPost(true);
			$this->_curlOpts[CURLOPT_POSTFIELDS] = $args;
		}
	}
	
	// ========================================================
	
	/**
	 * getSource() - ソースを取得
	 */
	public function getSource($url="") {
		if ($url == ""){
			$this->_result["status"]["message"] = "no url";
			return $this->_result["status"]["message"];
		}
		
		$getUrl = $this->convertUrl($url);
		$this->_result["status"]["inputUrl"] = $getUrl;
		$this->_curlOpts[CURLOPT_URL] = $getUrl;
		
		curl_setopt_array($this->_ch, $this->_curlOpts);
		
		$getSource = curl_exec($this->_ch);
		$allInfo   = curl_getinfo($this->_ch);
		
		$this->_result["status"]["code"] = $allInfo["http_code"];
		
		if(!curl_errno($this->_ch)){
			if (300 <= $allInfo["http_code"] && $allInfo["http_code"] < 400){
				// リダイレクト先のURL取得
				$this->_result["status"]["redirect"] = $this->getRedirectUrl($allInfo, $getSource);
			}
			
			$tmpSource = $this->splitSource($allInfo, $getSource);
			$this->_result["header"] = $tmpSource["header"];
			$this->_result["source"] = $tmpSource["body"];
			$this->_result["status"]["message"] = $allInfo;
		}
		else {
			// エラー
			$this->_result["source"] = "取得失敗: Curl error: " . curl_error($this->_ch);
		}
		
		return $this->_result["source"];
	}
	
}
?>

使い方

$objCurl = new ClassCurlSupport();
print_r( $objCurl->getSource("http://○○○○○○") );

例えば、UAを設定する場合は下記のような感じ。

$objCurl = new ClassCurlSupport();
$objCurl->setOptUserAgent( "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)" );
print_r( $objCurl->getSource("http://○○○○○○") );

※UAいれたいとか、Proxy通したいとか各オプションの追加・修正は「$objCurl->setOpt○○○○○();」とかする。

関連項目