zobaken/daltron

PHP数据库抽象层

0.3.3 2019-01-12 08:44 UTC

This package is not auto-updated.

Last update: 2024-09-29 20:20:25 UTC


README

PHP数据库抽象层。

旨在成为一个尽可能简单的工具,用于创建和运行SQL查询。目前支持mysql和postgresql驱动程序。

要求

PHP7,mysqli扩展用于MySQL支持。pgsql扩展用于postgresql...

安装

通过composer安装它

composer require zobaken/daltron

配置

首先我们需要设置配置

\Dal\Dal::setConfiguration([
    'host' => '192.168.99.100',
    'user' => 'test',
    'password' => 'test',
    'dbname' => 'test',
    'driver' => 'mysql',
]);

可以从文件中加载配置。例如,'config.php'可以看起来像这样

<?php

return [
    'host' => '192.168.99.100',
    'user' => 'test',
    'password' => 'test',
    'dbname' => 'test',
    'driver' => 'mysql',
];

然后我们这样加载它

\Dal\Dal::loadConfiguration('config.php');

查询构建器

最简单的查询看起来像这样

$rows = db()->query('SELECT * FROM users')->fetchAllAssoc();

让我们尝试一个更复杂的例子。构建器模仿SQL语法,因此不需要学习新东西

$rows = db()
    ->select('*')
    ->from('users')
    ->where('created_ts = ?', $time)
    ->fetchAllAssoc();

查询中的每个"未知"方法,如本例中的select方法,都将术语添加到SQL请求中。所有与?占位符映射的参数(非整数)都进行了转义并带有引号。

前面的例子等同于

$query = sprintf("SELECT * FROM users WHERE created_ts < '%s'",
    mysqli_real_escape_string($connection, $time)
);
$result = mysqli_query($connection, $query);
$rows = mysqli_fetch_all($result, MYSQLI_ASSOC);

这是一个典型的查询条件依赖于用户输入的情况

$rows = db()->select('*')
    ->from('users')
    ->where('true')
    ->ifQuery($timeFrom, 'AND created_ts >= ?', $timeFrom)
    ->ifQuery($timeTo, 'AND created_ts < ?', $timeTo)
    ->ifQuery($order && $orderDirection, 'ORDER BY #? !?', $order, $orderDirection)
    ->ifQuery($limit, 'LIMIT ?', $limit)
    ->ifQuery($offset, 'OFFSET ?', $offset)
    ->fetchAllAssoc();

只有在ifQuery的第一个参数为true时,才会添加额外的条件。#?占位符用于字段名转义。在本例中,我们假设orderDirection等于ASC或DESC,而!?占位符不会转义值,请谨慎使用!

插入和更新示例(我们假设id字段是自增的)

// Insert query
$row = [
    'name' => 'Peter Userman',
    'created_ts' => dbtime(),
    'hash' => password_hash('REMEMBERME1', PASSWORD_DEFAULT),
];

$id = db()->insertRow('users', $row)
    ->exec(true);

// Update query
db()->update('users')
    ->set('hash = ?', '')
    ->where('id = ?', $id)
    ->exec();

// User needs to know
printf("Updated %d row(s)\n", db()->affectedRows());

insertRow方法是对插入请求的快捷方式。dbtime函数不带参数返回当前时间,格式为Y-m-d H:i:s。将true传递给exec方法,我们要求它返回最后一个插入的id。affectedRows方法用于获取前一个查询影响的行数,很明显。

模型

生成

要生成模型,我们需要已经初始化的数据库,具有现有的数据结构。在本例中,我们使用提供的脚本,利用上面提供的配置文件

vendor/bin/dbgen config.php model

模型类将被创建在"model"文件夹中。如果您需要创建自己的模型生成脚本(带有黑杰克和闭包),您可以编写如下内容

\Dal\Dal::loadConfiguration('config.php');
$generator = \Dal\Model\GeneratorFactory::createGenerator('model');
$generator->run();

您可以根据需要修改模型类,如果数据结构更改,则再次运行生成器。模型类不会被覆盖,只有它们的原型类。

基本用法

使用spl_autoload_register函数或其他您喜欢的任何方法加载模型类是您的责任。

以下是使用模型类的示例

// Create new object
$user = new User();
$user->name = 'Mike Swoloch';
$user->created_ts = dbtime();
$user->hash = md5('hash');
$user->id = $user->insert(true);

将true传递给insert,我们要求它返回最后一个插入的id。

接下来,我们将从数据库获取对象并更新它

// Get object from database
$user = User::get($id);
if ($user) {
    // Update object
    $user->name = 'Mike Sweety';
    $user->update();
}

简单到如此!

使用remove删除对象

// Delete object
$user->remove();

高级模型请求

我们可以通过将where条件传递给findRow方法来获取对象

$user = User::findRow('name = ?', 'Alexandr Flea');

对于对象列表,可以使用find方法

$objects = User::find('created_ts < ?', dbtime('- 1 day'));

这将返回一天前创建的对象。

您不仅可以传递where条件,还可以传递请求的一些其他部分。您可以将我们的请求限制为只返回10行

$objects = User::find('created_ts < ? LIMIT ?', dbtime('- 1 day'), 10);

我们还可以使用稍微修改后的查询构建器语法。这里是从上面某个例子中稍微修改过的请求。查询将返回User对象的数组。

$rows = User::querySelect()
    ->where('true')
    ->ifQuery($timeFrom, 'AND created_ts >= ?', $timeFrom)
    ->ifQuery($timeTo, 'AND created_ts < ?', $timeTo)
    ->ifQuery($order && $orderDirection, 'ORDER BY #? !?', $order, $orderDirection)
    ->ifQuery($limit, 'LIMIT ?', $limit)
    ->ifQuery($offset, 'OFFSET ?', $offset)
    ->fetchAll();

以下是更新请求的示例

User::queryUpdate()
    ->set('hash = ?', '[some old man]')
    ->where('created_ts < ?', dbtime('- 1 month'))
    ->exec();

对于删除也是一样

User::queryDelete()
    ->where('created_ts < ?', dbtime('- 1 year'))
    ->exec();

// Lets inform user
printf("Deleted %d row(s)\n", User::query()->affectedRows());

使用queryUpdateRow方法更新多个字段更简单

User::queryUpdateRow([
        'name' => '[some old man]',
        'hash' => md5('password'),
    ])
    ->where('created_ts < ?', dbtime('- 1 month'))
    ->exec();

在这种情况下,"SET"语句将生成具有转义值的传递字段的声明。

命名空间

默认情况下,模型类是在根命名空间中创建的。您可以通过在配置中添加"namespace"选项来更改它

<?php

return [
    'host' => '192.168.99.100',
    'user' => 'test',
    'password' => 'test',
    'dbname' => 'test',
    'driver' => 'mysql',
    'namespace' => 'UserNamespace',
];

配置配置文件

您可以创建多个配置文件以访问不同的数据库。在上面的示例中,我们只使用了一个名为“default”的配置文件。要创建更多配置文件,您需要在配置中定义它们,如下所示

<?php

return [
    'default' => [
        'host' => '192.168.99.100',
        'user' => 'test',
        'password' => 'test',
        'dbname' => 'test',
        'driver' => 'mysql',
    ],
    'postgres' => [
        'host' => '192.168.99.100',
        'user' => 'test',
        'password' => 'test',
        'dbname' => 'test',
        'driver' => 'pgsql',
    ],
];

现在我们有一个与之前完全相同的“default”配置文件,还有一个名为“postgres”的配置文件。现在我们可以通过将其传递给我们的db函数来使用它

$rows = db('postgres')->q('SELECT * FROM users')->fetchAll();

我们还可以将配置文件传递给模型生成器,因此模型将使用它而不是“default”

$generator = \Dal\Model\GeneratorFactory::createGenerator('model', 'postgres');

许可证

版权(c)2009-2018 Nikolay Neizvesny

在此特此授予任何获得本软件及其相关文档副本(“软件”)的个人免费使用软件的权利,不受任何限制,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本的权利,并允许向软件提供方提供软件的个人这样做,前提是遵守以下条件

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、适用于特定目的和不受侵犯的保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论这些责任是基于合同、侵权或其他原因,以及与软件或其使用或其他方式有关的事件。