このドキュメントは現在翻訳中です。一部のページが韓国語で表示される場合があります。
メインコンテンツまでスキップ
バージョン: 13.x

Artisan 콘솔 (Artisan Console)

소개 (Introduction)

Artisan은 Laravel에 포함된 명령줄 인터페이스입니다. Artisan은 애플리케이션 루트에 artisan 스크립트로 존재하며, 애플리케이션을 개발하는 동안 도움이 되는 여러 명령어를 제공합니다. 사용 가능한 모든 Artisan 명령어 목록을 보려면 list 명령어를 사용할 수 있습니다.

php artisan list

모든 명령어에는 해당 명령어에서 사용할 수 있는 인수와 옵션을 표시하고 설명하는 "help" 화면도 포함되어 있습니다. help 화면을 보려면 명령어 이름 앞에 help를 붙입니다.

php artisan help migrate

Laravel Sail

로컬 개발 환경으로 Laravel Sail을 사용하고 있다면, Artisan 명령어를 호출할 때 sail 명령줄을 사용해야 한다는 점을 기억하세요. Sail은 애플리케이션의 Docker 컨테이너 안에서 Artisan 명령어를 실행합니다.

./vendor/bin/sail artisan list

Tinker (REPL)

Laravel TinkerPsySH 패키지를 기반으로 동작하는 Laravel 프레임워크용 강력한 REPL입니다.

설치

모든 Laravel 애플리케이션에는 기본적으로 Tinker가 포함되어 있습니다. 하지만 애플리케이션에서 Tinker를 이전에 제거했다면 Composer를 사용하여 다시 설치할 수 있습니다.

composer require laravel/tinker

Laravel 애플리케이션과 상호작용할 때 핫 리로딩, 여러 줄 코드 편집, 자동 완성을 찾고 있나요? Tinkerwell을 확인해 보세요!

사용법

Tinker를 사용하면 명령줄에서 Eloquent 모델, 작업, 이벤트 등을 포함한 Laravel 애플리케이션 전체와 상호작용할 수 있습니다. Tinker 환경에 진입하려면 tinker Artisan 명령어를 실행합니다.

php artisan tinker

vendor:publish 명령어를 사용하여 Tinker의 설정 파일을 게시할 수 있습니다.

php artisan vendor:publish --provider="Laravel\Tinker\TinkerServiceProvider"

dispatch 헬퍼 함수와 Dispatchable 클래스의 dispatch 메서드는 작업을 큐에 넣기 위해 가비지 컬렉션에 의존합니다. 따라서 Tinker를 사용할 때는 작업을 디스패치하려면 Bus::dispatch 또는 Queue::push를 사용해야 합니다.

명령어 허용 목록

Tinker는 셸 안에서 실행할 수 있는 Artisan 명령어를 결정하기 위해 "allow" 목록을 사용합니다. 기본적으로 clear-compiled, down, env, inspire, migrate, migrate:install, up, optimize 명령어를 실행할 수 있습니다. 더 많은 명령어를 허용하려면 tinker.php 설정 파일의 commands 배열에 추가할 수 있습니다.

'commands' => [
// App\Console\Commands\ExampleCommand::class,
],

별칭으로 지정하지 않아야 하는 클래스

일반적으로 Tinker는 Tinker에서 클래스와 상호작용할 때 해당 클래스에 자동으로 별칭을 지정합니다. 하지만 일부 클래스는 절대 별칭으로 지정하지 않기를 원할 수 있습니다. 이 경우 tinker.php 설정 파일의 dont_alias 배열에 해당 클래스를 나열하면 됩니다.

'dont_alias' => [
App\Models\User::class,
],

명령어 작성하기 (Writing Commands)

Artisan에서 제공하는 명령어 외에도 직접 커스텀 명령어를 만들 수 있습니다. 명령어는 일반적으로 app/Console/Commands 디렉터리에 저장되지만, Laravel에 다른 디렉터리에서 Artisan 명령어를 스캔하도록 지시한다면 원하는 저장 위치를 자유롭게 선택할 수 있습니다.

명령어 생성하기

새 명령어를 생성하려면 make:command Artisan 명령어를 사용할 수 있습니다. 이 명령어는 app/Console/Commands 디렉터리에 새 명령어 클래스를 생성합니다. 애플리케이션에 이 디렉터리가 없어도 걱정하지 마세요. make:command Artisan 명령어를 처음 실행할 때 생성됩니다.

php artisan make:command SendEmails

명령어 구조

명령어를 생성한 후에는 SignatureDescription 속성을 사용하여 명령어의 시그니처와 설명을 정의해야 합니다. Signature 속성을 사용하면 명령어의 입력 기대값도 정의할 수 있습니다. 명령어가 실행되면 handle 메서드가 호출됩니다. 이 메서드 안에 명령어 로직을 작성할 수 있습니다.

예제 명령어를 살펴보겠습니다. 명령어의 handle 메서드를 통해 필요한 의존성을 요청할 수 있다는 점에 주목하세요. Laravel 서비스 컨테이너는 이 메서드의 시그니처에 타입 힌트된 모든 의존성을 자동으로 주입합니다.

<?php

namespace App\Console\Commands;

use App\Models\User;
use App\Support\DripEmailer;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;

#[Signature('mail:send {user}')]
#[Description('Send a marketing email to a user')]
class SendEmails extends Command
{
/**
* Execute the console command.
*/
public function handle(DripEmailer $drip): void
{
$drip->send(User::find($this->argument('user')));
}
}

코드를 더 잘 재사용하려면 콘솔 명령어는 가볍게 유지하고, 실제 작업은 애플리케이션 서비스에 위임하는 것이 좋습니다. 위 예제에서는 이메일 전송이라는 "무거운 작업"을 수행하기 위해 서비스 클래스를 주입한다는 점에 주목하세요.

종료 코드

handle 메서드에서 아무것도 반환하지 않고 명령어가 성공적으로 실행되면, 명령어는 성공을 의미하는 0 종료 코드로 종료됩니다. 하지만 handle 메서드는 명령어의 종료 코드를 직접 지정하기 위해 선택적으로 정수를 반환할 수 있습니다.

$this->error('Something went wrong.');

return 1;

명령어 안의 어떤 메서드에서든 명령어를 "실패" 처리하고 싶다면 fail 메서드를 사용할 수 있습니다. fail 메서드는 즉시 명령어 실행을 종료하고 1 종료 코드를 반환합니다.

$this->fail('Something went wrong.');

클로저 명령어

클로저 기반 명령어는 콘솔 명령어를 클래스로 정의하는 방식의 대안입니다. 라우트 클로저가 컨트롤러의 대안인 것처럼, 명령어 클로저는 명령어 클래스의 대안이라고 생각하면 됩니다.

routes/console.php 파일은 HTTP 라우트를 정의하지는 않지만, 애플리케이션으로 진입하는 콘솔 기반 진입점(라우트)을 정의합니다. 이 파일 안에서 Artisan::command 메서드를 사용하여 모든 클로저 기반 콘솔 명령어를 정의할 수 있습니다. command 메서드는 두 개의 인수를 받습니다. 명령어 시그니처와 명령어의 인수 및 옵션을 받는 클로저입니다.

Artisan::command('mail:send {user}', function (string $user) {
$this->info("Sending email to: {$user}!");
});

클로저는 내부 명령어 인스턴스에 바인딩되므로, 일반적인 전체 명령어 클래스에서 접근할 수 있는 모든 헬퍼 메서드에 그대로 접근할 수 있습니다.

의존성 타입 힌트

명령어의 인수와 옵션을 받는 것 외에도, 명령어 클로저는 서비스 컨테이너에서 해결하고 싶은 추가 의존성을 타입 힌트할 수 있습니다.

use App\Models\User;
use App\Support\DripEmailer;
use Illuminate\Support\Facades\Artisan;

Artisan::command('mail:send {user}', function (DripEmailer $drip, string $user) {
$drip->send(User::find($user));
});

클로저 명령어 설명

클로저 기반 명령어를 정의할 때 purpose 메서드를 사용하여 명령어에 설명을 추가할 수 있습니다. 이 설명은 php artisan list 또는 php artisan help 명령어를 실행할 때 표시됩니다.

Artisan::command('mail:send {user}', function (string $user) {
// ...
})->purpose('Send a marketing email to a user');

격리 가능한 명령어

이 기능을 사용하려면 애플리케이션의 기본 캐시 드라이버로 memcached, redis, dynamodb, database, file, array 캐시 드라이버 중 하나를 사용해야 합니다. 또한 모든 서버가 동일한 중앙 캐시 서버와 통신해야 합니다.

때로는 명령어 인스턴스가 한 번에 하나만 실행되도록 보장하고 싶을 수 있습니다. 이를 위해 명령어 클래스에 Illuminate\Contracts\Console\Isolatable 인터페이스를 구현할 수 있습니다.

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Contracts\Console\Isolatable;

class SendEmails extends Command implements Isolatable
{
// ...
}

명령어를 Isolatable로 표시하면 Laravel은 명령어의 옵션에 명시적으로 정의하지 않아도 해당 명령어에서 --isolated 옵션을 자동으로 사용할 수 있게 합니다. 이 옵션과 함께 명령어를 호출하면 Laravel은 같은 명령어의 다른 인스턴스가 이미 실행 중이지 않은지 확인합니다. Laravel은 애플리케이션의 기본 캐시 드라이버를 사용해 원자적 잠금을 획득하려고 시도하여 이를 수행합니다. 명령어의 다른 인스턴스가 실행 중이라면 명령어는 실행되지 않습니다. 하지만 명령어는 여전히 성공 종료 상태 코드로 종료됩니다.

php artisan mail:send 1 --isolated

명령어를 실행할 수 없을 때 반환할 종료 상태 코드를 지정하려면 isolated 옵션을 통해 원하는 상태 코드를 제공할 수 있습니다.

php artisan mail:send 1 --isolated=12

잠금 ID

기본적으로 Laravel은 애플리케이션 캐시에서 원자적 잠금을 획득하는 데 사용할 문자열 키를 생성하기 위해 명령어 이름을 사용합니다. 하지만 Artisan 명령어 클래스에 isolatableId 메서드를 정의하여 이 키를 커스터마이징할 수 있으며, 이를 통해 명령어의 인수나 옵션을 키에 포함할 수 있습니다.

/**
* Get the isolatable ID for the command.
*/
public function isolatableId(): string
{
return $this->argument('user');
}

잠금 만료 시간

기본적으로 격리 잠금은 명령어가 완료된 후 만료됩니다. 또는 명령어가 중단되어 완료되지 못한 경우 잠금은 한 시간 후에 만료됩니다. 하지만 명령어에 isolationLockExpiresAt 메서드를 정의하여 잠금 만료 시간을 조정할 수 있습니다.

use DateTimeInterface;
use DateInterval;

/**
* Determine when an isolation lock expires for the command.
*/
public function isolationLockExpiresAt(): DateTimeInterface|DateInterval
{
return now()->plus(minutes: 5);
}

입력 기대값 정의하기 (Defining Input Expectations)

콘솔 명령어를 작성할 때는 인수나 옵션을 통해 사용자로부터 입력을 수집하는 일이 흔합니다. Laravel은 명령어의 signature 속성을 사용하여 사용자에게 기대하는 입력을 매우 편리하게 정의할 수 있게 해 줍니다. signature 속성을 사용하면 명령어의 이름, 인수, 옵션을 하나의 표현력 있는 라우트와 비슷한 문법으로 정의할 수 있습니다.

인수

사용자가 제공하는 모든 인수와 옵션은 중괄호로 감쌉니다. 다음 예제에서 명령어는 하나의 필수 인수인 user를 정의합니다.

/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mail:send {user}';

인수를 선택 사항으로 만들거나 인수의 기본값을 정의할 수도 있습니다.

// Optional argument...
'mail:send {user?}'

// Optional argument with default value...
'mail:send {user=foo}'

옵션

옵션은 인수와 마찬가지로 사용자 입력의 또 다른 형태입니다. 명령줄을 통해 옵션을 제공할 때는 두 개의 하이픈(--)을 접두사로 붙입니다. 옵션에는 값을 받는 옵션과 값을 받지 않는 옵션, 두 가지 유형이 있습니다. 값을 받지 않는 옵션은 불리언 "스위치" 역할을 합니다. 이 유형의 옵션 예제를 살펴보겠습니다.

/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mail:send {user} {--queue}';

이 예제에서 Artisan 명령어를 호출할 때 --queue 스위치를 지정할 수 있습니다. --queue 스위치가 전달되면 옵션 값은 true가 됩니다. 그렇지 않으면 값은 false가 됩니다.

php artisan mail:send 1 --queue

값을 가지는 옵션

다음으로 값을 기대하는 옵션을 살펴보겠습니다. 사용자가 옵션에 값을 반드시 지정해야 한다면 옵션 이름 뒤에 = 기호를 붙여야 합니다.

/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mail:send {user} {--queue=}';

이 예제에서 사용자는 다음과 같이 옵션 값을 전달할 수 있습니다. 명령어를 호출할 때 옵션을 지정하지 않으면 해당 값은 null이 됩니다.

php artisan mail:send 1 --queue=default

옵션 이름 뒤에 기본값을 지정하여 옵션에 기본값을 할당할 수 있습니다. 사용자가 옵션 값을 전달하지 않으면 기본값이 사용됩니다.

'mail:send {user} {--queue=default}'

옵션 단축키

옵션을 정의할 때 단축키를 할당하려면 옵션 이름 앞에 단축키를 지정하고, | 문자를 구분자로 사용하여 단축키와 전체 옵션 이름을 구분할 수 있습니다.

'mail:send {user} {--Q|queue=}'

터미널에서 명령어를 호출할 때 옵션 단축키에는 하나의 하이픈을 접두사로 붙여야 하며, 옵션 값을 지정할 때 = 문자는 포함하지 않아야 합니다.

php artisan mail:send 1 -Qdefault

입력 배열

여러 입력 값을 기대하는 인수나 옵션을 정의하려면 * 문자를 사용할 수 있습니다. 먼저 이러한 인수를 지정하는 예제를 살펴보겠습니다.

'mail:send {user*}'

이 명령어를 실행할 때 user 인수는 명령줄에 순서대로 전달할 수 있습니다. 예를 들어 다음 명령어는 user 값을 12를 값으로 가지는 배열로 설정합니다.

php artisan mail:send 1 2

* 문자는 선택적 인수 정의와 결합하여 인수가 0개 이상 올 수 있도록 허용할 수 있습니다.

'mail:send {user?*}'

옵션 배열

여러 입력 값을 기대하는 옵션을 정의할 때는 명령어에 전달되는 각 옵션 값 앞에 옵션 이름을 붙여야 합니다.

'mail:send {--id=*}'

이러한 명령어는 여러 개의 --id 인수를 전달하여 호출할 수 있습니다.

php artisan mail:send --id=1 --id=2

입력 설명

입력 인수와 옵션에는 인수 이름과 설명을 콜론으로 구분하여 설명을 지정할 수 있습니다. 명령어를 정의할 공간이 조금 더 필요하다면, 정의를 여러 줄로 나누어 작성해도 됩니다.

/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mail:send
{user : The ID of the user}
{--queue : Whether the job should be queued}';

누락된 입력 요청

명령어에 필수 인수가 포함되어 있는데 사용자가 이를 제공하지 않으면 오류 메시지가 표시됩니다. 또는 PromptsForMissingInput 인터페이스를 구현하여 필수 인수가 누락되었을 때 명령어가 사용자에게 자동으로 입력을 요청하도록 설정할 수 있습니다.

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Contracts\Console\PromptsForMissingInput;

class SendEmails extends Command implements PromptsForMissingInput
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mail:send {user}';

// ...
}

Laravel이 사용자로부터 필수 인수를 받아야 하는 경우, 인수 이름이나 설명을 활용해 질문 문장을 적절히 만들어 사용자에게 자동으로 해당 인수를 묻습니다. 필수 인수를 받기 위해 사용할 질문을 직접 지정하고 싶다면 promptForMissingArgumentsUsing 메서드를 구현하면 됩니다. 이 메서드는 인수 이름을 키로 하는 질문 배열을 반환해야 합니다.

/**
* Prompt for missing input arguments using the returned questions.
*
* @return array<string, string>
*/
protected function promptForMissingArgumentsUsing(): array
{
return [
'user' => 'Which user ID should receive the mail?',
];
}

질문과 플레이스홀더를 포함하는 튜플을 사용하여 플레이스홀더 텍스트도 제공할 수 있습니다.

return [
'user' => ['Which user ID should receive the mail?', 'E.g. 123'],
];

프롬프트를 완전히 직접 제어하고 싶다면, 사용자에게 입력을 요청하고 그 답변을 반환하는 클로저를 제공할 수 있습니다.

use App\Models\User;
use function Laravel\Prompts\search;

// ...

return [
'user' => fn () => search(
label: 'Search for a user:',
placeholder: 'E.g. Taylor Otwell',
options: fn ($value) => strlen($value) > 0
? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()
: []
),
];

포괄적인 Laravel Prompts 문서에는 사용할 수 있는 프롬프트와 사용법에 대한 추가 정보가 포함되어 있습니다.

사용자가 options를 선택하거나 입력하도록 요청하고 싶다면, 명령어의 handle 메서드 안에 프롬프트를 포함할 수 있습니다. 하지만 누락된 인수에 대해 자동으로 프롬프트가 표시된 경우에만 사용자에게 추가로 묻고 싶다면 afterPromptingForMissingArguments 메서드를 구현할 수 있습니다.

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use function Laravel\Prompts\confirm;

// ...

/**
* Perform actions after the user was prompted for missing arguments.
*/
protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output): void
{
$input->setOption('queue', confirm(
label: 'Would you like to queue the mail?',
default: $this->option('queue')
));
}

명령어 I/O (Command I/O)

입력 가져오기

명령어가 실행되는 동안에는 명령어가 받는 인수와 옵션의 값에 접근해야 할 때가 많습니다. 이를 위해 argumentoption 메서드를 사용할 수 있습니다. 인수나 옵션이 존재하지 않으면 null이 반환됩니다.

/**
* Execute the console command.
*/
public function handle(): void
{
$userId = $this->argument('user');
}

모든 인수를 array로 가져와야 한다면 arguments 메서드를 호출하세요.

$arguments = $this->arguments();

옵션도 인수와 마찬가지로 option 메서드를 사용해 쉽게 가져올 수 있습니다. 모든 옵션을 배열로 가져오려면 options 메서드를 호출하세요.

// Retrieve a specific option...
$queueName = $this->option('queue');

// Retrieve all options as an array...
$options = $this->options();

입력 요청

Laravel Prompts는 명령줄 애플리케이션에 아름답고 사용하기 쉬운 폼을 추가하기 위한 PHP 패키지입니다. 플레이스홀더 텍스트와 유효성 검증을 포함한 브라우저와 비슷한 기능을 제공합니다.

출력을 표시하는 것뿐만 아니라, 명령어 실행 중에 사용자에게 입력을 요청할 수도 있습니다. ask 메서드는 주어진 질문을 사용자에게 표시하고, 사용자의 입력을 받은 뒤, 그 입력을 명령어로 반환합니다.

/**
* Execute the console command.
*/
public function handle(): void
{
$name = $this->ask('What is your name?');

// ...
}

ask 메서드는 선택적으로 두 번째 인수를 받을 수도 있습니다. 이 인수는 사용자가 아무 입력도 하지 않았을 때 반환할 기본값을 지정합니다.

$name = $this->ask('What is your name?', 'Taylor');

secret 메서드는 ask와 비슷하지만, 사용자가 콘솔에 입력하는 동안 입력값이 화면에 보이지 않습니다. 이 메서드는 비밀번호처럼 민감한 정보를 요청할 때 유용합니다.

$password = $this->secret('What is the password?');

확인 요청

사용자에게 간단한 "예 또는 아니오" 확인을 요청해야 한다면 confirm 메서드를 사용할 수 있습니다. 기본적으로 이 메서드는 false를 반환합니다. 하지만 사용자가 프롬프트에 대한 응답으로 y 또는 yes를 입력하면 true를 반환합니다.

if ($this->confirm('Do you wish to continue?')) {
// ...
}

필요하다면 confirm 메서드의 두 번째 인수로 true를 전달하여 확인 프롬프트의 기본 반환값이 true가 되도록 지정할 수 있습니다.

if ($this->confirm('Do you wish to continue?', true)) {
// ...
}

자동 완성

anticipate 메서드는 가능한 선택지에 대한 자동 완성을 제공하는 데 사용할 수 있습니다. 사용자는 자동 완성 힌트와 관계없이 어떤 답변이든 입력할 수 있습니다.

$name = $this->anticipate('What is your name?', ['Taylor', 'Dayle']);

또는 anticipate 메서드의 두 번째 인수로 클로저를 전달할 수 있습니다. 이 클로저는 사용자가 입력 문자를 하나씩 입력할 때마다 호출됩니다. 클로저는 지금까지의 사용자 입력을 담은 문자열 파라미터를 받아야 하며, 자동 완성 옵션 배열을 반환해야 합니다.

use App\Models\Address;

$name = $this->anticipate('What is your address?', function (string $input) {
return Address::whereLike('name', "{$input}%")
->limit(5)
->pluck('name')
->all();
});

객관식 질문

질문을 할 때 사용자에게 미리 정의된 선택지 목록을 제공해야 한다면 choice 메서드를 사용할 수 있습니다. 사용자가 아무 옵션도 선택하지 않았을 때 반환할 기본값은 해당 배열 인덱스를 메서드의 세 번째 인수로 전달하여 설정할 수 있습니다.

$name = $this->choice(
'What is your name?',
['Taylor', 'Dayle'],
$defaultIndex
);

또한 choice 메서드는 올바른 응답을 선택할 수 있는 최대 시도 횟수와 여러 선택을 허용할지 여부를 결정하기 위해 선택적인 네 번째와 다섯 번째 인수를 받습니다.

$name = $this->choice(
'What is your name?',
['Taylor', 'Dayle'],
$defaultIndex,
$maxAttempts = null,
$allowMultipleSelections = false
);

출력 작성

콘솔로 출력을 보내려면 line, newLine, info, comment, question, warn, alert, error 메서드를 사용할 수 있습니다. 각 메서드는 목적에 맞는 ANSI 색상을 사용합니다. 예를 들어 사용자에게 일반적인 정보를 표시해 보겠습니다. 일반적으로 info 메서드는 콘솔에 초록색 텍스트로 표시됩니다.

/**
* Execute the console command.
*/
public function handle(): void
{
// ...

$this->info('The command was successful!');
}

오류 메시지를 표시하려면 error 메서드를 사용하세요. 오류 메시지 텍스트는 일반적으로 빨간색으로 표시됩니다.

$this->error('Something went wrong!');

line 메서드를 사용하면 색상이 없는 일반 텍스트를 표시할 수 있습니다.

$this->line('Display this on the screen');

newLine 메서드를 사용하면 빈 줄을 표시할 수 있습니다.

// Write a single blank line...
$this->newLine();

// Write three blank lines...
$this->newLine(3);

테이블

table 메서드를 사용하면 여러 행 / 컬럼의 데이터를 올바른 형식으로 쉽게 출력할 수 있습니다. 컬럼 이름과 테이블 데이터를 제공하기만 하면 Laravel이 적절한 테이블 너비와 높이를 자동으로 계산해 줍니다.

use App\Models\User;

$this->table(
['Name', 'Email'],
User::all(['name', 'email'])->toArray()
);

진행률 표시줄

오래 실행되는 작업에서는 작업이 얼마나 완료되었는지 사용자에게 알려 주는 진행률 표시줄을 보여 주면 도움이 됩니다. withProgressBar 메서드를 사용하면 Laravel이 진행률 표시줄을 표시하고, 주어진 반복 가능한 값의 각 반복마다 진행률을 앞으로 이동시킵니다.

use App\Models\User;

$users = $this->withProgressBar(User::all(), function (User $user) {
$this->performTask($user);
});

때로는 진행률 표시줄이 어떻게 진행될지 더 직접적으로 제어해야 할 수 있습니다. 먼저 프로세스가 반복할 전체 단계 수를 정의합니다. 그런 다음 각 항목을 처리한 뒤 진행률 표시줄을 앞으로 이동시킵니다.

$users = App\Models\User::all();

$bar = $this->output->createProgressBar(count($users));

$bar->start();

foreach ($users as $user) {
$this->performTask($user);

$bar->advance();
}

$bar->finish();

더 고급 옵션은 Symfony Progress Bar component documentation을 확인하세요.

명령어 등록 (Registering Commands)

기본적으로 Laravel은 app/Console/Commands 디렉터리 안의 모든 명령어를 자동으로 등록합니다. 하지만 애플리케이션의 bootstrap/app.php 파일에서 withCommands 메서드를 사용하여 Laravel이 Artisan 명령어를 찾을 다른 디렉터리를 스캔하도록 지시할 수 있습니다.

->withCommands([
__DIR__.'/../app/Domain/Orders/Commands',
])

필요하다면 명령어의 클래스 이름을 withCommands 메서드에 제공하여 명령어를 직접 등록할 수도 있습니다.

use App\Domain\Orders\Commands\SendEmails;

->withCommands([
SendEmails::class,
])

Artisan이 부팅될 때, 애플리케이션의 모든 명령어는 서비스 컨테이너를 통해 해석되고 Artisan에 등록됩니다.

프로그래밍 방식으로 명령어 실행 (Programmatically Executing Commands)

때로는 CLI 외부에서 Artisan 명령어를 실행하고 싶을 수 있습니다. 예를 들어 라우트나 컨트롤러에서 Artisan 명령어를 실행하고 싶을 수 있습니다. 이를 위해 Artisan 파사드의 call 메서드를 사용할 수 있습니다. call 메서드는 첫 번째 인수로 명령어의 시그니처 이름이나 클래스 이름을 받고, 두 번째 인수로 명령어 파라미터 배열을 받습니다. 종료 코드가 반환됩니다.

use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Route;

Route::post('/user/{user}/mail', function (string $user) {
$exitCode = Artisan::call('mail:send', [
'user' => $user, '--queue' => 'default'
]);

// ...
});

또는 전체 Artisan 명령어를 문자열로 call 메서드에 전달할 수도 있습니다.

Artisan::call('mail:send 1 --queue=default');

배열 값 전달

명령어가 배열을 받는 옵션을 정의한다면, 해당 옵션에 값 배열을 전달할 수 있습니다.

use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Route;

Route::post('/mail', function () {
$exitCode = Artisan::call('mail:send', [
'--id' => [5, 13]
]);
});

불리언 값 전달

문자열 값을 받지 않는 옵션의 값을 지정해야 하는 경우가 있습니다. 예를 들어 migrate:refresh 명령어의 --force 플래그가 그렇습니다. 이 경우 옵션 값으로 true 또는 false를 전달해야 합니다.

$exitCode = Artisan::call('migrate:refresh', [
'--force' => true,
]);

Artisan 명령어 큐에 넣기

Artisan facade의 queue 메서드를 사용하면 Artisan 명령어를 큐에 넣어 큐 워커가 백그라운드에서 처리하도록 할 수도 있습니다. 이 메서드를 사용하기 전에 큐를 설정하고 큐 리스너를 실행 중인지 확인하세요.

use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Route;

Route::post('/user/{user}/mail', function (string $user) {
Artisan::queue('mail:send', [
'user' => $user, '--queue' => 'default'
]);

// ...
});

onConnectiononQueue 메서드를 사용하면 Artisan 명령어를 디스패치할 연결 또는 큐를 지정할 수 있습니다.

Artisan::queue('mail:send', [
'user' => 1, '--queue' => 'default'
])->onConnection('redis')->onQueue('commands');

다른 명령어에서 명령어 호출하기

기존 Artisan 명령어 안에서 다른 명령어를 호출하고 싶을 때가 있습니다. 이 작업은 call 메서드를 사용하여 수행할 수 있습니다. 이 call 메서드는 명령어 이름과 명령어 인수 / 옵션 배열을 받습니다.

/**
* Execute the console command.
*/
public function handle(): void
{
$this->call('mail:send', [
'user' => 1, '--queue' => 'default'
]);

// ...
}

다른 콘솔 명령어를 호출하면서 모든 출력을 표시하지 않으려면 callSilently 메서드를 사용할 수 있습니다. callSilently 메서드는 call 메서드와 동일한 시그니처를 가집니다.

$this->callSilently('mail:send', [
'user' => 1, '--queue' => 'default'
]);

시그널 처리 (Signal Handling)

아시다시피 운영 체제는 실행 중인 프로세스에 시그널을 보낼 수 있습니다. 예를 들어 SIGTERM 시그널은 운영 체제가 프로그램에 종료를 요청하는 방식입니다. Artisan 콘솔 명령어에서 시그널을 감지하고 시그널이 발생했을 때 코드를 실행하고 싶다면 trap 메서드를 사용할 수 있습니다.

/**
* Execute the console command.
*/
public function handle(): void
{
$this->trap(SIGTERM, fn () => $this->shouldKeepRunning = false);

while ($this->shouldKeepRunning) {
// ...
}
}

여러 시그널을 한 번에 감지하려면 trap 메서드에 시그널 배열을 전달하면 됩니다.

$this->trap([SIGTERM, SIGQUIT], function (int $signal) {
$this->shouldKeepRunning = false;

dump($signal); // SIGTERM / SIGQUIT
});

Stub 커스터마이징 (Stub Customization)

Artisan 콘솔의 make 명령어는 컨트롤러, job, migration, 테스트 등 다양한 클래스를 생성하는 데 사용됩니다. 이러한 클래스는 입력값을 기반으로 채워지는 "stub" 파일을 사용해 생성됩니다. 하지만 Artisan이 생성하는 파일을 조금 수정하고 싶을 수 있습니다. 이를 위해 stub:publish 명령어를 사용하여 가장 자주 사용되는 stub을 애플리케이션에 게시하고 직접 커스터마이징할 수 있습니다.

php artisan stub:publish

게시된 stub은 애플리케이션 루트의 stubs 디렉터리에 위치합니다. 이 stub에 변경한 내용은 Artisan의 make 명령어를 사용하여 해당 클래스를 생성할 때 반영됩니다.

이벤트 (Events)

Artisan은 명령어를 실행할 때 세 가지 이벤트를 디스패치합니다. Illuminate\Console\Events\ArtisanStarting, Illuminate\Console\Events\CommandStarting, Illuminate\Console\Events\CommandFinished입니다. ArtisanStarting 이벤트는 Artisan이 실행되기 시작하는 즉시 디스패치됩니다. 다음으로 CommandStarting 이벤트는 명령어가 실행되기 직전에 디스패치됩니다. 마지막으로 CommandFinished 이벤트는 명령어 실행이 완료되면 디스패치됩니다.