pontikis / dacapo
Dacapo - 简单的 PHP 数据库包装器
Requires
- php: ^7.0
Requires (Dev)
- phpunit/php-invoker: ^1.1
- phpunit/phpunit: ^6
This package is not auto-updated.
Last update: 2024-09-29 05:09:19 UTC
README
Dacapo 类 (简单的 PHP 数据库包装器)
版权所有 Christos Pontikis http://www.pontikis.net
许可证 MIT https://raw.github.com/pontikis/dacapo/master/MIT_LICENSE
概述 - 数据库
- 支持的 RDMBS: MySQLi (或 MariaDB), POSTGRESQL
- 简单清晰的语法
- 仅使用预处理语句
- 支持的查询:单个 SELECT、UPDATE、INSERT、DELETE。
- 支持事务
- 轻松安全地编写 SQL。在参数值的位置使用 dacapo
sql_placeholder(默认为 ?)。Dacapo 将从标准的 ANSI SQL 创建预处理语句。
$sql = 'SELECT procuct_name FROM products WHERE manufacturer = ? and type IN (?,?,?)';
备注
- 对于 MYSQLi SELECT 预处理语句,需要
mysqlnd - 不支持持久数据库连接。
- 不支持 BLOB 字段
- 避免布尔字段,使用整数代替(1,0)
- 使用
$ds->execute()来执行一个或多个 SQL 语句(例如 SQL 脚本)。在这里不能使用预处理语句。
关于异常
您应该在您的应用程序中创建自定义包装器来捕获异常。
Dacapo 错误处理器将抛出 DacapoErrorException。
如果您选择不使用 Dacapo 错误处理器,您将在自己的错误处理器中定义异常类型。
关于 Postgresql 序列
当您在 Postgres 中执行 INSERT 查询时,如果您想要获取主键列中的最后一个插入值,您还需要查询序列。在这种情况下使用 setQueryInsertPgSequence()。有三个选项
self::PG_SEQUENCE_NAME_AUTO在这种情况下,序列名称将自动构建为tablename_id_seq。这是默认设置(适用于 SERIAL 列)null(在未定义主键的罕见情况下)- 序列的真实名称
记住,在每次 INSERT 查询后,query_insert_pg_sequence 将重置为默认的 self::PG_SEQUENCE_NAME_AUTO。
文档
对于 HTML 文档,请参阅 docs/doxygen/html/ 文件夹(在浏览器中打开 index.html 文件)。
安装
使用 Composer(推荐)
composer require pontikis/dacapo
或老式方法
require_once 'path/to/Dacapo.php'; require_once 'path/to/DacapoErrorException.php';
使用示例
创建实例
use Pontikis\Database\Dacapo; use Pontikis\Database\DacapoErrorException; $db_settings = [ 'rdbms' => Dacapo::RDBMS_POSTGRES, // or Dacapo::RDBMS_MYSQLI for MySQL/MariaDB 'db_server' => 'localhost', 'db_user' => 'foo', 'db_passwd' => 'bar', 'db_name' => 'baz', ]; try { $ds = new Dacapo($db_settings); } catch (Exception $e) { // your code here }
选择
$sql = 'SELECT id, firstname, lastname FROM customers WHERE lastname LIKE ?'; $bind_params = ['%' . $str . '%']; try { $ds->select($sql, $bind_params); $customers = $ds->getData(); } catch (DacapoErrorException $e) { // your code here }
遍历数据
if($ds->getNumRows() > 0) { foreach($customers as $customer) { $id = $customer['id']; $lastname = $customer['lastname']; $firstname = $customer['firstname']; } }
选择行
$sql = 'SELECT firstname, lastname FROM customers WHERE id = ?'; $bind_params = [$id]; try { $ds->select($sql, $bind_params); if(1 === $ds->getNumRows()) { $customer = $ds->getRow(); $firstname = $customer['firstname']; $lastname = $customer['lastname']; } } catch (DacapoErrorException $e) { // your code here }
插入
$sql = 'INSERT INTO customers (firstname, lastname) VALUES (?,?)'; $bind_params = [$firstname, $lastname]; try { $ds->insert($sql, $bind_params); $new_customer_id = $ds->getInsertId(); } catch (DacapoErrorException $e) { // your code here }
更新
$sql = 'UPDATE customers SET category = ? WHERE balance > ?'; $bind_params = [$category, $balance]; try { $ds->update($sql, $bind_params); $affected_rows = $ds->getAffectedRows(); } catch (DacapoErrorException $e) { // your code here }
删除
$sql = 'DELETE FROM customers WHERE category = ?'; $bind_params = [$category]; try { $ds->delete($sql, $bind_params); $affected_rows = $ds->getAffectedRows(); } catch (DacapoErrorException $e) { // your code here }
事务
try { $ds->beginTrans(); // delete from customers $sql = 'DELETE FROM customers WHERE id = ?'; $bind_params = [$customers_id]; $ds->delete($sql, $bind_params); // delete from demographics $sql = 'DELETE FROM demographics WHERE id = ?'; $bind_params = [$customer_demographics_id]; $ds->delete($sql, $bind_params); $ds->commitTrans(); } catch (DacapoErrorException $e) { $ds->rollbackTrans(); // your code here }
实用函数
lower
// check for unique username (CASE IN-SENSITIVE) $sql = "SELECT count('id') as total_rows FROM users WHERE {$ds->lower('username')} = ?"; $bind_params = [mb_strtolower($username)]; $ds->select($sql, $bind_params); if($ds->getNumRows() > 0) { echo 'Username in use...'; }
limit
$limitSQL = $ds->limit($rows_per_page, ($page_num - 1) * $rows_per_page);
PHPUnit
在 Debian 9 Linux 服务器上进行的测试,使用
- php 7
- MariaDB Ver 15.1 Distrib 10.1.26-MariaDB(类似于 MySQL 5.7)
- Postgres 9.6.7
测试数据库位于 tests/dbdata 文件夹中。在 tests/phpunit.xml 中自定义凭据。首先将 phpunit.dest.xml 复制到 phpunit.xml
MySQL 测试
测试 connect 和 select
./vendor/bin/phpunit --configuration tests/phpunit.xml tests/MySQLTest.php
mysqli 超时使某些测试变慢。运行一次,然后使用
./vendor/bin/phpunit --enforce-time-limit --configuration tests/phpunit.xml tests/MySQLTest.php
在这种情况下需要 PHP_Invoker https://github.com/sebastianbergmann/php-invoker
CUD 测试插入(C)更新(U)和删除(D)操作以及事务
./vendor/bin/phpunit --configuration tests/phpunit.xml tests/MySQLCUDTest.php
Postgres 测试
测试 connect 和 select
./vendor/bin/phpunit --configuration tests/phpunit.xml tests/PostgresqlTest.php
CUD 测试插入(C)更新(U)和删除(D)操作以及事务
./vendor/bin/phpunit --configuration tests/phpunit.xml tests/PostgresqlCUDTest.php
运行特定的测试,例如 testConnectFails1()
./vendor/bin/phpunit --configuration tests/phpunit.xml tests/PostgresqlTest.php --filter '/testConnectFails1$/'
您不能在 CUD 测试中使用 --filter。实际上,每个 CUD 测试都依赖于之前的测试。
贡献
欢迎您的贡献。
- 仅接受
dev分支的拉取请求。 - 请记住也要提交相关的 PHPUnit 测试。
- 审查总是必要的。