thoom / dbm
PHP 5.3 类,通过实体管理器关系扩展 doctrine DBAL,并为 Silex 提供钩子
Requires
- php: >=5.3.2
- doctrine/dbal: 2.2.*
Requires (Dev)
- silex/silex: dev-master
Suggests
- silex/silex: dev-master
This package is not auto-updated.
Last update: 2023-11-11 09:02:59 UTC
README
摘要
注意:这些类仍在开发中,经常变化。请谨慎使用,并自行承担风险!
这是一个数据库类集合,用于使用 Silex 框架构建简单网站。数据库类建立在 Silex 包含的 Doctrine DBAL 支持之上。
Thoom\Provider\DbServiceProvider
DbServiceProvider 实现了 Silex\ServiceProviderInterface。此提供程序还注册了 Silex\Provider\DoctrineServiceProvider,因此不需要单独注册。此外,此提供程序将 Thoom\Db\ManagerFactory 对象添加到 DI 容器中。这使得能够访问管理器,而无需将每个管理器添加到 Silex 应用程序中。
在注册数组中需要传递的一个额外参数
- dbm.options:此数组集合目前只包含一个键:format。这是您的管理器的完全限定名,采用 printf 格式。例如,如果您有名为 My\Db\UserManager 和 My\Db\AppManager 的管理器,则格式将为 My\Db\%sManager。
注册提供程序
$app->register(new Thoom\Provider\DbServiceProvider(),
array(
'db.options' => array(
'host' => 'localhost',
'dbname' => 'mydb',
'user' => 'user',
'password' => 'pass',
),
'dbm.options' => array(
'format' => 'My\Db\%sManager'
)
));
Thoom\Db
Db 类使用实体管理器关系,其中抽象实体代表数据库行。管理器是其与数据库的连接,并提供 CRUD 方法来与之交互。
显然,有许多面向对象的数据库实现。Doctrine ORM 是一个明显的替代品,因为 Thoom\Db 也利用 Doctrine 的 DBAL 与数据库接口。这个框架不是为了作为功能齐全的替代品,而是一个不同的实体管理方式的轻量级替代品。
实体
实体不仅仅是数据存储。其逻辑的广度仅涉及如何将其数据隔离到三个不同的数组:值、已修改和容器。
每个数组都有其独特的目的
-
values:此数组中的数据受到极度的保护,仅在实体创建或在 resetData 方法中填充。值应表示当前的数据库值。此数组是唯一存储在序列化中的数组!
-
modified:每次使用 ArrayAccess 或 __set 方法提交数据时,都会填充此数组。其值用于在数据库中插入/更新记录。
-
container:任何传递给实体但键不在值数组中的值将放置在容器数组中。容器的作用是为附加额外的数据提供一个空间,而不会污染表数据。
用法
以最简单的方式创建实体很容易
namespace My\DbNamespace;
use Thoom\Db\EntityAbstract;
class User extends EntityAbstract{}
有几种方法可以访问实体中的数据。这里有一些选项
-
作为对象
$entity->foo = 'bar'; echo $entity->foo; //prints "bar" -
作为数组
$entity['foo'] = 'bar'; echo $entity['foo']; //prints "bar"
实体默认将数据保存到修改数组中,如果键存在于值数组中,否则将其保存到容器数组中。可以通过创建名为要覆盖的键的 get/set 方法非常容易地覆盖此行为。
例如,如果我们想确保在将其保存到修改数组之前,键 foo 被转换为小写,则在我们的实体类中添加一个 setFoo 方法
class BazEntity extends Thoom\Db\EntityAbstract
{
protected function setFoo($value)
{
$this->modified['foo'] = strtolower($value);
}
}
现在如果我们执行与之前相同的调用
$entity['foo'] = 'BaR';
echo $entity['foo'] // prints "bar" not "BaR"!
显然,您需要小心使用此功能,因为您的输入可能不会与输出匹配!
使用此功能,您还可以引入一些模拟属性。例如,假设您的数据库将用户名存储为firstName和lastName。您不想每次都要连接这些值。相反,创建一个模拟属性!
class UserEntity extends Thoom\Db\EntityAbstract
{
protected function getFullName()
{
return $this['firstName'] . ' ' . $this['lastName'];
}
}
现在就像使用任何其他属性一样使用它(比如说这个用户的名字是Bruce,姓氏是Banner)
$user = $userManager->read($primaryKey);
echo $user->fullName; //prints "Bruce Banner"
注意,如果您尝试设置全名,除非您也创建了一个setFullName方法,否则它最终会在容器数组中存储该值
protected function setFullName($value)
{
$names = explode(' ', $value);
$this->modified['firstName'] = $names[0];
$this->modified['lastName'] = $names[1];
}
哇!
经理
经理是实体与数据库的接口。经理的行为类似于实体工厂,它创建新实体并注入任何依赖项。它包含它所代表的表的所有数据,包括表的名称、具有默认值和类型的列、主键的字段名称等。
经理使用依赖注入来接收其数据库连接。
用法
创建新的经理时,应该定义一些属性。以下是一个示例
namespace My\DbNamespace;
use Thoom\Db\ManagerAbstract;
class UserManager extends ManagerAbstract
{
protected $entity = 'My\DbNamespace\User';
protected $columns = array(
'uid',
'firstName',
'lastName',
'username',
'password',
'modified'
);
protected $primaryKey = 'uid';
protected $table = 'users';
}
让我们回顾一下这些属性
- entity:这是从CRUD调用返回的实体类的完全限定名称。
- columns:这是一个数据库列名称数组。这些用于确定在实体中保存哪些数据到数据库。
- primaryKey:表的主键列名称。
- table:经理管理的表的名称。如果此字段未填充,则经理将根据类的名称设置它。
要使用Silex,我建议使用Thoom\Provider\DbServiceProvider。这将创建一个指向ManagerFactory的对象引用,这将在下面详细解释。然而,为了在Silex 控制器中通用地使用经理
$app->get('/user/{primary_key}', function($primary_key) use ($app)
{
$userManager = new My\DBNamespace\UserManager($app['db']);
$user = $userManager->read($primary_key);
return $app['twig']->render('index.html.twig', array('name' => $user['fullName'], 'email' => $user['email']));
});
每当您将实体发送到经理以更新数据库时,如果您想使其反映对数据库所做的更改(例如通过触发器等),则需要刷新实体。
以下是一个创建名为Bruce Banner的新用户并刷新实体以便数据存在的示例
$user = $userManager->fresh();
$user['fullName'] = 'Bruce Banner';
$id = $userManager->create($user);
if (!$id){
//Handle this error condition
$user['id'] = $id;
$userManager->refresh($user);
或者,您可以使用便利方法(对创建和更新方法都可用)
$user = $userManager->fresh();
$user['fullName'] = 'Bruce Banner';
$user = $userManager->createAndRefresh($user);
if (!$user){
//Handle this error condition
经理工厂
每次创建经理的替代方案是使用ManagerFactory。一旦实例化,工厂对象有两个方法
-
get($name):根据名称返回对象的实例。如果一个对象已经被创建,它返回存储的对象。
-
fresh($name):始终根据名称返回对象的新的实例。
用法
在Silex 控制器中使用Thoom\Provider\DbServiceProvider
$app->get('/user/{primary_key}', function($primary_key) use ($app)
{
$user = $app['dbm']->get('User')->read($primary_key);
return $app['twig']->render('index.html.twig', array('name' => $user['name'], 'email' => $user['email']));
});
手动创建对象
$factory = new Thoom\Db\ManagerFactory($db, 'My\Db\%sManager');
$userManager = $factory->get('User');
工厂的第二个参数是您的经理命名的printf格式。您只需要在get和fresh方法中传递格式中的缺失部分。