我使用雄辩的外面的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();
什么是正确的方法?
答案 0 :(得分:1)
首先,不需要将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
实例而不是基础连接,因为文档中建议的方法是直接使用{ {1}}