获取数据库实例的正确语法是什么?
What is the proper syntax to get a db instance?
我在laravel之外使用eloquent。
这是负责它的文件:
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
实例)包装在另一个 class 中以便于检索它。事实上,Illuminate\Database\Capsule\Manager
提供了一个单例实例和简单的访问器。
一旦你打电话
$capsule->setAsGlobal();
Capsule
实例可以通过 Capsule::
从任何地方静态访问。
这是因为 setAsGlobal()
方法在幕后只是简单地执行以下操作:
static::$instance = $this;
将实例保存在静态 class 变量中,以便在后续调用 Capsule::
时检索它。
因此,一旦调用 setAsGlobal()
,就可以执行,例如:
Capsule::select('select * from user');
您将获得对先前创建的连接的查询结果。
但是,您可以看到 Manager
(别名 Capsule
)class 上不存在 select
方法。
为什么它有效?
因为 Manager
class 覆盖 __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
包装在外部 class 中,因为它已经是 Connection
class 的包装器.无需添加另一个包装器。
- 但是,如果您更喜欢包装它,我建议您返回
Manager
/Capsule
实例而不是底层连接,因为文档中建议的方法是直接使用Manager
我在laravel之外使用eloquent。
这是负责它的文件:
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
实例)包装在另一个 class 中以便于检索它。事实上,Illuminate\Database\Capsule\Manager
提供了一个单例实例和简单的访问器。
一旦你打电话
$capsule->setAsGlobal();
Capsule
实例可以通过 Capsule::
从任何地方静态访问。
这是因为 setAsGlobal()
方法在幕后只是简单地执行以下操作:
static::$instance = $this;
将实例保存在静态 class 变量中,以便在后续调用 Capsule::
时检索它。
因此,一旦调用 setAsGlobal()
,就可以执行,例如:
Capsule::select('select * from user');
您将获得对先前创建的连接的查询结果。
但是,您可以看到 Manager
(别名 Capsule
)class 上不存在 select
方法。
为什么它有效?
因为 Manager
class 覆盖 __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
包装在外部 class 中,因为它已经是Connection
class 的包装器.无需添加另一个包装器。 - 但是,如果您更喜欢包装它,我建议您返回
Manager
/Capsule
实例而不是底层连接,因为文档中建议的方法是直接使用Manager