我独自走进 Laravel5.5 的❤(九)

关于 laravel 的数据库驱动启动流程

  1. 配置
    我们都知道,要配置 laravel 项目的数据库,要在 .env 中配置下面几个参数

    DB_CONNECTION
    DB_HOST
    DB_PORT
    DB_DATABASE
    DB_USERNAME
    DB_PASSWORD

    我们也知道这几个参数会在配置文件 config/database.php 中被引用

    'connections' => [
    
        'sqlite' => [
            'driver' => 'sqlite',
            'database' => env('DB_DATABASE', database_path('database.sqlite')),
            'prefix' => '',
        ],
    
        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
        ],
    
        'pgsql' => [
            'driver' => 'pgsql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '5432'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'prefix' => '',
            'schema' => 'public',
            'sslmode' => 'prefer',
        ],
    
        'sqlsrv' => [
            'driver' => 'sqlsrv',
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '1433'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'prefix' => '',
        ],
    
    ],

    好的,眼前不止苟且,一起深入进去。
    2.数据库服务提供者
    在 config/app.php 中的 providers 中有注册
    Illuminate\Database\DatabaseServiceProvider::class,
    Illuminate\Database\DatabaseServiceProvider::class,注册时会触发注册数据库连接服务

    protected function registerConnectionServices()
    {
        // The connection factory is used to create the actual connection instances on
        // the database. We will inject the factory into the manager so that it may
        // make the connections while they are actually needed and not of before.
        $this->app->singleton('db.factory', function ($app) {
            **return new ConnectionFactory($app);**
        });
    
        // The database manager is used to resolve various connections, since multiple
        // connections might be managed. It also implements the connection resolver
        // interface which may be used by other components requiring connections.
        $this->app->singleton('db', function ($app) {
            return new DatabaseManager($app, $app['db.factory']);
        });
    
        $this->app->bind('db.connection', function ($app) {
            return $app['db']->connection();
        });
    }

    3.连接工厂
    在连接工厂中,会根据配置的驱动不同生成不同的数据库连接器,真香

    public function createConnector(array $config)
    {
        if (! isset($config['driver'])) {
            throw new InvalidArgumentException('A driver must be specified.');
        }
    
        if ($this->container->bound($key = "db.connector.{$config['driver']}")) {
            return $this->container->make($key);
        }
    
       ** switch ($config['driver']) {
            case 'mysql':
                return new MySqlConnector;
            case 'pgsql':
                return new PostgresConnector;
            case 'sqlite':
                return new SQLiteConnector;
            case 'sqlsrv':
                return new SqlServerConnector;
        }**
    
        throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]");
    }

    4.连接器
    在各个 Connector 中都会有一个连接方法 connect,
    在 connect() 中会生成一个 连接

    $connection = $this->createConnection(
            **$this->getDsn($config),** $config, $this->getOptions($config)
        );

    注意这里有一个 getDsn(),这个方法会返回一个特定的 PDO 驱动程序的名称,例如 mysql 会返回

    mysql:host=127.0.0.1;port=3306;dbname=homestead"

    4.1关于createConnection()

    public function createConnection($dsn, array $config, array $options)
    {
        list($username, $password) = [
            $config['username'] ?? null, $config['password'] ?? null,
        ];
    
        try {
            return $this->createPdoConnection(
                $dsn, $username, $password, $options
            );
        } catch (Exception $e) {
            return $this->tryAgainIfCausedByLostConnection(
                $e, $dsn, $username, $password, $options
            );
        }
    }

    这里可以看到获取数据库用户名和密码,然后创建一个 pdo 连接
    4.2关于createPdoConnection()

    protected function createPdoConnection($dsn, $username, $password, $options)
    {
        if (class_exists(PDOConnection::class) && ! $this->isPersistentConnection($options)) {
            return new **PDOConnection($dsn, $username, $password, $options)**;
        }
    
        return new PDO($dsn, $username, $password, $options);
    }

    4.3关于 PDOConnection
    Doctrine/DBAL/Driver/PDOConnection::class 其实是一个继承了 PDO 的类,重新封装了 exec()、query()等一些方法
    具体可以 github 上观摩。
    https://github.com/doctrine/dbal/blob/mast...

<-------------------------------------------------------------------------- End ---------------------------------------------------------------------->

至此,
致敬知识。

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!