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

关于 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/master/lib/Doctrine/DBAL/Driver/PDOConnection.php

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

至此,
致敬知识。

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 1
HI

nice

1周前

  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!