jitsu/sqldb

面向对象接口,方便访问SQL数据库

0.2.1 2016-05-07 08:27 UTC

This package is auto-updated.

Last update: 2024-09-11 17:50:35 UTC


README

本软件包定义了一个方便的对象化接口,用于访问SQL数据库和SQL语句,它建立在PHP的PDO库之上。虽然PDO已经提供了一种统一的对象化API,支持多个SQL驱动程序,但此库提供了一个更易于使用的API,添加了一些额外的辅助方法,并提供了更好的错误处理。特别是它使参数绑定更加容易。

此软件包是Jitsu的一部分。

安装

使用Composer安装此软件包

composer require jitsu/sqldb

命名空间

所有类都定义在命名空间Jitsu下。与数据库相关的类定义在Jitsu\Sql下。

用法

以下是一个示例

<?php
use Jitsu\Sql\Database;
use Jitsu\Sql\MysqlDatabase;

$search_term = $_GET['query'];

// Connect to the database
$db = new MysqlDatabase('localhost', 'my_database',
                        'my_user', 'my_password');
// Run a query with named parameters
$stmt = $db->query(<<<SQL
  select `name`, `description`
  from `packages`
  where `description` like :pattern
  order by `description` = :term desc
SQL
  , [
    'pattern' => '%' . Database::escapeLike($search_term) . '%',
    'term' => $search_term
  ]);

// Iterate over results
foreach($stmt as $row) {
  echo $row->name, ': ', $row->description, "\n";
}

$user_id = $_SESSION['user_id'];

// Get a single record using a positional parameter
$user = $db->row(<<<SQL
  select `first_name`
  from `users`
  where `id` = ?
SQL
  , $user_id);
echo "Welcome back, ", $user->first_name, "\n";

// Get the first column of the first row
$exists = $db->evaluate(<<<SQL
  select exists(
    select 1
    from `bookmarks`
    join `packages` on `bookmarks`.`package_id` = `packages`.`id`
    where `bookmarks`.`user_id` = ?
    and `packages`.`name` = ?
  )
SQL
  , $user_id, $search_term);
if($exists) {
  echo "You have already bookmarked this package.\n"
} else {
  echo "You have not bookmarked this package.\n";
}

此软件包还定义了jitsu/app软件包的数据库插件。在您的应用程序类中包含特质\Jitsu\App\Databases将添加一个database方法,可用于为您的应用程序配置数据库连接。此database方法注册的请求处理器将数据库连接对象添加到请求的$data对象中。此数据库对象有一个特点——它是懒加载的,这意味着直到使用对象的方法之一,才会建立数据库连接。这使得它很容易为您的应用程序中的多个请求处理器配置数据库连接,但也可以避免在您的应用程序路由到不需要数据库的处理器时建立该连接(例如,页面找不到处理器)。

database方法接受两个参数:连接对象将分配给请求$data对象上的属性名称,以及配置选项,这些选项定义在一个数组中。对于第二个参数,database方法将接受一个数组或$data->config对象上的属性名称。默认情况下,这与第一个参数相同。第一个参数的默认值也是'database'

一个简单的示例

<?php
class MyApp extends \Jitsu\App\Application {
  use \Jitsu\App\Databases;
  public function initialize() {
    $this->database('database', [
      'driver'     => 'mysql',
      'host'       => 'localhost',
      'database'   => 'my_database',
      'user'       => 'my_user',
      'password'   => 'shhhhhhh',
      'persistent' => true
    ]);
    $this->get('count-users', function($data) {
      $count = $data->database->evaluate('select count(*) from `users`');
      echo "There are $count users. Honestly, that's $count more than I expected.\n";
    });
    $this->notFound(function($data) {
      $data->response->setStatusCode(404, 'Not Found');
      echo "Nothing to see here. No database connection made.\n";
    });
  }
}

API

class Jitsu\Sql\Database

SQL数据库的对象化接口。

这实际上是对PDO库的一个有用的包装。

new Database($driver_str, $username = null, $password = null, $options = array())

在构造时连接到数据库。

$database->query($query, $args,...)

执行SQL查询。

执行一次性查询,并返回一个可迭代的Statement对象中的结果行。其余参数可以用于传递查询的参数。如果只传递了一个数组作为附加参数,则其内容将用作参数。

例如,

$stmt = $db->query($sql_code);
$stmt = $db->query($sql_code, $arg1, $arg2, ...);
$stmt = $db->query($sql_code, $arg_array);
foreach($stmt as $row) { $row->column_name ... }

$database->queryWith($query, $args)

query相同,但参数始终以单个$args数组的形式传递。

$database->row($query, $args,...)

返回查询的第一行并忽略其余部分。

$database->rowWith($query, $args)

row相同,但参数始终以数组的形式传递。

$database->evaluate($query, $args,...)

返回第一行的第一列并忽略其余部分。

$database->evaluateWith($query, $args)

evaluate相同,但参数始终以数组的形式传递。

$database->execute()

执行SQL语句。

如果带有参数调用,返回一个Statement对象。注意,受影响的行数可以通过Statement->affectedRows()获取。如果没有参数调用,则返回一个StatementStub对象,该对象只提供affectedRows()方法。

$database->executeWith($statement, $args)

execute类似,但参数始终以数组形式传递。

$database->prepare($statement)

准备一个SQL语句并将其作为Statement返回。

$database->quote($s)

转义并引用一个字符串值,以便在SQL查询中进行插值。

请注意,结果包括添加到字符串周围的引号。

Database::escapeLike($s, $esc = '\\')

转义在SQL "like"模式中有特殊意义的字符串中的字符。请注意,这应该与SQL中的ESCAPE子句一起使用;例如,

"column" LIKE '%foo\%bar%' ESCAPE '\'

\是默认的转义字符。

$database->lastInsertId()

获取最后插入记录的ID。

请注意,结果始终是一个字符串。

$database->begin()

开始一个事务。

请注意,未提交的事务在脚本结束时将自动回滚。

$database->inTransaction()

确定是否有一个事务正在活跃。

$database->rollback()

回滚当前事务。

$database->commit()

提交当前事务。

$database->transaction($callback)

在事务中安全地运行回调。

如果回调抛出异常,则事务将被回滚,并且异常将被重新抛出。

$database->attribute($name)

获取数据库连接属性。

传递的名称应为一个字符串(不区分大小写),并对应于带有PDO::ATTR_前缀的PDO常量。

可能的名字包括

  • autocommit
  • case
  • client_version
  • connection_status
  • driver_name
  • errmode
  • oracle_nulls
  • persistent
  • prefetch
  • server_info
  • server_version
  • timeout

$database->setAttribute($name, $value)

设置数据库连接属性。

使用与attribute相同的属性名称约定。值应为一个字符串(不区分大小写),并对应于带有PDO::ATTR_前缀的PDO常量。

$database->attributes()

生成所有属性名称和值的映射。

Database::drivers()

获取可用的数据库驱动程序列表。

$database->connection()

获取底层的PDO连接对象。

$database->setFetchMode($mode)

设置获取模式。

获取模式决定了行以何种形式被获取。直接使用PDO::FETCH_常量。默认的PDO::FETCH_OBJ会导致行以具有与列名相对应的属性名的stdClass对象返回。

$database->fetchMode($mode)

获取获取模式。

class Jitsu\Sql\MysqlDatabase

扩展Database

Database的MySQL特殊化。

new MysqlDatabase($host, $database, $username, $password, $charset = 'utf8mb4', $options = null)

class Jitsu\Sql\SqliteDatabase

扩展Database

Database的SQLite特殊化。

new SqliteDatabase($filename, $options = null)

连接到SQLite数据库。

请注意,这始终启用外键约束。如果出于某种奇怪的原因你想将其关闭,你可以运行

$db = new SqliteDatabase('foo.db');
$db->execute('pragma foreign_keys = off');

class Jitsu\Sql\Statement

一个用于准备或执行SQL语句的面向对象的接口。

这是PDO语句类的一个方便的包装。

new Statement($stmt, $mode = \PDO::FETCH_OBJ)

构造一个SQL语句对象。

可选地指定一个获取模式,该模式决定了行以何种形式被获取。直接使用PDO::FETCH_常量。默认为PDO::FETCH_OBJ,这将导致行以具有与列名相对应的属性名的stdClass对象返回。

$statement->bindOutput($col, &$var, $type = null, $inout = false)

将结果列绑定到一个变量上。

列可以是1索引的,或者可以通过名称引用。

$stmt = $db->prepare('select id, name from users');
$stmt->bind_output('name', $name);
foreach($stmt as $row) echo $name, "\n";

类型可以可选指定。以下值可以作为字符串传递

  • 布尔型
  • 空值
  • 整型
  • 字符串型
  • lob(大对象)

$inout参数指定列是否为存储过程的INOUT参数。

$statement->bindInput($param, &$var, $type = null, $inout = false)

将预定义语句的输入参数绑定到一个变量。

参数可以是1索引或通过名称(包含冒号)引用。

示例1

$stmt = $db->prepare('select id, name from users where phone = ?');
$stmt->bind_input(1, $phone);
$phone = '5551234567';
$stmt->execute();

示例2

$stmt = $db->prepare('select id, name from users where phone = :phone');
$stmt->bind_input(':phone', $phone);

$statement->assignInput($param, $value, $type = null, $inout = false)

为预定义语句的输入参数分配一个值。

如果$type为空,则根据值的PHP类型使用适当类型。

$statement->assign($values,...)

为预定义语句的输入分配一个值数组。

对于命名参数,传递一个将名称(不包含冒号)映射到值的数组。对于位置参数,传递一个顺序数组(0索引)。位置参数数组可以作为一个单个数组参数传递,或者作为可变参数列表传递。

$stmt = $db->prepare('select * from users where first = ? and last = ?');
$stmt->assign('John', 'Doe');

$statement->assignWith($values)

assign类似,但总是以数组的形式传递参数。

$statement->execute($values = null)

执行此语句,可选地提供一个0索引的值数组。

值数组在简单情况下可能很方便,但它只适用于位置参数,并将所有值转换为SQL字符串类型('str')。一个更灵活的替代方法是先调用assign

$statement->evaluate($values = null)

等同于运行$this->execute()并返回$this->value()

$statement->close()

忽略此语句返回的其余记录,以便再次使其可执行。

$statement->first()

返回第一行并忽略其余行。

如果没有返回记录,则返回null

注意,这可能与某些提取模式不兼容。

$statement->value()

返回第一行的第一个单元格并忽略其余内容。

如果没有返回记录,则返回null

$statement->columnCount()

返回结果集中列的数量,如果没有结果集,则为0。

$statement->affectedRows()

返回最后执行此语句影响的行数。

$statement->toArray()

将所有复制的行返回到一个数组中。

$statement->map($callback)

将所有通过函数传递的行返回到一个数组中。

每行的列作为位置参数传递给函数。

$statement->nextRowset()

前进到查询返回的下一组行,这是某些存储过程支持的。

$statement->current()

$statement->key()

$statement->next()

$statement->rewind()

$statement->valid()

$statement->debug()

将调试信息打印到stdout

class Jitsu\Sql\StatementStub

实现了QueryResultInterface接口。

只包含受影响行数的查询结果。

new StatementStub($affected_rows)

$statement_stub->affectedRows()

interface Jitsu\Sql\QueryResultInterface

$query_result_interface->affectedRows()

SQL语句影响的行数。

class Jitsu\Sql\DatabaseException

数据库相关错误的异常类。

new DatabaseException($msg, $errstr, $code = null, $state = null, $sql = null)

构造数据库异常对象。

$database_exception->getSqlErrorCode()

获取SQL引擎的错误代码。

$database_exception->getSqlState()

获取SQL状态缩写。

$database_exception->getErrorString()

获取数据库驱动程序报告的错误字符串。

$database_exception->getSql()

获取引起错误的SQL代码。

$database_exception->__toString()

返回数据库错误的合适字符串表示。

trait Jitsu\App\Databases

Mixin为Jitsu\App\Application,它添加了可配置的数据库连接功能。

$databases->database($data_prop = 'database', $config = null)

配置设置应在数组中定义。以下键被识别

  • driver:数据库使用的SQL软件的名称。可以是'sqlite''mysql'。必选。
  • persistent:是否使用持久数据库连接。默认为false
  • host:(MySQL) 存储数据库的主机名称。
  • database:(MySQL) MySQL数据库的名称。
  • user:(MySQL) 用于登录的MySQL用户名。
  • password:(MySQL) 登录时使用的密码。
  • charset:(MySQL) 连接使用的字符集。默认为'utf8mb4',支持所有UTF-8编码的Unicode字符。
  • file:(SQLite) 数据库文件的名称。