获取数据库实例的正确语法是什么?

时间:2017-04-24 10:19:18

标签: php laravel eloquent laravel-eloquent

我使用雄辩的外面的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();

什么是正确的方法?

1 个答案:

答案 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}}