以驱动无关的方式安全方便地访问SQL数据库

v1.3.1 2020-02-21 10:46 UTC

This package is auto-updated.

Last update: 2024-08-24 07:06:23 UTC


README

以驱动无关的方式安全方便地访问SQL数据库

特性

  • 方便的接口
  • 执行相同任务时编写更少的代码
  • 通过使用预处理语句防止SQL注入
  • 服务器返回的数据具有正确的本地类型(即没有字符串化字段)
  • 支持多个数据库系统的驱动无关支持

要求

  • PHP 5.6.0+
    • PDO扩展

安装

  1. 通过Composer包含库[?]

    $ composer require delight-im/db
    
  2. 包含Composer自动加载器

    require __DIR__ . '/vendor/autoload.php';

用法

连接到数据库

  • 从动态数据库配置

    $dataSource = new \Delight\Db\PdoDataSource('mysql'); // see "Available drivers for database systems" below
    $dataSource->setHostname('localhost');
    $dataSource->setPort(3306);
    $dataSource->setDatabaseName('my-database');
    $dataSource->setCharset('utf8mb4');
    $dataSource->setUsername('my-username');
    $dataSource->setPassword('my-password');
    
    $db = \Delight\Db\PdoDatabase::fromDataSource($dataSource);

    这是建立数据库连接最方便的方式,因为正确的DSN(数据源名称)将为您自动创建。您可以使用流畅的接口中的各种设置器来设置您的配置。

    您可以省略任何不需要的选项,并查看PdoDataSource类以获取其他可用的设置器。

    连接将按需创建,即在实际使用之前不会消耗任何资源。所有这些都会自动完成。

  • 从DSN(数据源名称)

    $db = \Delight\Db\PdoDatabase::fromDsn(
        new \Delight\Db\PdoDsn(
            'mysql:dbname=my-database;host=localhost',
            'my-username',
            'my-password'
        )
    );

    PdoDsn构造函数的参数与PDO构造函数的参数完全相同。但是,如果您不需要另一个PDO实例,那么不使用PDO并直接从DSN创建此库的实例会更有效。

    连接将按需创建,即在实际使用之前不会消耗任何资源。

  • 使用现有的PDO实例

    // $pdo = new PDO('mysql:dbname=my-database;host=localhost;charset=utf8mb4', 'my-username', 'my-password');
    
    $db = \Delight\Db\PdoDatabase::fromPdo($pdo);

    这不会创建另一个数据库连接,而是会重用您提供的PDO实例中现有的连接。

    此外,您可以从此库的行为的强保证中受益,并从其便利性中受益,同时仍然能够使用现有的PDO实例而不会产生任何副作用。

    只需将true作为fromPdo方法的第二个参数传递,即可完全保留您PDO实例的原始状态

    $db = \Delight\Db\PdoDatabase::fromPdo($pdo, true);

数据库系统的可用驱动程序

\Delight\Db\PdoDataSource::DRIVER_NAME_MYSQL;
\Delight\Db\PdoDataSource::DRIVER_NAME_POSTGRESQL;
\Delight\Db\PdoDataSource::DRIVER_NAME_SQLITE;

选择数据

在选择数据时,只需一个方法调用即可获得所需的结果。当然,您也可以轻松选择是否想要获取多行、单行、单个值或所有行的单个列。

$rows = $db->select('SELECT id, name FROM books');

// or

$rows = $db->select(
    'SELECT name, year FROM books WHERE author = ? ORDER BY copies DESC LIMIT 0, 10',
    [ 'Charles Dickens' ]
);

// or

$row = $db->selectRow(
    'SELECT author, year FROM books WHERE author <> ? ORDER BY year ASC LIMIT 0, 1',
    [ 'Miguel de Cervantes' ]
);

// or

$value = $db->selectValue(
    'SELECT year FROM books WHERE name <> ? AND name <> ? ORDER BY year DESC LIMIT 0, 1',
    [
        'Tale of Two Cities',
        'Alice in Wonderland'
    ]
);

// or

$column = $db->selectColumn(
    'SELECT author FROM books ORDER BY copies DESC LIMIT ?, ?',
    [
        0,
        3
    ]
);

插入数据

对于简单的插入,您可以使用方便的缩写

$db->insert(
    'books',
    [
        // set
        'name' => 'Don Quixote',
        'author' => 'Miguel de Cervantes',
        'year' => 1612
    ]
);

您的表有自动生成的主键ID吗?通过另一个简短的方法调用可以访问这些插入的ID。序列名称仅适用于一些数据库驱动程序,例如PostgreSQL。

$newId = $db->getLastInsertId();
// or
$newId = $db->getLastInsertId('my-sequence-name');

如果您需要执行更复杂的语句,请参阅下面的“执行语句”部分。

更新数据

对于简单的更新,您也可以使用方便的缩写

$db->update(
    'books',
    [
        // set
        'author' => 'J. K. Rowling',
        'copies' => 2
    ],
    [
        // where
        'name' => "Harry Potter and the Philosopher's Stone"
    ]
);

您想知道此操作更新了多少行吗?只需从update方法调用中获取返回值即可。

如果您需要执行更复杂的语句,请参阅下面的“执行语句”部分。

删除数据

同样,对于简单的删除,您也可以使用方便的缩写

$db->delete(
    'books',
    [
        // where
        'author' => 'C. S. Lewis',
        'year' => 1949
    ]
);

delete方法调用的返回值将告诉您此操作删除了多少行。

如果您需要执行更复杂的语句,请参阅下面的“执行语句”部分。

执行语句

您可以像以下示例所示执行任何任意的SQL语句

$db->exec(
    'INSERT INTO books (name, author, year) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE copies = copies + 1',
    [
        "Harry Potter and the Philosopher's Stone",
        'J. K. Rowling',
        1997
    ]
);

// or

$db->exec(
    "UPDATE books SET name = CONCAT(LEFT(name, 5), ' in ', RIGHT(name, 10)) WHERE year >= ? AND year < ?",
    [
        1860,
        1890
    ]
);

对于您执行的每个语句,返回值将是受影响的行数。

如果您正在执行的语句是INSERT,您可以通过getLastInsertId方法再次获取插入的ID。

事务

事务控制应该像现在这样简单。

$db->beginTransaction();

// and later

$db->commit();
// or
$db->rollBack();

// and optionally
$active = $db->isTransactionActive();

错误处理

该库中的方法不返回任何错误代码。您将通过异常了解任何问题。

输入转义

您无需手动转义任何输入。只需像上面所示使用占位符并单独传递数据来使用方法。所有输入都将自动为您转义。

性能分析

为了在开发过程中监控查询性能,您可以启用性能分析。

$db->setProfiler(new \Delight\Db\SimpleProfiler());

无论何时您想查看分析过的查询或将它们存储在日志文件中,您都可以获取分析器记录的所有测量值作为一个数组。

$db->getProfiler()->getMeasurements();

通常,您在检索之前会想要对测量值进行排序,以便将运行时间最长的查询列在前面。

$db->getProfiler()->sort();

服务器和客户端信息

为了获取有关您连接的数据库服务器或PHP使用的数据库客户端的一些信息,您可以使用以下方法之一。

$db->getDriverName();
// e.g. 'MySQL'

$db->getServerInfo();
// e.g. 'Uptime: 82196  Threads: 1  Questions: 2840  Slow queries: 0  Opens: 23  Flush tables: 1  Open tables: 33  Queries per second avg: 0.736'

$db->getServerVersion();
// e.g. '5.5.5-10.1.13-MariaDB'

$db->getClientVersion();
// e.g. 'mysqlnd 5.0.1-dev'

监听器

连接建立

$db->addOnConnectListener(function (\Delight\Db\PdoDatabase $db) {
	// do something
});

贡献

所有贡献都受欢迎!如果您想贡献,请先创建一个问题,这样您的功能、问题或问题就可以进行讨论。

许可证

该项目遵循MIT许可证的条款。