pajamasql/pajamasql

PHP SQL 数据库层

1.0.0 2019-10-16 15:38 UTC

This package is not auto-updated.

Last update: 2024-09-14 14:30:32 UTC


README

pajamaSQL 是一个 PHP SQL 数据库层。它支持 MySQL、PostgreSQL 和 SQLite。

目录

文档
要求
源代码
单元测试
示例
安装
概述
MySQL
PostgreSQL
SQLite
模型
错误处理
许可证

文档

README 目前是唯一的文档。

要求

PHP 5.6.0+ 或 7+Composer;以及以下 PHP 供应商特定的数据库扩展之一: MysqliPostgreSQL 和/或 SQLite3。单元测试需要 PHP 7.2.0+

源代码

项目 及其 源代码 可在 GitHub 上找到。

单元测试

tests 目录中存在单元测试。您需要编辑 MysqlTest.phpPgsqlTest.php 顶部的数据库凭据。

示例

此 README 中的所有示例代码都在 examples 目录中。示例目录还包含 README 中未包含的其他示例。在运行任何示例之前,您需要在示例目录中运行 composer install

安装

使用 composer 安装

{
    "require": {
        "pajamasql/pajamasql": "1.0.0",
    }
}

概述

pajamaSQL 包装了 MysqliPostgreSQLSQLite3 预处理语句。这些是可用的方法: exec()query()rquery()prepare()bexec()bquery()brquery()conn()error()esc()。基本用法如下

$db->exec(
    'insert into foo values(?), (?)',
    'bar',
    'baz');

$data = $db->query(
    'select * from foo where rowid > ?',
    1);

还有一个模型层。一个基本的模型如下所示

<?php

namespace purple;

class FooModel extends \pjsql\DatabaseAdapter {
    public function createFoo($name) {
        $this->exec(
            'insert into foo values(?)',
            $name);
    }    
}

模型实例化和使用

<?php

require 'vendor/autoload.php';

$foo_model = purple\ModelFactory::get('purple\FooModel');

$foo_model->createFoo('fred');

MySQL

使用 Mysql() 连接到数据库

<?php

require 'vendor/autoload.php';

$db = new pjsql\Mysql(
    'host',
    'username',
    'password',
    'database');

echo $db->conn()->stat();

上面的 conn() 是一个 mysqli 对象。

使用 exec()query() 执行查询

$db->exec('create table tanimal(
    animal_id int auto_increment primary key,
    name varchar(32))');

$db->exec('insert into tanimal(name) values("tiger")');

$data = $db->query('select * from tanimal');

print_r($data);

exec()query() 可以接受查询参数

$db->exec(
    'insert into tanimal(name) values(?), (?)',
    'tiger',
    'eagle');

$data = $db->query(
    'select * from tanimal where animal_id = ?',
    2);

print_r($data);

query() 返回包含所有数据的数组。如果您想使用 mysqli_result 对象,则使用 rquery()

$result = $db->rquery('select * from tanimal');

while($row = $result->fetch_object()) {
    print_r($row);
}

使用 prepare()bexec()bquery() 来多次运行查询

$stmt = $db->prepare('insert into tanimal values(null, ?)');
$db->bexec($stmt, 'bird');
$db->bexec($stmt, 'frog');
$db->bexec($stmt, 'cat');

$ids = [1, 2, 3, 4];
$stmt = $db->prepare('select name from tanimal where animal_id = ?');

foreach($ids as $id) {
    $data = $db->bquery($stmt, $id);
    print_r($data);
}

bquery() 返回包含所有数据的数组。如果您想使用 mysqli_result 对象,则使用 brquery()

$floors = [1, 5];
$stmt = $db->prepare('select name from tanimal where animal_id >= ?');

foreach($floors as $f) {
    $result = $db->brquery($stmt, $f);

    while($row = $result->fetch_assoc()) {
        print_r($row);
    }
}

在所有 exec 和 query 方法中,您可以放入参数值到一个数组中,并使用类型字符串作为第三个参数以指定查询参数类型

$db->exec(
    'insert into tanimal(name) values(?), (?), (?)',
    ['lizard', 'cow', 'monkey'],
    'sss');

$data = $db->query(
    'select * from tanimal where animal_id < ?',
    [3],
    'i');

print_r($data);

上述参数类型字符串与 mysqli_stmt::bind_param$types 参数具有相同的作用。

PostgreSQL

使用 Pgsql() 连接到数据库

<?php

require 'vendor/autoload.php';

$db = new pjsql\Pgsql('dbname=foo user=bar password=baz');

echo pg_host($db->conn());

conn() 上面是一个 PostgreSQL 连接资源,由 pg_connect() 返回。

使用 exec()query() 执行查询

$db->exec('create table tcolor(
    color_id serial primary key,
    name varchar(40))');

$db->exec("insert into tcolor(name) values('green')");

$data = $db->query('select * from tcolor');

print_r($data);

exec()query() 可以接受查询参数

$db->exec(
    'insert into tcolor(name) values($1), ($2)',
    'gold',
    'silver');

$data = $db->query(
    'select * from tcolor where color_id <> $1',
    1);

print_r($data);

query() 返回包含所有数据的数组。如果您想使用查询结果资源,则使用 rquery()

$result = $db->rquery('select * from tcolor');

while($row = pg_fetch_assoc($result)) {
    print_r($row);
}

使用 prepare()bexec()bquery() 来多次运行查询

$stmt_name = 'insert1';
$db->prepare('insert into tcolor values(default, $1)', $stmt_name);
$db->bexec($stmt_name, 'pink');
$db->bexec($stmt_name, 'purple');
$db->bexec($stmt_name, 'black');

$ids = [1, 2, 3, 4];
$stmt_name = 'select1';
$db->prepare('select name from tcolor where color_id = $1', $stmt_name);

foreach($ids as $id) {
    $data = $db->bquery($stmt_name, $id);
    var_dump($data);
}

bquery() 返回包含所有数据的数组。如果您想使用查询结果资源,则使用 brquery()

$floors = [4, 3];
$stmt_name = 'select1';
$db->prepare('select * from tcolor where color_id >= $1', $stmt_name);

foreach($floors as $f) {
    $result = $db->brquery($stmt_name, $f);

    while($row = pg_fetch_object($result)) {
        print_r($row);
    }
}

SQLite

使用 Sqlite() 连接到数据库

<?php

require 'vendor/autoload.php';

$db = new pjsql\Sqlite('mydb.db');

echo get_class($db->conn());

conn() 上面是一个 SQLite3 对象。

使用 exec()query() 执行查询

$db->exec('create table tshape(name text)');

$db->exec('insert into tshape values("circle")');

$data = $db->query('select * from tshape');

print_r($data);

exec()query() 可以接受查询参数

$db->exec(
    'insert into tshape values(?), (?)',
    'triangle',
    'square');

$data = $db->query(
    'select * from tshape where rowid > ?',
    1);

print_r($data);

query() 返回包含所有数据的数组。如果您想使用 SQLite3Result 对象,则使用 rquery()

$result = $db->rquery('select * from tshape');

while($row = $result->fetchArray(SQLITE3_ASSOC)) {
    print_r($row);
}

使用 prepare()bexec()bquery() 来多次运行查询

$stmt = $db->prepare('insert into tshape values(?)');
$db->bexec($stmt, 'octagon');
$db->bexec($stmt, 'oval');
$db->bexec($stmt, 'circle');

$ids = [1, 2, 3, 4];
$stmt = $db->prepare('select name from tshape where rowid = ?');

foreach($ids as $id) {
    $data = $db->bquery($stmt, $id);
    print_r($data);
}

bquery() 返回包含所有数据的数组。如果您想使用 SQLite3Result 对象,则使用 brquery()

$stmt = $db->prepare('select * from tshape where rowid >= ?');
$floors = [4, 3, 4];

foreach($floors as $f) {
    $result = $db->brquery($stmt, $f);

    while($row = $result->fetchArray()) {
        print_r($row);
    }
}

在所有 exec 和 query 方法中,您可以放入参数值到一个数组中,并使用类型字符串作为第三个参数以指定查询参数类型

$db->exec(
    'insert into tshape values(?), (?)',
    ['square', 'circle'],
    'tt');

$data = $db->query(
    'select * from tshape where rowid < ?',
    [500],
    'i');

print_r($data);

上述类型字符串中的字符使用以下映射

i = SQLITE3_INTEGER
f = SQLITE3_FLOAT
t = SQLITE3_TEXT
b = SQLITE3_BLOB
n = SQLITE3_NULL

模型

设置模型工厂

<?php

namespace purple;

class ModelFactory extends \pjsql\AdapterFactory {
    protected static function databaseHandle() {
        return new \pjsql\Mysql(
            'host',
            'username',
            'password',
            'database');
    }
}

如果您想使用 PostgreSQL 或 SQLite,则使用 Pgsql()Sqlite() 而不是上面的 Mysql()

创建模型

<?php

namespace purple;

class DogModel extends \pjsql\DatabaseAdapter {
    public function install() {
        $this->exec('create table tdog(
            dog_id int auto_increment primary key,
            name varchar(50))');
    }

    public function createDog($name) {
        $this->exec(
            'insert into tdog(name) values(?)',
            $name);
    }

    public function getDogs() {
        return $this->query('select * from tdog');
    }     
}

获取模型并调用其方法

<?php

require 'vendor/autoload.php';

$dog_model = purple\ModelFactory::get('purple\DogModel');

$dog_model->install();

$dog_model->createDog('spike');
$dog_model->createDog('buster');

$data = $dog_model->getDogs();

print_r($data);

错误处理

使用 exec、query 和 prepare 方法,您可以使用异常处理程序处理错误

set_exception_handler(function($e) {
    if($e instanceof pjsql\DatabaseException) {
        die($e->getMessage());
    }
    else {
        throw $e;
    }
});

如果您使用 conn(),则在适当的时候调用 error()(MySQL 示例)

if($status = $db->conn()->stat()) {
    echo $status;
}
else {
    $db->error();
}

上面的 error() 将抛出异常,该异常将被上面的异常处理程序捕获。

授权协议

MIT http://ryf.mit-license.org/