Laravel база данных: настраиваем соединение

Дата публикации: 11.06.2018

laravel-databaseВсем хэллоу! 🙂

Выдалась свободная минутка, и я решил сделать очередной шаг к созданию своего тестового Laravel сайта, в процессе чего я знакомлю вас с основными конструкциями и механизмами Laravel фреймворка.

Сегодня на повестке дня обзор настроек соединения нашего сайта с Laravel database, в которой в дальнейшем будут храниться данные наших пользователей и посты блога.

Сразу скажу, что у Laravel с database settings всё хорошо, и на их произведение в рамках предыдущей статьи об установке механизма Laravel аутентификации у меня лично ушло 2 минуты.

Причём, первую минуту я создавал саму базу, а половину второй размышлял, какую СУБД всё-таки выбрать 🙂 Остальным же 30 секундам и будет посвящена дальнейшая информация, которой, как вы понимаете, сегодня много не будет.

Laravel DB connection: какие СУБД поддерживаются?

Из коробки Laravel позволяет использовать следующие реляционные СУБД:

  • MySQL
  • PostgreSQL
  • SQLite
  • SQL Server

Также Laravel поддерживает NoSQL СУБД Redis, который зачастую используют для хранения кэшированных данных благодаря высокой скорости записи и извлечения данных из неё, поэтому о настройках соединения с ним поговорим чуть позже, когда разговор дойдёт до описания методов работы с серверным кешом сайта.

Настройки соединения с Laravel database: способ первый

Давно пора уже переходить к самой сути 🙂 Итак, допустим, БД вы уже создали, и самое время настроить подключение к базе данных в Laravel приложении.

Если же у вас вдруг возникли проблемы с созданием самой БД, то для MySQL могу порекомендовать статью о создании MySQL БД в консоли и произведении с ней других действий через командную строку сервера. А если вы являетесь поклонником визуальных инструментов для работы с БД, например, phpMyAdmin, то милости прошу сюда.

Настройки соединения Laravel с базой данных можно задать двумя способами. Первый — самый простой и правильный — заключается в редактировании файла .env, расположенного в корне проекта. Интересовать нас будет следующая секция:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

Так выглядит она по умолчанию, т.е. непосредственно после установки Laravel на сервер. Как видите по значением параметров конфигурации соединения, разработчики Laravel предполагают использование MySQL в качестве СУБД по умолчанию и Laravel Homestead для локальной разработки.

Небольшие пояснения по поводу названия параметров, хотя при базовых знаниях английского проблем с пониманием их назначения возникнуть не должно.

DB_CONNECTION — СУБД, которая будет использоваться для управления базой данных.
DB_HOST — адрес сервера БД. При локальной разработке (с использованием локального веб-сервера) в 90% случаев он будет таким, как по умолчанию — 127.0.0.1.
DB_PORT — номер сетевого порта, через который будет происходить соединение с сервером базы данных. Если вы не указывали его явно при настройке СУБД на сервере, то для MySQL по умолчанию он будет 3306, как и в примере выше, для PostgeSQL5432, для остальных поддерживаемых Laravel DB нужно смотреть, наизусть не помню 🙂
DB_DATABASE — собственно, имя базы данных, которая будет использоваться для хранения информации Laravel приложения.
DB_USERNAME — имя пользователя СУБД для доступа к данным, хранимым в БД. Пользователей, естественно, у вас может быть несколько, причём каждый из них может обладать своим набором прав. Действия по манимуляции юзеров из консоли MySQL описаны в статье по ссылке в начале данной публикации.
DB_PASSWORD — пароль пользователя СУБД для подключения к database из Laravel приложения.

Тем, кто заглядывает в .env впервые, хочу отметить, что значения интересующих нас переменных окружения: пользователя, БД, адрес сервера в файле нужно указывать без кавычек, хотя это и строковые данные. Но у нас тут и не PHP используется, в принципе 🙂

Конфигурация соединения с Laravel базой данных: способ второй

Первый способ настройки связи сайта на Laravel с БД мы рассмотрели. Кроме него существует вариант расширенной конфигурации через файл корень_сайта\config\database.php.

Приведу небольшую расшифровочку его необходимых нам на данном этапе параметров на случай, если вам нужна будет тонкая настройка Laravel database connection. Начинается файл со следующей строки:

'default' => env('DB_CONNECTION', 'mysql'),

Параметр default содержит название соединения (по умолчанию имеют названия, созвучные используемым СУБД), которое будет применяться по умолчанию для всех баз. Как видите, значение переменной берётся из .env DB_CONNECTION. Если она не будет указана, то используется mysql. Вы сами можете прописать жёстко значение, какое посчитаете нужным.

Под названием соединения, указываемого в параметре default, имеются ввиду элементы массива connections, который описан немного ниже:

'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' => true,
        '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' => '',
    ],
],

Здесь, как вы видите, содержатся как раз настройки подключения к серверу Laravel базы данных, разбитые на разные секции, которые создатели Laravel нарекли «подключениями» для каждой из поддерживаемых фреймворком СУБД, которые были перечислены в начале статьи.

Думаю, какое подключение какой СУБД соответствует, пояснять не нужно. Значения многим параметрам, как вы видите, можно задавать в файле .env. Некоторых используемых в данном файле переменных, кстати, даже нет в .env по умолчанию (например, DB_SOCKET из секции настроек MySQL соединения), наверное, из-за отсутствия необходимости их использования в большинстве случаев.

http://cccp-blog.com/wp-includes/images/banners/templatemonster/banner_content.jpg

Для соединения с Laravel SQLite базой, кстати, тоже используется несуществующая по умолчанию переменная DB_DATABASE, значение которой должно быть абсолютным путём к файлу базы данных, указанному в .env в следующем формате:

DB_DATABASE=/абсолютный/путь/к/database.sqlite

Если же для какого-то из необходимых вам параметров нужно будет менять значение в зависимости от окружения, в котором будет работать ваше Laravel приложение, то вы знаете, что делать 🙂 Правильно — создать для неё переменную в файле .env и использовать её в данном конфиге с помощью хэлпера env() в том виде, в каком сейчас используются существующие.

По поводу данного блока настроек, есть ещё один нюанс… Он заключается в том, что код Laravel взаимодействует с базами данных через методы PHP PDO. А в данном блоке настроек у каждого массива сеттингов соединения с определённой СУБД есть параметр driver, значения которого соответствуют PHP PDO драйверам, которые должны быть установлены на вашем сервере для успешного взаимодействия с Laravel БД.

Поэтому, если вы указали все параметры соединения с Laravel DB верно, но фреймворк выдаёт ошибку соединения, скорее всего, проблема именно в драйвере PDO. Поставьте необходимый для вашей СУБД и проверьте его подключение в файле конфигурации php.ini. Нужно, чтобы он не был закомментирован:

;extension=php_pdo_firebird.dll

Если требуемый вам параметр будет содержаться в представленном выше виде, то уберите символ точки с запятой в самом начале строки, чтобы включить требуемое расширение.

Также в рассматриваемом нами конфиге config\database.php ещё есть секции настроек миграций и соединения с Redis, на которых я не буду сейчас задерживаться, и рассмотрю их при обзоре механизма Laravel миграций и кэширования, которые будут ждать вас в дальнейших публикациях.

Поэтому, чтобы быть в курсе их выхода, рекомендую подписаться на обновления и проверять почаще свой электронный почтовый ящик 🙂

Настройки чтения и записи для одной Laravel БД

Иногда в процессе разработки появляется необходимость использовать одно подключение к БД для чтения информации (выполнять SELECT запросы), а другое — для модификации данных (INSERT, UPDATE и DELETE запросы). Laravel позволяет сделать данное разграничение легко и быстро на уровне рассматриваемого нами конфига database.php.

При этом необходимые вам соединения будут использоваться при отправке чистых (raw) запросов к БД, а также при использовании конструктора запросов Laravel (query builder) и Eloquent ORM.

Для разграничения сеттингов чтения и записи в настройки соединения с необходимой СУБД нужно добавить секции read и write в следующем формате:

'mysql' => [
    'read' => [
        'host' => ['192.168.1.1'],
    ],
    'write' => [
        'host' => ['196.168.1.2'],
    ],
    'sticky'    => true,
    'driver'    => 'mysql',
    'database'  => 'database',
    'username'  => 'root',
    'password'  => '',
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix'    => '',
],

Пример выше взят из официальной документации Laravel по работе с БД и подразумевает, что база данных находится на нескольких серверах (репликах), т.е. разделение настроек соединения с БД может быть полезно при репликации данных, что на Highload проектах встречается достаточно часто, но при запуске стартапов (если они не будут сразу проектироваться под высокие нагрузки, конечно) вы с этим не скоро столкнётесь 🙂

Более жизненный пример, о котором я уже говорил ранее, — это использование нескольких пользователей БД: одного с правами на чтение, а второго с возможностью изменения данных. В таком случае Laravel позволит вам разграничить операции с базой следующим образом:

'mysql' => [
    'read' => [
        'username'  => 'user1',
        'password'  => 'secret'
    ],
    'write' => [
        'username'  => 'user2',
        'password'  => 'secret'
    ],
    'host' => '127.0.0.1',
    'sticky'    => true,
    'driver'    => 'mysql',
    'database'  => 'database',
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix'    => '',
],

В обоих приведённых примерах данные из массивов write и read переопределяют одноимённые переменные из родительского массива mysql. Остальные же будут действительны для обоих случаев.

Конфигурация Laravel базы данных: опция sticky

Также в примерах выше вы могли обратить внимание на переменную конфигурации соединения с Laravel database под названием sticky.

Данный параметр не является обязательным и может использоваться в случаях, когда нужно будет организовать немедленное чтение записей, которые были записаны в Laravel БД в рамках текущего запроса или цикла запросов. Принимает булевские значения, т.е. true/false.

Если sticky имеет значение true, и в рамках текущего цикла запроса была выполнена операция записи данных в БД, то любая операция чтения данных будет использовать write соединение.

Это гарантирует, что любые данные, записанные в течение цикла запроса, могут быть немедленно прочитаны из базы данных во время этого же запроса. Хотите ли вы делать данную фичу доступной в вашем Laravel приложении или нет — полностью зависит от вас.

Работа с несколькими Laravel DB

Когда вы используете в рамках своего приложения несколько БД, то в процессе разработки вы можете получить доступ к каждому соединению с помощью метода connection фасада Laravel DB, более подробно с полным списком методов которого я познакомлю вас в следующих статьях, где будут рассматриваться механизмы отправки запросов к базе.

Пользоваться данным методов можно следующим образом:

$users = DB::connection('mysql')->select('select * from users');

Имя используемого соединения с БД должно соответствовать одному из соединений, описанных в конфиге config\database.php.

http://cccp-blog.com/wp-includes/images/banners/partner_web_studio/banner_728x90.gif

Также вы можете получить чистый объект PHP PDO для произведения дальнейших действий с БД с помощью метода getPdo() следующим образом:

$pdo = DB::connection('pgsql')->getPdo();

Laravel database: выводы по поводу настроек связи

Вот мы с вами и рассмотрели основные настройки соединения Laravel c базой данных, которые, как выяснилось, могут быть указаны двумя способами: через главный конфиг config/database.php и через файл настроек окружения .env, расположенном в корне приложения.

Я лично пользуюсь вторым вариантом, а также советую и вам к нему прибегать, т.к. он является наиболее правильным и позволяет разделить настройки Laravel приложения для различных его окружений (речь идёт о DEV, STAGE и PROD).

Даже если вы льёте файлы проекта с локалки сразу на прод, то без данного способа вам всё равно не обойтись, т.к. как минимум, два окружения у вас уже будет, следовательно, и настроек соединения с Laravel БД также будет два разных набора. Поэтому .env и извлечён из-под контроля версий, т.к. каждая копия приложения будет содержать уникальный набор параметров.

Конфиг же config\database.php в репозиторий записывается, поэтому в нём необходимо указывать лишь общие для всех окружений настройки. Обратите на это, пожалуйста, особое внимание.

Возможно, приведённая сегодня информация многим покажется очевидной и недостойной внимания, но, если хотя бы одному из ста читателей она была полезна, то я уже буду считать свою цель достигнутой и понимать, что всё, чем я занимаюсь, кому-то да нужно 🙂

Поэтому оставляйте свои комментарии со своими отзывами (пусть даже негативными), чтобы я понимал, что нужно улучшить и обратить внимание в дальнейшем.

Всем удачи и до новых встреч! 😉

Понравилась статья? Поделись с друзьями:
  1. 5
  2. 4
  3. 3
  4. 2
  5. 1
3 голоса, в среднем: 5 из 5

Похожие темы

4 комментария к статье "Laravel база данных: настраиваем соединение"

  1. Иван

    По поводу соединения с базой можете объяснить как к любым соединениям подвязывать подключение к одной таблице? Например контакты выводятся на всех страницах и делать отдельный запрос на каждой странице я так понял не очень хорошая идея, нужно чтобы на каждой странице когда происходит запрос к данным этой странице, то каким-нибудь union выбирались данные из таблицы контактов, тоесть чтобы все было одним запросом, как это сделать? Может какой-то шаблон есть и его можно применять ко всем моделям? Простите может вопрос глупый, но какой есть

    1. Pashaster Автор

      Добрый вечер 🙂 Ну почему же глупый вопрос? Глупым можно назвать только тот, который не был задан 🙂 Ход мыслей у Вас также правильный. Только решается задача намного проще, чем извращениями с запросами к БД. Для этого нужно кэширование данных на стороне сервера, чтобы брать их при запросе не из БД, а из кэша.

      Извлечение кэшированных данных занимает намного меньше времени и ресурсов, а также применяется для информации, которая часто запрашивается и редко изменяется — как раз то, что Вам нужно. И при кэшировании можно не сильно париться по поводу излишней оптимизации запросов к БД (но это и не значит, что ей стоит пренебрегать полностью) — долго будет выполняться только самый первый, далее, при помещении данных в кэш, извлекаться оттуда они будут мгновенно. И особенно эта разница заметна как раз на «тяжёлых» запросах, которые стараются кэшировать в первую очередь.

      В Laravel этот механизм очень удобный и хорошо реализован. Как и в случае с БД, можно выбирать различные драйвера (Redis, Memcached, файловое хранилище — я лично первый предпочитаю за счёт лёгкого сэтапа и хорошей производительности). И API уже реализовано для работы с кэшом: его записью и чтением оттуда — https://laravel.com/docs/5.7/cache

      Обо всём этом я планирую написать отдельную статью, как всегда, с реальными примерами, так что подписывайтесь на обновления, чтобы быть в курсе 🙂

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *