Aura SQL

Aura SQLパッケージはMySQL、PostgreSQL、それにSqliteなどのデータベースのクエリーとその接続を提供します。 接続のほとんどはPDO接続でラップされたものです。

Aura SQL は4つの接続アダプターをサポートします。'mysql'はMySQL、 'pgsql'はPostgreSQL、 'sqlite'はSQLite3それに'sqlsrv' は Microsoft SQL Serverに使われます。

インストール

もしAura.SqlをDIで使うならこの章はスキップできます。

scripts/instance.phpスクリプトを使いConnectionFactory を取得して接続するのが始めるのに簡単な方法です。

<?php
$connection_factory = include '/path/to/Aura.Sql/scripts/instance.php';
$connection = $connection_factory->newInstance(

    // adapter name
    'mysql',

    // DSN elements for PDO; this can also be
    // an array of key-value pairs
    'host=localhost;dbname=database_name',

    // username for the connection
    'username',

    // password for the connection
    'password'
);

代わりに、別のautoloaderに'/path/to/Aura.Sql/src'を加えて手動で接続を取得する事もできます。

<?php
use Aura\Sql\ConnectionFactory;
$connection_factory = new ConnectionFactory;
$connection = $connection_factory->newInstance(...);

接続

接続はクエリーを発行したときに遅延接続されます。つまり接続オブジェクトを作成しても、もしクエリーを発行しなければデータベースに接続される事はありません。

手動でconnect()を使って接続する事もできます。

<?php
$connection->connect();

結果の取得

一度接続すれば、データベースから結果を取得することもできます。

<?php
// returns all rows
$result = $connection->fetchAll('SELECT * FROM foo');

これらのメソッドを使って結果を取得することができます。

  • fetchAll()は全ての行の連続した配列を返します。行は列の名前をキーとした連想配列が返ります。

returns a sequential array of all rows. The rows themselves are associative arrays where the keys are the column names.

  • fetchAssoc() は最初の列がキーとなった全ての行の連想配列が返ります。

  • fetchCol() は最初の列の全ての値を連続した配列として返します。

  • fetchOne()は最初の行を列名をキーとした連想配列で返します。

  • fetchPairs()は最初の列をキーとして次の列を値とした連想配列を返します。

  • fetchValue() 最初の列の最初の行の値を返します。

SQLインジェクションの防御

通常、ユーザーが提供するデータをクエリーに組み入れる必要があります。 つまり、全ての値をクオートしてクエリー文字列に差し込むSQL injectionの防止をしなければなりません。

Aura SQLはクオートするメソッドを提供していますが、それよりプリペアードステートを使って値をバインドする方が良いでしょう。 その為にクエリーの文字列中に名前を使ったプレースホルダーを置いて、そのプレースホルダーに配列の値をバインドします。

<?php
// the text of the query
$text = 'SELECT * FROM foo WHERE id = :id';

// values to bind to query placeholders
$bind = [
    'id' => 1,
];

// returns one row; the data has been parameterized
// into a prepared statement for you
$result = $connection->fetchOne($text, $bind);

Aura SQL は配列とクオートする値をカンマ区切りのリストとして、認識します。

<?php
// the text of the query
$text = 'SELECT * FROM foo WHERE id = :id AND bar IN(:bar_list)';

// values to bind to query placeholders
$bind = [
    'id' => 1,
    'bar_list' => ['a', 'b', 'c'],
];

// returns all rows; the query ends up being
// "SELECT * FROM foo WHERE id = 1 AND bar IN('a', 'b', 'c')"
$result = $connection->fetchOne($text, $bind);

クエリーオブジェクト

Aura SQLは4つのタイプのクエリーオブジェクトを用意します。 それによってオブジェクト指向スタイルで記述することができます。

Select

新しいSelectオブジェクトを取得するのにはnewSelect()メソッドを接続の時に実行します。 それからSelect オブジェクトを変更して、query()fetch*()メソッドに渡します。

<?php
// create a new Select object
$select = $connection->newSelect();

// SELECT * FROM foo WHERE bar > :bar ORDER BY baz
$select->cols(['*'])
       ->from('foo')
       ->where('bar > :bar')
       ->orderBy('baz');

$bind = ['bar' => '88'];

$list = $connection->fetchAll($select, $bind);

Selectオブジェクトはこれらのメソッド以上のものを提供します。 更なる情報はソースコードをご覧になってください。

  • distinct(): SELECT DISTINCTtrueをセットします。

  • cols(): コラム(列)をセレクトします。

  • from(): テーブルをセレクトします。

  • join(): 特定条件のテーブルをジョインします。

  • where(): 条件にWHEREを使います。(ANDを使用します)

  • orWhere(): 条件にWHEREを使います。(ORを使用します)

  • groupBy(): コラム(列)をGROUP BYします。

  • having(): 条件にHAVINGを使います。 (ANDを使用します)

  • orHaving(): 条件にHAVINGを使います。 (ORを使用します)

  • orderBy(): コラム(列)をORDER BYします。

  • limit(): ロー(行)に対してLIMITします。

  • offset(): ロー(行)に対してOFFSETします。

  • union(): SELECTUNIONを続けます。

  • unionAll(): SELECTUNION ALLを続けます。

Insert

新しいInsertオブジェクトを取得するのにはnewInsert()メソッドを接続の時に実行します。 それからInsert オブジェクトを変更して、query()メソッドに渡します。

<?php
// create a new Insert object
$insert = $connection->newInsert();

// INSERT INTO foo (bar, baz, date) VALUES (:bar, :baz, NOW());
$insert->into('foo')
       ->cols(['bar', 'baz'])
       ->set('date', 'NOW()');

$bind = [
    'bar' => null,
    'baz' => 'zim',
];

$stmt = $connection->query($insert, $bind);

Update

新しいUpdateオブジェクトを取得するのにはnewUpdate()メソッドを接続の時に実行します。 それからUpdate オブジェクトを変更して、query()メソッドに渡します。

<?php
// create a new Update object
$update = $connection->newUpdate();

// UPDATE foo SET bar = :bar, baz = :baz, date = NOW() WHERE zim = :zim OR gir = :gir
$update->table('foo')
       ->cols(['bar', 'baz'])
       ->set('date', 'NOW()')
       ->where('zim = :zim')
       ->orWhere('gir = :gir');

$bind = [
    'bar' => 'barbar',
    'baz' => 99,
    'zim' => 'dib',
    'gir' => 'doom',
];

$stmt = $connection->query($update, $bind);

Delete

新しいDeleteオブジェクトを取得するのにはnewDelete()メソッドを接続の時に実行します。 それからDelete オブジェクトを変更して、query()メソッドに渡します。

<?php
// create a new Delete object
$delete = $connection->newDelete();

// DELETE FROM WHERE zim = :zim OR gir = :gir
$delete->from('foo')
       ->where('zim = :zim')
       ->orWhere('gir = :gir');

$bind = [
    'zim' => 'dib',
    'gir' => 'doom',
];

$stmt = $connection->query($delete, $bind);

テーブル情報の取得

データベースのテーブル情報を取得するにはfetchTableList()を発行します:

<?php
// get the list of tables
$list = $connection->fetchTableList();

// show them
foreach ($list as $table) {
    echo $table . PHP_EOL;
}

テーブルのカラムについての情報を取得するにはfetchTableCols()を発行します;

<?php
// the table to get cols for
$table = 'foo';

// get the cols
$cols = $connection->fetchTableCols($table);

// show them
foreach ($cols as $name => $col) {
    echo "Column $name is of type "
       . $col->type
       . " with a size of "
       . $col->size
       . PHP_EOL;
}

それぞれのコラムは以下のプロパティを持つColumnオブジェクトとして表されます。

  • name: (string) コラム名

  • type: (string) データベースにより伝えられるコラムのデータの型。

  • size: (int) コラムサイズ

  • scale: (int) (もしあれば)コラムの数

  • notnull: (bool) NOT NULLとマークされてるコラムの数

  • default: (mixed) コラムのデフォルト値。timestampが自動でセットされる場合はnullの時があることに注意。

  • autoinc: (bool) auto-incrementedのコラムかどうか

  • primary: (bool) プライマリーキーかどうか

トランザクション

Aura SQL接続はいつもautocommitモードで始まります(PDOと同じです) これをオフにしてトランザクションはbeginTransaction()で開始してcommit()または rollBack() することができます。 コミットとロールバックは接続をautocommitモードに戻します。

<?php
// turn off autocommit and start a transaction
$connection->beginTransaction();

try {
    // ... perform some queries ...
    // now commit to the database:
    $connection->commit();
} catch (Exception $e) {
    // there was an error, roll back the queries
    $connection->rollBack();
}

// at this point we are back in autocommit mode

マニュアルクエリー

手動でのクエリーも可能です。query()メソッドでこのようにします;

<?php
$text = "SELECT * FROM foo WHERE id = :id";
$bind = ['id' => 1];
$stmt = $connection->query($text, $bind);

返される$stmtPDOStatementで自由に操作できます。

プロファイリング

クエリーがどのように実行されているかプロファイルする事もできます。

<?php
// turn on the profiler
$connection->getProfiler()->setActive(true);

// issue a query
$result = $connection->fetchAll('SELECT * FROM foo');

// now get the profiler information
foreach ($connection->getProfiler()->getProfiles() as $i => $profile) {
    echo 'Query #' . ($i + 1)
       . ' took ' . $profile->time . ' seconds.'
       . PHP_EOL;
}

プロファイルオブジェクトはそれぞれ以下のプロパティを持ちます。 operties:

  • text: (string) クエリー文字列

  • time: (float) クエリーが完了するまでの時間。単位は秒。

  • data: (array) クエリーにバインドされたデータ。

  • trace: (array) クエリーがどうやって呼ばれたかを知る事のできるdebug_backtrace