获取数据库实例的正确语法是什么?
问题描述:
我用laravel之外的雄辩。获取数据库实例的正确语法是什么?
这里是负责它的文件:
class DbSql
{
public function db()
{
$capsule = new Capsule;
$capsule->addConnection([
'driver' => Settings::DATABASE_DRIVER,
'host' => Settings::DATABASE_HOST,
'database' => Settings::DATABASE_NAME,
'username' => Settings::DATABASE_USERNAME,
'password' => Settings::DATABASE_PASSWORD,
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => ''
]);
# Make this Capsule instance available globally
$capsule->setAsGlobal();
return $capsule;
}
}
在控制器,我实例化实例一次,可以使用几个时间在控制器:
$dbInstance = (new DbSql())->db(); // Create the instance
// Instance usages:
$images = $dbInstance->table('images_attachments')->where...
$files = $dbInstance->table('files')->where...
.....
我应该用实例:
$dbInstance = (new DbSql())->db();
如上面的代码
或:
$dbInstance = (new DbSql())->db()->getConnection();
什么是正确的方法是什么?
答
首先,不需要将Capsule
(这是一个Illuminate\Database\Capsule\Manager
实例)包装到另一个类中,以便更容易检索它。实际上,Illuminate\Database\Capsule\Manager
提供了一个单例实例和简单的访问器。
一旦你调用
$capsule->setAsGlobal();
的Capsule
实例将访问静态来自世界各地通过Capsule::
。 这是因为setAsGlobal()
方法,引擎盖下,确实简单:
static::$instance = $this;
在一个静态类变量保存实例来检索它的后续调用Capsule::
。 所以,一旦你打电话setAsGlobal()
,这是可以做到的,例如:
Capsule::select('select * from user');
,你会得到先前创建的连接上的查询结果。
但是,您可以看到select
方法在Manager
(别名Capsule
)类中不存在。 它为什么有效? 由于Manager
类重写__callStatic()
php magic method
class Manager
{
use CapsuleManagerTrait;
// ...
public static function __callStatic($method, $parameters)
{
return static::connection()->$method(...$parameters);
}
}
所以调用select()
方法被重定向到底层\Illuminate\Database\Connection
实例自动地。
这意味着:
- 没有必要来包装
Manager
/Capsule
在外部类,因为它已经在Connection
类的包装。无需添加另一个包装。 - 如果你喜欢把它包起来,但是,我建议你返回
Manager
/Capsule
实例,而不是底层的连接,因为在文档中建议的方法是直接与Manager
如果你的目标而努力就像使用Laravel一样使用'Eloquent',那么你所要做的就是像你一样创建'Capsule'对象,而不是'$ capsule-> setAsGlobal()',你可以使用'$ capsule- > bootEloquent();'。然后,只需创建并调用Capsule对象一次,然后像使用Laravel一样使用'Eloquent'('Class X extends Model {....}')。如果这不是你的预期用途,我很抱歉浪费你的时间:) – Mjh
你有没有机会尝试我的解决方案? – LombaX