*上記の続き
異なるデータベース、NoSQLなどを結合できるということが理解できたと思います。
それではPHPのアプリケーションから実際に利用してみましょう。
PHP Prestodb Client
PHPのPrestoクライアントライブラリは、古いものがありますが、
自分の用途に合わなかった(最新のPHP向けにしたかったなど)為、
新たに作り、公開しました。
*新しく作ったもの
*以前からある古いもの
prestoはpdoのようにネイティブのコネクタはなく、
REST APIによる操作が可能です。
以前からあるもののスタイルではなく、javaのクライアントに近い実装にしました。
早速クライアントを利用して、前回のクエリを発行します。
Install
PHP7.0以上にのみ対応していますので、7.0以上の環境で実行してください。
installはcomposerを利用してください。
下記のコマンドを実行するだけでOKです。
$ composer require ytake/php-presto-client
Usage
prestoに問い合わせるクライアントのインスタンス生成は次の通りです。
<?php $query = "SELECT _key, _value, test_id, test_name, created_at FROM my_tests.testing.tests AS myttt INNER JOIN red_tests.test.string AS redttt ON redttt._key = myttt.test_name WHERE myttt.test_name = 'presto'"; $client = new \Ytake\PrestoClient\StatementClient( new \Ytake\PrestoClient\ClientSession('http://127.0.0.1:8080/', 'my_tests'), $query );
ClientSessionクラスに接続先と、第二引数にカタログ名を指定します。
カタログ名を指定すると、そのカタログ名を省略できるようになります。
ClientSessionクラスのインスタンスをStatementClientクラスに与えると、
Prestoに問い合わせる準備が整います。
一番簡単に利用できるのは、Ytake\PrestoClient\ResultsSession
経由で結果を取得する方法です。
<?php $resultSession = new \Ytake\PrestoClient\ResultsSession($client); $result = $resultSession->execute()->yieldResults(); /** @var \Ytake\PrestoClient\QueryResult $row */ foreach($result as $row) { foreach($row->yieldData() as $yieldRow) { if($yieldRow instanceof \Ytake\PrestoClient\FixData) { var_dump($yieldRow->offsetGet('_key'), $yieldRow['_key']); } } }
yieldResultで様々なデータが返却されます。
Prestoはデータを取得するまでに複数回リクエストをおくる必要があり、
Queryの結果取得以外にも様々なデータを分割して返却する為です。
Prestoから返却されるQueryの結果は Ytake\PrestoClient\FixData
で返却されますので、
これを取得します。
このクラスは ArrayAccess
を実装していますので、
一般的な配列へのアクセスと同等にカラムの値を取得できます。
前回利用したクエリの結果は次のようになります。
class Ytake\PrestoClient\FixData#20 (5) { public $_key => string(6) "presto" public $_value => string(7) "awesome" public $test_id => int(1) public $test_name => string(6) "presto" public $created_at => string(23) "2017-09-15 03:49:30.000" }
接続にユーザーなどが必要であれば、ClientSessionクラスのメソッドが利用できます。
Prepared Statementは現在のバージョンではサポートされていない為、
利用できませんが(ユーザーに近いフロントから利用するものではない為)
サポートされていた以前のバージョンではPreparedStatementクラスがそのまま使えると思います。
利用方法のまとめ
簡単な利用方法をまとめると次のようになります。
<?php require_once __DIR__ . '/vendor/autoload.php'; $query = "SELECT _key, _value, test_id, test_name, created_at FROM my_tests.testing.tests AS myttt INNER JOIN red_tests.test.string AS redttt ON redttt._key = myttt.test_name WHERE myttt.test_name = 'presto'"; $client = new \Ytake\PrestoClient\StatementClient( new \Ytake\PrestoClient\ClientSession('http://127.0.0.1:8080/', 'my_tests'), $query ); $resultSession = new \Ytake\PrestoClient\ResultsSession($client); // yield results instead of returning them. Recommended. $result = $resultSession->execute()->yieldResults(); /** @var \Ytake\PrestoClient\QueryResult $row */ foreach($result as $row) { foreach($row->yieldData() as $yieldRow) { if($yieldRow instanceof \Ytake\PrestoClient\FixData) { var_dump($yieldRow->offsetGet('_key'), $yieldRow['_key']); } } }
オブジェクト マッピング
PDOのFETCH_CLASSのように、任意のオブジェクトで変更することもできます。
PHP: PDOStatement::fetch - Manual
任意のオブジェクトで返却したい場合、カラムをクラスのプロパティとして作成します。
指定したカラム以外の値は返却されませんので、
以下のようにすると、プロパティに記述した2つのカラム以外は返却されません。
尚、プロパティはpublic, protected, privateのいずれでも値が挿入されますので、
アプリケーションの設計に合わせて利用してください。
<?php class Testing { /** @var string */ private $_key; /** @var string */ private $_value; /** * @return string */ public function key() { return $this->_key; } /** * @return string */ public function value(): string { return $this->_value; } }
あとはyieldObjectメソッドにクラス名を指定して値を取得します。
<?php $resultSession = new \Ytake\PrestoClient\ResultsSession($client); $result = $resultSession->execute()->yieldResults(); /** @var \Ytake\PrestoClient\QueryResult $row */ foreach ($result as $row) { foreach ($row->yieldObject(Testing::class) as $item) { if ($item instanceof Testing) { var_dump($item); } } }
これでPHPのアプリケーションからPrestoを操作することができるようになりました。
管理画面や、分析用途に活用してみてください。