Всем хэллоу! 🙂
Выдалась свободная минутка, и я решил сделать очередной шаг к созданию своего тестового Laravel сайта, в процессе чего я знакомлю вас с основными конструкциями и механизмами Laravel фреймворка.
Сегодня на повестке дня обзор настроек соединения нашего сайта с Laravel database, в которой в дальнейшем будут храниться данные наших пользователей и посты блога.
Сразу скажу, что у Laravel с database settings всё хорошо, и на их произведение в рамках предыдущей статьи об установке механизма Laravel аутентификации у меня лично ушло 2 минуты.
Причём, первую минуту я создавал саму базу, а половину второй размышлял, какую СУБД всё-таки выбрать 🙂 Остальным же 30 секундам и будет посвящена дальнейшая информация, которой, как вы понимаете, сегодня много не будет.
- Laravel DB connection: какие СУБД поддерживаются?
- Настройки соединения с Laravel database: способ первый
- Конфигурация соединения с Laravel базой данных: способ второй
- Настройки чтения и записи для одной Laravel БД
- Конфигурация Laravel базы данных: опция sticky
- Работа с несколькими Laravel DB
- Laravel database: выводы по поводу настроек связи
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, как и в примере выше, для PostgeSQL — 5432, для остальных поддерживаемых 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 соединения), наверное, из-за отсутствия необходимости их использования в большинстве случаев.
Для соединения с 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.
Также вы можете получить чистый объект 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 в репозиторий записывается, поэтому в нём необходимо указывать лишь общие для всех окружений настройки. Обратите на это, пожалуйста, особое внимание.
Возможно, приведённая сегодня информация многим покажется очевидной и недостойной внимания, но, если хотя бы одному из ста читателей она была полезна, то я уже буду считать свою цель достигнутой и понимать, что всё, чем я занимаюсь, кому-то да нужно 🙂
Поэтому оставляйте свои комментарии со своими отзывами (пусть даже негативными), чтобы я понимал, что нужно улучшить и обратить внимание в дальнейшем.
Всем удачи и до новых встреч! 😉
P.S.: если вам нужен сайт либо необходимо внести правки на существующий, но для этого нет времени и желания, могу предложить свои услуги.
Более 5 лет опыта профессиональной разработки сайтов. Работа с PHP, OpenCart, WordPress, Laravel, Yii, MySQL, PostgreSQL, JavaScript, React, Angular и другими технологиями web-разработки.
Опыт разработки проектов различного уровня: лендинги, корпоративные сайты, Интернет-магазины, CRM, порталы. В том числе поддержка и разработка HighLoad проектов. Присылайте ваши заявки на email cccpblogcom@gmail.com.
И с друзьями не забудьте поделиться 😉
Большое спасибо!Все по теме.
С нетерпением ждем продолжения!
По поводу соединения с базой можете объяснить как к любым соединениям подвязывать подключение к одной таблице? Например контакты выводятся на всех страницах и делать отдельный запрос на каждой странице я так понял не очень хорошая идея, нужно чтобы на каждой странице когда происходит запрос к данным этой странице, то каким-нибудь union выбирались данные из таблицы контактов, тоесть чтобы все было одним запросом, как это сделать? Может какой-то шаблон есть и его можно применять ко всем моделям? Простите может вопрос глупый, но какой есть
Добрый вечер 🙂 Ну почему же глупый вопрос? Глупым можно назвать только тот, который не был задан 🙂 Ход мыслей у Вас также правильный. Только решается задача намного проще, чем извращениями с запросами к БД. Для этого нужно кэширование данных на стороне сервера, чтобы брать их при запросе не из БД, а из кэша.
Извлечение кэшированных данных занимает намного меньше времени и ресурсов, а также применяется для информации, которая часто запрашивается и редко изменяется — как раз то, что Вам нужно. И при кэшировании можно не сильно париться по поводу излишней оптимизации запросов к БД (но это и не значит, что ей стоит пренебрегать полностью) — долго будет выполняться только самый первый, далее, при помещении данных в кэш, извлекаться оттуда они будут мгновенно. И особенно эта разница заметна как раз на «тяжёлых» запросах, которые стараются кэшировать в первую очередь.
В Laravel этот механизм очень удобный и хорошо реализован. Как и в случае с БД, можно выбирать различные драйвера (Redis, Memcached, файловое хранилище — я лично первый предпочитаю за счёт лёгкого сэтапа и хорошей производительности). И API уже реализовано для работы с кэшом: его записью и чтением оттуда — https://laravel.com/docs/5.7/cache
Обо всём этом я планирую написать отдельную статью, как всегда, с реальными примерами, так что подписывайтесь на обновления, чтобы быть в курсе 🙂
Здравствуйте, у меня на локалке (OpenServer) в файле .env настроено подключение к базе ‘db1’. Всё работает хорошо, далее я указал настройки второй базы ‘db2’ в файле config/database.php, изменил запрос с
$users = DB::select(‘select * from users where age > :age’, [‘age’ => 18]);
на
$users = DB::connection(‘db2’)->select(‘select * from users where age > :age’, [‘age’ => 18]);
и ответ приходит от ‘db1’ из файла .env. Поясните пожалуйста в чём может быть проблема?
Добрый день. Отвечаю с больший запозданием, но, может, кому-то ответ пригодится. Laravel кэширует конфиги, чтобы сократить время на их чтение. Чтобы после изменений конфигов в Laravel подтягивались изменения, нужно чистить кэш конфигов: