├── .gitignore ├── readme.md ├── license.md ├── encryption.md ├── console-tests.md ├── hashing.md ├── documentation.md ├── rate-limiting.md ├── redirects.md ├── seeding.md ├── starter-kits.md ├── csrf.md ├── lifecycle.md ├── deployment.md ├── contributions.md ├── eloquent-serialization.md ├── eloquent-collections.md ├── socialite.md ├── testing.md ├── providers.md ├── localization.md ├── urls.md ├── verification.md ├── views.md ├── configuration.md ├── envoy.md ├── passwords.md ├── errors.md └── structure.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | Перевод документации Laravel 8.x 2 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Taylor Otwell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /encryption.md: -------------------------------------------------------------------------------- 1 | git 212cf52490604efe98f1e486c9db94dd69be24e4 2 | 3 | --- 4 | 5 | # Шифрование 6 | 7 | - [Введение](#introduction) 8 | - [Конфигурирование](#configuration) 9 | - [Использование шифровальщика](#using-the-encrypter) 10 | 11 | 12 | ## Введение 13 | 14 | Сервисы шифрования Laravel предоставляют простой и удобный интерфейс для шифрования и дешифрования текста через OpenSSL с использованием шифрования AES-256 и AES-128. Все зашифрованные значения Laravel подписываются с использованием кода аутентификации сообщения (MAC), поэтому их базовое значение не может быть изменено или подделано после шифрования. 15 | 16 | 17 | ## Конфигурирование 18 | 19 | Перед использованием шифровальщика Laravel вы должны установить параметр `key` в конфигурационном файле `config/app.php`. Это значение конфигурации управляется переменной окружения `APP_KEY`. Вы должны использовать команду `php artisan key:generate` для генерации значения этой переменной, поскольку команда `key:generate` будет использовать безопасный генератор случайных байтов PHP для создания криптографически безопасного ключа для вашего приложения. Обычно значение переменной среды `APP_KEY` генерируется для вас во время [установки Laravel](/docs/{{version}}/installation). 20 | 21 | 22 | ## Использование шифровальщика 23 | 24 | 25 | #### Шифрование значения 26 | 27 | Вы можете зашифровать значение, используя метод `encryptString` фасада `Crypt`. Все значения будут зашифрованы с использованием OpenSSL и шифра `AES-256-CBC`. Кроме того, все зашифрованные значения подписываются кодом аутентификации сообщения (MAC). Встроенный код аутентификации сообщений предотвратит расшифровку любых значений, которые были подделаны злоумышленниками: 28 | 29 | user()->fill([ 49 | 'token' => Crypt::encryptString($request->token), 50 | ])->save(); 51 | } 52 | } 53 | 54 | 55 | #### Расшифровка значения 56 | 57 | Вы можете расшифровать значения, используя метод `decryptString` фасада `Crypt`. Если значение не может быть правильно расшифровано, например, когда код аутентификации сообщения недействителен, будет выброшено исключение `Illuminate\Contracts\Encryption\DecryptException`: 58 | 59 | use Illuminate\Contracts\Encryption\DecryptException; 60 | use Illuminate\Support\Facades\Crypt; 61 | 62 | try { 63 | $decrypted = Crypt::decryptString($encryptedValue); 64 | } catch (DecryptException $e) { 65 | // 66 | } 67 | -------------------------------------------------------------------------------- /console-tests.md: -------------------------------------------------------------------------------- 1 | git 8f0031b4ea65784d5786507f76fbf9843c0ea388 2 | 3 | --- 4 | 5 | # Тестирование · Тесты консольных команд 6 | 7 | - [Введение](#introduction) 8 | - [Ожидания успеха / неудачи](#success-failure-expectations) 9 | - [Ожидания ввода / вывода](#input-output-expectations) 10 | 11 | 12 | ## Введение 13 | 14 | Помимо упрощенного HTTP-тестирования, Laravel предлагает простой API для тестирования [пользовательских консольных команд](artisan) вашего приложения. 15 | 16 | 17 | 18 | ## Ожидания успеха / неудачи 19 | 20 | Для начала давайте рассмотрим, как делать утверждения относительно кода выхода команды Artisan. Для этого мы будем использовать метод `artisan` для вызова Artisan-команды из нашего теста. Затем мы будем использовать метод `assertExitCode`, чтобы подтвердить, что команда завершилась с заданным кодом выхода: 21 | 22 | /** 23 | * Test a console command. 24 | * 25 | * @return void 26 | */ 27 | public function test_console_command() 28 | { 29 | $this->artisan('inspire')->assertExitCode(0); 30 | } 31 | 32 | Вы можете использовать метод `assertNotExitCode` чтобы подтвердить, что команда не завершилась с заданным кодом выхода: 33 | 34 | $this->artisan('inspire')->assertNotExitCode(1); 35 | 36 | Конечно, все команды терминала обычно завершаются с кодом состояния `0`, когда они успешны, и с ненулевым кодом выхода, когда они не успешны. Поэтому для удобства вы можете использовать утверждения `assertSuccessful` и `assertFailed` чтобы утверждать, что данная команда завершилась с успешным кодом выхода или нет: 37 | 38 | $this->artisan('inspire')->assertSuccessful(); 39 | 40 | $this->artisan('inspire')->assertFailed(); 41 | 42 | 43 | ## Ожидания ввода / вывода 44 | 45 | Laravel позволяет вам легко «имитировать» ввод пользователем в консольных командах, используя метод `expectsQuestion`. Кроме того, вы можете указать код выхода / возврата и текст, который вы ожидаете получить от консольной команды, используя методы `assertExitCode` и `expectsOutput`. Например, рассмотрим следующую консольную команду: 46 | 47 | Artisan::command('question', function () { 48 | $name = $this->ask('What is your name?'); 49 | 50 | $language = $this->choice('Which language do you prefer?', [ 51 | 'PHP', 52 | 'Ruby', 53 | 'Python', 54 | ]); 55 | 56 | $this->line('Your name is '.$name.' and you prefer '.$language.'.'); 57 | }); 58 | 59 | Вы можете протестировать эту команду с помощью следующего теста, который использует методы `expectsQuestion`,` expectsOutput`, `doesntExpectOutput` и `assertExitCode`: 60 | 61 | /** 62 | * Тестирование консольной команды. 63 | * 64 | * @return void 65 | */ 66 | public function test_console_command() 67 | { 68 | $this->artisan('question') 69 | ->expectsQuestion('What is your name?', 'Taylor Otwell') 70 | ->expectsQuestion('Which language do you prefer?', 'PHP') 71 | ->expectsOutput('Your name is Taylor Otwell and you prefer PHP.') 72 | ->doesntExpectOutput('Your name is Taylor Otwell and you prefer Ruby.') 73 | ->assertExitCode(0); 74 | } 75 | 76 | 77 | #### Ожидания подтверждения 78 | 79 | При написании команды, которая ожидает подтверждения в виде ответа «да» или «нет», вы можете использовать метод `expectsConfirmation`: 80 | 81 | $this->artisan('module:import') 82 | ->expectsConfirmation('Do you really wish to run this command?', 'no') 83 | ->assertExitCode(1); 84 | 85 | 86 | #### Таблица ожиданий 87 | 88 | Если ваша команда отображает таблицу информации с использованием метода `table` Artisan, может быть обременительно записывать ожидаемые результаты для всей таблицы. Вместо этого вы можете использовать метод `expectsTable`. Этот метод принимает заголовки таблицы в качестве первого аргумента и данные таблицы в качестве второго аргумента: 89 | 90 | $this->artisan('users:all') 91 | ->expectsTable([ 92 | 'ID', 93 | 'Email', 94 | ], [ 95 | [1, 'taylor@example.com'], 96 | [2, 'abigail@example.com'], 97 | ]); 98 | -------------------------------------------------------------------------------- /hashing.md: -------------------------------------------------------------------------------- 1 | git 0ab96f0b7c55966f5402b99e37268a0e9dacd03e 2 | 3 | --- 4 | 5 | # Хеширование 6 | 7 | - [Введение](#introduction) 8 | - [Конфигурирование](#configuration) 9 | - [Основы использования](#basic-usage) 10 | - [Хеширование паролей](#hashing-passwords) 11 | - [Проверка совпадения пароля с хешем](#verifying-that-a-password-matches-a-hash) 12 | - [Определение необходимости повторного хеширования пароля](#determining-if-a-password-needs-to-be-rehashed) 13 | 14 | 15 | ## Введение 16 | 17 | [Фасад](/docs/{{version}}/facades) `Hash` фреймворка Laravel обеспечивает безопасное хеширование Bcrypt и Argon2 для хранения паролей пользователей. Если вы используете каркас одного из [стартовых комплектов приложений Laravel](starter-kits), то для регистрации и аутентификации по умолчанию будет использоваться Bcrypt. 18 | 19 | Bcrypt – отличный выбор для хеширования паролей, потому что его «коэффициент работы» регулируется, а это означает, что время, необходимое для генерации хеш-кода, может быть увеличено по мере увеличения мощности оборудования. При хешировании паролей – чем медленнее, тем лучше. Чем больше времени требуется алгоритму для хеширования пароля, тем больше времени требуется злоумышленникам для создания «радужных таблиц» всех возможных строковых хеш-значений, которые могут использоваться в атаках. 20 | 21 | 22 | ## Конфигурирование 23 | 24 | Драйвер хеширования по умолчанию для вашего приложения настраивается в файле конфигурации `config/hashing.php`. В настоящее время существует несколько поддерживаемых драйверов: [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt) и [Argon2](https://en.wikipedia.org/wiki/Argon2) (вариации Argon2i и Argon2id). 25 | 26 | > {note} Для драйвера Argon2i требуется PHP 7.2.0 или выше, а для драйвера Argon2id требуется PHP 7.3.0 или выше. 27 | 28 | 29 | ## Основы использования 30 | 31 | 32 | ### Хеширование паролей 33 | 34 | Вы можете хешировать пароль, вызвав метод `make` фасада `Hash`: 35 | 36 | user()->fill([ 57 | 'password' => Hash::make($request->newPassword) 58 | ])->save(); 59 | } 60 | } 61 | 62 | 63 | #### Регулировка коэффициента работы Bcrypt 64 | 65 | Если вы используете алгоритм Bcrypt, метод `make` позволяет вам управлять коэффициентом работы алгоритма с помощью параметра `rounds`; однако значение по умолчанию приемлемо для большинства приложений: 66 | 67 | $hashed = Hash::make('password', [ 68 | 'rounds' => 12, 69 | ]); 70 | 71 | 72 | #### Регулировка коэффициента работы Argon2 73 | 74 | Если вы используете алгоритм Argon2, метод `make` позволяет вам управлять коэффициентом работы алгоритма с помощью параметров `memory`, `time` и `threads`; однако значения по умолчанию приемлемы для большинства приложений: 75 | 76 | $hashed = Hash::make('password', [ 77 | 'memory' => 1024, 78 | 'time' => 2, 79 | 'threads' => 2, 80 | ]); 81 | 82 | > {tip} Дополнительную информацию об этих параметрах можно найти в [официальной документации PHP](https://www.php.net/manual/ru/function.password-hash.php). 83 | 84 | 85 | ### Проверка совпадения пароля с хешем 86 | 87 | Метод `check` фасада `Hash` позволяет проверить, что указанная текстовая строка соответствует заданному хешу: 88 | 89 | if (Hash::check('plain-text', $hashedPassword)) { 90 | // Пароли совпадают ... 91 | } 92 | 93 | 94 | ### Определение необходимости повторного хеширования пароля 95 | 96 | Метод `needsRehash` фасада `Hash` позволяет определить, изменился ли коэффициентом работы, используемый хешером, с момента хеширования пароля. Некоторые приложения предпочитают выполнять эту проверку во время процесса аутентификации приложения: 97 | 98 | if (Hash::needsRehash($hashed)) { 99 | $hashed = Hash::make('plain-text'); 100 | } 101 | -------------------------------------------------------------------------------- /documentation.md: -------------------------------------------------------------------------------- 1 | git 9f92262a5af04c855905cae8a6a0e9fb2b9c46ba 2 | 3 | --- 4 | 5 | - ## Пролог 6 | - [Примечания к релизу](/docs/{{version}}/releases) 7 | - [Руководство по обновлению](/docs/{{version}}/upgrade) 8 | - [Рекомендации по участию](/docs/{{version}}/contributions) 9 | - ## Начало работы 10 | - [Установка](/docs/{{version}}/installation) 11 | - [Конфигурация](/docs/{{version}}/configuration) 12 | - [Структура каталогов](/docs/{{version}}/structure) 13 | - [Стартовые наборы](/docs/{{version}}/starter-kits) 14 | - [Развертывание](/docs/{{version}}/deployment) 15 | - ## Архитектурные концепции 16 | - [Жизненный цикл запроса](/docs/{{version}}/lifecycle) 17 | - [Сервис-контейнер](/docs/{{version}}/container) 18 | - [Сервис-провайдеры](/docs/{{version}}/providers) 19 | - [Фасады](/docs/{{version}}/facades) 20 | - ## Основное 21 | - [Маршрутизация](/docs/{{version}}/routing) 22 | - [Посредники](/docs/{{version}}/middleware) 23 | - [CSRF Защита](/docs/{{version}}/csrf) 24 | - [Контроллеры](/docs/{{version}}/controllers) 25 | - [HTTP-запросы](/docs/{{version}}/requests) 26 | - [HTTP-ответы](/docs/{{version}}/responses) 27 | - [Представления](/docs/{{version}}/views) 28 | - [Шаблоны Blade](/docs/{{version}}/blade) 29 | - [Генерация URL](/docs/{{version}}/urls) 30 | - [Сессии](/docs/{{version}}/session) 31 | - [Валидация](/docs/{{version}}/validation) 32 | - [Обработка ошибок](/docs/{{version}}/errors) 33 | - [Логирование](/docs/{{version}}/logging) 34 | - ## Погружение 35 | - [Artisan консоль](/docs/{{version}}/artisan) 36 | - [Широковещание](/docs/{{version}}/broadcasting) 37 | - [Кэширование](/docs/{{version}}/cache) 38 | - [Коллекции](/docs/{{version}}/collections) 39 | - [Компиляция JS и CSS](/docs/{{version}}/mix) 40 | - [Контракты](/docs/{{version}}/contracts) 41 | - [События](/docs/{{version}}/events) 42 | - [Файловое хранилище](/docs/{{version}}/filesystem) 43 | - [Помощники](/docs/{{version}}/helpers) 44 | - [HTTP Клиент](/docs/{{version}}/http-client) 45 | - [Локализация](/docs/{{version}}/localization) 46 | - [Почта](/docs/{{version}}/mail) 47 | - [Уведомления](/docs/{{version}}/notifications) 48 | - [Разработка пакетов](/docs/{{version}}/packages) 49 | - [Очереди](/docs/{{version}}/queues) 50 | - [Ограничение скорости](/docs/{{version}}/rate-limiting) 51 | - [Планировщик](/docs/{{version}}/scheduling) 52 | - ## Безопасность 53 | - [Аутентификация](/docs/{{version}}/authentication) 54 | - [Авторизация](/docs/{{version}}/authorization) 55 | - [Верификация email](/docs/{{version}}/verification) 56 | - [Шифрование](/docs/{{version}}/encryption) 57 | - [Хеширование](/docs/{{version}}/hashing) 58 | - [Сброс пароля](/docs/{{version}}/passwords) 59 | - ## База данных 60 | - [Начало работы](/docs/{{version}}/database) 61 | - [Конструктор запросов](/docs/{{version}}/queries) 62 | - [Пагинация](/docs/{{version}}/pagination) 63 | - [Миграции](/docs/{{version}}/migrations) 64 | - [Загрузка начальных данных](/docs/{{version}}/seeding) 65 | - [Redis](/docs/{{version}}/redis) 66 | - ## Eloquent ORM 67 | - [Начало работы](/docs/{{version}}/eloquent) 68 | - [Отношения](/docs/{{version}}/eloquent-relationships) 69 | - [Коллекции](/docs/{{version}}/eloquent-collections) 70 | - [Мутаторы / Типизация](/docs/{{version}}/eloquent-mutators) 71 | - [API Ресурсы](/docs/{{version}}/eloquent-resources) 72 | - [Сериализация](/docs/{{version}}/eloquent-serialization) 73 | - ## Тестирование 74 | - [Начало работы](/docs/{{version}}/testing) 75 | - [HTTP Тесты](/docs/{{version}}/http-tests) 76 | - [Консольные Тесты](/docs/{{version}}/console-tests) 77 | - [Браузерные Тесты](/docs/{{version}}/dusk) 78 | - [База данных](/docs/{{version}}/database-testing) 79 | - [Имитация](/docs/{{version}}/mocking) 80 | - ## Пакеты 81 | - [Breeze](/docs/{{version}}/starter-kits#laravel-breeze) 82 | - [Cashier (Stripe)](/docs/{{version}}/billing) 83 | - [Cashier (Paddle)](/docs/{{version}}/cashier-paddle) 84 | - [Dusk](/docs/{{version}}/dusk) 85 | - [Envoy](/docs/{{version}}/envoy) 86 | - [Fortify](/docs/{{version}}/fortify) 87 | - [Homestead](/docs/{{version}}/homestead) 88 | - [Horizon](/docs/{{version}}/horizon) 89 | - [Jetstream](https://jetstream.laravel.com) 90 | - [Octane](/docs/{{version}}/octane) 91 | - [Passport](/docs/{{version}}/passport) 92 | - [Sail](/docs/{{version}}/sail) 93 | - [Sanctum](/docs/{{version}}/sanctum) 94 | - [Scout](/docs/{{version}}/scout) 95 | - [Socialite](/docs/{{version}}/socialite) 96 | - [Telescope](/docs/{{version}}/telescope) 97 | - [Valet](/docs/{{version}}/valet) 98 | - [API Документация](https://laravel.com/api/8.x) 99 | -------------------------------------------------------------------------------- /rate-limiting.md: -------------------------------------------------------------------------------- 1 | git 34eb006893f9e86010025689656aa8cba0096687 2 | 3 | --- 4 | 5 | # Ограничение скорости 6 | 7 | - [Введение](#introduction) 8 | - [Конфигурация кеша](#cache-configuration) 9 | - [Базовое использование](#basic-usage) 10 | - [Ручное увеличение числа попыток](#manually-incrementing-attempts) 11 | - [Очистка счетчика попыток](#clearing-attempts) 12 | 13 | 14 | ## Введение 15 | 16 | Laravel включает простую в использовании абстракцию ограничения скорости, которая в сочетании с [кешем](/docs/{{version}}/cache) вашего приложения обеспечивает простой способ ограничить любое действие в течение указанного периода времени. 17 | 18 | > {tip} Если вас интересует ограничение скорости входящих HTTP-запросов, обратитесь к документации [посредника для ограничения частоты запросов](/docs/{{version}}/routing#rate-limiting). 19 | 20 | 21 | ### Конфигурация кеша 22 | 23 | Обычно ограничитель скорости использует кеш вашего приложения по умолчанию, как определено ключом `default` в файле конфигурации `cache` вашего приложения. Однако вы можете указать, какой драйвер кеша должен использовать ограничитель скорости, задав ключ `limiter` в файле конфигурации `cache` вашего приложения: 24 | 25 | 'default' => 'memcached', 26 | 27 | 'limiter' => 'redis', 28 | 29 | 30 | ## Базовое использование 31 | 32 | Фасад `Illuminate\Support\Facades\RateLimiter` может использоваться для взаимодействия с ограничителем скорости. Самый простой метод, предлагаемый ограничителем скорости - это метод `attempt` который ограничивает скорость данного обратного вызова на заданное количество секунд. 33 | 34 | Метод `attempt` возвращает `false` если для обратного вызова не осталось доступных попыток; в противном случае метод `attempt` вернет результат обратного вызова или `true`. Первым аргументом, принимаемым методом `attempt` является «ключ» ограничителя скорости, который может быть любой строкой по вашему выбору, представляющей действие с ограничением скорости: 35 | 36 | use Illuminate\Support\Facades\RateLimiter; 37 | 38 | $executed = RateLimiter::attempt( 39 | 'send-message:'.$user->id, 40 | $perMinute = 5, 41 | function() { 42 | // Send message... 43 | } 44 | ); 45 | 46 | if (! $executed) { 47 | return 'Too many messages sent!'; 48 | } 49 | 50 | 51 | ### Ручное увеличение числа попыток 52 | 53 | Если вы хотите вручную взаимодействовать с ограничителем скорости, доступно множество других методов. Например, вы можете вызвать метод `tooManyAttempts`, чтобы определить, не превысил ли заданный ключ ограничителя скорости максимальное количество разрешенных попыток в минуту: 54 | 55 | use Illuminate\Support\Facades\RateLimiter; 56 | 57 | if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) { 58 | return 'Too many attempts!'; 59 | } 60 | 61 | В качестве альтернативы вы можете использовать метод `remaining` для получения количества попыток, оставшихся для данного ключа. Если для данного ключа остались повторные попытки, вы можете вызвать метод `hit`, чтобы увеличить общее количество попыток: 62 | 63 | use Illuminate\Support\Facades\RateLimiter; 64 | 65 | if (RateLimiter::remaining('send-message:'.$user->id, $perMinute = 5)) { 66 | RateLimiter::hit('send-message:'.$user->id); 67 | 68 | // Send message... 69 | } 70 | 71 | 72 | #### Определение доступности ограничителя скорости 73 | 74 | Когда у ключа больше не осталось попыток, метод `availableIn` возвращает количество секунд, оставшихся до тех пор, пока не будут доступны новые попытки: 75 | 76 | use Illuminate\Support\Facades\RateLimiter; 77 | 78 | if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) { 79 | $seconds = RateLimiter::availableIn('send-message:'.$user->id); 80 | 81 | return 'You may try again in '.$seconds.' seconds.'; 82 | } 83 | 84 | 85 | ### Очистка счетчика попыток 86 | 87 | Вы можете сбросить количество попыток для данного ключа ограничителя скорости, используя метод `clear`. Например, вы можете сбросить количество попыток, когда данное сообщение прочитано получателем: 88 | 89 | use App\Models\Message; 90 | use Illuminate\Support\Facades\RateLimiter; 91 | 92 | /** 93 | * Отметьте сообщение как прочитанное. 94 | * 95 | * @param \App\Models\Message $message 96 | * @return \App\Models\Message 97 | */ 98 | public function read(Message $message) 99 | { 100 | $message->markAsRead(); 101 | 102 | RateLimiter::clear('send-message:'.$message->user_id); 103 | 104 | return $message; 105 | } 106 | -------------------------------------------------------------------------------- /redirects.md: -------------------------------------------------------------------------------- 1 | git 2a0615c0b2833c9a6c80052c6896071fa525d0fc 2 | 3 | --- 4 | 5 | # HTTP переадресация 6 | 7 | - [Создание переадресации](#creating-redirects) 8 | - [Переадресация на именованные маршруты](#redirecting-named-routes) 9 | - [Переадресация на методы контроллера](#redirecting-controller-actions) 10 | - [Переадресация с данными сеанса](#redirecting-with-flashed-session-data) 11 | 12 | 13 | ## Создание переадресации 14 | 15 | Переадресация является экземпляром класса `Illuminate\Http\RedirectResponse` и содержит в ответе правильные заголовки, необходимые для перенаправления пользователя на другой URL. Есть несколько способов сгенерировать экземпляр `RedirectResponse`. Самый простой способ — использовать глобальный помощник `redirect`: 16 | 17 | Route::get('/dashboard', function () { 18 | return redirect('/home/dashboard'); 19 | }); 20 | 21 | Иногда необходимо перенаправить пользователя в его предыдущее местоположение, например, когда отправленная форма недействительна. Это можно сделать с помощью глобальной вспомогательной функции `back`. Поскольку эта функция использует [сессии](/docs/{{version}}/session), убедитесь, что маршрут, вызывающий функцию `back`, использует группу посредников` web` или применяет все необходимые посредники сессии: 22 | 23 | Route::post('/user/profile', function () { 24 | // Validate the request... 25 | 26 | return back()->withInput(); 27 | }); 28 | 29 | 30 | ## Переадресация на именованные маршруты 31 | 32 | Когда вы вызываете помощник `redirect` без параметров, возвращается экземпляр `Illuminate\Routing\Redirector`, что позволяет вам вызывать любой метод в экземпляре `Redirector`. Например, чтобы сгенерировать `RedirectResponse` на именованный маршрут, вы можете использовать метод route: 33 | 34 | return redirect()->route('login'); 35 | 36 | Если ваш маршрут имеет параметры, вы можете передать их в качестве второго аргумента методу `route`: 37 | 38 | // For a route with the following URI: profile/{id} 39 | 40 | return redirect()->route('profile', ['id' => 1]); 41 | 42 | 43 | #### Передача параметров через модели Eloquent 44 | 45 | Если вы перенаправляете на маршрут с параметром "ID", который заполняется из модели Eloquent, вы можете передать саму модель. ID будет извлечен автоматически: 46 | 47 | // For a route with the following URI: profile/{id} 48 | 49 | return redirect()->route('profile', [$user]); 50 | 51 | Если вы хотите настроить значение, которое помещается в параметр маршрута, вы должны переопределить метод `getRouteKey` в вашей модели Eloquent: 52 | 53 | /** 54 | * Получить значение ключа маршрута модели. 55 | * 56 | * @return mixed 57 | */ 58 | public function getRouteKey() 59 | { 60 | return $this->slug; 61 | } 62 | 63 | 64 | ## Перенаправление на методы контроллера 65 | 66 | Вы также можете обеспечить перенаправления на [методы контроллера](/docs/{{version}}/controllers). Для этого передайте имя контроллера и его метода методу `action` экземпляра `redirect`: 67 | 68 | use App\Http\Controllers\HomeController; 69 | 70 | return redirect()->action([HomeController::class, 'index']); 71 | 72 | Если метод контроллера требует параметров, вы можете передать их в качестве второго аргумента методу `action`: 73 | 74 | return redirect()->action( 75 | [UserController::class, 'profile'], ['id' => 1] 76 | ); 77 | 78 | 79 | ## Перенаправление с данными сеанса 80 | 81 | Перенаправление на новый URL-адрес и [передача данных в сеанс](/docs/{{version}}/session#flash-data) обычно выполняются одновременно. Обычно это делается после успешного выполнения действия, когда вы отправляете сообщение об успешном завершении сеанса. Для удобства вы можете создать экземпляр `RedirectResponse` и передать данные в сеанс в цепочке методов: 82 | 83 | Route::post('/user/profile', function () { 84 | // Update the user's profile... 85 | 86 | return redirect('/dashboard')->with('status', 'Profile updated!'); 87 | }); 88 | 89 | Вы можете использовать метод `withInput`, предоставляемый экземпляром `RedirectResponse`, для передачи входных данных текущего запроса в сеанс перед перенаправлением пользователя на новый URL. После того как данные были переданы в сеанс, вы можете легко [получить их](/docs/{{version}}/requests#retrieving-old-input) во время следующего запроса: 90 | 91 | return back()->withInput(); 92 | 93 | После перенаправления вы можете отобразить всплывающее сообщение [сеанса](/docs/{{version}}/session). Например, используя [синтаксис Blade](/docs/{{version}}/blade): 94 | 95 | @if (session('status')) 96 |
97 | {{ session('status') }} 98 |
99 | @endif 100 | -------------------------------------------------------------------------------- /seeding.md: -------------------------------------------------------------------------------- 1 | git 20512e525670be13f3a1607a9939db2c5ce65f96 2 | 3 | --- 4 | 5 | # База данных · Наполнение фиктивными данными 6 | 7 | - [Введение](#introduction) 8 | - [Написание наполнителей](#writing-seeders) 9 | - [Использование фабрик моделей](#using-model-factories) 10 | - [Вызов дополнительных наполнителей](#calling-additional-seeders) 11 | - [Запуск наполнителей](#running-seeders) 12 | 13 | 14 | ## Введение 15 | 16 | Laravel предлагает возможность наполнения вашей базы тестовыми данными с использованием классов-наполнителей. Все классы наполнителей хранятся в каталоге `database/seeders`. Класс `DatabaseSeeder` уже определен по умолчанию. В этом классе вы можете использовать метод `call` для запуска других наполнителей, что позволит вам контролировать порядок наполнения БД. 17 | 18 | > {tip} При наполнении базы данных автоматически отключается защита [массового присвоения](/docs/{{version}}/eloquent#mass-assignment). 19 | 20 | 21 | ## Написание наполнителей 22 | 23 | Чтобы сгенерировать новый наполнитель, используйте команду `make:seeder` [Artisan](artisan). Эта команда поместит новый класс наполнителя в каталог `database/seeders` вашего приложения: 24 | 25 | php artisan make:seeder UserSeeder 26 | 27 | Класс наполнителя по умолчанию содержит только один метод: `run`. Этот метод вызывается при выполнении команды `db:seed` Artisan. В методе `run` вы можете вставлять данные в свою базу данных, как хотите. Вы можете использовать [построитель запросов](/docs/{{version}}/queries) для самостоятельной вставки данных или использовать [фабрики моделей Eloquent](database-testing#defining-model-factories). 28 | 29 | В качестве примера давайте изменим класс `DatabaseSeeder`, созданный по умолчанию, и добавим выражение вставки фасада `DB` в методе `run`: 30 | 31 | insert([ 50 | 'name' => Str::random(10), 51 | 'email' => Str::random(10).'@gmail.com', 52 | 'password' => Hash::make('password'), 53 | ]); 54 | } 55 | } 56 | 57 | > {tip} В методе `run` вы можете объявить любые необходимые типы зависимостей. Они будут автоматически извлечены и внедрены через [контейнер служб](/docs/{{version}}/container) Laravel. 58 | 59 | 60 | ### Использование фабрик моделей 61 | 62 | Конечно, ручное указание атрибутов для каждой модели наполнителя обременительно. Вместо этого вы можете использовать [фабрики моделей](database-testing#defining-model-factories) для удобного создания большого количества записей в БД. Сначала просмотрите [документацию фабрики моделей](database-testing#defining-model-factories), чтобы узнать, как определить свои фабрики. 63 | 64 | Например, давайте создадим 50 пользователей, у каждого из которых будет по одному посту: 65 | 66 | use App\Models\User; 67 | 68 | /** 69 | * Запустить наполнение базы данных. 70 | * 71 | * @return void 72 | */ 73 | public function run() 74 | { 75 | User::factory() 76 | ->count(50) 77 | ->hasPosts(1) 78 | ->create(); 79 | } 80 | 81 | 82 | ### Вызов дополнительных наполнителей 83 | 84 | Внутри класса `DatabaseSeeder` вы можете использовать метод `call` для запуска других наполнителей. Использование метода `call` позволяет вам разбить ваши наполнители БД на несколько файлов, так что ни один класс наполнителя не станет слишком большим. Метод `call` принимает массив классов, которые должны быть выполнены: 85 | 86 | /** 87 | * Запустить наполнение базы данных. 88 | * 89 | * @return void 90 | */ 91 | public function run() 92 | { 93 | $this->call([ 94 | UserSeeder::class, 95 | PostSeeder::class, 96 | CommentSeeder::class, 97 | ]); 98 | } 99 | 100 | 101 | ## Запуск наполнителей 102 | 103 | Вы можете выполнить команду `db:seed` Artisan для наполнения вашей базы данных. По умолчанию команда `db:seed` запускает класс `Database\Seeders\DatabaseSeeder`, который, в свою очередь, может вызывать другие классы. Однако вы можете использовать параметр `--class`, чтобы указать конкретный класс наполнителя для его индивидуального запуска: 104 | 105 | php artisan db:seed 106 | 107 | php artisan db:seed --class=UserSeeder 108 | 109 | Вы также можете заполнить свою базу данных с помощью команды `migrate:fresh` в сочетании с параметром `--seed`, которая удалит все таблицы и повторно запустит все ваши миграции. Эта команда полезна для полного перестроения вашей базы данных: 110 | 111 | php artisan migrate:fresh --seed 112 | 113 | 114 | #### Принудительное наполнение при эксплуатации приложения 115 | 116 | Некоторые операции наполнения могут привести к изменению или потере данных. В окружении `production`, чтобы защитить вас от запуска команд наполнения эксплуатируемой базы данных, вам будет предложено подтвердить их запуск. Чтобы заставить наполнители запускаться без подтверждений, используйте флаг `--force`: 117 | 118 | php artisan db:seed --force 119 | -------------------------------------------------------------------------------- /starter-kits.md: -------------------------------------------------------------------------------- 1 | git ce3a0010f10469471667ab7eb177ce27217aca86 2 | 3 | --- 4 | 5 | # Стартовые комплекты 6 | 7 | - [Введение](#introduction) 8 | - [Laravel Breeze](#laravel-breeze) 9 | - [Установка](#laravel-breeze-installation) 10 | - [Breeze & Inertia](#breeze-and-inertia) 11 | - [Breeze & Next.js / API](#breeze-and-next) 12 | - [Laravel Jetstream](#laravel-jetstream) 13 | 14 | 15 | ## Введение 16 | 17 | Чтобы дать вам фору при создании нового приложения Laravel, мы рады предложить стартовые комплекты приложения и, в частности, аутентификации. Эти комплекты автоматически дополнят ваше приложение маршрутами, контроллерами и шаблонами, необходимыми для регистрации и аутентификации пользователей вашего приложения. 18 | 19 | Вы можете использовать эти стартовые комплекты, но они не требуются. Вы можете создать собственное приложение с нуля, просто установив новую копию Laravel. В любом случае мы знаем, что вы создадите что-то отличное! 20 | 21 | 22 | ## Laravel Breeze 23 | 24 | [**Laravel Breeze**](https://github.com/laravel/breeze) – это минимальная и простая реализация всего [функционала аутентификации](authentication) Laravel, включая вход в систему, регистрацию, сброс пароля, подтверждение адреса электронной почты и пароля. Слой «View» комплекта Laravel Breeze по умолчанию состоит из простых [шаблонов Blade](/docs/{{version}}/blade), стилизованных с помощью [Tailwind CSS](https://tailwindcss.com). 25 | 26 | Breeze обеспечивает прекрасную отправную точку для создания нового приложения Laravel, а также является отличным выбором для проектов, которые планируют вывести свои шаблоны Blade на новый уровень с помощью [Laravel Livewire](https://laravel-livewire.com) 27 | 28 | 29 | ### Установка 30 | 31 | Сначала вы должны [создать новое приложение Laravel](/docs/{{version}}/installation), настроить свою базу данных и запустить [миграции базы данных](/docs/{{version}}/migrations): 32 | 33 | ```bash 34 | curl -s https://laravel.build/example-app | bash 35 | 36 | cd example-app 37 | 38 | php artisan migrate 39 | ``` 40 | 41 | Создав новое приложение Laravel, вы можете установить Laravel Breeze с помощью Composer: 42 | 43 | ```bash 44 | composer require laravel/breeze:1.9.2 45 | ``` 46 | 47 | После того как Composer установит пакет Laravel Breeze, вы можете запустить команду `breeze:install` Artisan. Эта команда опубликует для вашего приложения шаблоны, маршруты, контроллеры и другие ресурсы аутентификации. Laravel Breeze опубликует весь свой код в вашем приложении, чтобы у вас был полный контроль, а также обзор всего функционала и его реализации. После установки Breeze вы также должны скомпилировать свои исходники, чтобы был доступен файл стилей вашего приложения: 48 | 49 | ```nothing 50 | php artisan breeze:install 51 | 52 | npm install 53 | 54 | npm run dev 55 | php artisan migrate 56 | ``` 57 | 58 | Затем, вы можете перейти в своем веб-браузере по URL-адресам вашего приложения `/login` или `/register`. Все маршруты Breeze определены в файле `routes/auth.php`. 59 | 60 | > {tip} Чтобы узнать больше о компиляции CSS и JavaScript вашего приложения, ознакомьтесь с [документацией Laravel Mix](/docs/{{version}}/mix#running-mix). 61 | 62 | 63 | ### Breeze и Inertia 64 | 65 | Laravel Breeze также предлагает реализацию внешнего интерфейса [Inertia.js](https://inertiajs.com) на базе Vue или React. Чтобы использовать стек Inertia, укажите `vue` или` react` в качестве желаемого стека при выполнении Artisan-команды `breeze:install`: 66 | 67 | ```nothing 68 | php artisan breeze:install vue 69 | 70 | // Or... 71 | 72 | php artisan breeze:install react 73 | 74 | npm install 75 | npm run dev 76 | php artisan migrate 77 | ``` 78 | 79 | 80 | 81 | ### Breeze & Next.js / API 82 | 83 | Laravel Breeze также может формировать API аутентификации, готовый для аутентификации современных приложений JavaScript, таких, как те, которые работают на [Next](https://nextjs.org), [Nuxt](https://nuxtjs.org) и других. Для начала укажите стек `api` в качестве желаемого стека при выполнении Artisan-команды `breeze:install`: 84 | 85 | ```nothing 86 | php artisan breeze:install api 87 | 88 | php artisan migrate 89 | ``` 90 | 91 | Во время установки Breeze добавит переменную среды `FRONTEND_URL` в файл `.env` вашего приложения. Этот URL-адрес должен быть URL-адресом вашего приложения JavaScript. Обычно во время локальной разработки это будет `http://localhost:3000`. 92 | 93 | 94 | #### Эталонная реализация Next.js 95 | 96 | Наконец, вы готовы связать этот бэкэнд с выбранным вами интерфейсом. Следующая эталонная реализация интерфейса Breeze [доступна на GitHub](https://github.com/laravel/breeze-next). Этот интерфейс поддерживается Laravel и содержит тот же пользовательский интерфейс, что и традиционные стеки Blade и Inertia, предоставляемые Breeze. 97 | 98 | 99 | ## Laravel Jetstream 100 | 101 | В то время как Laravel Breeze обеспечивает простую и минимальную отправную точку для создания приложения Laravel, Jetstream дополняет эту функциональность более надежными функциями и дополнительными стеками технологий клиентского интерфейса. **Для тех, кто новичок в Laravel, мы рекомендуем изучить основы работы с Laravel Breeze перед тем, как перейти на Laravel Jetstream.** 102 | 103 | Jetstream предлагает красиво оформленный каркас приложений для Laravel и включает в себя вход в систему, регистрацию, подтверждение адреса электронной почты, двухфакторную аутентификацию, управление сессиями, поддержку API через Laravel Sanctum, и дополнительно, управление командой. Jetstream разработан с использованием [Tailwind CSS](https://tailwindcss.com) и предлагает на ваш выбор каркас клиентского интерфейса под управлением [Livewire](https://laravel-livewire.com) либо [Inertia.js](https://inertiajs.com). 104 | 105 | Полное описание по установке Laravel Jetstream можно найти в [официальной документации Jetstream](https://jetstream.laravel.com/2.x/introduction.html). 106 | -------------------------------------------------------------------------------- /csrf.md: -------------------------------------------------------------------------------- 1 | git 1ca38aade2baea9b663c3524846f6f5b7d1e27bf 2 | 3 | --- 4 | 5 | # Предотвращение атак CSRF 6 | 7 | - [Введение](#csrf-introduction) 8 | - [Предотвращение запросов CSRF](#preventing-csrf-requests) 9 | - [Исключение URI из защиты от CSRF](#csrf-excluding-uris) 10 | - [Токен X-CSRF](#csrf-x-csrf-token) 11 | - [Токен X-XSRF](#csrf-x-xsrf-token) 12 | 13 | 14 | ## Введение 15 | 16 | Межсайтовая подделка запроса – это разновидность вредоносного эксплойта, при котором неавторизованные команды выполняются от имени аутентифицированного пользователя. К счастью, Laravel позволяет легко защитить ваше приложение от [Межсайтовой подделки запроса](https://ru.wikipedia.org/wiki/Межсайтовая_подделка_запроса) ([Cross Site Request Forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery) – CSRF). 17 | 18 | 19 | #### Объяснение уязвимости 20 | 21 | Если вы не знакомы с Межсайтовой подделкой запросов, то давайте обсудим пример того, как можно использовать эту уязвимость. Представьте, что ваше приложение имеет маршрут `/user/email`, который принимает `POST`-запрос для изменения адреса электронной почты аутентифицированного пользователя. Скорее всего, этот маршрут ожидает, что поле ввода `email` будет содержать адрес электронной почты, который пользователь хотел бы начать использовать. 22 | 23 | Без защиты от CSRF вредоносный веб-сайт может создать HTML-форму, которая указывает на маршрут вашего приложения `/user/email` и отправляет собственный адрес электронной почты злоумышленника: 24 | 25 |
26 | 27 |
28 | 29 | 32 | 33 | Если вредоносный веб-сайт автоматически отправляет форму при загрузке страницы, злоумышленнику нужно только подтолкнуть ничего не подозревающего пользователя вашего приложения посетить свой веб-сайт, и его адрес электронной почты будет изменен в вашем приложении. 34 | 35 | Чтобы предотвратить эту уязвимость, нам необходимо проверять каждый входящий запрос `POST`, `PUT`, `PATCH`, или `DELETE` на секретное значение сессии, к которому вредоносное приложение не может получить доступ. 36 | 37 | 38 | ## Предотвращение запросов CSRF 39 | 40 | Laravel автоматически генерирует «токен» CSRF для каждой активной [пользовательской сессии](/docs/{{version}}/session), управляемой приложением. Этот токен используется для проверки того, что аутентифицированный пользователь действительно является лицом, выполняющим запросы к приложению. Поскольку этот токен хранится в сессии пользователя и изменяется каждый раз при повторном создании сессии, вредоносное приложение не может получить к нему доступ. 41 | 42 | К CSRF-токену текущей сессии можно получить доступ через сессию запроса или с помощью глобального помощника `csrf_token`: 43 | 44 | use Illuminate\Http\Request; 45 | 46 | Route::get('/token', function (Request $request) { 47 | $token = $request->session()->token(); 48 | 49 | $token = csrf_token(); 50 | 51 | // ... 52 | }); 53 | 54 | Каждый раз, когда вы создаете HTML-форму «POST», «PUT», «PATCH» или «DELETE» в своем приложении, вы должны включать в форму скрытое поле `_token` CSRF, чтобы посредник CSRF мог проверить запрос. Для удобства вы можете использовать директиву Blade `@csrf` для создания скрытого поля ввода, содержащего токен: 55 | 56 |
57 | @csrf 58 | 59 | 60 | 61 |
62 | 63 | [Посредник](/docs/{{version}}/middleware) `App\Http\Middleware\VerifyCsrfToken`, который по умолчанию стоит в группе посредников `web`, автоматически проверяет соответствие токена во входном запросе и токен, хранящийся в сессии. Когда эти два токена совпадают, мы знаем, что запрос инициирует аутентифицированный пользователь. 64 | 65 | 66 | ### CSRF-токены и SPA-приложения 67 | 68 | Если вы создаете SPA, который использует Laravel в качестве серверной части API, вам следует обратиться к [документации Laravel Sanctum](/docs/{{version}}/sanctum) для получения информации об аутентификации с помощью вашего API и защите от уязвимостей CSRF. 69 | 70 | 71 | ### Исключение URI из защиты от CSRF 72 | 73 | По желанию можно исключить набор URI из защиты от CSRF. Например, если вы используете [Stripe](https://stripe.com) для обработки платежей и используете их систему веб-хуков, вам нужно будет исключить маршрут обработчика веб-хуков Stripe из защиты от CSRF, поскольку Stripe не будет знать, какой токен CSRF отправить вашим маршрутам. 74 | 75 | Как правило, вы должны размещать эти виды маршрутов вне группы посредников `web`, которую `App\Providers\RouteServiceProvider` применяет ко всем маршрутам в файле `routes/web.php`. Однако, вы также можете исключить маршруты, добавив их URI в свойство `$except` посредника `VerifyCsrfToken`: 76 | 77 | {tip} Для удобства посредник CSRF автоматически отключается для всех маршрутов при [выполнении тестов](/docs/{{version}}/testing). 98 | 99 | 100 | ## Токен X-CSRF 101 | 102 | В дополнение к проверке токена CSRF в качестве параметра POST-запроса посредник `App\Http\Middleware\VerifyCsrfToken` также проверяет заголовок запроса `X-CSRF-TOKEN`. Вы можете, например, сохранить токен в HTML-теге `meta`: 103 | 104 | 105 | 106 | Затем, вы можете указать библиотеке, такой как jQuery, автоматически добавлять токен во все заголовки запросов. Это обеспечивает простую и удобную защиту от CSRF для ваших приложений с использованием устаревшей технологии JavaScript на основе AJAX: 107 | 108 | $.ajaxSetup({ 109 | headers: { 110 | 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') 111 | } 112 | }); 113 | 114 | 115 | ## Токен X-XSRF 116 | 117 | Laravel хранит текущий токен CSRF в зашифрованном файле Cookies `XSRF-TOKEN`, который содержится в каждом ответе, генерируемым фреймворком. Вы можете использовать значение Cookies для установки заголовка запроса `X-XSRF-TOKEN`. 118 | 119 | Этот файл Cookies, в первую очередь, отправляется для удобства разработчика, поскольку некоторые фреймворки и библиотеки JavaScript, такие, как Angular и Axios, автоматически помещают его значение в заголовок `X-XSRF-TOKEN` в запросах с одним и тем же источником. 120 | 121 | > {tip} По умолчанию файл `resources/js/bootstrap.js` включает HTTP-библиотеку Axios, которая автоматически отправляет заголовок `X-XSRF-TOKEN`. 122 | -------------------------------------------------------------------------------- /lifecycle.md: -------------------------------------------------------------------------------- 1 | git 3997418dec9e03d10bfefb1620ff51a34fb10b0b 2 | 3 | --- 4 | 5 | # Жизненный цикл запроса 6 | 7 | - [Введение](#introduction) 8 | - [Обзор жизненного цикла](#lifecycle-overview) 9 | - [Первые шаги](#first-steps) 10 | - [HTTP-ядро и ядро консоли](#http-console-kernels) 11 | - [Поставщики служб](#service-providers) 12 | - [Маршрутизация](#routing) 13 | - [Окончание](#finishing-up) 14 | - [Сосредоточьтесь на поставщиках служб](#focus-on-service-providers) 15 | 16 | 17 | ## Введение 18 | 19 | При использовании любого инструмента в «реальном мире» вы чувствуете себя более уверенно, если понимаете, как работает этот инструмент. Разработка приложений ничем не отличается. Вы чувствуете себя более комфортно и уверенно, когда понимаете, как работают используемые вами инструменты разработки. 20 | 21 | Цель этого документа – дать вам хороший общий обзор того, как работает фреймворк Laravel. Если вы лучше узнаете общую структуру, то все станет менее «волшебным», и вы будете более уверены при создании своих приложений. Если вы не сразу поняли все термины, то не унывайте! Просто попытайтесь получить общее представление о том, что происходит, и ваши знания будут расти по мере изучения других разделов документации. 22 | 23 | 24 | ## Обзор жизненного цикла 25 | 26 | 27 | ### Первые шаги 28 | 29 | Точкой входа для всех запросов к приложению Laravel является файл `public/index.php`. Все запросы направляются в этот файл конфигурацией вашего веб-сервера (Apache / Nginx). Файл `index.php` не содержит большого количества кода. Скорее, это отправная точка для загрузки остальной части фреймворка. 30 | 31 | Файл `index.php` загружает автозагрузчик, созданный менеджером пакетов Composer, а затем извлекает экземпляр приложения Laravel из `bootstrap/app.php`. Первым действием, предпринимаемым самим Laravel, является создание экземпляра приложения / [контейнера служб](/docs/{{version}}/container). 32 | 33 | 34 | ### HTTP-ядро и ядро консоли 35 | 36 | Затем входящий запрос отправляется либо HTTP-ядру, либо ядру консоли, в зависимости от типа запроса, поступающего в приложение. Эти два ядра служат центральным местом, через которое проходят все запросы. А пока давайте сосредоточимся на ядре HTTP, которое находится в `app/Http/Kernel.php`. 37 | 38 | HTTP-ядро расширяет класс `Illuminate\Foundation\Http\Kernel`, который определяет массив загрузчиков (`bootstrappers`), запускающихся до выполнения запроса. Эти загрузчики настраивают обработку ошибок, логирование, [определяют среду приложения](/docs/{{version}}/configuration#environment-configuration) и выполняют другие задачи, которые необходимо выполнить до фактической обработки запроса. Обычно эти классы обращаются ко внутренней конфигурации Laravel, о которой вам не нужно беспокоиться. 39 | 40 | Ядро HTTP также определяет список [HTTP-посредников](/docs/{{version}}/middleware), через которые должны пройти все запросы, прежде чем они будут обработаны приложением. Эти посредники обрабатывают чтение и запись [HTTP-сессий](/docs/{{version}}/session), определяют, находится ли приложение в режиме обслуживания, [проверяют токен CSRF](/docs/{{version}}/csrf) и многое другое. Мы поговорим об этом позже. 41 | 42 | Сигнатура метода `handle` HTTP-ядра довольно проста: он получает запрос (`Request`) и возвращает ответ (`Response`). Думайте о ядре как о большом черном ящике, который представляет все ваше приложение. Дайте ему HTTP-запросы, и он вернет HTTP-ответы. 43 | 44 | 45 | #### Поставщики служб 46 | 47 | Одним из наиболее важных действий начальной загрузки ядра является загрузка [поставщиков служб](/docs/{{version}}/providers) вашего приложения. Все поставщики служб приложения настраиваются в массиве `providers` конфигурационного файла `config/app.php`. 48 | 49 | Laravel будет перебирать этот список поставщиков и создавать экземпляры каждого из них. После создания экземпляров поставщиков, будет вызван метод `register` всех поставщиков. Затем, как только все поставщики будут зарегистрированы, будет вызван метод `boot` каждого из них. Это сделано для того, чтобы те поставщики служб, которые имеют зависимости от других поставщиков, могли быть вызваны гарантированно после создания своих зависимостей, вызываемых в методе `boot`. 50 | 51 | Поставщики служб несут ответственность за загрузку всевозможных компонентов инфраструктуры, таких как компоненты БД, очереди, валидации и маршрутизации. По сути, каждая основная функция Laravel загружается и настраивается поставщиком служб. Поскольку они запускают и настраивают так много функций, предлагаемых фреймворком, поставщики служб являются наиболее важным аспектом всего процесса начальной загрузки Laravel. 52 | 53 | 54 | ### Маршрутизация 55 | 56 | Одним из наиболее важных поставщиков служб в вашем приложении является `App\Providers\RouteServiceProvider`. Этот поставщик загружает файлы маршрутов, содержащиеся в каталоге `routes` приложения. Откройте код `RouteServiceProvider` и посмотрите, как он работает! 57 | 58 | После того как приложение было загружено и все поставщики служб зарегистрированы, `Request` будет передан маршрутизатору для исполнения. Маршрутизатор отправит запрос на маршрут или контроллер, а также запустит посредник для конкретного маршрута. 59 | 60 | Посредники обеспечивают удобный механизм фильтрации или интерпретации HTTP-запросов, поступающих в ваше приложение. Например, Laravel содержит посредника, который проверяет аутентификацию пользователя вашего приложения. Если пользователь не аутентифицирован, посредник перенаправит пользователя, например, на экран входа в систему. Однако, если пользователь аутентифицирован, посредник позволит запросу продолжить работу в приложении. Некоторые посредники назначаются всем маршрутам в приложении, например, определенным в свойстве `$middleware` вашего ядра HTTP, тогда как некоторые назначаются только для определенных маршрутов или групп маршрутов. Вы можете узнать больше о посредниках, прочитав полную [документацию по посредникам](/docs/{{version}}/middleware). 61 | 62 | Если запрос проходит через всех посредников, назначенных определенному маршруту, то метод маршрута или контроллера будет выполнен, а ответ, возвращенный методом маршрута или контроллера, будет отправлен обратно через цепочку посредников маршрута. 63 | 64 | 65 | ### Окончание 66 | 67 | Когда метод маршрута или контроллера вернет ответ, тогда ответ отправится обратно через посредников маршрута, обеспечивая приложению возможность изменения или проверки исходящего ответа. 68 | 69 | Наконец, как только ответ проходит через посредников, метод `handle` ядра HTTP возвращает объект ответа, а файл `index.php` вызывает метод `send` для возвращенного ответа. Метод `send` отправляет содержимое ответа в веб-браузер пользователя. Мы завершили наш путь через весь жизненный цикл запроса Laravel! 70 | 71 | 72 | ## Сосредоточьтесь на поставщиках служб 73 | 74 | Поставщики служб действительно являются ключом к начальной загрузке приложения Laravel. Экземпляр приложения создается, поставщики служб регистрируются, и запрос передается загружаемому приложению. Это действительно так просто! 75 | 76 | Очень важно иметь четкое представление о том, как создается и загружается приложение Laravel через поставщиков служб. Поставщики служб для вашего приложения хранятся в каталоге `app/Providers`. 77 | 78 | По умолчанию поставщик `AppServiceProvider` относительно пуст. Этот поставщик является отличным местом для добавления собственной инициализации и связываний контейнера служб вашего приложения. Для больших приложений вы можете создать несколько поставщиков, каждый из которых детализирует начальную загрузку для конкретных сервисов, используемых вашим приложением. 79 | -------------------------------------------------------------------------------- /deployment.md: -------------------------------------------------------------------------------- 1 | git 6ac13f37adbed3ce6a6532fd790f70bd731b8571 2 | 3 | --- 4 | 5 | # Развертывание 6 | 7 | - [Введение](#introduction) 8 | - [Требования к серверу](#server-requirements) 9 | - [Конфигурация сервера](#server-configuration) 10 | - [Nginx](#nginx) 11 | - [Оптимизация](#optimization) 12 | - [Оптимизация автозагрузчика](#autoloader-optimization) 13 | - [Оптимизация загрузки конфигурации](#optimizing-configuration-loading) 14 | - [Оптимизация загрузки маршрута](#optimizing-route-loading) 15 | - [Оптимизация загрузки шаблонов](#optimizing-view-loading) 16 | - [Режим отладки](#debug-mode) 17 | - [Развертывание с помощью Forge / Vapor](#deploying-with-forge-or-vapor) 18 | 19 | 20 | ## Введение 21 | 22 | Когда вы будете готовы развернуть свое приложение Laravel в эксплуатационном окружении, вы должны сделать несколько важных вещей, чтобы убедиться, что ваше приложение работает максимально эффективно. В этой документации мы рассмотрим несколько отличных отправных точек, чтобы убедиться, что ваше приложение Laravel развернуто правильно. 23 | 24 | 25 | ## Требования к серверу 26 | 27 | Фреймворк Laravel имеет несколько системных требований. Вы должны убедиться, что ваш веб-сервер имеет следующую минимальную версию PHP и расширения: 28 | 29 | 30 | 31 | - PHP >= 7.3 32 | - Расширение PHP BCMath 33 | - Расширение PHP Ctype 34 | - Расширение PHP Fileinfo 35 | - Расширение PHP JSON 36 | - Расширение PHP Mbstring 37 | - Расширение PHP OpenSSL 38 | - Расширение PHP PDO 39 | - Расширение PHP Tokenizer 40 | - Расширение PHP XML 41 | 42 | 43 | 44 | 45 | ## Конфигурация сервера 46 | 47 | 48 | ### Nginx 49 | 50 | Если вы развертываете свое приложение на сервере, на котором работает Nginx, то вы можете использовать следующий конфигурационный файл в качестве отправной точки для настройки веб-сервера. Скорее всего, этот файл нужно будет настроить в зависимости от конфигурации вашего сервера. **Если вам нужна помощь в управлении вашим сервером, рассмотрите возможность использования собственной службы управления и развертывания серверов Laravel, такой как [Laravel Forge](https://forge.laravel.com).** 51 | 52 | Убедитесь, что, как и в конфигурации ниже, ваш веб-сервер направляет все запросы в файл `public/index.php` вашего приложения. Вы никогда не должны пытаться переместить файл `index.php` в корень вашего проекта, поскольку обслуживание приложения из корня проекта откроет доступ ко многим конфиденциальным файлам конфигурации из общедоступной сети Интернет: 53 | 54 | server { 55 | listen 80; 56 | listen [::]:80; 57 | server_name example.com; 58 | root /srv/example.com/public; 59 | 60 | add_header X-Frame-Options "SAMEORIGIN"; 61 | add_header X-Content-Type-Options "nosniff"; 62 | 63 | index index.php; 64 | 65 | charset utf-8; 66 | 67 | location / { 68 | try_files $uri $uri/ /index.php?$query_string; 69 | } 70 | 71 | location = /favicon.ico { access_log off; log_not_found off; } 72 | location = /robots.txt { access_log off; log_not_found off; } 73 | 74 | error_page 404 /index.php; 75 | 76 | location ~ \.php$ { 77 | fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; 78 | fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; 79 | include fastcgi_params; 80 | } 81 | 82 | location ~ /\.(?!well-known).* { 83 | deny all; 84 | } 85 | } 86 | 87 | 88 | ## Оптимизация 89 | 90 | 91 | ### Оптимизация автозагрузчика 92 | 93 | При развертывании в эксплуатационном окружении, убедитесь, что вы оптимизировали файл автозагрузчика классов Composer, чтобы он мог быстро найти нужный файл для загрузки конкретного класса: 94 | 95 | composer install --optimize-autoloader --no-dev 96 | 97 | > {tip} Помимо оптимизации автозагрузчика, вы всегда должны обязательно включать файл `composer.lock` в репозиторий системы управления версиями вашего проекта. Зависимости вашего проекта могут быть установлены намного быстрее, если присутствует файл `composer.lock`. 98 | 99 | 100 | ### Оптимизация загрузки конфигурации 101 | 102 | При развертывании вашего приложения в эксплуатационном окружении, вы должны убедиться, что вы выполнили команду `config:cache` Artisan в процессе развертывания: 103 | 104 | php artisan config:cache 105 | 106 | Эта команда объединит все файлы конфигурации Laravel в один кешированный файл, что значительно сократит количество обращений, которые фреймворк должен совершить к файловой системе при загрузке значений вашей конфигурации. 107 | 108 | > {note} Если вы выполняете команду `config:cache` в процессе развертывания, вы должны быть уверены, что вызываете функцию `env` только из ваших файлов конфигурации. После кеширования конфигурации файл `.env` не будет загружаться, и все вызовы функции `env` для переменных файла `.env` вернут `null`. 109 | 110 | 111 | ### Оптимизация загрузки маршрута 112 | 113 | Если вы создаете большое приложение с множеством маршрутов, вам следует убедиться, что вы выполнили команду `route:cache` Artisan в процессе развертывания: 114 | 115 | php artisan route:cache 116 | 117 | Эта команда сокращает регистрации всех маршрутов до одного вызова метода в кешированном файле, повышая производительность при регистрации сотен маршрутов. 118 | 119 | 120 | ### Оптимизация загрузки шаблонов 121 | 122 | При развертывании вашего приложения в эксплуатационном окружении, вы должны убедиться, что вы выполнили команду `view:cache` Artisan в процессе развертывания: 123 | 124 | php artisan view:cache 125 | 126 | Эта команда предварительно скомпилирует все ваши шаблоны Blade, чтобы они не компилировались во время запроса, повышая производительность каждого запроса, возвращающего шаблоном. 127 | 128 | 129 | ## Режим отладки 130 | 131 | Параметр отладки в файле конфигурации `config/app.php` определяет, сколько информации об ошибке фактически отображается пользователю. По умолчанию для этого параметра задано значение переменной среды `APP_DEBUG`, которая хранится в вашем файле `.env`. 132 | 133 | **В вашем эксплуатационном окружении это значение всегда должно быть `false`. Если значение для переменной `APP_DEBUG` установлено как `true`, то вы рискуете раскрыть конфиденциальные значения конфигурации конечным пользователям вашего приложения.** 134 | 135 | 136 | ## Развертывание с помощью Forge / Vapor 137 | 138 | 139 | #### Laravel Forge 140 | 141 | Если вы не совсем готовы управлять конфигурацией своего собственного сервера или вам неудобно настраивать все различные службы, необходимые для запуска надежного приложения Laravel, то [Laravel Forge](https://forge.laravel.com) – замечательная альтернатива. 142 | 143 | Laravel Forge может создавать серверы на различных поставщиках инфраструктуры, таких как DigitalOcean, Linode, AWS и других. Кроме того, Forge устанавливает и управляет всеми инструментами, необходимыми для создания надежных приложений Laravel, таких как Nginx, MySQL, Redis, Memcached, Beanstalk и других. 144 | 145 | 146 | #### Laravel Vapor 147 | 148 | Если вам нужна полностью бессерверная платформа развертывания с автоматическим масштабированием, настроенная для Laravel, ознакомьтесь с [Laravel Vapor](https://vapor.laravel.com). Laravel Vapor – это платформа для бессерверного развертывания Laravel, работающая на AWS. Запустите свою инфраструктуру Laravel на Vapor и влюбитесь в масштабируемую простоту бессерверной архитектуры. Laravel Vapor настроен создателями Laravel для бесперебойной работы с фреймворком, поэтому вы можете продолжать писать свои приложения Laravel точно так, как вы привыкли. 149 | -------------------------------------------------------------------------------- /contributions.md: -------------------------------------------------------------------------------- 1 | git 9871b627f83ecf235ff439e7599be0ca95b39623 2 | 3 | --- 4 | 5 | # Рекомендации по участию 6 | 7 | - [Отчеты об ошибках](#bug-reports) 8 | - [Вопросы поддержки](#support-questions) 9 | - [Обсуждение разработки ядра](#core-development-discussion) 10 | - [Какую ветку выбрать при запросах слияния?](#which-branch) 11 | - [Скомпилированные ресурсы исходников](#compiled-assets) 12 | - [Уязвимости безопасности](#security-vulnerabilities) 13 | - [Стиль кодирования](#coding-style) 14 | - [PHPDoc](#phpdoc) 15 | - [StyleCI](#styleci) 16 | - [Нормы поведения](#code-of-conduct) 17 | 18 | 19 | ## Отчеты об ошибках 20 | 21 | Чтобы стимулировать активное сотрудничество, Laravel настоятельно рекомендует запросы на слияние, а не только отчеты об ошибках. «Отчеты об ошибках» также могут быть отправлены в форме запроса на слияние, но содержащего тест с воспроизведением ошибки. Запросы на слияние будут рассматриваться только в том случае, если они помечены как «готовые к рассмотрению» (не в состоянии «черновик») и все тесты для новых функций пройдены. Устаревшие неактивные запросы на слияние, оставшиеся в состоянии «черновик», будут закрыты через несколько дней. 22 | 23 | Однако, если вы отправляете отчет об ошибке, ваш тикет о проблеме должен содержать заголовок и четкое описание проблемы. Вы также должны включить как можно больше релевантной информации и образец кода, демонстрирующий проблему. Цель отчета об ошибке – упростить для вас и окружающих воспроизведение ошибки и разработать исправления. 24 | 25 | Помните, отчеты об ошибках создаются в надежде, что другие с той же проблемой смогут сотрудничать с вами при ее решении. Не ожидайте, что отчет об ошибке автоматически сподвигнет на какие-либо действия или что другие будут прыгать, чтобы исправить ее. Создание отчета об ошибке поможет вам и другим начать работу по устранению проблемы. Если хотите внести свой вклад, то вы можете помочь, исправив [любые ошибки, перечисленные в нашем трекере тикетов ошибок](https://github.com/issues?q=is%3Aopen+is%3Aissue+label%3Abug+user%3Alaravel). Вы должны пройти аутентификацию в GitHub, чтобы просмотреть все проблемы Laravel. 26 | 27 | В управлении исходным кодом Laravel используется GitHub, и для каждого проекта есть репозитории: 28 | 29 | 30 | 31 | - [Приложение Laravel](https://github.com/laravel/laravel) 32 | - [Логотипы Laravel](https://github.com/laravel/art) 33 | - [Документация Laravel](https://github.com/laravel/docs) 34 | - [Пакет Laravel Dusk](https://github.com/laravel/dusk) 35 | - [Пакет Laravel Cashier Stripe](https://github.com/laravel/cashier) 36 | - [Пакет Laravel Cashier Paddle](https://github.com/laravel/cashier-paddle) 37 | - [Пакет Laravel Echo](https://github.com/laravel/echo) 38 | - [Пакет Laravel Envoy](https://github.com/laravel/envoy) 39 | - [Фреймворк Laravel](https://github.com/laravel/framework) 40 | - [Пакет Laravel Homestead](https://github.com/laravel/homestead) 41 | - [Скрипты для сборки Laravel Homestead](https://github.com/laravel/settler) 42 | - [Пакет Laravel Horizon](https://github.com/laravel/horizon) 43 | - [Пакет Laravel Jetstream](https://github.com/laravel/jetstream) 44 | - [Пакет Laravel Passport](https://github.com/laravel/passport) 45 | - [Пакет Laravel Sail](https://github.com/laravel/sail) 46 | - [Пакет Laravel Sanctum](https://github.com/laravel/sanctum) 47 | - [Пакет Laravel Scout](https://github.com/laravel/scout) 48 | - [Пакет Laravel Socialite](https://github.com/laravel/socialite) 49 | - [Пакет Laravel Telescope](https://github.com/laravel/telescope) 50 | - [Исходники официального сайта Laravel](https://github.com/laravel/laravel.com-next) 51 | 52 | 53 | 54 | 55 | ## Вопросы поддержки 56 | 57 | Трекеры с тикетами проблем Laravel на GitHub не предназначены для предоставления помощи или поддержки Laravel. Вместо этого используйте один из следующих каналов: 58 | 59 | 60 | 61 | - [Обсуждения на GitHub](https://github.com/laravel/framework/discussions) 62 | - [Форум Laracasts](https://laracasts.com/discuss) 63 | - [Форум Laravel.io](https://laravel.io/forum) 64 | - [StackOverflow](https://stackoverflow.com/questions/tagged/laravel) 65 | - [Discord](https://discord.gg/laravel) 66 | - [Larachat](https://larachat.co) 67 | - [IRC](https://web.libera.chat/?nick=artisan&channels=#laravel) 68 | 69 | 70 | 71 | 72 | ## Обсуждение разработки ядра 73 | 74 | Вы можете предлагать новый функционал или улучшения к уже существующему поведению в репозитории фреймворка Laravel на [доске обсуждений GitHub](https://github.com/laravel/framework/discussions). Если вы предлагаете новый функционал, то, пожалуйста, будьте готовы реализовать по крайней мере часть кода, который потребуется для его завершения. 75 | 76 | Неформальное обсуждение ошибок, нового функционала и реализаций существующего происходит на канале `#internals` сервера [Laravel Discord](https://discord.gg/laravel). Тейлор Отвелл, сопровождающий Laravel, обычно присутствует на канале в будние дни с 8:00 до 17:00 (UTC-06:00 или Америка / Чикаго) и от случая к случаю – в остальное время. 77 | 78 | 79 | ## Какую ветку выбрать при запросах слияния? 80 | 81 | **Все** исправления ошибок следует отправлять в последнюю стабильную ветку. Исправления ошибок **никогда** не следует отправлять в ветку `master`, если они не исправляют функционал, которой присутствует только в следующем релизе. 82 | 83 | **Минорный** функционал, **полностью обратно совместимый** с текущим релизом, может быть отправлен в последнюю стабильную ветку. 84 | 85 | **Мажорный** новый функционал всегда следует отправлять в ветку `master`, содержащую предстоящий релиз. 86 | 87 | Если вы не уверены, квалифицируется ли ваш функционал как мажорный или минорный, то спросите Тейлора Отвелла на канале `#internals` сервера [Laravel Discord](https://discord.gg/laravel). 88 | 89 | 90 | ## Скомпилированные ресурсы исходников 91 | 92 | Если вы отправляете изменение, которое повлияет на скомпилированные файлы, например, касательно файлов в `resources/css` или` resources/js` репозитория `laravel/laravel`, то не включайте в коммит эти скомпилированные файлы. Из-за большого размера они не могут быть реально рассмотрены сопровождающим. Это может быть использовано как способ внедрения вредоносного кода в Laravel. Чтобы предотвратить это, все скомпилированные файлы будут сгенерированы и включены в коммит сопровождающими Laravel. 93 | 94 | 95 | ## Уязвимости безопасности 96 | 97 | Если вы обнаружите уязвимость в системе безопасности Laravel, отправьте электронное письмо Тейлору Отвеллу по адресу taylor@laravel.com. Все уязвимости безопасности будут незамедлительно устранены. 98 | 99 | 100 | ## Стиль кодирования 101 | 102 | Laravel следует стандарту кодирования [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide) и стандарту автозагрузки [PSR- 4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader). 103 | 104 | 105 | ### PHPDoc 106 | 107 | Ниже приведен пример валидного блока документации Laravel. Обратите внимание, что за атрибутом `@param` идут два пробела, тип аргумента, еще два пробела и, наконец, имя переменной: 108 | 109 | /** 110 | * Register a binding with the container. 111 | * 112 | * @param string|array $abstract 113 | * @param \Closure|string|null $concrete 114 | * @param bool $shared 115 | * @return void 116 | * 117 | * @throws \Exception 118 | */ 119 | public function bind($abstract, $concrete = null, $shared = false) 120 | { 121 | // 122 | } 123 | 124 | 125 | ### StyleCI 126 | 127 | Не волнуйтесь, если стиль вашего кода не идеален! [StyleCI](https://styleci.io/) автоматически объединит любые исправления стиля после слияния вашего запроса с репозиторием Laravel. Это позволяет нам сосредоточиться на содержании вашего вклада, а не на стиле кода. 128 | 129 | 130 | ## Нормы поведения 131 | 132 | Кодекс поведения Laravel основан на кодексе поведения Ruby. О любых нарушениях кодекса поведения можно сообщить Тейлору Отвеллу (taylor@laravel.com): 133 | 134 | 135 | 136 | - Участники будут терпимо относиться к противоположным взглядам. 137 | - Участники должны гарантировать, что их язык и действия не содержат личных нападок и пренебрежительных личных замечаний. 138 | - Толкуя слова и действия других, участники всегда должны исходить из добрых намерений. 139 | - Не допускается поведение, которое можно обоснованно считать преследованием. 140 | 141 | 142 | -------------------------------------------------------------------------------- /eloquent-serialization.md: -------------------------------------------------------------------------------- 1 | git 0ab96f0b7c55966f5402b99e37268a0e9dacd03e 2 | 3 | --- 4 | 5 | # Eloquent · Сериализация 6 | 7 | - [Введение](#introduction) 8 | - [Сериализация моделей и коллекций](#serializing-models-and-collections) 9 | - [Сериализация в массивы](#serializing-to-arrays) 10 | - [Сериализация в JSON](#serializing-to-json) 11 | - [Скрытие атрибутов из JSON](#hiding-attributes-from-json) 12 | - [Добавление значений в JSON](#appending-values-to-json) 13 | - [Сериализация Даты](#date-serialization) 14 | 15 | 16 | ## Введение 17 | 18 | При создании API-интерфейсов с использованием Laravel вам часто нужно преобразовывать свои модели и отношения в массивы или JSON. Eloquent включает удобные методы для выполнения этих преобразований, а также для управления тем, какие атрибуты включаются в сериализованное представление ваших моделей. 19 | 20 | > {tip} Чтобы получить еще более надежный способ обработки JSON-сериализации модели Eloquent и коллекции, ознакомьтесь с документацией на [Ресурсы API Eloquent](/docs/{{version}}/eloquent-resources). 21 | 22 | 23 | ## Сериализация моделей и коллекций 24 | 25 | 26 | ### Сериализация в массивы 27 | 28 | Чтобы преобразовать модель и ее загруженные [отношения](/docs/{{version}}/eloquent-relationships) в массив, вы должны использовать метод `toArray`. Этот метод является рекурсивным, поэтому все атрибуты и все отношения (включая отношения отношений) будут преобразованы в массивы: 29 | 30 | use App\Models\User; 31 | 32 | $user = User::with('roles')->first(); 33 | 34 | return $user->toArray(); 35 | 36 | Метод `attributesToArray` используется для преобразования атрибутов модели в массив, но не его отношений: 37 | 38 | $user = User::first(); 39 | 40 | return $user->attributesToArray(); 41 | 42 | Вы также можете преобразовать целые [коллекции](/docs/{{version}}/eloquent-collections) моделей в массивы, вызвав метод `toArray` экземпляра коллекции: 43 | 44 | $users = User::all(); 45 | 46 | return $users->toArray(); 47 | 48 | 49 | ### Сериализация в JSON 50 | 51 | Чтобы преобразовать модель в JSON, вы должны использовать метод `toJson`. Как и `toArray`, метод `toJson` является рекурсивным, поэтому все атрибуты и отношения будут преобразованы в JSON. Вы также можете указать любые параметры кодировки JSON, которые [поддерживаются PHP](https://www.php.net/manual/ru/function.json-encode.php): 52 | 53 | use App\Models\User; 54 | 55 | $user = User::find(1); 56 | 57 | return $user->toJson(); 58 | 59 | return $user->toJson(JSON_PRETTY_PRINT); 60 | 61 | В качестве альтернативы вы можете преобразовать модель или коллекцию в строку, которая автоматически вызовет метод `toJson` модели или коллекции: 62 | 63 | return (string) User::find(1); 64 | 65 | Поскольку модели и коллекции преобразуются в JSON при преобразовании в строку, вы можете возвращать объекты Eloquent непосредственно из маршрутов или контроллеров вашего приложения. Laravel автоматически сериализует ваши модели и коллекции Eloquent в JSON, когда они возвращаются из маршрутов или контроллеров: 66 | 67 | Route::get('users', function () { 68 | return User::all(); 69 | }); 70 | 71 | 72 | #### Отношения 73 | 74 | Когда модель Eloquent преобразуется в JSON, ее загруженные отношения автоматически включаются в качестве атрибутов в объект JSON. Кроме того, хотя методы-отношения Eloquent определены с использованием имен методов в «верблюжьей нотации», атрибут JSON отношения будет в «змеиной нотации». 75 | 76 | 77 | ## Скрытие атрибутов из JSON 78 | 79 | По желанию можно исключить атрибуты, такие как пароли, содержащиеся в массиве модели или представлении JSON. Для этого добавьте в модель свойство `$hidden`. Атрибуты, перечисленные в массиве свойств `$hidden`, не будут включены в сериализованное представление модели: 80 | 81 | {tip} Чтобы скрыть отношения, добавьте имя метода-отношения к свойству `$hidden` модели Eloquent. 98 | 99 | В качестве альтернативы вы можете использовать свойство `visible` для определения «разрешенного списка» атрибутов, которые должны быть включены в массив модели и представление JSON. Все атрибуты, отсутствующие в массиве `$visible`, будут скрыты при преобразовании модели в массив или JSON: 100 | 101 | 118 | #### Временное изменение видимости атрибута 119 | 120 | По желанию можно сделать некоторые обычно скрытые атрибуты видимыми на конкретном экземпляре модели, для этого используйте метод `makeVisible`. Метод `makeVisible` возвращает экземпляр модели: 121 | 122 | return $user->makeVisible('attribute')->toArray(); 123 | 124 | Аналогично, если вы хотите скрыть некоторые атрибуты, которые обычно видны, вы можете использовать метод `makeHidden`: 125 | 126 | return $user->makeHidden('attribute')->toArray(); 127 | 128 | 129 | ## Добавление значений в JSON 130 | 131 | Иногда при преобразовании моделей в массивы или JSON вы можете добавить атрибуты, которым нет соответствующего столбца в вашей базе данных. Для этого сначала определите [аксессоры](/docs/{{version}}/eloquent-mutators) для значения: 132 | 133 | attributes['admin'] === 'yes'; 149 | } 150 | } 151 | 152 | После создания аксессора добавьте имя атрибута к свойству `appends` модели. Обратите внимание, что на имена атрибутов обычно ссылаются в «змеиной нотации», даже если аксессор определяется с помощью «верблюжьей нотации»: 153 | 154 | 173 | #### Добавление во время запроса 174 | 175 | Во время выполнения скрипта вы можете указать экземпляру модели добавить дополнительные атрибуты с помощью метода `append`. Или вы можете использовать метод `setAppends`, чтобы переопределить весь массив добавленных свойств для конкретного экземпляра модели: 176 | 177 | return $user->append('is_admin')->toArray(); 178 | 179 | return $user->setAppends(['is_admin'])->toArray(); 180 | 181 | 182 | ## Сериализация Даты 183 | 184 | 185 | #### Настройка формата даты по умолчанию 186 | 187 | Вы можете настроить формат сериализации по умолчанию для всех дат вашей модели, переопределив метод `serializeDate` вашей модели. Этот метод не влияет на форматирование дат для их сохранения в базе данных: 188 | 189 | /** 190 | * Подготовить дату для сериализации массива / JSON. 191 | * 192 | * @param \DateTimeInterface $date 193 | * @return string 194 | */ 195 | protected function serializeDate(DateTimeInterface $date) 196 | { 197 | return $date->format('Y-m-d'); 198 | } 199 | 200 | 201 | #### Настройка формата даты для каждого атрибута 202 | 203 | Вы можете настроить формат сериализации отдельных атрибутов даты, указав формат даты при [объявлении типизации](/docs/{{version}}/eloquent-mutators#attribute-casting) модели: 204 | 205 | protected $casts = [ 206 | 'birthday' => 'date:Y-m-d', 207 | 'joined_at' => 'datetime:Y-m-d H:00', 208 | ]; 209 | -------------------------------------------------------------------------------- /eloquent-collections.md: -------------------------------------------------------------------------------- 1 | git 0114efaa616fc2853168f9fccfc072f9d11f7f43 2 | 3 | --- 4 | 5 | # Eloquent · Коллекции 6 | 7 | - [Введение](#introduction) 8 | - [Доступные методы](#available-methods) 9 | - [Пользовательские коллекции](#custom-collections) 10 | 11 | 12 | ## Введение 13 | 14 | Все методы Eloquent, которые возвращают более одного результата модели, будут возвращать экземпляры класса `Illuminate\Database\Eloquent\Collection`, включая результаты, полученные с помощью метода `get` или доступные через отношения. Объект коллекции Eloquent расширяет [базовую коллекцию](/docs/{{version}}/collections) Laravel, поэтому он естественным образом наследует десятки методов, использующих в работе текучий интерфейс с базовым массивом моделей Eloquent. Обязательно ознакомьтесь с документацией по коллекции Laravel, чтобы узнать все об этих полезных методах! 15 | 16 | Все коллекции также являются итераторами, что позволяет вам перебирать их, как если бы они были простыми массивами PHP: 17 | 18 | use App\Models\User; 19 | 20 | $users = User::where('active', 1)->get(); 21 | 22 | foreach ($users as $user) { 23 | echo $user->name; 24 | } 25 | 26 | Однако, как упоминалось ранее, коллекции намного мощнее массивов и предоставляют множество методов типа `map` / `reduce`, которые могут быть связаны с помощью интуитивно понятного интерфейса. Например, мы можем удалить все неактивные модели, а затем собрать имена оставшихся пользователей: 27 | 28 | $names = User::all()->reject(function ($user) { 29 | return $user->active === false; 30 | })->map(function ($user) { 31 | return $user->name; 32 | }); 33 | 34 | 35 | #### Преобразование коллекций Eloquent 36 | 37 | В то время как большинство методов коллекции Eloquent возвращают новый экземпляр коллекции Eloquent, методы `collapse`, `flatten`, `flip`, `keys`, `pluck`, и `zip` возвращают экземпляр [базовой коллекции](/docs/{{version}}/collections ). Аналогично, если метод `map` возвращает коллекцию, не содержащую никаких моделей Eloquent, она будет преобразована в экземпляр базовой коллекции. 38 | 39 | 40 | ## Доступные методы 41 | 42 | Все коллекции Eloquent расширяют базовый класс [коллекций Laravel](/docs/{{version}}/collections#available-methods); поэтому они наследуют все мощные методы, предоставляемые классом базовой коллекции. 43 | 44 | Кроме того, класс `Illuminate\Database\Eloquent\Collection` содержит расширенный набор методов, помогающих управлять коллекциями моделей. Большинство методов возвращают экземпляры `Illuminate\Database\Eloquent\Collection`; однако некоторые методы, такие как `modelKeys`, возвращают экземпляр `Illuminate\Support\Collection`. 45 | 46 | 56 | 57 | 58 | 59 | - [contains](#method-contains) 60 | - [diff](#method-diff) 61 | - [except](#method-except) 62 | - [find](#method-find) 63 | - [fresh](#method-fresh) 64 | - [intersect](#method-intersect) 65 | - [load](#method-load) 66 | - [loadMissing](#method-loadMissing) 67 | - [modelKeys](#method-modelKeys) 68 | - [makeVisible](#method-makeVisible) 69 | - [makeHidden](#method-makeHidden) 70 | - [only](#method-only) 71 | - [toQuery](#method-toquery) 72 | - [unique](#method-unique) 73 | 74 | 75 | 76 | 77 | #### `contains($key, $operator = null, $value = null)` 78 | 79 | Метод `contains` используется для определения того, содержится ли переданный экземпляр модели в коллекции. Этот метод принимает первичный ключ или экземпляр модели: 80 | 81 | $users->contains(1); 82 | 83 | $users->contains(User::find(1)); 84 | 85 | 86 | #### `diff($items)` 87 | 88 | Метод `diff` возвращает все модели, которых нет в переданной коллекции: 89 | 90 | use App\Models\User; 91 | 92 | $users = $users->diff(User::whereIn('id', [1, 2, 3])->get()); 93 | 94 | 95 | #### `except($keys)` 96 | 97 | Метод `except` возвращает все модели, у которых нет переданных первичных ключей: 98 | 99 | $users = $users->except([1, 2, 3]); 100 | 101 | 102 | #### `find($key)` 103 | 104 | Метод `find` возвращает модель, у которой есть первичный ключ, соответствующий переданному ключу. Если `$key` является экземпляром модели, `find` попытается вернуть модель, соответствующую первичному ключу. Если `$key` является массивом ключей, `find` вернет все модели, у которых есть первичный ключ в переданном массиве: 105 | 106 | $users = User::all(); 107 | 108 | $user = $users->find(1); 109 | 110 | 111 | #### `fresh($with = [])` 112 | 113 | Метод `fresh` извлекает из базы данных свежий экземпляр каждой модели в коллекции. Кроме того, будут загружены любые указанные отношения: 114 | 115 | $users = $users->fresh(); 116 | 117 | $users = $users->fresh('comments'); 118 | 119 | 120 | #### `intersect($items)` 121 | 122 | Метод `intersect` возвращает все модели, которые также присутствуют в переданной коллекции: 123 | 124 | use App\Models\User; 125 | 126 | $users = $users->intersect(User::whereIn('id', [1, 2, 3])->get()); 127 | 128 | 129 | #### `load($relations)` 130 | 131 | Метод `load` нетерпеливо загружает указанные отношения для всех моделей в коллекции: 132 | 133 | $users->load(['comments', 'posts']); 134 | 135 | $users->load('comments.author'); 136 | 137 | 138 | #### `loadMissing($relations)` 139 | 140 | Метод `loadMissing` нетерпеливо загружает указанные отношения для всех моделей в коллекции, если отношения еще не загружены: 141 | 142 | $users->loadMissing(['comments', 'posts']); 143 | 144 | $users->loadMissing('comments.author'); 145 | 146 | 147 | #### `modelKeys()` 148 | 149 | Метод `modelKeys` возвращает первичные ключи для всех моделей в коллекции: 150 | 151 | $users->modelKeys(); 152 | 153 | // [1, 2, 3, 4, 5] 154 | 155 | 156 | #### `makeVisible($attributes)` 157 | 158 | Метод `makeVisible` [делает видимыми атрибуты](/docs/{{version}}/eloquent-serialization#hiding-attributes-from-json), которые обычно «скрыты» для каждой модели коллекции: 159 | 160 | $users = $users->makeVisible(['address', 'phone_number']); 161 | 162 | 163 | #### `makeHidden($attributes)` 164 | 165 | Метод `makeHidden` [скрывает атрибуты](/docs/{{version}}/eloquent-serialization#hiding-attributes-from-json), которые обычно «видны» для каждой модели в коллекции: 166 | 167 | $users = $users->makeHidden(['address', 'phone_number']); 168 | 169 | 170 | #### `only($keys)` 171 | 172 | Метод `only` возвращает все модели с указанными первичными ключами: 173 | 174 | $users = $users->only([1, 2, 3]); 175 | 176 | 177 | #### `toQuery()` 178 | 179 | Метод `toQuery` возвращает экземпляр построителя запросов Eloquent, содержащий ограничение `whereIn` для первичных ключей модели коллекции: 180 | 181 | use App\Models\User; 182 | 183 | $users = User::where('status', 'VIP')->get(); 184 | 185 | $users->toQuery()->update([ 186 | 'status' => 'Administrator', 187 | ]); 188 | 189 | 190 | #### `unique($key = null, $strict = false)` 191 | 192 | Метод `unique` возвращает все уникальные модели в коллекции. Все модели того же типа с тем же первичным ключом, что и другая модель в коллекции, удаляются: 193 | 194 | $users = $users->unique(); 195 | 196 | 197 | ## Пользовательские коллекции 198 | 199 | Если вы хотите использовать пользовательский класс `Collection` при взаимодействии с конкретной моделью, вы можете определить метод `newCollection` модели: 200 | 201 | 19 | ## Введение 20 | 21 | Помимо типичной аутентификации на основе форм, Laravel также предлагает простой и удобный способ аутентификации через провайдеров OAuth с помощью [Laravel Socialite](https://github.com/laravel/socialite). Socialite в настоящее время поддерживает аутентификацию через Facebook, Twitter, LinkedIn, Google, GitHub, GitLab, и Bitbucket. 22 | 23 | > {tip} Адаптеры для других платформ перечислены на веб-сайте [Socialite Providers](https://socialiteproviders.com/), управляемом сообществом. 24 | 25 | 26 | ## Установка 27 | 28 | Чтобы начать работу с Socialite, используйте менеджер пакетов Composer, чтобы добавить пакет в зависимости вашего проекта: 29 | 30 | composer require laravel/socialite 31 | 32 | 33 | ## Обновление пакета Socialite 34 | 35 | При обновлении Socialite важно внимательно изучить [руководство по обновлению](https://github.com/laravel/socialite/blob/master/UPGRADE). 36 | 37 | 38 | ## Конфигурирование 39 | 40 | Перед использованием Socialite вам нужно будет добавить учетные данные для провайдеров OAuth, которые использует ваше приложение. Эти учетные данные должны быть размещены в файле конфигурации вашего приложения `config/services.php` и должны использовать ключ `facebook`, `twitter`, `linkedin`, `google`, `github`, `gitlab`, или `bitbucket`, в зависимости от провайдеров, которые требуются вашему приложению: 41 | 42 | 'github' => [ 43 | 'client_id' => env('GITHUB_CLIENT_ID'), 44 | 'client_secret' => env('GITHUB_CLIENT_SECRET'), 45 | 'redirect' => 'http://example.com/callback-url', 46 | ], 47 | 48 | > {tip} Если параметр `redirect` содержит относительный путь, то он будет автоматически преобразован в абсолютный URL. 49 | 50 | 51 | ## Аутентификация 52 | 53 | 54 | ### Маршрутизация 55 | 56 | Для аутентификации пользователей с помощью провайдера OAuth вам понадобятся два маршрута: один для перенаправления пользователя к провайдеру OAuth, а другой для получения обратного вызова от провайдера после аутентификации. Пример контроллера ниже демонстрирует реализацию обоих маршрутов: 57 | 58 | use Laravel\Socialite\Facades\Socialite; 59 | 60 | Route::get('/auth/redirect', function () { 61 | return Socialite::driver('github')->redirect(); 62 | }); 63 | 64 | Route::get('/auth/callback', function () { 65 | $user = Socialite::driver('github')->user(); 66 | 67 | // $user->token 68 | }); 69 | 70 | Метод `redirect` фасада `Socialite`, отвечает за перенаправление пользователя к провайдеру OAuth, в то время как метод `user` обрабатывает входящий запрос и получает информацию о пользователе от провайдера после его аутентификации. 71 | 72 | 73 | ### Аутентификация и хранение 74 | 75 | После того как пользователь был получен от поставщика OAuth, вы можете определить, существует ли пользователь в базе данных вашего приложения и [аутентифицировать пользователя](/docs/{{version}}/authentication#authenticate-a-user-instance). Если пользователь не существует в базе данных вашего приложения, вы обычно создаете новую запись в своей базе данных: 76 | 77 | use App\Models\User; 78 | use Illuminate\Support\Facades\Auth; 79 | use Laravel\Socialite\Facades\Socialite; 80 | 81 | Route::get('/auth/callback', function () { 82 | $githubUser = Socialite::driver('github')->user(); 83 | 84 | $user = User::where('github_id', $githubUser->id)->first(); 85 | 86 | if ($user) { 87 | $user->update([ 88 | 'github_token' => $githubUser->token, 89 | 'github_refresh_token' => $githubUser->refreshToken, 90 | ]); 91 | } else { 92 | $user = User::create([ 93 | 'name' => $githubUser->name, 94 | 'email' => $githubUser->email, 95 | 'github_id' => $githubUser->id, 96 | 'github_token' => $githubUser->token, 97 | 'github_refresh_token' => $githubUser->refreshToken, 98 | ]); 99 | } 100 | 101 | Auth::login($user); 102 | 103 | return redirect('/dashboard'); 104 | }); 105 | 106 | > {tip} Для получения дополнительной информации о том, какая информация о пользователях доступна от конкретных поставщиков OAuth, обратитесь к документации по [получению сведений о пользователе](#retrieving-user-details). 107 | 108 | 109 | ### Права доступа 110 | 111 | Перед перенаправлением пользователя вы также можете добавить дополнительные «права» к запросу аутентификации, используя метод `scopes`. Этот метод объединит все существующие права с указанными: 112 | 113 | use Laravel\Socialite\Facades\Socialite; 114 | 115 | return Socialite::driver('github') 116 | ->scopes(['read:user', 'public_repo']) 117 | ->redirect(); 118 | 119 | Вы можете перезаписать все существующие права в запросе аутентификации, используя метод `setScopes`: 120 | 121 | return Socialite::driver('github') 122 | ->setScopes(['read:user', 'public_repo']) 123 | ->redirect(); 124 | 125 | 126 | ### Необязательные параметры 127 | 128 | Некоторые провайдеры OAuth поддерживают необязательные параметры в запросе перенаправления. Чтобы включить в запрос любые необязательные параметры, вызовите метод `with` с ассоциативным массивом: 129 | 130 | use Laravel\Socialite\Facades\Socialite; 131 | 132 | return Socialite::driver('google') 133 | ->with(['hd' => 'example.com']) 134 | ->redirect(); 135 | 136 | > {note} При использовании метода `with` будьте осторожны, чтобы не передавать какие-либо зарезервированные ключевые слова, такие как `state` или `response_type`. 137 | 138 | 139 | ## Получение сведений о пользователе 140 | 141 | После того как пользователь будет перенаправлен обратно на ваш маршрут `callback` аутентификации, вы можете получить данные пользователя, используя метод `user` пакета Socialite. Объект пользователя, возвращаемый методом `user`, содержит множество свойств и методов, которые вы можете использовать для сохранения информации о пользователе в вашей собственной базе данных. Различные свойства и методы могут быть доступны в зависимости от версии провайдера OAuth, с которым вы выполняете аутентификацию, OAuth 1.0 или OAuth 2.0: 142 | 143 | use Laravel\Socialite\Facades\Socialite; 144 | 145 | Route::get('/auth/callback', function () { 146 | $user = Socialite::driver('github')->user(); 147 | 148 | // Провайдер OAuth 2.0 ... 149 | $token = $user->token; 150 | $refreshToken = $user->refreshToken; 151 | $expiresIn = $user->expiresIn; 152 | 153 | // Провайдер OAuth 1.0 ... 154 | $token = $user->token; 155 | $tokenSecret = $user->tokenSecret; 156 | 157 | // Все провайдеры ... 158 | $user->getId(); 159 | $user->getNickname(); 160 | $user->getName(); 161 | $user->getEmail(); 162 | $user->getAvatar(); 163 | }); 164 | 165 | 166 | #### Получение сведений о пользователе из токена (OAuth2) 167 | 168 | Если у вас уже есть действительный токен доступа пользователя, то вы можете получить его данные с помощью метода `userFromToken` пакета Socialite: 169 | 170 | use Laravel\Socialite\Facades\Socialite; 171 | 172 | $user = Socialite::driver('github')->userFromToken($token); 173 | 174 | 175 | #### Получение сведений о пользователе из токена и секретного ключа (OAuth1) 176 | 177 | Если у вас уже есть действительный токен и секретный ключ пользователя, то вы можете получить его данные с помощью метода `userFromTokenAndSecret` пакета Socialite: 178 | 179 | use Laravel\Socialite\Facades\Socialite; 180 | 181 | $user = Socialite::driver('twitter')->userFromTokenAndSecret($token, $secret); 182 | 183 | 184 | #### Аутентификация без сохранения состояния 185 | 186 | Метод `stateless` используется для отключения проверки состояния сессии. Это полезно при добавлении социальной аутентификации в API: 187 | 188 | use Laravel\Socialite\Facades\Socialite; 189 | 190 | return Socialite::driver('google')->stateless()->user(); 191 | 192 | > {note} Аутентификация без сохранения состояния недоступна для драйвера `twitter`, который использует OAuth 1.0 для аутентификации. 193 | -------------------------------------------------------------------------------- /testing.md: -------------------------------------------------------------------------------- 1 | git 5c1c29be353a06c6e7065c04ec90ab816bb2a7c9 2 | 3 | --- 4 | 5 | # Тестирование · Начало работы 6 | 7 | - [Введение](#introduction) 8 | - [Окружение](#environment) 9 | - [Создание тестов](#creating-tests) 10 | - [Запуск тестов](#running-tests) 11 | - [Параллельное выполнение тестов](#running-tests-in-parallel) 12 | 13 | 14 | ## Введение 15 | 16 | Laravel построен с учетом требований тестирования. Поддержка тестирования с помощью PHPUnit включена прямо из коробки, и файл `phpunit.xml` уже настроен для вашего приложения. Фреймворк также поставляется с удобными вспомогательными методами, позволяющими выразительно тестировать ваши приложения. 17 | 18 | По умолчанию каталог `tests` вашего приложения содержит два каталога: `Feature` и `Unit`. Модульные (юнит) тесты – это тесты, которые фокусируются на очень небольшой изолированной части вашего кода. Фактически, большинство модульных тестов, вероятно, сосредоточены на одном методе. Тесты в каталоге «Unit» тестов не загружают ваше приложение Laravel и, следовательно, не могут получить доступ к базе данных вашего приложения или другим службам фреймворка. 19 | 20 | Функциональные тесты могут тестировать большую часть вашего кода, включая взаимодействие нескольких объектов друг с другом, или даже целый HTTP-запрос, возвращающий JSON. **Как правило, большинство ваших тестов должны быть функциональными. Эти типы тестов обеспечивают максимальную уверенность в том, что ваша система в целом работает должным образом.** 21 | 22 | Файл `ExampleTest.php` находится в каталогах тестов `Feature` и `Unit`. После установки нового приложения Laravel выполните команды `vendor/bin/phpunit` или `php artisan test` из командной строки для запуска ваших тестов. 23 | 24 | 25 | ## Окружение 26 | 27 | При запуске тестов Laravel автоматически устанавливает [конфигурацию окружения](/docs/{{version}}/configuration#environment-configuration) в `testing` благодаря переменной окружения, определенной в файле `phpunit.xml`. Laravel во время тестирования также автоматически настраивает для сессии и кеша драйверы `array`, что означает, что во время тестирования данные сессии или кеша не сохраняются. 28 | 29 | При необходимости вы можете определять другие значения конфигурации среды тестирования. Переменные окружения `testing` могут быть настроены в файле `phpunit.xml`, но перед запуском тестов не забудьте очистить кеш конфигурации с помощью Artisan-команды `config:clear`. 30 | 31 | 32 | #### Переменная окружения `.env.testing` 33 | 34 | Кроме того, вы можете создать файл `.env.testing` в корне вашего проекта. Этот файл будет использоваться вместо `.env` при запуске тестов PHPUnit или выполнении команд Artisan с параметром `--env=testing`. 35 | 36 | 37 | #### Трейт `CreatesApplication` 38 | 39 | Laravel содержит трейт `CreatesApplication`, который применяется к базовому классу `TestCase` вашего приложения. Этот трейт содержит метод `createApplication`, который загружает приложение Laravel перед запуском ваших тестов. Важно, чтобы вы оставили этот трейт в его исходном месте, так как от него зависит некоторый функционал, например, функционал параллельного тестирования Laravel. 40 | 41 | 42 | ## Создание тестов 43 | 44 | Чтобы сгенерировать новый тест, используйте [Artisan](artisan)-команду `make:test`. Эта команда поместит новый класс теста в каталог `tests/Feature` вашего приложения: 45 | 46 | php artisan make:test UserTest 47 | 48 | Если вы хотите создать тест в каталоге `tests/Unit`, то используйте параметр `--unit` при выполнении команды `make:test`: 49 | 50 | php artisan make:test UserTest --unit 51 | 52 | Если вы хотите создать тест [Pest PHP](https://pestphp.com), вы можете указать параметр `--pest` для команды `make:test`: 53 | 54 | php artisan make:test UserTest --pest 55 | php artisan make:test UserTest --unit --pest 56 | 57 | > {tip} Заготовки тестов можно настроить с помощью [публикации заготовок](artisan#stub-customization). 58 | 59 | После того как тест был сгенерирован, вы можете определить методы тестирования, как обычно, используя [PHPUnit](https://phpunit.de). Чтобы запустить ваши тесты, выполните команду `vendor/bin/phpunit` или `php artisan test` из вашего терминала: 60 | 61 | assertTrue(true); 77 | } 78 | } 79 | 80 | > {note} Если вы определяете свои собственные методы `setUp` / `tearDown` в тестовом классе, обязательно вызывайте соответствующие методы `parent::setUp()` / `parent::tearDown()` родительского класса. 81 | 82 | 83 | ## Запуск тестов 84 | 85 | Как упоминалось ранее, после того, как вы написали тесты, вы можете запускать их с помощью `phpunit`: 86 | 87 | ./vendor/bin/phpunit 88 | 89 | В дополнение к команде `phpunit`, вы можете использовать команду `test` Artisan для запуска ваших тестов. Тестер Artisan отображает подробные отчеты о тестах для упрощения разработки и отладки: 90 | 91 | php artisan test 92 | 93 | Любые аргументы, которые могут быть переданы команде `phpunit`, также могут быть переданы команде Artisan `test`: 94 | 95 | php artisan test --testsuite=Feature --stop-on-failure 96 | 97 | 98 | 99 | ### Параллельное выполнение тестов 100 | 101 | По умолчанию Laravel и PHPUnit выполняют ваши тесты последовательно в рамках одного процесса. Однако вы можете значительно сократить время, необходимое для запуска тестов, за счет одновременного выполнения тестов в нескольких процессах. Для начала добавьте параметр `--parallel` при выполнении команды `test` Artisan: 102 | 103 | php artisan test --parallel 104 | 105 | По умолчанию Laravel создает столько процессов, сколько ядер ЦП доступно на вашем компьютере. Однако вы можете настроить количество процессов, используя параметр `--processes`: 106 | 107 | php artisan test --parallel --processes=4 108 | 109 | > {note} При параллельном запуске тестов некоторые параметры PHPUnit (такие, как `--do-not-cache-result`) могут быть недоступны. 110 | 111 | 112 | #### Параллельное тестирование и базы данных 113 | 114 | Laravel автоматически обрабатывает создание и миграцию тестовой базы данных для каждого параллельного процесса, в котором выполняются ваши тесты. К тестовым базам данных будет добавлен суффикс, уникальный для каждого процесса. Например, если у вас есть два параллельных тестовых процесса, Laravel создаст и будет использовать тестовые базы данных `your_db_test_1` и `your_db_test_2`. 115 | 116 | По умолчанию тестовые базы данных сохраняются между вызовами команды `test` Artisan, чтобы их можно было использовать снова при последующих вызовах `test`. Однако вы можете пересоздать их, используя параметр `--recreate-databases`: 117 | 118 | php artisan test --parallel --recreate-databases 119 | 120 | 121 | #### Хуки параллельного тестирования 122 | 123 | Иногда требуется подготовить определенные ресурсы, используемые тестами вашего приложения, чтобы их можно было безопасно использовать в нескольких процессах тестирования. 124 | 125 | Используя фасад `ParallelTesting`, вы можете указать код, который будет выполняться в `setUp` и `tearDown` процесса или тестового класса. Переданные замыкания получат переменные `$token` и `$testCase`, которые содержат токен процесса и текущий тестовый класс, соответственно: 126 | 127 | 168 | #### Доступ к токену процесса параллельного тестирования 169 | 170 | Если вы хотите получить доступ к «токену» текущего процесса из любого другого места в коде теста вашего приложения, то вы можете использовать метод `token`. Этот токен представляет собой уникальный строковый идентификатор для каждого из процессов тестирования и может использоваться для разделения [подготавливаемых ресурсов](#parallel-testing-hooks) процессов параллельного тестирования. Например, Laravel автоматически добавляет этот токен в конец тестовых баз данных, создаваемых каждым процессом параллельного тестирования: 171 | 172 | $token = ParallelTesting::token(); 173 | -------------------------------------------------------------------------------- /providers.md: -------------------------------------------------------------------------------- 1 | git 452b5680b3a434f6736003dd3e7011d270c08fe0 2 | 3 | --- 4 | 5 | # Сервис-провайдеры 6 | 7 | - [Введение](#introduction) 8 | - [Написание сервис-провайдеров](#writing-service-providers) 9 | - [Метод `register`](#the-register-method) 10 | - [Метод `boot`](#the-boot-method) 11 | - [Регистрация сервис-провайдеров](#registering-providers) 12 | - [Отложенные сервис-провайдеры](#deferred-providers) 13 | 14 | 15 | ## Введение 16 | 17 | Сервис-провайдеры – это центральное место начальной загрузки всех приложений Laravel. Ваше собственное приложение, а также все основные службы и сервисы Laravel загружаются через них. 18 | 19 | Но, что мы подразумеваем под «начальной загрузкой»? В общем, мы имеем в виду **регистрацию** элементов, включая регистрацию связываний контейнера служб (service container), слушателей событий (event listener), посредников (middleware) и даже маршрутов (route). Сервис-провайдеры являются центральным местом для конфигурирования приложения. 20 | 21 | Если вы откроете файл `config/app.php`, включенный в Laravel, вы увидите массив `'providers'`. Это все классы сервис-провайдеров, которые будут загружены вашим приложением. По умолчанию в этом массиве перечислены основные сервис-провайдеры Laravel. Они загружают основные компоненты Laravel, такие, как подсистема отправки почты, очередь, кеш и другие. Многие из этих провайдеров являются «отложенными», что означает, что они не будут загружаться при каждом запросе, а только тогда, когда предоставляемые ими службы действительно необходимы. 22 | 23 | В этой документации вы узнаете, как писать собственные сервис-провайдеры и регистрировать их в приложении Laravel. 24 | 25 | > {tip} Если вы хотите узнать больше о том, как Laravel обрабатывает запросы и работает изнутри, ознакомьтесь с нашей документацией по [жизненному циклу запроса](/docs/{{version}}/lifecycle) Laravel. 26 | 27 | 28 | ## Написание сервис-провайдеров 29 | 30 | Все сервис-провайдеры расширяют класс `Illuminate\Support\ServiceProvider`. Большинство сервис-провайдеров содержат метод `register` и `boot`. В рамках метода `register` следует **только связывать (bind) сущности в [контейнере служб](/docs/{{version}}/container)**. Никогда не следует пытаться зарегистрировать каких-либо слушателей событий, маршруты или что-то другое в методе `register`. 31 | 32 | Чтобы сгенерировать новый сервис-провайдер, используйте команду `make:provider` [Artisan](artisan): 33 | 34 | php artisan make:provider RiakServiceProvider 35 | 36 | 37 | ### Метод `register` 38 | 39 | Как упоминалось ранее, в рамках метода `register` следует только связывать сущности в [контейнере служб](/docs/{{version}}/container). Никогда не следует пытаться зарегистрировать слушателей событий, маршруты или что-то другое в методе `register`. В противном случае вы можете случайно воспользоваться подсистемой, чей сервис-провайдер еще не загружен. 40 | 41 | Давайте взглянем на рядовой сервис-провайдер приложения. В любом из методов сервис-провайдера у вас всегда есть доступ к свойству `$app`, которое обеспечивает доступ к контейнеру служб: 42 | 43 | app->singleton(Connection::class, function ($app) { 60 | return new Connection(config('riak')); 61 | }); 62 | } 63 | } 64 | 65 | Этот сервис-провайдер определяет только метод `register` и использует этот метод для указания, какая именно реализация `App\Services\Riak\Connection` будет применена в нашем приложении - при помощи контейнера служб. Если вы еще не знакомы с контейнером служб Laravel, ознакомьтесь с [его документацией](/docs/{{version}}/container). 66 | 67 | 68 | #### Свойства `bindings` и `singletons` 69 | 70 | Если ваш сервис-провайдер регистрирует много простых связываний, вы можете использовать свойства `bindings` и `singletons` вместо ручной регистрации каждого связывания контейнера. Когда сервис-провайдер загружается фреймворком, он автоматически проверяет эти свойства и регистрирует их связывания: 71 | 72 | DigitalOceanServerProvider::class, 92 | ]; 93 | 94 | /** 95 | * Все синглтоны контейнера, которые должны быть зарегистрированы. 96 | * 97 | * @var array 98 | */ 99 | public $singletons = [ 100 | DowntimeNotifier::class => PingdomDowntimeNotifier::class, 101 | ServerProvider::class => ServerToolsProvider::class, 102 | ]; 103 | } 104 | 105 | 106 | ### Метод `boot` 107 | 108 | Итак, что, если нам нужно зарегистрировать [компоновщик шаблонов](/docs/{{version}}/views#view-composers) в нашем сервис-провайдере? Это должно быть сделано в рамках метода `boot`. **Этот метод вызывается после регистрации всех остальных сервис-провайдеров**, что означает, что в этом месте у вас уже есть доступ ко всем другим службам, которые были зарегистрированы фреймворком: 109 | 110 | 133 | #### Внедрение зависимости в методе `boot` 134 | 135 | Вы можете указывать тип зависимостей в методе `boot` сервис-провайдера. [Контейнер служб](/docs/{{version}}/container) автоматически внедрит любые необходимые зависимости: 136 | 137 | use Illuminate\Contracts\Routing\ResponseFactory; 138 | 139 | /** 140 | * Загрузка любых служб приложения. 141 | * 142 | * @param \Illuminate\Contracts\Routing\ResponseFactory $response 143 | * @return void 144 | */ 145 | public function boot(ResponseFactory $response) 146 | { 147 | $response->macro('serialized', function ($value) { 148 | // 149 | }); 150 | } 151 | 152 | 153 | ## Регистрация сервис-провайдеров 154 | 155 | Все сервис-провайдеры регистрируются в файле конфигурации `config/app.php`. Этот файл содержит массив `providers`, в котором можно перечислить имена классов. По умолчанию в этом массиве перечислены основные сервис-провайдеры Laravel. Эти поставщики загружают основные компоненты Laravel, такие, как почтовая подсистема, очереди, кеш и другие. 156 | 157 | Чтобы зарегистрировать сервис-провайдер, добавьте его в массив: 158 | 159 | 'providers' => [ 160 | // Другие сервис-провайдеры 161 | 162 | App\Providers\ComposerServiceProvider::class, 163 | ], 164 | 165 | 166 | ## Отложенные сервис-провайдеры 167 | 168 | Если ваш сервис-провайдер регистрирует **только** связывания в [контейнере служб](/docs/{{version}}/container), вы можете отложить его регистрацию до тех пор, пока одно из зарегистрированных связываний не понадобится. Отсрочка загрузки такого сервис-провайдера повысит производительность вашего приложения, так как он не загружается из файловой системы при каждом запросе. 169 | 170 | Laravel составляет и сохраняет список всех служб, предоставляемых отложенными сервис-провайдерами, а также имя класса сервис-провайдера. Laravel загрузит сервис-провайдер только при необходимости в одной из этих служб. 171 | 172 | Чтобы отложить загрузку сервис-провайдера, реализуйте интерфейс `\Illuminate\Contracts\Support\DeferrableProvider`, описав метод `provides`. Метод `provides` должен вернуть связывания контейнера службы, регистрируемые данным классом: 173 | 174 | app->singleton(Connection::class, function ($app) { 192 | return new Connection($app['config']['riak']); 193 | }); 194 | } 195 | 196 | /** 197 | * Получить службы, предоставляемые поставщиком. 198 | * 199 | * @return array 200 | */ 201 | public function provides() 202 | { 203 | return [Connection::class]; 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /localization.md: -------------------------------------------------------------------------------- 1 | git 534aaa9e4789f0a6f5d55bc797f6a765f131cc63 2 | 3 | --- 4 | 5 | # Локализация интерфейса 6 | 7 | - [Введение](#introduction) 8 | - [Конфигурирование языка по умолчанию](#configuring-the-locale) 9 | - [Определение строк перевода](#defining-translation-strings) 10 | - [Использование коротких ключей](#using-short-keys) 11 | - [Использование строк перевода в качестве ключей](#using-translation-strings-as-keys) 12 | - [Получение строк перевода](#retrieving-translation-strings) 13 | - [Замена параметров в строках перевода](#replacing-parameters-in-translation-strings) 14 | - [Плюрализация](#pluralization) 15 | - [Переопределение языковых файлов пакета](#overriding-package-language-files) 16 | 17 | 18 | ## Введение 19 | 20 | Функционал локализации Laravel предоставляют удобный способ извлечения строк разных языков, что позволяет легко поддерживать мультиязычность интерфейса вашего приложения. 21 | 22 | Laravel предлагает два способа управления строками перевода. Во-первых, языковые строки могут храниться в файлах в каталоге `resources/lang`. В этом каталоге могут быть подкаталоги для каждого языка, поддерживаемого приложением. Это подход, который Laravel использует для управления строками перевода собственного функционала, например сообщений об ошибках валидации: 23 | 24 | /resources 25 | /lang 26 | /en 27 | messages.php 28 | /es 29 | messages.php 30 | 31 | Или строки перевода могут быть определены в файлах JSON, которые помещаются в каталог `resources/lang`. При таком подходе каждый язык, поддерживаемый вашим приложением, будет иметь соответствующий файл JSON в этом каталоге. Этот подход рекомендуется для приложений с большим количеством переводимых строк: 32 | 33 | /resources 34 | /lang 35 | en.json 36 | es.json 37 | 38 | Мы обсудим каждый подход по управлению строками перевода в этой документации. 39 | 40 | 41 | ### Конфигурирование языка по умолчанию 42 | 43 | Язык по умолчанию для вашего приложения хранится в параметре `locale` конфигурационного файла `config/app.php`. Вы можете изменить это значение в соответствии с потребностями вашего приложения. 44 | 45 | Вы можете изменить язык по умолчанию для одного HTTP-запроса во время выполнения, используя метод `setLocale` фасада `App`: 46 | 47 | use Illuminate\Support\Facades\App; 48 | 49 | Route::get('/greeting/{locale}', function ($locale) { 50 | if (! in_array($locale, ['en', 'es', 'fr'])) { 51 | abort(400); 52 | } 53 | 54 | App::setLocale($locale); 55 | 56 | // 57 | }); 58 | 59 | Вы можете указать «резервный язык», который будет использоваться, когда активный язык не содержит конкретной строки перевода. Как и язык по умолчанию, резервный язык также задается в конфигурационном файле `config/app.php`: 60 | 61 | 'fallback_locale' => 'en', 62 | 63 | 64 | #### Определение текущего языка 65 | 66 | Вы можете использовать методы `currentLocale` и `isLocale` фасада `App`, чтобы определить текущий язык или проверить соответствие указанного языка: 67 | 68 | use Illuminate\Support\Facades\App; 69 | 70 | $locale = App::currentLocale(); 71 | 72 | if (App::isLocale('en')) { 73 | // 74 | } 75 | 76 | 77 | ## Определение строк перевода 78 | 79 | 80 | ### Использование коротких ключей 81 | 82 | Обычно строки перевода хранятся в файлах в каталоге `resources/lang`. В этом каталоге должен быть подкаталог для каждого языка, поддерживаемого вашим приложением. Это подход, который Laravel использует для управления строками перевода собственного функционала, например сообщений об ошибках валидации: 83 | 84 | /resources 85 | /lang 86 | /en 87 | messages.php 88 | /es 89 | messages.php 90 | 91 | Все языковые файлы возвращают массив строк с ключами. Например: 92 | 93 | 'Welcome to our application!', 99 | ]; 100 | 101 | > {note} Для языков, отличающихся территориально, вы должны назвать языковые каталоги в соответствии со стандартом ISO 15897. Например, для британского английского следует использовать «en_GB», а не «en-gb». 102 | 103 | 104 | ### Использование строк перевода в качестве ключей 105 | 106 | Для приложений с большим количеством переводимых строк определение каждой строки с помощью «короткого ключа» может сбивать с толку при обращении к ключам в ваших шаблонах, и постоянно изобретать ключи для каждой строки перевода, поддерживаемой вашим приложением, затруднительно. 107 | 108 | По этой причине Laravel предлагает определение строк перевода с использованием переводимой строки в качестве ключа «по умолчанию». Файлы перевода, которые используют строки перевода в качестве ключей, хранятся как файлы JSON в каталоге `resources/lang`. Например, если ваше приложение имеет испанский перевод, то вы должны создать файл `resources/lang/es.json`: 109 | 110 | ```json 111 | { 112 | "I love programming.": "Me encanta programar." 113 | } 114 | ``` 115 | 116 | #### Конфликты ключей и имен файлов 117 | 118 | Вы не должны определять строковые ключи перевода, которые конфликтуют с именами файлов перевода. Например, перевод `__('Action')` для языка `NL` при условии существования файла `nl/action.php` и отсутствии файла `nl.json` приведет к тому, что переводчик Laravel вернет содержимое всего файла `nl/action.php`. 119 | 120 | 121 | ## Получение строк перевода 122 | 123 | Вы можете получить строки перевода из ваших языковых файлов с помощью глобального помощника `__`. Если вы используете «короткие ключи» для определения ваших строк перевода, то вы должны передать файл, содержащий ключ, и сам ключ в функцию `__`, используя «точечную нотацию». Например, давайте извлечем строку перевода `welcome` из языкового файла `resources/lang/en/messages.php`: 124 | 125 | echo __('messages.welcome'); 126 | 127 | Если указанная строка перевода не существует, то функция `__` вернет ключ строки перевода. Итак, используя приведенный выше пример, функция `__` вернет `messages.welcome`, если строка перевода не существует. 128 | 129 | Если вы используете свои [строки перевода в качестве ключей перевода](#using-translation-strings-as-keys), то вы должны передать перевод вашей строки по умолчанию в функцию `__`: 130 | 131 | echo __('I love programming.'); 132 | 133 | Опять же, если строка перевода не существует, то функция `__` вернет ключ строки перевода, который ей был передан. 134 | 135 | Если вы используете [шаблонизатор Blade](/docs/{{version}}/blade), то вы можете использовать синтаксис `{{}}` для вывода строки перевода: 136 | 137 | {{ __('messages.welcome') }} 138 | 139 | 140 | ### Замена параметров в строках перевода 141 | 142 | При желании вы можете определить метку-заполнитель в строках перевода. Все заполнители имеют префикс `:`. Например, вы можете определить приветственное сообщение с именем-заполнителем: 143 | 144 | 'welcome' => 'Welcome, :name', 145 | 146 | Чтобы заменить заполнители при получении строки перевода, вы можете передать массив для замены в качестве второго аргумента функции `__`: 147 | 148 | echo __('messages.welcome', ['name' => 'dayle']); 149 | 150 | Если все буквы заполнителя заглавные или заполнитель имеет только первую заглавную букву, то переведенное значение будет с соответствующим регистром: 151 | 152 | 'welcome' => 'Welcome, :NAME', // Welcome, DAYLE 153 | 'goodbye' => 'Goodbye, :Name', // Goodbye, Dayle 154 | 155 | 156 | ### Плюрализация 157 | 158 | Плюрализация – сложная задача, поскольку разные языки имеют множество сложных правил плюрализации; однако Laravel может помочь вам переводить строки по-разному в зависимости от правил множественного числа, которые вы определяете. Используя мета-символ `|`, вы можете различать формы единственного и множественного числа строки: 159 | 160 | 'apples' => 'There is one apple|There are many apples', 161 | 162 | Конечно, множественное число также поддерживается при использовании [строк перевода в качестве ключей](#using-translation-strings-as-keys): 163 | 164 | ```json 165 | { 166 | "There is one apple|There are many apples": "Hay una manzana|Hay muchas manzanas" 167 | } 168 | ``` 169 | 170 | Вы даже можете создать более сложные правила множественного числа, которые определяют строки перевода для нескольких диапазонов значений: 171 | 172 | 'apples' => '{0} There are none|[1,19] There are some|[20,*] There are many', 173 | 174 | После определения строки перевода, которая имеет параметры множественного числа, вы можете использовать функцию `trans_choice` для извлечения строки соответствующую указанному «количеству». В этом примере, поскольку количество больше единицы, возвращается форма множественного числа строки перевода: 175 | 176 | echo trans_choice('messages.apples', 10); 177 | 178 | Вы также можете определить метку-заполнитель в строках множественного числа. Эти заполнители могут быть заменены передачей массива в качестве третьего аргумента функции `trans_choice`: 179 | 180 | 'minutes_ago' => '{1} :value minute ago|[2,*] :value minutes ago', 181 | 182 | echo trans_choice('time.minutes_ago', 5, ['value' => 5]); 183 | 184 | Если вы хотите отобразить целочисленное значение, переданное в функцию `trans_choice`, то вы можете использовать встроенный заполнитель `:count`: 185 | 186 | 'apples' => '{0} There are none|{1} There is one|[2,*] There are :count', 187 | 188 | 189 | ## Переопределение языковых файлов пакета 190 | 191 | Некоторые пакеты могут содержать собственные языковые файлы. Вместо того чтобы изменять строки файлов пакета, вы можете переопределить их, поместив файлы в каталог `resources/lang/vendor/{package}/{locale}`. 192 | 193 | Так, например, если вам нужно переопределить строки перевода на английский в `messages.php` для пакета с именем `skyrim/hearthfire`, вы должны поместить языковой файл в каталог: `resources/lang/vendor/hearthfire/en/messages.php`. В этом файле вы должны определять только те строки перевода, которые хотите переопределить. Любые строки перевода, которые вы не меняете, все равно будут загружены из исходных языковых файлов пакета. 194 | -------------------------------------------------------------------------------- /urls.md: -------------------------------------------------------------------------------- 1 | git 34eb006893f9e86010025689656aa8cba0096687 2 | 3 | --- 4 | 5 | # Генерация URL-адресов 6 | 7 | - [Введение](#introduction) 8 | - [Основы](#the-basics) 9 | - [Создание URL](#generating-urls) 10 | - [Доступ к текущему URL](#accessing-the-current-url) 11 | - [URL для именованных маршрутов](#urls-for-named-routes) 12 | - [Подписанные URL](#signed-urls) 13 | - [URL для действий контроллера](#urls-for-controller-actions) 14 | - [Значения по умолчанию](#default-values) 15 | 16 | 17 | ## Введение 18 | 19 | Laravel предлагает несколько функций, которые помогут вам в создании URL-адресов для вашего приложения. Эти помощники в первую очередь полезны при построении ссылок в ваших шаблонах и ответах API или при создании ответов-перенаправлений в другую часть вашего приложения. 20 | 21 | 22 | ## Основы 23 | 24 | 25 | ### Создание URL 26 | 27 | Помощник `url` используется для генерации произвольных URL-адресов для вашего приложения. Сгенерированный URL-адрес будет автоматически использовать схему (HTTP или HTTPS) и хост из текущего запроса, обрабатываемого приложением: 28 | 29 | $post = App\Models\Post::find(1); 30 | 31 | echo url("/posts/{$post->id}"); 32 | 33 | // http://example.com/posts/1 34 | 35 | 36 | ### Доступ к текущему URL 37 | 38 | Если не передан путь помощнику `url`, то возвращается экземпляр `Illuminate\Routing\UrlGenerator`, позволяющий вам получить доступ к информации о текущем URL: 39 | 40 | // Получить текущий URL без строки запроса ... 41 | echo url()->current(); 42 | 43 | // Получить текущий URL, включая строку запроса ... 44 | echo url()->full(); 45 | 46 | // Получить полный URL-адрес предыдущего запроса ... 47 | echo url()->previous(); 48 | 49 | К каждому из этих методов также можно получить доступ через [фасад](/docs/{{version}}/facades) `URL`: 50 | 51 | use Illuminate\Support\Facades\URL; 52 | 53 | echo URL::current(); 54 | 55 | 56 | ## URL для именованных маршрутов 57 | 58 | Помощник `route` используется для генерации URL-адресов для [именованных маршрутов](/docs/{{version}}/routing#named-routes). Именованные маршруты позволяют создавать URL-адреса без привязки к фактическому URL-адресу, определенному в маршруте. Следовательно, если URL-адрес маршрута изменится, никаких изменений в ваши вызовы функции `route` вносить не нужно. Например, представьте, что ваше приложение содержит маршрут, определенный следующим образом: 59 | 60 | Route::get('/post/{post}', function (Post $post) { 61 | // 62 | })->name('post.show'); 63 | 64 | Чтобы сгенерировать URL-адрес этого маршрута, вы можете использовать помощник `route` следующим образом: 65 | 66 | echo route('post.show', ['post' => 1]); 67 | 68 | // http://example.com/post/1 69 | 70 | Конечно, помощник `route` также может использоваться для генерации URL-адресов для маршрутов с несколькими параметрами: 71 | 72 | Route::get('/post/{post}/comment/{comment}', function (Post $post, Comment $comment) { 73 | // 74 | })->name('comment.show'); 75 | 76 | echo route('comment.show', ['post' => 1, 'comment' => 3]); 77 | 78 | // http://example.com/post/1/comment/3 79 | 80 | Любые дополнительные элементы массива, не соответствующие параметрам определения маршрута, будут добавлены в строку запроса URL: 81 | 82 | echo route('post.show', ['post' => 1, 'search' => 'rocket']); 83 | 84 | // http://example.com/post/1?search=rocket 85 | 86 | 87 | #### Модели Eloquent 88 | 89 | Вы часто будете генерировать URL-адреса, используя ключ маршрута (обычно первичный ключ) [модели Eloquent](/docs/{{version}}/eloquent). По этой причине вы можете передавать модели Eloquent в качестве значений параметров. Помощник `route` автоматически извлечет ключ маршрута модели: 90 | 91 | echo route('post.show', ['post' => $post]); 92 | 93 | 94 | ### Подписанные URL 95 | 96 | Laravel позволяет вам легко создавать «подписанные» URL-адреса для именованных маршрутов. Эти URL-адреса имеют хеш «подписи», добавленный к строке запроса, который позволяет Laravel проверять, что URL-адрес не был изменен с момента его создания. Подписанные URL-адреса особенно полезны для маршрутов, которые общедоступны, но требуют уровня защиты от манипуляций с URL-адресами. 97 | 98 | Например, вы можете использовать подписанные URL-адреса для реализации общедоступной ссылки «отказаться от подписки», которая отправляется вашим клиентам по электронной почте. Чтобы создать подписанный URL для именованного маршрута, используйте метод `signedRoute` фасада `URL`: 99 | 100 | use Illuminate\Support\Facades\URL; 101 | 102 | return URL::signedRoute('unsubscribe', ['user' => 1]); 103 | 104 | Если вы хотите сгенерировать временный подписанный URL-адрес маршрута, срок действия которого истекает по истечении определенного времени, вы можете использовать метод `temporarySignedRoute`. Когда Laravel проверяет временный подписанный URL-адрес маршрута, он гарантирует, что метка времени истечения срока, закодированная в подписанный URL-адрес, не истекла: 105 | 106 | use Illuminate\Support\Facades\URL; 107 | 108 | return URL::temporarySignedRoute( 109 | 'unsubscribe', now()->addMinutes(30), ['user' => 1] 110 | ); 111 | 112 | 113 | #### Проверка запросов подписанного маршрута 114 | 115 | Чтобы убедиться, что входящий запрос имеет действительную подпись, вы должны вызвать метод `hasValidSignature` для входящего запроса `Request`: 116 | 117 | use Illuminate\Http\Request; 118 | 119 | Route::get('/unsubscribe/{user}', function (Request $request) { 120 | if (! $request->hasValidSignature()) { 121 | abort(401); 122 | } 123 | 124 | // ... 125 | })->name('unsubscribe'); 126 | 127 | В качестве альтернативы, вы можете назначить маршруту [посредник](/docs/{{version}}/middleware) `Illuminate\Routing\Middleware\ValidateSignature`. Если его еще нет, вы должны назначить этому посреднику ключ в массиве `routeMiddleware` в HTTP-ядре: 128 | 129 | /** 130 | * Посредники маршрутов приложения. 131 | * 132 | * Эти посредники могут быть групповыми или использоваться по отдельности. 133 | * 134 | * @var array 135 | */ 136 | protected $routeMiddleware = [ 137 | 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 138 | ]; 139 | 140 | После того как вы зарегистрировали посредников в ядре приложения, вы можете назначить его маршруту. Если входящий запрос не имеет действительной подписи, посредник автоматически вернет HTTP-ответ `403`: 141 | 142 | Route::post('/unsubscribe/{user}', function (Request $request) { 143 | // ... 144 | })->name('unsubscribe')->middleware('signed'); 145 | 146 | 147 | #### Ответ на недействительные подписанные маршруты 148 | 149 | Когда кто-то посещает подписанный URL-адрес, срок действия которого истек, он получит общую страницу с ошибкой для кода состояния `403` HTTP. Однако вы можете настроить это поведение, определив пользовательское «отображаемое» замыкание для исключения `InvalidSignatureException` в обработчике исключений. Это замыкание должно вернуть HTTP-ответ: 150 | 151 | use Illuminate\Routing\Exceptions\InvalidSignatureException; 152 | 153 | /** 154 | * Зарегистрируйте обратные вызовы обработки исключений для приложения. 155 | * 156 | * @return void 157 | */ 158 | public function register() 159 | { 160 | $this->renderable(function (InvalidSignatureException $e) { 161 | return response()->view('error.link-expired', [], 403); 162 | }); 163 | } 164 | 165 | 166 | ## URL для действий контроллера 167 | 168 | Функция `action` генерирует URL-адрес для переданного действия контроллера: 169 | 170 | use App\Http\Controllers\HomeController; 171 | 172 | $url = action([HomeController::class, 'index']); 173 | 174 | Если метод контроллера принимает параметры маршрута, вы можете передать ассоциативный массив параметров маршрута в качестве второго аргумента функции: 175 | 176 | $url = action([UserController::class, 'profile'], ['id' => 1]); 177 | 178 | 179 | ## Значения по умолчанию 180 | 181 | Для некоторых приложений вы можете указать значения по умолчанию для определенных параметров URL-адреса. Например, представьте, что многие из ваших маршрутов определяют параметр `{locale}`: 182 | 183 | Route::get('/{locale}/posts', function () { 184 | // 185 | })->name('post.index'); 186 | 187 | Обременительно передавать `locale` каждый раз при вызове помощника `route`. Итак, вы можете использовать метод `URL::defaults`, чтобы определить значение по умолчанию для этого параметра, которое всегда будет применяться во время текущего запроса. Вы можете вызвать этот метод из [посредника маршрута](/docs/{{version}}/middleware#assigning-middleware-to-routes), чтобы получить доступ к текущему запросу: 188 | 189 | $request->user()->locale]); 208 | 209 | return $next($request); 210 | } 211 | } 212 | 213 | После установки значения по умолчанию для параметра `locale` вам больше не потребуется передавать его значение при генерации URL-адресов с помощью помощника `route`. 214 | 215 | 216 | #### Параметры URL по умолчанию и приоритет посредника 217 | 218 | Установка значений URL по умолчанию может мешать Laravel обрабатывать неявные привязки модели. Следовательно, необходимо [установить приоритет посреднику](/docs/{{version}}/middleware#sorting-middleware), который задает значения URL по умолчанию, и должен выполняться перед посредником Laravel `SubstituteBindings`. Вы можете добиться этого, убедившись, что ваш посредник находится перед посредником `SubstituteBindings` в свойстве `$middlewarePriority` HTTP-ядра вашего приложения. 219 | 220 | Свойство `$middlewarePriority` определено в базовом классе `Illuminate\Foundation\Http\Kernel`. Вы можете скопировать его определение из этого класса и перезаписать его в HTTP-ядре вашего приложения, чтобы изменить приоритет: 221 | 222 | /** 223 | * Список посредников, отсортированный по приоритетности. 224 | * 225 | * Заставит неглобальных посредников всегда быть в заданном порядке. 226 | * 227 | * @var array 228 | */ 229 | protected $middlewarePriority = [ 230 | // ... 231 | \App\Http\Middleware\SetDefaultLocaleForUrls::class, 232 | \Illuminate\Routing\Middleware\SubstituteBindings::class, 233 | // ... 234 | ]; 235 | -------------------------------------------------------------------------------- /verification.md: -------------------------------------------------------------------------------- 1 | git e40c6670934574de22db31ad6e84c4a035d65c6c 2 | 3 | --- 4 | 5 | # Подтверждение адреса электронной почты 6 | 7 | - [Введение](#introduction) 8 | - [Подготовка модели](#model-preparation) 9 | - [Подготовка базы данных](#database-preparation) 10 | - [Маршрутизация](#verification-routing) 11 | - [Уведомление о подтверждении электронной почты](#the-email-verification-notice) 12 | - [Обработчик проверки электронной почты](#the-email-verification-handler) 13 | - [Повторная отправка письма с подтверждением](#resending-the-verification-email) 14 | - [Защита маршрутов](#protecting-routes) 15 | - [Настройка](#customization) 16 | - [События](#events) 17 | 18 | 19 | ## Введение 20 | 21 | Многие веб-приложения требуют от пользователей подтверждения своего адреса электронной почты перед использованием приложения. Вместо того чтобы заставлять вас самостоятельно реализовывать этот функционал повторно для каждого создаваемого вами приложения, Laravel предлагает удобные встроенные службы для отправки и проверки запросов подтверждения адреса электронной почты. 22 | 23 | > {tip} Хотите быстро начать? Установите один из [стартовых комплектов](starter-kits) в новое приложение Laravel. Стартовые комплекты позаботятся о построении всей вашей системы аутентификации, включая поддержку подтверждения электронной почты. 24 | 25 | 26 | ### Подготовка модели 27 | 28 | Убедитесь, что ваша модель `App\Models\User` реализует контракт `Illuminate\Contracts\Auth\MustVerifyEmail`: 29 | 30 | 54 | ### Подготовка базы данных 55 | 56 | Ваша таблица `users` должна содержать столбец` email_verified_at` для сохранения даты и времени подтверждения адреса электронной почты пользователем. По умолчанию миграция таблицы пользователей, содержащаяся в Laravel, уже содержит этот столбец. Просто запустите миграцию базы данных: 57 | 58 | php artisan migrate 59 | 60 | 61 | ## Маршрутизация 62 | 63 | Чтобы правильно реализовать подтверждение электронной почты, необходимо определить три маршрута. Во-первых, потребуется маршрут для отображения уведомления пользователю о том, что он должен щелкнуть ссылку подтверждения электронной почты в письме, которое Laravel отправит ему после регистрации. 64 | 65 | Во-вторых, потребуется маршрут для обработки запросов, сгенерированных, когда пользователь щелкает ссылку подтверждения электронной почты в электронном письме. 66 | 67 | В-третьих, потребуется маршрут для повторной отправки ссылки для подтверждения, если пользователь случайно потеряет первую ссылку для подтверждения. 68 | 69 | 70 | ### Уведомление о подтверждении электронной почты 71 | 72 | Как упоминалось ранее, должен быть определен маршрут, возвращающий страницу, инструктирующую пользователя щелкнуть ссылку для подтверждения электронной почты, которая была отправлена ему Laravel по электронной почте после регистрации. Эта страница будет отображаться для пользователей, когда они попытаются получить доступ к другим частям приложения без предварительной проверки своего адреса электронной почты. Помните, что ссылка автоматически отправляется пользователю по электронной почте, если ваша модель `App\Models\User` реализует интерфейс `MustVerifyEmail`: 73 | 74 | Route::get('/email/verify', function () { 75 | return view('auth.verify-email'); 76 | })->middleware('auth')->name('verification.notice'); 77 | 78 | Маршрут, который возвращает уведомление о подтверждении по электронной почте, должен называться `verification.notice`. Важно, чтобы маршруту было присвоено это точное имя, поскольку посредник `verify`, [включенный в Laravel](#protecting-routes), будет автоматически перенаправлять на это имя маршрута, если пользователь не подтвердил свой адрес электронной почты. 79 | 80 | > {tip} При выполнении проверки электронной почты самостоятельно, вам необходимо определить содержание страницы уведомления о проверке. Если вам необходим каркас, включающий все необходимые страницы для аутентификации и проверки, ознакомьтесь со [стартовыми комплектами приложений Laravel](starter-kits). 81 | 82 | 83 | ### Обработчик проверки электронной почты 84 | 85 | Затем, нам нужно определить маршрут, обрабатывающий запросы, сгенерированные, когда пользователь щелкает ссылку подтверждения электронной почты, которая была отправлена ему по электронной почте. Этот маршрут должен называться `verification.verify` и ему должны быть назначены посредники `auth` и `signed`: 86 | 87 | use Illuminate\Foundation\Auth\EmailVerificationRequest; 88 | 89 | Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) { 90 | $request->fulfill(); 91 | 92 | return redirect('/home'); 93 | })->middleware(['auth', 'signed'])->name('verification.verify'); 94 | 95 | Прежде чем двигаться дальше, давайте подробнее рассмотрим этот маршрут. Во-первых, вы заметите, что мы используем тип запроса `EmailVerificationRequest` вместо типичного экземпляра `Illuminate\Http\Request`. `EmailVerificationRequest` – это [запрос формы](/docs/{{version}}/validation#form-request-validation), который включен в Laravel. Этот запрос автоматически позаботится о проверке параметров запроса `id` и `hash`. 96 | 97 | Далее, мы можем приступить непосредственно к вызову метода `fulfill` запроса. Этот метод вызовет метод `markEmailAsVerified` для аутентифицированного пользователя и запустит событие `Illuminate\Auth\Events\Verified`. Метод `markEmailAsVerified` доступен для модели по умолчанию `App\Models\User` через базовый класс `Illuminate\Foundation\Auth\User`. После подтверждения адреса электронной почты пользователя вы можете перенаправить его куда пожелаете. 98 | 99 | 100 | ### Повторная отправка письма с подтверждением 101 | 102 | Иногда пользователь может потерять или случайно удалить письмо с подтверждением адреса электронной почты. Чтобы учесть это, вы можете определить маршрут, позволяющий пользователю запрашивать повторную отправку письма с подтверждением. Затем, вы можете сделать запрос по этому маршруту, поместив простую кнопку отправки формы на [странице уведомления о подтверждении](#the-email-verification-notice): 103 | 104 | use Illuminate\Http\Request; 105 | 106 | Route::post('/email/verification-notification', function (Request $request) { 107 | $request->user()->sendEmailVerificationNotification(); 108 | 109 | return back()->with('message', 'Verification link sent!'); 110 | })->middleware(['auth', 'throttle:6,1'])->name('verification.send'); 111 | 112 | 113 | ### Защита маршрутов 114 | 115 | [Посредник маршрута](/docs/{{version}}/middleware) может использоваться только для того, чтобы разрешить доступ к конкретному маршруту только подтвержденным пользователям. Laravel содержит посредник `verified`, который ссылается на класс `Illuminate\Auth\Middleware\EnsureEmailIsVerified`. Поскольку этот посредник уже зарегистрирован в HTTP-ядре вашего приложения, все, что вам нужно сделать, так это назначить посредник маршруту: 116 | 117 | Route::get('/profile', function () { 118 | // Только подтвержденные пользователи могут получить доступ к этому маршруту ... 119 | })->middleware('verified'); 120 | 121 | Если непроверенный пользователь попытается получить доступ к маршруту, которому назначен этот посредник, то он будет автоматически перенаправлен на [именованный маршрут](/docs/{{version}}/routing#named-routes) `verification.notice`. 122 | 123 | 124 | ## Настройка 125 | 126 | 127 | #### Настройка подтверждения адреса электронной почты 128 | 129 | Хотя уведомление о подтверждении электронной почты по умолчанию должно удовлетворять требованиям большинства приложений, Laravel позволяет вам изменить сообщение подтверждения электронной почты. 130 | 131 | Для начала, передайте замыкание методу `toMailUsing` уведомления `Illuminate\Auth\Notifications\VerifyEmail`. Замыкание получит экземпляр модели, содержащий уведомление, а также подписанный URL-адрес подтверждения электронной почты, который пользователь должен посетить для проверки адреса электронной почты. Замыкание должно вернуть экземпляр `Illuminate\Notifications\Messages\MailMessage`. Как правило, вызов метода `toMailUsing` осуществляется в методе `boot` класса `App\Providers\AuthServiceProvider` вашего приложения: 132 | 133 | use Illuminate\Auth\Notifications\VerifyEmail; 134 | use Illuminate\Notifications\Messages\MailMessage; 135 | 136 | /** 137 | * Регистрация любых служб аутентификации / авторизации. 138 | * 139 | * @return void 140 | */ 141 | public function boot() 142 | { 143 | // ... 144 | 145 | VerifyEmail::toMailUsing(function ($notifiable, $url) { 146 | return (new MailMessage) 147 | ->subject('Verify Email Address') 148 | ->line('Click the button below to verify your email address.') 149 | ->action('Verify Email Address', $url); 150 | }); 151 | } 152 | 153 | > {tip} Чтобы узнать больше о почтовых уведомлениях, обратитесь к [документации по почтовым уведомлениям](notifications#mail-notifications). 154 | 155 | 156 | ## События 157 | 158 | При использовании [стартовых комплектов](starter-kits) Laravel запускает [события](/docs/{{version}}/events) в процессе проверки электронной почты. Если вы самостоятельно обрабатываете проверку электронной почты для своего приложения, то вы должны запускать эти события после завершения проверки. Вы можете назначить слушателей для этих событий в `EventServiceProvider` вашего приложения: 159 | 160 | /** 161 | * Карта слушателей событий приложения. 162 | * 163 | * @var array 164 | */ 165 | protected $listen = [ 166 | 'Illuminate\Auth\Events\Verified' => [ 167 | 'App\Listeners\LogVerifiedUser', 168 | ], 169 | ]; 170 | -------------------------------------------------------------------------------- /views.md: -------------------------------------------------------------------------------- 1 | git fa38597c7d27bf505b912772e848272d44cc3adf 2 | 3 | --- 4 | 5 | # HTML-шаблоны 6 | 7 | - [Введение](#introduction) 8 | - [Создание и отрисовка шаблонов](#creating-and-rendering-views) 9 | - [Вложенные каталоги шаблонов](#nested-view-directories) 10 | - [Использование первого доступного шаблона](#creating-the-first-available-view) 11 | - [Определение наличия шаблона](#determining-if-a-view-exists) 12 | - [Передача данных шаблону](#passing-data-to-views) 13 | - [Общедоступные данные для всех шаблонов](#sharing-data-with-all-views) 14 | - [Компоновщики шаблонов](#view-composers) 15 | - [Создатели шаблонов](#view-creators) 16 | - [Оптимизация шаблонов](#optimizing-views) 17 | 18 | 19 | ## Введение 20 | 21 | Конечно, нецелесообразно возвращать целые строки HTML-документов непосредственно из ваших маршрутов и контроллеров. К счастью, шаблоны предоставляют удобный способ разместить весь наш HTML в отдельных файлах. Шаблоны отделяют логику контроллера / приложения от логики представления и хранятся в каталоге `resources/views`. Простой шаблон может выглядеть примерно так: 22 | 23 | ```html 24 | 25 | 26 | 27 | 28 |

Привет, {{ $name }}

29 | 30 | 31 | ``` 32 | 33 | Поскольку этот шаблон сохранен в `resources/views/greeting.blade.php`, мы можем вернуть его, используя глобальный помощник `view`, например: 34 | 35 | Route::get('/', function () { 36 | return view('greeting', ['name' => 'James']); 37 | }); 38 | 39 | > {tip} Ищете дополнительную информацию о том, как писать шаблоны Blade? Ознакомьтесь с полной [документацией по Blade](/docs/{{version}}/blade), чтобы начать работу. 40 | 41 | 42 | ## Создание и отрисовка шаблонов 43 | 44 | Вы можете создать шаблон, поместив файл с расширением `.blade.php` в каталог `resources/views` вашего приложения. Расширение `.blade.php` сообщает фреймворку, что файл содержит [шаблон Blade](/docs/{{version}}/blade). Шаблоны Blade содержат HTML, а также директивы Blade, которые позволяют легко выводить значения, создавать операторы «если», выполнять итерацию данных и многое другое. 45 | 46 | После того как вы создали шаблон, вы можете вернуть его из маршрута или контроллера вашего приложения, используя глобальный помощник `view`: 47 | 48 | Route::get('/', function () { 49 | return view('greeting', ['name' => 'James']); 50 | }); 51 | 52 | Шаблон также могут быть возвращены с помощью фасада `View`: 53 | 54 | use Illuminate\Support\Facades\View; 55 | 56 | return View::make('greeting', ['name' => 'James']); 57 | 58 | Как видно, первый аргумент, переданный помощнику `view`, соответствует имени файла шаблона в каталоге `resources/views`. Второй аргумент – это массив данных, которые должны быть доступны в шаблоне. В этом случае мы передаем переменную `name`, которая будет выведена в шаблоне с использованием [синтаксиса Blade](/docs/{{version}}/blade). 59 | 60 | 61 | ### Вложенные каталоги шаблонов 62 | 63 | Шаблоны также могут быть вложены в подкаталоги каталога `resources/views`. «Точечная нотация» используется для указания вложенности шаблона. Например, если ваш шаблон хранится в `resources/views/admin/profile.blade.php`, то вы можете вернуть его из маршрута / контроллера вашего приложения следующим образом: 64 | 65 | return view('admin.profile', $data); 66 | 67 | > {note} Имена каталогов шаблонов не должны содержать символа `.`. 68 | 69 | 70 | ### Использование первого доступного шаблона 71 | 72 | Используя метод `first` фасада `View`, вы можете отобразить первый шаблон, который существует в переданном массиве шаблонов. Это может быть полезно, если ваше приложение или пакет позволяют настраивать или перезаписывать шаблоны: 73 | 74 | use Illuminate\Support\Facades\View; 75 | 76 | return View::first(['custom.admin', 'admin'], $data); 77 | 78 | 79 | ### Определение наличия шаблона 80 | 81 | Если вам нужно определить, существует ли шаблон, вы можете использовать фасад `View`. Метод `exists` вернет `true`, если он существует: 82 | 83 | use Illuminate\Support\Facades\View; 84 | 85 | if (View::exists('emails.customer')) { 86 | // 87 | } 88 | 89 | 90 | ## Передача данных шаблону 91 | 92 | Как вы видели в предыдущих примерах, вы можете передать массив данных шаблонам, чтобы сделать эти данные доступными для них: 93 | 94 | return view('greetings', ['name' => 'Victoria']); 95 | 96 | При передаче информации таким образом данные должны быть массивом с парами ключ / значение. После предоставления данных в шаблон вы можете получить доступ к каждому значению, используя ключи данных, схожее с ``. 97 | 98 | В качестве альтернативы передаче полного массива данных вспомогательной функции `view` вы можете использовать метод `with` для добавления некоторых данных в шаблон. Метод `with` возвращает экземпляр объекта представления, так что вы можете продолжить связывание методов перед возвратом шаблона: 99 | 100 | return view('greeting') 101 | ->with('name', 'Victoria') 102 | ->with('occupation', 'Astronaut'); 103 | 104 | 105 | ### Общедоступные данные для всех шаблонов 106 | 107 | Иногда требуется сделать данные общедоступными для всех шаблонов, отображаемыми вашим приложением. Вы можете сделать это, используя метод `share` фасада `View`. Как правило, вызов метода `share` осуществляется в методе `boot` поставщика служб. Вы можете добавить их в класс `App\Providers\AppServiceProvider` или создать отдельного поставщика для их размещения: 108 | 109 | 139 | ## Компоновщики шаблонов 140 | 141 | Компоновщики шаблонов – это замыкания или методы класса, которые вызываются при отрисовке шаблонов. Если у вас есть данные, которые вы хотите привязать к шаблону каждый раз при его отрисовке, компоновщик шаблонов поможет вам организовать эту логику в одном месте. Компоновщики шаблонов особенно полезны, если один и тот же шаблон возвращается несколькими маршрутами или контроллерами в вашем приложении и всегда требует определенного фрагмента данных. 142 | 143 | Как правило, компоновщики шаблонов регистрируются в одном из [поставщиков служб](/docs/{{version}}/provider) вашего приложения. В этом примере мы предположим, что мы создали новый `App\Providers\ViewServiceProvider` для размещения этой логики. 144 | 145 | Мы будем использовать метод `composer` фасада `View`, чтобы зарегистрировать компоновщик. Laravel по умолчанию не содержит каталог для классов компоновщиков, поэтому вы можете организовать их, как хотите. Например, вы можете создать каталог `app/View/Composers` для размещения всех компоновщиков вашего приложения: 146 | 147 | {note} Помните, что если вы создаете нового поставщика служб, который будет содержать регистрации вашего компоновщика, вам нужно будет добавить поставщика служб в массив `providers` в файле конфигурации `config/app.php`. 185 | 186 | Теперь, когда мы зарегистрировали компоновщик, метод `compose` класса `App\View\Composers\ProfileComposer` будет выполняться каждый раз, когда отрисовывается шаблон профиля. Давайте посмотрим на пример класса компоновщика: 187 | 188 | users = $users; 214 | } 215 | 216 | /** 217 | * Привязать данные к шаблону. 218 | * 219 | * @param \Illuminate\View\View $view 220 | * @return void 221 | */ 222 | public function compose(View $view) 223 | { 224 | $view->with('count', $this->users->count()); 225 | } 226 | } 227 | 228 | Как видите, все компоновщики внедряются через [контейнер служб](/docs/{{version}}/container), поэтому вы можете указать любые зависимости, которые вам нужны, в конструкторе компоновщика. 229 | 230 | 231 | #### Связывание компоновщика с несколькими шаблонами 232 | 233 | Вы можете связать компоновщика с несколькими шаблонами одновременно, передав массив шаблонов в качестве первого аргумента методу `composer`: 234 | 235 | use App\Views\Composers\MultiComposer; 236 | 237 | View::composer( 238 | ['profile', 'dashboard'], 239 | MultiComposer::class 240 | ); 241 | 242 | Допускается использование метасимвола подстановки `*`, что позволит вам прикрепить компоновщик ко всем шаблонам: 243 | 244 | View::composer('*', function ($view) { 245 | // 246 | }); 247 | 248 | 249 | ### Создатели шаблонов 250 | 251 | «Создатели» шаблонов очень похожи на компоновщиков; но, они выполняются сразу после создания экземпляра, а не ожидают отрисовки шаблона. Чтобы зарегистрировать создателя шаблона, используйте метод `creator`: 252 | 253 | use App\View\Creators\ProfileCreator; 254 | use Illuminate\Support\Facades\View; 255 | 256 | View::creator('profile', ProfileCreator::class); 257 | 258 | 259 | ## Оптимизация шаблонов 260 | 261 | По умолчанию шаблоны Blade компилируются по требованию. Когда выполняется запрос, который отрисовывает шаблон, Laravel определит, существует ли скомпилированная версия шаблона. Если файл существует, Laravel далее определит, был ли исходный шаблон изменен позднее скомпилированного. Если скомпилированного шаблона либо не существует, либо исходный шаблон был изменен, Laravel перекомпилирует шаблон. 262 | 263 | Компиляция шаблонов во время запроса отрицательно влияет на производительность, поэтому Laravel содержит команду Artisan `view:cache` для предварительной компиляции всех шаблонов, используемых вашим приложением. Для повышения производительности вы можете выполнить эту команду как часть процесса развертывания: 264 | 265 | php artisan view:cache 266 | 267 | Вы можете использовать команду `view:clear` для очистки кеша шаблонов: 268 | 269 | php artisan view:clear 270 | -------------------------------------------------------------------------------- /configuration.md: -------------------------------------------------------------------------------- 1 | git 9bb78f08a26b86b5d43153d23fe0d663befbec7e 2 | 3 | --- 4 | 5 | # Конфигурирование 6 | 7 | - [Введение](#introduction) 8 | - [Конфигурация окружения](#environment-configuration) 9 | - [Типы переменных окружения](#environment-variable-types) 10 | - [Получение конфигурации окружения](#retrieving-environment-configuration) 11 | - [Определение текущего окружения](#determining-the-current-environment) 12 | - [Доступ к значениям конфигурации](#accessing-configuration-values) 13 | - [Кеширование конфигурации](#configuration-caching) 14 | - [Режим отладки](#debug-mode) 15 | - [Режим обслуживания](#maintenance-mode) 16 | 17 | 18 | ## Введение 19 | 20 | Все конфигурационные файлы фреймворка Laravel хранятся в каталоге `config`. Каждый параметр задокументирован, поэтому не стесняйтесь просматривать эти файлы и знакомиться с доступными вам вариантами. 21 | 22 | Конфигурационные файлы позволяют настраивать такие вещи, как информация о подключении к базе данных, информация о почтовом сервере, а также другие основные параметры, например, часовой пояс приложения и ключ шифрования. 23 | 24 | 25 | ## Конфигурация окружения 26 | 27 | Часто бывает полезно иметь различные конфигурации в зависимости от окружения, в котором выполняется приложение. Например, по желанию можно использовать разные драйверы кеша в локальном и эксплуатационном окружении. 28 | 29 | Чтобы упростить это, Laravel использует библиотеку [DotEnv](https://github.com/vlucas/phpdotenv) PHP. В корневом каталоге вашего нового приложения будет содержаться файл `.env.example`, определяющий множество основных переменных окружения. Этот файл будет автоматически скопирован в `.env` в процессе установки Laravel. 30 | 31 | Файл `.env` Laravel по умолчанию содержит некоторые основные значения конфигурации, которые могут зависеть от того, работает ли ваше приложение локально или на конечном веб-сервере. Эти значения могут быть получены из различных конфигурационных файлов каталога `config` Laravel с помощью глобальной функции `env()` Laravel. 32 | 33 | Если вы работаете в команде, то вы можете не исключать файл `.env.example` из своего приложения. Размещая значения-заполнители в этот файл, другие разработчики в вашей команде могут четко видеть, какие переменные окружения необходимы для запуска вашего приложения. 34 | 35 | > {tip} Любая переменная в вашем файле `.env` может быть переопределена внешними переменными окружения, такими как переменные окружения уровня сервера или системы. 36 | 37 | 38 | #### Безопасность файлов окружения 39 | 40 | Ваш файл `.env` не должен быть привязан к системе контроля версий вашего приложения, поскольку каждому разработчику / серверу, использующему ваше приложение, может потребоваться другая конфигурация окружения. Кроме того, это будет угрозой безопасности в случае, если злоумышленник получит доступ к вашему репозиторию системы управления версиями, поскольку любые конфиденциальные учетные данные будут раскрыты. 41 | 42 | 43 | #### Дополнительные файлы окружения 44 | 45 | Перед загрузкой переменных окружения вашего приложения Laravel определяет, была ли переменная среды `APP_ENV` предоставлена извне или указан аргумент CLI` --env`. Если это так, Laravel попытается загрузить файл `.env.[APP_ENV]`. Если он не существует, будет загружен `.env` файл по умолчанию. 46 | 47 | 48 | ### Типы переменных окружения 49 | 50 | Все переменные в файлах `.env` обычно анализируются как строки, поэтому были созданы некоторые зарезервированные значения, позволяющие вам возвращать более широкий диапазон типов из функции `env()`: 51 | 52 | | Значение `.env` | Значение `env()` | 53 | |-----------------|------------------| 54 | | true | (bool) true | 55 | | (true) | (bool) true | 56 | | false | (bool) false | 57 | | (false) | (bool) false | 58 | | empty | (string) '' | 59 | | (empty) | (string) '' | 60 | | null | (null) null | 61 | | (null) | (null) null | 62 | 63 | Если вам нужно определить переменную окружения со значением, содержащим пробелы, то вы можете сделать это, заключив значение в двойные кавычки: 64 | 65 | APP_NAME="My Application" 66 | 67 | 68 | ### Получение конфигурации окружения 69 | 70 | Все переменные, перечисленные в этом файле, будут загружены в суперглобальную переменную `$_ENV` PHP, когда ваше приложение получит запрос. Однако вы можете использовать помощник `env()` для получения значений из переменных ваших конфигурационных файлов. Фактически, если вы просмотрите файлы конфигурации Laravel, вы заметите, что многие параметры уже используют этот помощник: 71 | 72 | 'debug' => env('APP_DEBUG', false), 73 | 74 | Второе значение, переданное в функцию `env`, является «значением по умолчанию». Это значение будет возвращено, если для данного ключа не существует переменной окружения. 75 | 76 | 77 | ### Определение текущего окружения 78 | 79 | Текущее окружение приложения определяется с помощью переменной `APP_ENV` из вашего файла `.env`. Вы можете получить доступ к этому значению через метод `environment` [фасада](/docs/{{version}}/facades) `App`: 80 | 81 | use Illuminate\Support\Facades\App; 82 | 83 | $environment = App::environment(); 84 | 85 | Вы также можете передать аргументы методу `environment`, чтобы определить, соответствует ли окружение переданному значению. Метод вернет `true`, если окружение соответствует любому из указанных значений: 86 | 87 | if (App::environment('local')) { 88 | // Локальное окружение ... 89 | } 90 | 91 | if (App::environment(['local', 'staging'])) { 92 | // Окружение либо локальное, либо промежуточное ... 93 | } 94 | 95 | > {tip} Определение текущего окружения приложения может быть отменено путем определения переменной окружения `APP_ENV` на уровне сервера. 96 | 97 | 98 | ## Доступ к значениям конфигурации 99 | 100 | Вы можете легко получить доступ к своим значениям конфигурации, используя глобальный помощник `config` из любого места вашего приложения. Доступ к значениям конфигурации можно получить с помощью «точечной нотации», включающую имя файла и параметр, к которому вы хотите получить доступ. Также может быть указано значение по умолчанию, которое будет возвращено, если параметр конфигурации отсутствует: 101 | 102 | $value = config('app.timezone'); 103 | 104 | // Получить значение по умолчанию, если значение конфигурации не существует ... 105 | $value = config('app.timezone', 'Asia/Seoul'); 106 | 107 | Чтобы установить значения конфигурации во время выполнения скрипта, передайте массив помощнику `config`: 108 | 109 | config(['app.timezone' => 'America/Chicago']); 110 | 111 | 112 | ## Кеширование конфигурации 113 | 114 | Чтобы ускорить работу вашего приложения, вы должны кешировать все конфигурационные файлы в один файл с помощью команды `config:cache` Artisan. Это объединит все конфигурационные параметры вашего приложения в один файл, который может быть быстро загружен фреймворком. 115 | 116 | Обычно вы должны запускать команду `php artisan config:cache` как часть процесса развертывания эксплуатационного режима. Команду не следует запускать во время локальной разработки, поскольку конфигурационные параметры часто нужно будет изменять в ходе разработки вашего приложения. 117 | 118 | > {note} Если вы выполняете команду `config:cache` в процессе развертывания, то вы должны быть уверены, что вызываете функцию `env()` только из ваших файлов конфигурации. После кэширования конфигурации файл `.env` не будет подгружаться; следовательно, функция `env()` будет возвращать только внешние переменные окружения системного уровня. 119 | 120 | 121 | ## Режим отладки 122 | 123 | Параметр `debug` в конфигурационном файле `config/app.php` определяет, сколько информации об ошибках фактически отображается конечному пользователю. По умолчанию этот параметр установлен с учетом значения переменной `APP_DEBUG` окружения, расположенной в вашем файле `.env`. 124 | 125 | Для локальной разработки вы должны установить для переменной `APP_DEBUG` окружения значение `true`. **В эксплуатационном режиме это значение всегда должно быть `false`. Если для этой переменной будет установлено значение `true`, то вы рискуете раскрыть конфиденциальные значения конфигурации конечным пользователям вашего приложения.** 126 | 127 | 128 | ## Режим обслуживания 129 | 130 | Когда ваше приложение находится в режиме обслуживания, то для всех запросов к приложению будет отображаться специальная страница. Это позволяет легко «отключить» ваше приложение во время его обновления или технического обслуживания. Проверка режима обслуживания включена в стек посредников по умолчанию для вашего приложения. Если приложение находится в режиме обслуживания, то будет выброшено исключение `Symfony\Component\HttpKernel\Exception\HttpException` с `503` кодом состояния. 131 | 132 | Чтобы включить режим обслуживания, выполните команду `down` Artisan: 133 | 134 | php artisan down 135 | 136 | Если вы хотите, чтобы HTTP-заголовок `Refresh` отправлялся со всеми ответами в режиме обслуживания, вы можете указать параметр `refresh` при вызове команды `down`. Заголовок `Refresh` будет указывать браузеру автоматически обновлять страницу через указанное количество секунд: 137 | 138 | php artisan down --refresh=15 139 | 140 | Вы также можете передать команде `down` параметр `retry`, значение которого будет установлено в заголовке `Retry-After` HTTP`, хотя браузеры обычно игнорируют этот заголовок: 141 | 142 | php artisan down --retry=60 143 | 144 | 145 | #### Обход режима обслуживания 146 | 147 | Находясь в режиме обслуживания, вы можете использовать параметр `secret`, чтобы указать токен для обхода режима обслуживания: 148 | 149 | php artisan down --secret="1630542a-246b-4b66-afa1-dd72a4c43515" 150 | 151 | После перевода приложения в режим обслуживания, вы можете перейти по URL-адресу приложения, с учетом этого токена, и Laravel выдаст вашему браузеру файл куки для обхода режима обслуживания: 152 | 153 | https://example.com/1630542a-246b-4b66-afa1-dd72a4c43515 154 | 155 | При доступе к этому скрытому маршруту вы будете перенаправлены на маршрут `/` приложения. Как только куки будет отправлен вашему браузеру, вы сможете просматривать приложение в обычном режиме, как если бы оно не находилось в режиме обслуживания. 156 | 157 | > {tip} Параметр `secret` режима обслуживания должен состоять из буквенно-цифровых символов и, при необходимости, тире. Вам следует избегать использования в URL-адресах символов, имеющих особое значение, таких как `?`. 158 | 159 | 160 | #### Предварительный рендеринг шаблона режима обслуживания 161 | 162 | Если вы используете команду `php artisan down` во время развертывания, то ваши пользователи могут иногда сталкиваться с ошибками, если они обращаются к приложению во время обновления ваших зависимостей Composer или других компонентов фреймворка. Это происходит потому, для определения режима обслуживания и отображения шаблона режима обслуживания с помощью движка шаблонов должна быть загружена значительная часть фреймворка Laravel. 163 | 164 | По этой причине Laravel позволяет в самом начале цикла запроса отобразить шаблон режима обслуживания. Этот шаблон отображается перед загрузкой любых зависимостей вашего приложения. Вы можете выполнить предварительный рендеринг шаблона по вашему выбору, используя параметр `render` команды `down`: 165 | 166 | php artisan down --render="errors::503" 167 | 168 | 169 | #### Перенаправление запросов режима обслуживания 170 | 171 | В режиме обслуживания Laravel будет отображать шаблон режима обслуживания для всех URL-адресов приложения, к которым пользователь попытается получить доступ. Если хотите, то вы можете указать Laravel перенаправлять все запросы на определенный URL. Это может быть выполнено с помощью параметра `redirect`. Например, вы можете перенаправить все запросы на URI `/`: 172 | 173 | php artisan down --redirect=/ 174 | 175 | 176 | #### Отключение режима обслуживания 177 | 178 | Чтобы отключить режим обслуживания, используйте команду `up`: 179 | 180 | php artisan up 181 | 182 | > {tip} Вы можете определить свой шаблон режима обслуживания в `resources/views/errors/503.blade.php`. 183 | 184 | 185 | #### Режим обслуживания и очереди 186 | 187 | Пока ваше приложение находится в режиме обслуживания, [поставленные в очередь задания](/docs/{{version}}/queues) обрабатываться не будут. Задания продолжат обрабатываться в обычном режиме после выхода приложения из режима обслуживания. 188 | 189 | 190 | #### Альтернативы режиму обслуживания 191 | 192 | Поскольку режим обслуживания требует, чтобы ваше приложение простаивало несколько секунд, то рассмотрите альтернативы, например, [Laravel Vapor](https://vapor.laravel.com) и [Envoyer](https://envoyer.io) для выполнения развертывания с нулевым временем простоя. 193 | -------------------------------------------------------------------------------- /envoy.md: -------------------------------------------------------------------------------- 1 | git 9b744ef2a5e47ac201b3a06831d64513f6bf69c9 2 | 3 | --- 4 | 5 | # Пакет Laravel Envoy 6 | 7 | - [Введение](#introduction) 8 | - [Установка](#installation) 9 | - [Написание задач](#writing-tasks) 10 | - [Определение задач](#defining-tasks) 11 | - [Множество серверов](#multiple-servers) 12 | - [Предстартовая подготовка](#setup) 13 | - [Переменные](#variables) 14 | - [Истории](#stories) 15 | - [Хуки](#completion-hooks) 16 | - [Выполнение задач](#running-tasks) 17 | - [Подтверждение выполнения задачи](#confirming-task-execution) 18 | - [Уведомления](#notifications) 19 | - [Slack](#slack) 20 | - [Discord](#discord) 21 | - [Telegram](#telegram) 22 | - [Microsoft Teams](#microsoft-teams) 23 | 24 | 25 | ## Введение 26 | 27 | [**Laravel Envoy**](https://github.com/laravel/envoy) – это инструмент для выполнения общих задач, запускаемых на ваших удаленных серверах. Используя синтаксис в стиле [Blade](/docs/{{version}}/blade), вы можете легко настроить задачи для развертывания, команд Artisan и многое другое. В настоящее время Envoy поддерживает только операционные системы Mac и Linux. Однако поддержка Windows достижима с помощью [WSL2](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 28 | 29 | 30 | ## Установка 31 | 32 | Для начала установите Envoy с помощью менеджера пакетов Composer в свой проект: 33 | 34 | composer require laravel/envoy --dev 35 | 36 | После установки исполняемый файл Envoy будет доступен в каталоге вашего приложения `vendor/bin`: 37 | 38 | php vendor/bin/envoy 39 | 40 | 41 | ## Написание задач 42 | 43 | 44 | ### Определение задач 45 | 46 | Задачи – это основной «строительный блок» Envoy. Задачи определяются командами оболочки, выполняемыми на ваших удаленных серверах при вызове задачи. Например, вы можете определить задачу, которая выполнит команду `php artisan queue:restart` обработчика очереди на серверах вашего приложения. 47 | 48 | Все ваши задачи Envoy должны быть определены в файле `Envoy.blade.php` в корне вашего приложения. Например: 49 | 50 | ```bash 51 | @servers(['web' => ['user@192.168.1.1'], 'workers' => ['user@192.168.1.2']]) 52 | 53 | @task('restart-queues', ['on' => 'workers']) 54 | cd /home/user/example.com 55 | php artisan queue:restart 56 | @endtask 57 | ``` 58 | 59 | Как видите, в верхней части файла объявлен массив `@servers`, что позволяет вам ссылаться на эти серверы с помощью параметра `on` в определениях ваших задач. Объявление `@servers` всегда следует размещать в одной строке. В определениях `@task` вы должны поместить команды оболочки, которые должны выполняться на ваших серверах при вызове задачи. 60 | 61 | 62 | #### Локальные задачи 63 | 64 | Вы можете принудительно запустить сценарий на вашем локальном компьютере, указав IP-адрес сервера как `127.0.0.1`: 65 | 66 | ```bash 67 | @servers(['localhost' => '127.0.0.1']) 68 | ``` 69 | 70 | 71 | #### Импорт задач Envoy 72 | 73 | Используя директиву `@import`, вы можете импортировать другие файлы Envoy для добавления дополнительных историй и задач. После того как файлы были импортированы, вы можете выполнять задачи, содержащиеся в них, как если бы они были определены в вашем собственном файле Envoy: 74 | 75 | ```bash 76 | @import('vendor/package/Envoy.blade.php') 77 | ``` 78 | 79 | 80 | ### Множество серверов 81 | 82 | Envoy позволяет легко запускать задачу на нескольких серверах. Во-первых, добавьте необходимые серверы в объявление `@servers`. Каждому серверу должно быть присвоено уникальное имя. После определения дополнительных серверов, вы можете использовать каждый из них в массиве задачи `on`: 83 | 84 | ```bash 85 | @servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2']) 86 | 87 | @task('deploy', ['on' => ['web-1', 'web-2']]) 88 | cd /home/user/example.com 89 | git pull origin {{ $branch }} 90 | php artisan migrate --force 91 | @endtask 92 | ``` 93 | 94 | 95 | #### Параллельное выполнение 96 | 97 | По умолчанию задачи будут выполняться на каждом сервере поочередно. Другими словами, задача должна завершится на первом сервере, прежде чем будет выполнена на втором. Если вы хотите запустить задачу на нескольких серверах параллельно, то добавьте параметр `parallel` в определение задачи: 98 | 99 | ```bash 100 | @servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2']) 101 | 102 | @task('deploy', ['on' => ['web-1', 'web-2'], 'parallel' => true]) 103 | cd /home/user/example.com 104 | git pull origin {{ $branch }} 105 | php artisan migrate --force 106 | @endtask 107 | ``` 108 | 109 | 110 | ### Предстартовая подготовка 111 | 112 | По желанию можно выполнить произвольный PHP-код перед запуском ваших задач Envoy. Вы можете использовать директиву `@setup` для определения блока PHP-кода, который должен быть выполнен перед вашими задачами: 113 | 114 | ```php 115 | @setup 116 | $now = new DateTime; 117 | @endsetup 118 | ``` 119 | 120 | Если вам нужны другие файлы PHP перед выполнением вашей задачи, то вы можете использовать директиву `@include` в верхней части вашего файла `Envoy.blade.php`: 121 | 122 | ```bash 123 | @include('vendor/autoload.php') 124 | 125 | @task('restart-queues') 126 | # ... 127 | @endtask 128 | ``` 129 | 130 | 131 | ### Переменные 132 | 133 | При необходимости вы можете передать аргументы задачам Envoy, указав их в командной строке при вызове Envoy: 134 | 135 | php vendor/bin/envoy run deploy --branch=master 136 | 137 | Вы можете получить доступ к параметрам ваших задач, используя [синтаксис «вывода» Blade](/docs/{{version}}/blade#displaying-data). Вы также можете определять операторы `if` и циклы Blade в своих задачах. Например, давайте проверим наличие переменной `$branch` перед выполнением команды `git pull`: 138 | 139 | ```bash 140 | @servers(['web' => ['user@192.168.1.1']]) 141 | 142 | @task('deploy', ['on' => 'web']) 143 | cd /home/user/example.com 144 | 145 | @if ($branch) 146 | git pull origin {{ $branch }} 147 | @endif 148 | 149 | php artisan migrate --force 150 | @endtask 151 | ``` 152 | 153 | 154 | ### Истории 155 | 156 | Истории группируют набор задач под одним удобным названием. Например, вы можете сгруппировать запуск задач `update-code` и `install-dependencies`, перечислив их имена в определении истории `deploy`: 157 | 158 | ```bash 159 | @servers(['web' => ['user@192.168.1.1']]) 160 | 161 | @story('deploy') 162 | update-code 163 | install-dependencies 164 | @endstory 165 | 166 | @task('update-code') 167 | cd /home/user/example.com 168 | git pull origin master 169 | @endtask 170 | 171 | @task('install-dependencies') 172 | cd /home/user/example.com 173 | composer install 174 | @endtask 175 | ``` 176 | 177 | После написания история, вы можете запустить ее так же, как вы запускаете отдельную задачу: 178 | 179 | php vendor/bin/envoy run deploy 180 | 181 | 182 | ### Хуки 183 | 184 | Когда задачи и истории выполняются, то вызывается ряд хуков. Envoy поддерживает следующие типы хуков: `@before`, `@after`, `@error`, `@success`, и `@finished`. Весь код в этих хуках интерпретируется как PHP и выполняется локально, а не на удаленных серверах, с которыми взаимодействуют ваши задачи. 185 | 186 | Вы можете определить столько хуков, сколько захотите. Они будут выполняться в том порядке, в котором они указаны в вашем скрипте Envoy. 187 | 188 | 189 | #### `@before` 190 | 191 | Перед выполнением каждой задачи будут выполняться все хуки `@before`, зарегистрированные в вашем скрипте Envoy. Хуки `@before` получают имя задачи, которая будет выполняться: 192 | 193 | ```php 194 | @before 195 | if ($task === 'deploy') { 196 | // ... 197 | } 198 | @endbefore 199 | ``` 200 | 201 | 202 | #### Директива хука `@after` 203 | 204 | После выполнения каждой задачи будут выполняться все хуки `@after`, зарегистрированные в вашем сценарии Envoy. Хуки `@after` получат имя запущенной задачи: 205 | 206 | ```php 207 | @after 208 | if ($task === 'deploy') { 209 | // ... 210 | } 211 | @endafter 212 | ``` 213 | 214 | 215 | #### Директива хука `@error` 216 | 217 | После каждого сбоя задачи (выход с кодом состояния больше `0`) будут выполняться все хуки `@error`, зарегистрированные в вашем сценарии Envoy. Хуки `@error` получат имя запущенной задачи: 218 | 219 | ```php 220 | @error 221 | if ($task === 'deploy') { 222 | // ... 223 | } 224 | @enderror 225 | ``` 226 | 227 | 228 | #### Директива хука `@success` 229 | 230 | Если все задачи выполнены без ошибок, то все хуки `@success`, зарегистрированные в вашем сценарии Envoy, будут выполнены: 231 | 232 | ```bash 233 | @success 234 | // ... 235 | @endsuccess 236 | ``` 237 | 238 | 239 | #### Директива хука `@finished` 240 | 241 | После выполнения всех задач (независимо от статуса выхода) будут выполнены все хуки `@finished`. Хуки `@finished` получат код состояния завершенной задачи, который может быть `null` или `integer`, большим или равным `0`: 242 | 243 | ```bash 244 | @finished 245 | if ($exitCode > 0) { 246 | // В одной из задач произошли ошибки ... 247 | } 248 | @endfinished 249 | ``` 250 | 251 | 252 | ## Выполнение задач 253 | 254 | Чтобы запустить задачу или историю, которая определена в файле `Envoy.blade.php` вашего приложения, выполните команду `run` Envoy, передав имя задачи или истории, которую вы хотите выполнить. Envoy выполнит задачу и отобразит вывод с ваших удаленных серверов во время выполнения задачи: 255 | 256 | php vendor/bin/envoy run deploy 257 | 258 | 259 | ### Подтверждение выполнения задачи 260 | 261 | Если вы хотите получить запрос на подтверждение перед запуском конкретной задачи на своих серверах, вам следует добавить параметр `confirm` в директиву определения задачи. Этот параметр особенно полезен для деструктивных операций: 262 | 263 | ```bash 264 | @task('deploy', ['on' => 'web', 'confirm' => true]) 265 | cd /home/user/example.com 266 | git pull origin {{ $branch }} 267 | php artisan migrate 268 | @endtask 269 | ``` 270 | 271 | 272 | ## Уведомления 273 | 274 | 275 | ### Slack 276 | 277 | Envoy поддерживает отправку уведомлений в [Slack](https://slack.com) после выполнения каждой задачи. Директива `@slack` принимает WebHook URL и имя канала / пользователя. Вы можете получить WebHook URL, создав интеграцию «Incoming WebHooks» в панели управления Slack. 278 | 279 | Вы должны передать полный WebHook URL в качестве первого аргумента директивы `@slack`. Вторым аргументом, передаваемым директиве `@slack`, должно быть имя канала `#channel` или имя пользователя `@user`: 280 | 281 | @finished 282 | @slack('webhook-url', '#bots') 283 | @endfinished 284 | 285 | По умолчанию уведомления Envoy отправляют сообщение в канал уведомлений с описанием выполненной задачи. Однако вы можете назначить свое сообщение, передав третий аргумент директиве `@slack`: 286 | 287 | @finished 288 | @slack('webhook-url', '#bots', 'Hello, Slack.') 289 | @endfinished 290 | 291 | 292 | ### Discord 293 | 294 | Envoy также поддерживает отправку уведомлений в [Discord](https://discord.com) после выполнения каждой задачи. Директива `@discord` принимает WebHook URL и сообщение. Вы можете получить WebHook URL, создав «Webhook» в настройках сервера и выбрав канал, на который WebHook должен публиковать сообщения. Вы должны передать полный WebHook URL в директиву `@discord`: 295 | 296 | @finished 297 | @discord('discord-webhook-url') 298 | @endfinished 299 | 300 | 301 | ### Telegram 302 | 303 | Envoy также поддерживает отправку уведомлений в [Telegram](https://telegram.org) после выполнения каждой задачи. Директива `@telegram` принимает идентификатор бота Telegram и идентификатор чата. Вы можете получить свой идентификатор бота, создав нового бота в [BotFather](https://t.me/botfather). Вы можете получить действительный идентификатор чата, используя [`@username_to_id_bot`](https://t.me/username_to_id_bot). Вы должны передать полный идентификатор бота и идентификатор чата в директиву `@telegram`: 304 | 305 | @finished 306 | @telegram('bot-id','chat-id') 307 | @endfinished 308 | 309 | 310 | ### Microsoft Teams 311 | 312 | Envoy также поддерживает отправку уведомлений в [Microsoft Teams](https://www.microsoft.com/en-us/microsoft-teams) после выполнения каждой задачи. Директива `@microsoftTeams` принимает WebHook URL (обязательный), сообщение, цвет темы (success, info, warning, error) и массив параметров. Вы можете получить свой Teams WebHook URL, создав новый [incoming webhook](https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook). В Teams API есть множество других атрибутов для настройки окна сообщения, например заголовок, сводка и разделы. Дополнительную информацию можно найти в [Microsoft Teams documentation](https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using?tabs=cURL#example-of-connector-message). Вы должны передать весь URL-адрес веб-перехватчика в директиву `@microsoftTeams`: 313 | 314 | @finished 315 | @microsoftTeams('webhook-url') 316 | @endfinished 317 | -------------------------------------------------------------------------------- /passwords.md: -------------------------------------------------------------------------------- 1 | git 90d6599e62e47b3da7eeec67d4053732415f187a 2 | 3 | --- 4 | 5 | # Сброс пароля 6 | 7 | - [Введение](#introduction) 8 | - [Подготовка модели](#model-preparation) 9 | - [Подготовка базы данных](#database-preparation) 10 | - [Конфигурирование доверенных хостов](#configuring-trusted-hosts) 11 | - [Маршрутизация](#routing) 12 | - [Запрос ссылки для сброса пароля](#requesting-the-password-reset-link) 13 | - [Сброс пароля](#resetting-the-password) 14 | - [Удаление просроченных токенов](#deleting-expired-tokens) 15 | - [Настройка](#password-customization) 16 | 17 | 18 | ## Введение 19 | 20 | Большинство веб-приложений предоставляют пользователям возможность сбросить забытые пароли. Вместо того чтобы заставлять вас заново реализовывать этот функционал самостоятельно для каждого создаваемого вами приложения, Laravel предлагает удобные сервисы для отправки ссылок для сброса пароля и, собственно, безопасного сброса паролей. 21 | 22 | > {tip} Хотите быстро начать? Установите один из [стартовых комплектов](starter-kits) в новое приложение Laravel. Стартовые комплекты позаботятся о построении всей вашей системы аутентификации, включая сброс забытых паролей. 23 | 24 | 25 | ### Подготовка модели 26 | 27 | Перед использованием функционала сброса пароля Laravel модель вашего приложения `App\Models\User` должна использовать трейт `Illuminate\Notifications\Notifiable`. Обычно этот трейт уже содержится по умолчанию в модели `App\Models\User` при создании новых приложений Laravel. 28 | 29 | Затем убедитесь, что ваша модель `App\Models\User` реализует контракт `Illuminate\Contracts\Auth\CanResetPassword`. Модель `App\Models\User` Laravel, уже реализует этот интерфейс и использует трейт `Illuminate\Auth\Passwords\CanResetPassword`, включающий методы, необходимые для реализации интерфейса. 30 | 31 | 32 | ### Подготовка базы данных 33 | 34 | Необходимо создать таблицу для сохранения токенов сброса пароля вашего приложения. Миграция для этой таблицы содержится по умолчанию в Laravel, поэтому вам нужно только выполнить миграцию БД для создания этой таблицы: 35 | 36 | php artisan migrate 37 | 38 | 39 | ### Конфигурирование доверенных хостов 40 | 41 | По умолчанию Laravel будет отвечать на все запросы, которые он получает, независимо от содержимого заголовка `Host` HTTP-запроса. Кроме того, значение заголовка `Host` будет использоваться при генерации абсолютных URL-адресов вашего приложения во время веб-запроса. 42 | 43 | Как правило, вам следует настроить свой веб-сервер (Nginx или Apache), так, чтобы он обслуживал запросы, соответствующие только указанному имени хоста. Однако, если у вас нет возможности напрямую настроить свой веб-сервер и вам нужно указать Laravel, чтобы он отвечал только на определенные имена хостов, вы можете сделать это, задействовав посредник `App\Http\Middleware\TrustHosts` для вашего приложения. Это особенно важно, когда ваше приложение предлагает функционал сброса пароля. 44 | 45 | Чтобы узнать больше об этом посреднике, обратитесь к [документации посредника `TrustHosts`](/docs/{{version}}/requests#configuring-trusted-hosts). 46 | 47 | 48 | ## Маршрутизация 49 | 50 | Чтобы правильно реализовать поддержку, позволяющую пользователям сбрасывать свои пароли, нам нужно будет определить несколько маршрутов. Во-первых, нам понадобится пара маршрутов для обработки, позволяющей пользователю запрашивать ссылку для сброса пароля через свой адрес электронной почты. Во-вторых, нам понадобится пара маршрутов для обработки фактического сброса пароля при посещении пользователем ссылки для сброса пароля, отправленной ему по электронной почте, и последующего заполнения формы сброса пароля. 51 | 52 | 53 | ### Запрос ссылки для сброса пароля 54 | 55 | 56 | #### Форма запроса ссылки для сброса пароля 57 | 58 | Сначала мы определим маршруты, которые необходимы для запроса ссылок для сброса пароля. Для начала мы определим маршрут, который возвращает шаблон с формой запроса ссылки для сброса пароля: 59 | 60 | Route::get('/forgot-password', function () { 61 | return view('auth.forgot-password'); 62 | })->middleware('guest')->name('password.request'); 63 | 64 | Шаблон, возвращаемый этим маршрутом, должен иметь форму с полем `email` для указания адреса электронной почты, позволяющем пользователю запросить ссылку для сброса пароля. 65 | 66 | 67 | #### Обработка отправки формы 68 | 69 | Затем мы определим маршрут, который обрабатывает запрос на отправку формы из шаблона `forgot-password`. Этот маршрут будет отвечать за проверку адреса электронной почты и отправку запроса на сброс пароля соответствующему пользователю: 70 | 71 | use Illuminate\Http\Request; 72 | use Illuminate\Support\Facades\Password; 73 | 74 | Route::post('/forgot-password', function (Request $request) { 75 | $request->validate(['email' => 'required|email']); 76 | 77 | $status = Password::sendResetLink( 78 | $request->only('email') 79 | ); 80 | 81 | return $status === Password::RESET_LINK_SENT 82 | ? back()->with(['status' => __($status)]) 83 | : back()->withErrors(['email' => __($status)]); 84 | })->middleware('guest')->name('password.email'); 85 | 86 | Прежде чем двигаться дальше, давайте рассмотрим этот маршрут более подробно. Сначала проверяется атрибут запроса `email`. Затем мы будем использовать встроенный в Laravel «брокер паролей» через фасад `Password`, чтобы отправить пользователю ссылку для сброса пароля. Брокер паролей позаботится о получении пользователя по указанному полю (в данном случае по адресу электронной почты) и отправит пользователю ссылку для сброса пароля через встроенную [систему уведомлений](notifications) Laravel. 87 | 88 | Метод `sendResetLink` возвращает ключ «status». Этот статус может быть переведен с помощью помощников [локализации](/docs/{{version}}/localization) Laravel, чтобы показать пользователю удобное сообщение о статусе его запроса. Перевод статуса сброса пароля определяется языковым файлом `resources/lang/{lang}/passwords.php` вашего приложения. Запись для каждого возможного значения ключа статуса находится в языковом файле `passwords`. 89 | 90 | Вам может быть интересно: как Laravel знает о том, как получить запись пользователя из базы данных вашего приложения при вызове метода `sendResetLink` фасада `Password`? Брокер паролей Laravel использует «поставщиков пользователей» вашей системы аутентификации для получения записей из базы данных. Поставщик пользователей, используемый брокером паролей, настраивается в массиве `passwords` вашего файла конфигурации `config/auth.php`. Чтобы узнать больше о создании пользовательских поставщиков служб, обратитесь к [документации по аутентификации](authentication#adding-custom-user-providers). 91 | 92 | > {tip} При выполнении сброса пароля самостоятельно, вы должны сами определять содержимое страницы и маршрутов. Если вам необходим каркас, включающий всю необходимую логику аутентификации и проверки, ознакомьтесь со [стартовыми комплектами приложений Laravel](starter-kits). 93 | 94 | 95 | ### Сброс пароля 96 | 97 | 98 | #### Форма сброса пароля 99 | 100 | Затем мы определим маршруты, необходимые для фактического сброса пароля, когда пользователь щелкает ссылку для сброса пароля, отправленную ему по электронной почте, и предоставляет новый пароль. Во-первых, давайте определим маршрут, который будет отображать форму сброса пароля, после того как пользователь щелкает ссылку сброса пароля. Этот маршрут получит параметр `token`, который мы будем использовать позже для проверки запроса на сброс пароля: 101 | 102 | Route::get('/reset-password/{token}', function ($token) { 103 | return view('auth.reset-password', ['token' => $token]); 104 | })->middleware('guest')->name('password.reset'); 105 | 106 | Экран, возвращаемый этим маршрутом, должен отображать форму, содержащую поле `email`, поле `password`, поле `password_confirmation` и скрытое поле `token`, которое должно содержать значение секретного `$token`, полученного нашим маршрутом. 107 | 108 | 109 | #### Обработка отправки формы 110 | 111 | Конечно, нам нужно определить маршрут для фактической обработки отправки формы сброса пароля. Этот маршрут будет отвечать за проверку входящего запроса и обновление пароля пользователя в базе данных: 112 | 113 | use Illuminate\Auth\Events\PasswordReset; 114 | use Illuminate\Http\Request; 115 | use Illuminate\Support\Facades\Hash; 116 | use Illuminate\Support\Facades\Password; 117 | use Illuminate\Support\Str; 118 | 119 | Route::post('/reset-password', function (Request $request) { 120 | $request->validate([ 121 | 'token' => 'required', 122 | 'email' => 'required|email', 123 | 'password' => 'required|min:8|confirmed', 124 | ]); 125 | 126 | $status = Password::reset( 127 | $request->only('email', 'password', 'password_confirmation', 'token'), 128 | function ($user, $password) { 129 | $user->forceFill([ 130 | 'password' => Hash::make($password) 131 | ])->setRememberToken(Str::random(60)); 132 | 133 | $user->save(); 134 | 135 | event(new PasswordReset($user)); 136 | } 137 | ); 138 | 139 | return $status === Password::PASSWORD_RESET 140 | ? redirect()->route('login')->with('status', __($status)) 141 | : back()->withErrors(['email' => [__($status)]]); 142 | })->middleware('guest')->name('password.update'); 143 | 144 | Прежде чем двигаться дальше, давайте рассмотрим этот маршрут более подробно. Сначала проверяются атрибуты запроса `token`, `email`, и `password`. Далее мы будем использовать встроенный в Laravel «брокер паролей» (через фасад `Password`) для проверки учетных данных запроса сброса пароля. 145 | 146 | Если токен, адрес электронной почты и пароль, переданные брокеру паролей, действительны, будет вызвано замыкание, переданное методу `reset`. В рамках этого замыкания, которое получает экземпляр пользователя и пароль в виде обычного текста из формы сброса пароля, мы можем обновить пароль пользователя в базе данных. 147 | 148 | Метод `reset` возвращает ключ «status». Этот статус может быть переведен с помощью помощников [локализации](/docs/{{version}}/localization) Laravel, чтобы показать пользователю удобное сообщение о статусе его запроса. Перевод статуса сброса пароля определяется языковым файлом `resources/lang/{lang}/passwords.php` вашего приложения. Запись для каждого возможного значения ключа статуса находится в языковом файле `passwords`. 149 | 150 | Прежде чем двигаться дальше, вам может быть интересно, как Laravel знает, как получить запись пользователя из базы данных вашего приложения при вызове метода `reset` фасада `Password`. Брокер паролей Laravel использует «поставщиков пользователей» вашей системы аутентификации для получения записей из базы данных. Поставщик пользователей, используемый брокером паролей, настраивается в массиве `passwords` вашего файла конфигурации `config/auth.php`. Чтобы узнать больше о создании пользовательских поставщиков служб, обратитесь к [документации по аутентификации](authentication#adding-custom-user-providers). 151 | 152 | 153 | ## Удаление просроченных токенов 154 | 155 | Токены сброса пароля с истекшим сроком действия будут по-прежнему присутствовать в вашей базе данных. Однако вы можете легко удалить эти записи, используя Artisan-команду `auth:clear-resets`: 156 | 157 | php artisan auth:clear-resets 158 | 159 | Если вы хотите автоматизировать этот процесс, рассмотрите возможность добавления команды в [планировщик](/docs/{{version}}/scheduling) вашего приложения: 160 | 161 | $schedule->command('auth:clear-resets')->everyFifteenMinutes(); 162 | 163 | 164 | ## Настройка 165 | 166 | 167 | #### Настройка ссылки для сброса 168 | 169 | Вы можете изменить URL-адрес ссылки для сброса пароля, используя метод `createUrlUsing` класса уведомлений `ResetPassword`. Этот метод принимает замыкание, которое получает экземпляр ожидающего уведомление пользователя, а также токен ссылки для сброса пароля. Как правило, вызов этого метода осуществляется в методе `boot` вашего поставщика служб `App\Providers\AuthServiceProvider`: 170 | 171 | use Illuminate\Auth\Notifications\ResetPassword; 172 | 173 | /** 174 | * Регистрация любых служб аутентификации / авторизации. 175 | * 176 | * @return void 177 | */ 178 | public function boot() 179 | { 180 | $this->registerPolicies(); 181 | 182 | ResetPassword::createUrlUsing(function ($user, string $token) { 183 | return 'https://example.com/reset-password?token='.$token; 184 | }); 185 | } 186 | 187 | 188 | #### Настройка уведомлений о сбросе пароля 189 | 190 | Вы можете легко изменить класс уведомления, используемый для отправки пользователю ссылки для сброса пароля. Для начала переопределите метод `sendPasswordResetNotification` в модели `App\Models\User`. В этом методе вы можете отправить уведомление, используя любой [класс уведомлений](notifications), созданный вами. Токен для сброса пароля – это первый аргумент, получаемый методом. Вы можете использовать этот `$token` для создания URL сброса пароля по вашему усмотрению и для дальнейшей отправки уведомления пользователю: 191 | 192 | use App\Notifications\ResetPasswordNotification; 193 | 194 | /** 195 | * Отправить пользователю уведомление о сбросе пароля. 196 | * 197 | * @param string $token 198 | * @return void 199 | */ 200 | public function sendPasswordResetNotification($token) 201 | { 202 | $url = 'https://example.com/reset-password?token='.$token; 203 | 204 | $this->notify(new ResetPasswordNotification($url)); 205 | } 206 | -------------------------------------------------------------------------------- /errors.md: -------------------------------------------------------------------------------- 1 | git 0f19f3d770b961aee8576b24deb394a0b9a2f7ad 2 | 3 | --- 4 | 5 | # Обработка ошибок (Exception) 6 | 7 | - [Введение](#introduction) 8 | - [Конфигурирование](#configuration) 9 | - [Обработчик исключений](#the-exception-handler) 10 | - [Отчет об исключениях](#reporting-exceptions) 11 | - [Игнорирование исключений по типу](#ignoring-exceptions-by-type) 12 | - [Отображение исключений](#rendering-exceptions) 13 | - [Отчетные и отображаемые исключения](#renderable-exceptions) 14 | - [Сопоставление исключений по типу](#mapping-exceptions-by-type) 15 | - [HTTP-исключения](#http-exceptions) 16 | - [Пользовательские страницы ошибок HTTP](#custom-http-error-pages) 17 | 18 | 19 | ## Введение 20 | 21 | Когда вы запускаете новый проект Laravel, обработка ошибок и исключений уже настроена для вас. Класс `App\Exceptions\Handler` – это то место, где все исключения, созданные вашим приложением, регистрируются и затем отображаются пользователю. В этой документации мы углубимся в этот класс. 22 | 23 | 24 | ## Конфигурирование 25 | 26 | Параметр `debug` в конфигурационном файле `config/app.php` определяет, сколько информации об ошибке фактически отобразится пользователю. По умолчанию этот параметр установлен, чтобы учесть значение переменной окружения `APP_DEBUG`, которая содержится в вашем файле `.env`. 27 | 28 | Во время локальной разработки вы должны установить для переменной окружения `APP_DEBUG` значение `true`. **Во время эксплуатации приложения это значение всегда должно быть `false`. Если в рабочем окружении будет установлено значение `true`, вы рискуете раскрыть конфиденциальные значения конфигурации конечным пользователям вашего приложения.** 29 | 30 | 31 | ## Обработчик исключений 32 | 33 | 34 | ### Отчет об исключениях 35 | 36 | Все исключения обрабатываются классом `App\Exceptions\Handler`. Этот класс содержит метод `register`, в котором вы можете зарегистрировать свои отчеты об исключениях и замыкания рендеринга. Мы подробно рассмотрим каждую из этих концепций. Отчеты об исключениях используются для регистрации исключений или отправки их во внешнюю службу, например [Flare](https://flareapp.io), [Bugsnag](https://bugsnag.com) или [Sentry](https://github.com/getsentry/sentry-laravel). По умолчанию исключения будут регистрироваться в соответствии с вашей конфигурацией [логирования](/docs/{{version}}/logging). Однако вы можете регистрировать исключения как хотите. 37 | 38 | Например, если вам нужно сообщать о различных типах исключений по-разному, вы можете использовать метод `reportable` для регистрации замыкания, которое должно быть выполнено, когда необходимо сообщить об исключении конкретного типа. Laravel определит о каком типе исключения сообщает замыкание с помощью типизации аргументов: 39 | 40 | use App\Exceptions\InvalidOrderException; 41 | 42 | /** 43 | * Зарегистрировать замыкания, обрабатывающие исключения приложения. 44 | * 45 | * @return void 46 | */ 47 | public function register() 48 | { 49 | $this->reportable(function (InvalidOrderException $e) { 50 | // 51 | }); 52 | } 53 | 54 | Когда вы регистрируете собственные замыкания для создания отчетов об исключениях, используя метод `reportable`, Laravel по-прежнему регистрирует исключение, используя конфигурацию логирования по умолчанию для приложения. Если вы хотите остановить распространение исключения в стек журналов по умолчанию, вы можете использовать метод `stop` при определении замыкания отчета или вернуть `false` из замыкания: 55 | 56 | $this->reportable(function (InvalidOrderException $e) { 57 | // 58 | })->stop(); 59 | 60 | $this->reportable(function (InvalidOrderException $e) { 61 | return false; 62 | }); 63 | 64 | > {tip} Чтобы настроить отчет об исключениях для переданного исключения, вы можете рассмотреть возможность использования [отчетных исключений](#renderable-exceptions). 65 | 66 | 67 | #### Глобальное содержимое журнала 68 | 69 | Если доступно, Laravel автоматически добавляет идентификатор текущего пользователя в каждое сообщение журнала исключения в качестве контекстных данных. Вы можете определить свои собственные глобальные контекстные данные, переопределив метод `context` класса `App\Exceptions\Handler` вашего приложения. Эта информация будет включена в каждое сообщение журнала исключения, написанное вашим приложением: 70 | 71 | /** 72 | * Получить переменные контекста по умолчанию для ведения журнала. 73 | * 74 | * @return array 75 | */ 76 | protected function context() 77 | { 78 | return array_merge(parent::context(), [ 79 | 'foo' => 'bar', 80 | ]); 81 | } 82 | 83 | 84 | #### Контекст журнала исключений 85 | 86 | Хотя добавление контекста в каждое сообщение журнала может быть полезно, иногда конкретное исключение может иметь уникальный контекст, который вы хотели бы включить в свои журналы. Определив метод `context` для конкретного исключения вашего приложения, вы можете указать любые данные, относящиеся к этому исключению, которые должны быть добавлены в запись журнала исключения: 87 | 88 | $this->orderId]; 106 | } 107 | } 108 | 109 | 110 | #### Помощник `report` 111 | 112 | По желанию может потребоваться сообщить об исключении, но продолжить обработку текущего запроса. Помощник `report` позволяет вам быстро сообщить об исключении через обработчик исключений, не отображая страницу с ошибкой для пользователя: 113 | 114 | public function isValid($value) 115 | { 116 | try { 117 | // Проверка `$value` ... 118 | } catch (Throwable $e) { 119 | report($e); 120 | 121 | return false; 122 | } 123 | } 124 | 125 | 126 | ### Игнорирование исключений по типу 127 | 128 | При создании приложения будут некоторые типы исключений, которые вы просто хотите игнорировать и никогда не сообщать о них. Обработчик исключений вашего приложения содержит свойство `$dontReport`, которое инициализируется пустым массивом. Ни о каких классах, добавленных в это свойство, никогда не будет сообщено; однако у них все еще может быть собственная логика отображения: 129 | 130 | use App\Exceptions\InvalidOrderException; 131 | 132 | /** 133 | * Список типов исключений, о которых не следует сообщать. 134 | * 135 | * @var array 136 | */ 137 | protected $dontReport = [ 138 | InvalidOrderException::class, 139 | ]; 140 | 141 | > {tip} За кулисами Laravel уже игнорирует для вас некоторые типы ошибок, такие как исключения, возникающие из-за ошибок 404 HTTP «не найдено» или 419 HTTP-ответ, сгенерированный при недопустимом CSRF-токене. 142 | 143 | 144 | ### Отображение исключений 145 | 146 | По умолчанию обработчик исключений Laravel будет преобразовывать исключения в HTTP-ответ за вас. Однако вы можете зарегистрировать свое замыкание для отображения исключений конкретного типа. Вы можете сделать это с помощью метода `renderable` обработчика исключений. 147 | 148 | Замыкание, переданное методу `renderable`, должно вернуть экземпляр `Illuminate\Http\Response`, который может быть сгенерирован с помощью функции `response`. Laravel определит, какой тип исключения отображает замыкание с помощью типизации аргументов: 149 | 150 | use App\Exceptions\InvalidOrderException; 151 | 152 | /** 153 | * Зарегистрировать замыкания, обрабатывающие исключения приложения. 154 | * 155 | * @return void 156 | */ 157 | public function register() 158 | { 159 | $this->renderable(function (InvalidOrderException $e, $request) { 160 | return response()->view('errors.invalid-order', [], 500); 161 | }); 162 | } 163 | 164 | 165 | Вы также можете использовать метод `renderable` чтобы переопределить отображение для встроенных исключений Laravel или Symfony, таких, как `NotFoundHttpException`. Если замыкание, переданное методу `renderable` не возвращает значения, будет использоваться отрисовка исключений Laravel по умолчанию: 166 | 167 | use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 168 | 169 | /** 170 | * Зарегистрировать замыкания, обрабатывающие исключения приложения. 171 | * 172 | * @return void 173 | */ 174 | public function register() 175 | { 176 | $this->renderable(function (NotFoundHttpException $e, $request) { 177 | if ($request->is('api/*')) { 178 | return response()->json([ 179 | 'message' => 'Record not found.' 180 | ], 404); 181 | } 182 | }); 183 | } 184 | 185 | 186 | ### Отчетные и отображаемые исключения 187 | 188 | Вместо проверки типов исключений в методе `register` обработчика исключений вы можете определить методы `report` и `render` непосредственно для ваших исключений. Если эти методы существуют, то они будут автоматически вызываться фреймворком: 189 | 190 | {tip} Вы можете указать любые требуемые зависимости метода `report`, и они будут автоматически внедрены в метод [контейнером служб](/docs/{{version}}/container) Laravel. 251 | 252 | 253 | ### Сопоставление исключений по типу 254 | 255 | Иногда сторонние библиотеки, используемые вашим приложением, могут генерировать исключения, которые вы хотите сделать доступными для [рендеринга](#renderable-exceptions), но не можете этого сделать, потому что у вас нет контроля над определениями сторонних исключений. 256 | 257 | К счастью, Laravel позволяет вам удобно сопоставлять эти исключения с другими типами исключений, которыми вы управляете в своем приложении. Для этого вызовите метод `map` из метода `register` вашего обработчика исключений : 258 | 259 | use League\Flysystem\Exception; 260 | use App\Exceptions\FilesystemException; 261 | 262 | /** 263 | * Register the exception handling callbacks for the application. 264 | * 265 | * @return void 266 | */ 267 | public function register() 268 | { 269 | $this->map(Exception::class, FilesystemException::class); 270 | } 271 | 272 | Если вы хотите больше контролировать создание целевого исключения, вы можете передать методу `map` замыкание: 273 | 274 | use League\Flysystem\Exception; 275 | use App\Exceptions\FilesystemException; 276 | 277 | $this->map(fn (Exception $e) => new FilesystemException($e)); 278 | 279 | 280 | ## HTTP-исключения 281 | 282 | Некоторые исключения описывают коды HTTP-ошибок с сервера. Например, это может быть ошибка «страница не найдена» (404), «неавторизованный доступ» (401) или даже ошибка 500, сгенерированная разработчиком. Чтобы создать такой ответ из любой точки вашего приложения, вы можете использовать глобальный помощник `abort`: 283 | 284 | abort(404); 285 | 286 | 287 | ### Пользовательские страницы ошибок HTTP 288 | 289 | Laravel позволяет легко отображать пользовательские страницы ошибок для различных кодов состояния HTTP. Например, если вы хотите настроить страницу ошибок для кодов HTTP-состояния 404, создайте файл `resources/views/errors/404.blade.php`. Это представление будет отображено для всех ошибок 404, сгенерированных вашим приложением. Шаблоны в этом каталоге должны быть названы в соответствии с кодом состояния HTTP, которому они соответствуют. Экземпляр `Symfony\Component\HttpKernel\Exception\HttpException`, вызванный функцией `abort`, будет передан в шаблон как переменная `$exception`: 290 | 291 |

{{ $exception->getMessage() }}

292 | 293 | Вы можете опубликовать стандартные шаблоны страниц ошибок Laravel с помощью команды `vendor:publish` Artisan. После публикации шаблонов вы можете настроить их по своему вкусу: 294 | 295 | php artisan vendor:publish --tag=laravel-errors 296 | -------------------------------------------------------------------------------- /structure.md: -------------------------------------------------------------------------------- 1 | git 311a648538475de7e04c24bfa922e3c12288154a 2 | 3 | --- 4 | 5 | # Структура каталогов 6 | 7 | - [Введение](#introduction) 8 | - [Корневой каталог](#the-root-directory) 9 | - [Каталог `app`](#the-root-app-directory) 10 | - [Каталог `bootstrap`](#the-bootstrap-directory) 11 | - [Каталог `config`](#the-config-directory) 12 | - [Каталог `database`](#the-database-directory) 13 | - [Каталог `public`](#the-public-directory) 14 | - [Каталог `resources`](#the-resources-directory) 15 | - [Каталог `routes`](#the-routes-directory) 16 | - [Каталог `storage`](#the-storage-directory) 17 | - [Каталог `tests`](#the-tests-directory) 18 | - [Каталог `vendor`](#the-vendor-directory) 19 | - [Каталог пространства `App`](#the-app-directory) 20 | - [Каталог пространства `Broadcasting`](#the-broadcasting-directory) 21 | - [Каталог пространства `Console`](#the-console-directory) 22 | - [Каталог пространства `Events`](#the-events-directory) 23 | - [Каталог пространства `Exceptions`](#the-exceptions-directory) 24 | - [Каталог пространства `Http`](#the-http-directory) 25 | - [Каталог пространства `Jobs`](#the-jobs-directory) 26 | - [Каталог пространства `Listeners`](#the-listeners-directory) 27 | - [Каталог пространства `Mail`](#the-mail-directory) 28 | - [Каталог пространства `Models`](#the-models-directory) 29 | - [Каталог пространства `Notifications`](#the-notifications-directory) 30 | - [Каталог пространства `Policies`](#the-policies-directory) 31 | - [Каталог пространства `Providers`](#the-providers-directory) 32 | - [Каталог пространства `Rules`](#the-rules-directory) 33 | 34 | 35 | ## Введение 36 | 37 | Структура приложения Laravel по умолчанию предназначена для обеспечения отличной отправной точки как для больших, так и небольших приложений. Но вы можете организовать свое приложение так, как вам нравится. Laravel почти не налагает ограничений на расположение любого конкретного класса, до тех пор, пока Composer может автоматически загружать класс. 38 | 39 | 40 | ## Корневой каталог 41 | 42 | 43 | #### Каталог `app` 44 | 45 | Каталог `app` содержит основной код вашего приложения. Вскоре мы рассмотрим этот каталог более подробно; однако почти все классы в вашем приложении будут в этом каталоге. 46 | 47 | 48 | #### Каталог `bootstrap` 49 | 50 | Каталог `bootstrap` содержит файл `app.php`, который загружает фреймворк. В этом каталоге также находится каталог `cache`, содержащий файлы, сгенерированные фреймворком для оптимизации производительности, например, файлы кеша маршрутов и служб. Обычно вам не нужно изменять какие-либо файлы в этом каталоге. 51 | 52 | 53 | #### Каталог `config` 54 | 55 | Каталог `config`, как следует из названия, содержит все файлы конфигурации вашего приложения. Отличная идея прочитать все эти файлы и ознакомиться со всеми доступными вам параметрами. 56 | 57 | 58 | #### Каталог `database` 59 | 60 | Каталог `database` содержит миграции ваших баз данных, фабрики моделей и наполнители. При желании вы также можете использовать этот каталог для хранения SQLite БД. 61 | 62 | 63 | #### Каталог `public` 64 | 65 | Каталог `public` содержит файл `index.php`, который является точкой входа для всех запросов, поступающих в ваше приложение, и конфигурирует автозагрузку. В этом каталоге также находятся ваши ресурсы, например, изображения, JavaScript и CSS. 66 | 67 | 68 | #### Каталог `resources` 69 | 70 | Каталог `resources` содержит ваши [шаблоны](/docs/{{version}}/views), а также ваши необработанные, нескомпилированные ресурсы, например, JavaScript или CSS. В этом каталоге также находятся все ваши языковые файлы. 71 | 72 | 73 | #### Каталог `routes` 74 | 75 | Каталог `routes` содержит все определения маршрутов для вашего приложения. По умолчанию в Laravel входит несколько файлов маршрутов: `web.php`, `api.php`, `console.php` и `channels.php`. 76 | 77 | Файл `web.php` содержит маршруты, которые `RouteServiceProvider` размещает в группе посредников `web`, обеспечивающие состояние сессии, защиту CSRF и шифрование файлов куки. Если в вашем приложении не предполагается сохранение состояния и RESTful API, то, скорее всего, все ваши маршруты будут определены в файле `web.php`. 78 | 79 | Файл `api.php` содержит маршруты, которые `RouteServiceProvider` размещает в группе посредников `api`. Эти маршруты не предполагают сохранения состояния, поэтому запросы, поступающие в приложение через эти маршруты, предназначены для аутентификации [с помощью токенов](/docs/{{version}}/sanctum) и не имеют доступа к состоянию сессии. 80 | 81 | В файле `console.php` вы можете определить все ваши анонимные консольные команды. Каждое замыкание привязано к экземпляру команды, что обеспечивает простой подход к взаимодействию с методами ввода-вывода каждой команды. Несмотря на то, что этот файл не определяет маршруты HTTP, он определяет точки входа (маршруты) в ваше консольное приложение. 82 | 83 | В файле `channels.php` вы можете зарегистрировать все каналы [трансляции событий](/docs/{{version}}/broadcasting), которые поддерживает ваше приложение. 84 | 85 | 86 | #### Каталог `storage` 87 | 88 | Каталог `storage` содержит ваши журналы (логи), скомпилированные шаблоны Blade, файлы сессий, кеша и другие файлы, созданные фреймворком. Этот каталог разделен на каталоги `app`, `framework`, и `logs`. Каталог `app` может использоваться для хранения любых файлов, созданных вашим приложением. Каталог `framework` используется для хранения файлов и кешей, сгенерированных фреймворком. Наконец, каталог `logs` содержит файлы журнала вашего приложения. 89 | 90 | Каталог `storage/app/public` может использоваться для хранения файлов, созданных пользователями, таких как аватары профиля, которые должны быть общедоступными. Вы должны создать символическую ссылку (ярлык) в `public/storage`, которая указывает на этот каталог. Вы можете создать ссылку, используя команду `php artisan storage:link` Artisan. 91 | 92 | 93 | #### Каталог `tests` 94 | 95 | Каталог `tests` содержит ваши автоматизированные тесты. Примеры модульного [PHPUnit](https://phpunit.de/) и функционального тестов предоставляются из коробки. Каждый тестовый класс должен иметь суффикс `Test`. Вы можете запускать свои тесты с помощью команд `phpunit` или `php vendor/bin/phpunit`. Или, если вы хотите более подробное и красивое отображение результатов ваших тестов, вы можете запускать свои тесты с помощью команды `php artisan test` Artisan. 96 | 97 | 98 | #### Каталог `vendor` 99 | 100 | Каталог `vendor` содержит ваши [Composer](https://getcomposer.org)-зависимости. 101 | 102 | 103 | ## Каталог пространства `App` 104 | 105 | Большая часть вашего приложения находится в каталоге `app`. По умолчанию этот каталог находится в пространстве имен `App` и автоматически загружается Composer с использованием [автозагрузчика стандарта PSR-4](https://www.php-fig.org/psr/psr-4/). 106 | 107 | Каталог `app` содержит множество дополнительных каталогов, например, имеющих пространство `Console`, `Http`, и `Providers`. Думайте о каталогах `Console` и `Http` как о API-проводнике ядра вашего приложения. Протокол HTTP и интерфейс командной строки являются механизмами взаимодействия с вашим приложением, но фактически не содержат логики приложения. Другими словами – это два способа передачи команд вашему приложению. Каталог `Console` содержит все ваши Artisan-команды, тогда как каталог `Http` содержит контроллеры, посредники и запросы. 108 | 109 | Множество других каталогов будет создано внутри каталога `app`, когда вы будете использовать команды `make` Artisan для создания классов. Так, например, каталог `app/Jobs` не будет существовать, пока вы не выполните команду `make:job` Artisan для создания класса задания. 110 | 111 | > {tip} Многие классы в каталоге `app` могут быть созданы с помощью команд Artisan. Чтобы просмотреть доступные команды, выполните команду `php artisan list make` в консоли. 112 | 113 | 114 | #### Каталог пространства `Broadcasting` 115 | 116 | Каталог `Broadcasting` содержит все классы широковещательных каналов для вашего приложения. Эти классы генерируются с помощью команды `make:channel`. Этот каталог не существует по умолчанию, но будет создан для вас, когда вы создадите свой первый канал. Чтобы узнать больше о каналах, ознакомьтесь с документацией по [трансляции событий](/docs/{{version}}/broadcasting). 117 | 118 | 119 | #### Каталог пространства `Console` 120 | 121 | Каталог `Console` содержит все ваши Artisan-команды приложения. Эти команды могут быть созданы с помощью команды `make:command`. В этом каталоге также находится ядро вашей консоли, в котором регистрируются ваши пользовательские команды Artisan и определены ваши [запланированные задачи](/docs/{{version}}/scheduling). 122 | 123 | 124 | #### Каталог пространства `Events` 125 | 126 | Этот каталог не существует по умолчанию, но будет создан для вас, если вы выполните команды `event:generate` или `make:event` Artisan. В каталоге `Events` находятся [классы событий](/docs/{{version}}/events). События могут использоваться для предупреждения других частей вашего приложения о том, что произошло определенное действие, обеспечивая большую гибкость. 127 | 128 | 129 | #### Каталог пространства `Exceptions` 130 | 131 | Каталог `Exceptions` содержит обработчик исключений вашего приложения, а также является хорошим местом для размещения любых исключений, генерируемых вашим приложением. Если вы хотите скорректировать как ваши исключения будут отображаться или записываться в журнал, вам следует изменить класс `Handler` в этом каталоге. 132 | 133 | 134 | #### Каталог пространства `Http` 135 | 136 | Каталог `Http` содержит ваши контроллеры, посредники и запросы форм. Практически вся логика обработки запросов, поступающих в ваше приложение, будет размещена в этом каталоге. 137 | 138 | 139 | #### Каталог пространства `Jobs` 140 | 141 | Этот каталог не существует по умолчанию, но будет создан для вас, если вы выполните команду `make:job` Artisan. В каталоге `Jobs` находятся [планировщики заданий](/docs/{{version}}/queues) вашего приложения. Задания могут быть поставлены в очередь вашим приложением или выполняться синхронно в рамках жизненного цикла текущего запроса. Задания, которые выполняются синхронно во время текущего запроса, иногда называют «командами», поскольку они являются реализацией [шаблона команды](https://ru.wikipedia.org/wiki/Команда_(шаблон_проектирования)). 142 | 143 | 144 | #### Каталог пространства `Listeners` 145 | 146 | Этот каталог не существует по умолчанию, но будет создан для вас, если вы выполните команды `event:generate` или `make:listener` Artisan. Каталог `Listeners` содержит классы, которые обрабатывают ваши [события](/docs/{{version}}/events). Слушатели событий получают экземпляр события и выполняют логику в ответ на запускаемое событие. Например, событие `UserRegistered` может обрабатываться слушателем `SendWelcomeEmail`. 147 | 148 | 149 | #### Каталог пространства `Mail` 150 | 151 | Этот каталог не существует по умолчанию, но будет создан для вас, если вы выполните команду `make:mail` Artisan. Каталог `Mail` содержит все ваши [классы для работы с электронными письмами](/docs/{{version}}/mail), отправляемыми вашим приложением. Почтовые объекты позволяют вам инкапсулировать всю логику создания электронной почты в один простой класс, который может быть отправлен с помощью метода `Mail::send`. 152 | 153 | 154 | #### Каталог пространства `Models` 155 | 156 | Каталог `Models` содержит все ваши [классы моделей Eloquent](/docs/{{version}}/eloquent). Laravel содержит библиотеку Eloquent ORM, предоставляющую красивую и простую реализацию ActiveRecord для работы с вашей базой данных. Каждая таблица базы данных имеет соответствующую «Модель», которая используется для взаимодействия с этой таблицей. Модели позволяют запрашивать данные в таблицах, а также вставлять новые записи в таблицу. 157 | 158 | 159 | #### Каталог пространства `Notifications` 160 | 161 | Этот каталог не существует по умолчанию, но будет создан для вас, если вы выполните команду `make:notification` Artisan. Каталог `Notifications` содержит все «транзакционные» [уведомления](notifications), которые отправляются вашим приложением. Например, простые уведомления о событиях, которые происходят в вашем приложении. Уведомления Laravel позволяют абстрагироваться от отправки уведомлений по различным драйверам, таким как электронная почта, Slack, SMS, или сохранение в базе данных. 162 | 163 | 164 | #### Каталог пространства `Policies` 165 | 166 | Этот каталог не существует по умолчанию, но будет создан для вас, если вы выполните команду `make:policy` Artisan. Каталог `Policies` содержит [классы политик авторизации](authorization) вашего приложения. Политики используются для определения того, может ли пользователь выполнить определенное действие с ресурсом. 167 | 168 | 169 | #### Каталог пространства `Providers` 170 | 171 | Каталог `Providers` содержит всех [поставщиков служб](/docs/{{version}}/providers) вашего приложения. Поставщики служб загружают ваше приложение, связывая службы в контейнере служб, регистрируя события или выполняя любые другие задачи для подготовки вашего приложения к входящим запросам. 172 | 173 | В новом приложении Laravel этот каталог уже будет содержать несколько провайдеров. При необходимости вы можете добавить свои собственные провайдеры в этот каталог. 174 | 175 | 176 | #### Каталог пространства `Rules` 177 | 178 | Этот каталог не существует по умолчанию, но будет создан для вас, если вы выполните команду `make:rule` Artisan. Каталог `Rules` содержит пользовательские объекты правил валидации вашего приложения. Правила используются для инкапсуляции сложной логики проверки в простой объект. Для получения дополнительной информации ознакомьтесь с [документацией по валидации](/docs/{{version}}/validation). 179 | --------------------------------------------------------------------------------