08
2月

CakePHPでAmazon Web Service

CakephpでAmazon Web Serviceを利用するためにモデルをうまく使います。今回はPEARのServices_Amazonは使いません。賛否両論あるかもしれませんが、依存しまくりのライブラリを安易に使うと運用上ダルくなるので僕はなるべく使いません。ネット上にはPEARを使う方法のほうが多いし。

では、まずはデータベースを使用しないようにモデルを書きます。

/app/models/test.php

class Test extends AppModel
{
    var $name = 'Test';
    var $useTable = false;
}


次にAmazon Web Serviceへアクセスするメソッドを実装します。

/cake/libs/model/app_model.php

class AppModel extends Model
{
	var $xml;
	var $host = "ecs.amazonaws.jp";
	var $base_path = "/onca/xml?Service=AWSECommerceService";
	var $sub_id = "自分のアクセスID";
	var $aid = "自分のアソシエイトID";
	var $version = "2007-10-29";
	var $contentType= "text/xml";
	var $path = "";

	function setKeyword($keyword, $index, $page)
	{
		$this->path = $this->base_path
		. "&AWSAccessKeyId=" . $this->sub_id
		. "&AssociateTag=" . $this->aid
		. "&Version=" . $this->version
		. "&ContentType=" . $this->contentType;

		$this->path .= "&Operation=ItemSearch"
		. "&ResponseGroup=Small,Offers,Images,BrowseNodes,SalesRank"
		. "&Keywords=" . $keyword
		. "&SearchIndex=" . $index
		. "&Page=" . $page;

		return true;
	}

	function loadXml()
	{
		$doc = $this->connect();

		if(!$doc) return false;
		if(substr($doc,0,5) != "<?xml") return false;

		$this->xml = simplexml_load_string($doc);	

		return $this->xml;
	}

	function connect()
	{
		$sockPointer = fsockopen($this->host, 80, $errno, $errstr, 6); 

		if(!$sockPointer)
		{
			return false;
		}
		else
		{
			stream_set_timeout($sockPointer, 6, 0);

			fputs ($sockPointer, "GET $this->path HTTP/1.0rnHost: $this->hostrnrn");
			fputs ($sockPointer, "User-Agent: AwsDataSourcenn");
			fputs ($sockPointer, "Keep-Alive: 300nn");
			fputs ($sockPointer, "Connection: Keep-Alivenn");
			fputs ($sockPointer, "Referer: http://www.artsnet.jp/nn");

			$buf = "";
			$response = fgets($sockPointer);
			if(substr_count($response, "200 OK") > 0)
			{
				while(!feof($sockPointer))
				{
					$buf = $buf . fread($sockPointer,4096);
				}
			}
			else
			{
				$result = false;
			}
			$result = true;
		}
		fclose($sockPointer);

		if($result)
		{
			$doc = substr($buf, strpos($buf,"rnrn")+4);
			return $doc;
		}
		else
		{
			return false;
		}
	}
}

ちなみにこのコードはWebサービスをAmazonで知る――PHPでECS 4.0を使うテクニックそのまんまです。

最後にコントロールで使います。

/app/model/controllers/tests_controller.php

class TestsController extends AppController
{
    var $name = 'Tests';

    function index()
    {
    	$this->Test->setKeyword('PHP', 'Books', '1');
	$this->Test->loadXml();
	print_r($this->Test->xml);
    }
}

ちなみにCakePHPで楽天WEBサービスを使うのコメント欄でCakePHPのdatasourceをうまく使うヒントが書かれていました。これはデータ操作の全てをdatasourceに追いやることで、データ自体がRDBだろうがXMLだろうがJSONだろうが同じように使うためのものです。逆に言えばCakePHPでRDBを扱ってきたsetとかfindとか全てのメソッドが通るように実装しなければならないことを意味します。

今回はそんな必要も時間もないのでApp_modelで実装するだけにしました。


タグ

, , , ,

関連する投稿

1件のコメント

  • showBOO Said:

    トラックバックありがとうございます。
    app_model.phpにまとめると便利ですね。
    こういうやり方もあるんだと、勉強になりました。

コメントを書く

コメントRSS   トラックバックURL

?>-->