Artisan 콘솔
번역일: 2026년 6월 26일
Artisan 콘솔
소개
Artisan은 Laravel에 내장된 CLI(명령줄 인터페이스) 도구입니다. 프로젝트 루트의 artisan 스크립트를 통해 실행하며, 애플리케이션 개발에 유용한 다양한 커맨드를 제공합니다. 사용 가능한 모든 커맨드 목록을 보려면 list 커맨드를 사용하세요.
php artisan list각 커맨드에는 --help 플래그를 붙여 사용 가능한 인수와 옵션을 확인할 수 있습니다.
php artisan help migrateTinker (REPL)
Laravel Tinker는 Laravel 애플리케이션을 위한 강력한 REPL(Read-Eval-Print Loop) 환경으로, PsySH 패키지를 기반으로 합니다.
설치
모든 Laravel 애플리케이션에는 기본적으로 Tinker가 포함되어 있습니다. 단, 이전에 삭제한 경우 Composer를 통해 다시 설치할 수 있습니다.
composer require laravel/tinkerNOTE
Laravel 애플리케이션과 실시간으로 상호작용할 수 있는 GUI 도구를 찾고 있다면 Tinkerwell을 확인해 보세요.
사용법
Tinker를 사용하면 Eloquent 모델, Job, 이벤트 등 Laravel 애플리케이션의 모든 구성 요소를 커맨드 라인에서 직접 조작할 수 있습니다. Tinker 환경에 진입하려면 tinker Artisan 커맨드를 실행하세요.
php artisan tinkervendor:publish 커맨드로 Tinker의 설정 파일을 게시할 수 있습니다.
php artisan vendor:publish --provider="Laravel\Tinker\TinkerServiceProvider"WARNING
dispatch 헬퍼 함수와 Dispatchable 클래스의 dispatch 메서드는 Job을 큐에 넣기 위해 가비지 컬렉션에 의존합니다. 따라서 Tinker 내에서는 Bus::dispatch 또는 Queue::push를 사용하여 Job을 디스패치하는 것을 권장합니다.
허용 커맨드 목록
Tinker는 "허용 목록(allow list)"을 사용하여 쉘 내에서 실행 가능한 Artisan 커맨드를 제한합니다. 기본적으로 clear-compiled, down, env, inspire, migrate, optimize, up 커맨드를 실행할 수 있습니다. 추가로 허용하려면 tinker.php 설정 파일의 commands 배열에 해당 커맨드를 추가하세요.
'commands' => [
// App\Console\Commands\ExampleCommand::class,
],별칭에서 제외할 클래스
보통 Tinker는 사용하는 클래스에 자동으로 별칭을 부여합니다. 특정 클래스에 별칭을 부여하지 않으려면 tinker.php 설정 파일의 dont_alias 배열에 해당 클래스를 추가하세요.
'dont_alias' => [
App\Models\User::class,
],Artisan 콘솔
소개
Artisan은 Laravel에 내장된 커맨드라인 인터페이스(CLI)입니다. 애플리케이션 루트 디렉터리에 artisan 스크립트로 존재하며, 개발 과정에서 유용하게 활용할 수 있는 다양한 커맨드를 제공합니다. 사용 가능한 모든 Artisan 커맨드 목록을 확인하려면 list 커맨드를 실행하세요:
php artisan list각 커맨드에는 사용 가능한 인수(argument)와 옵션(option)을 설명하는 도움말 화면이 포함되어 있습니다. 도움말을 보려면 커맨드 이름 앞에 help를 붙여 실행하세요:
php artisan help migrateLaravel Sail
로컬 개발 환경으로 Laravel Sail을 사용하고 있다면, Artisan 커맨드를 실행할 때 반드시 sail 커맨드를 사용해야 합니다. Sail은 Artisan 커맨드를 애플리케이션의 Docker 컨테이너 내부에서 실행합니다:
./vendor/bin/sail artisan listTinker (REPL)
Laravel Tinker는 PsySH 패키지를 기반으로 동작하는 Laravel 프레임워크용 강력한 REPL(Read-Eval-Print Loop)입니다. 코드를 직접 실행하면서 애플리케이션의 동작을 빠르게 확인하고 싶을 때 유용합니다.
설치
모든 Laravel 애플리케이션에는 Tinker가 기본으로 포함되어 있습니다. 만약 이전에 제거했다면 Composer로 다시 설치할 수 있습니다:
composer require laravel/tinkerNOTE
핫 리로딩, 여러 줄 코드 편집, 자동 완성 기능이 필요하다면 Tinkerwell을 확인해 보세요!
사용법
Tinker를 사용하면 Eloquent 모델, Job, 이벤트 등 Laravel 애플리케이션의 모든 요소를 커맨드라인에서 직접 조작할 수 있습니다. Tinker 환경에 진입하려면 다음 Artisan 커맨드를 실행하세요:
php artisan tinkerTinker의 설정 파일을 애플리케이션으로 복사하려면 vendor:publish 커맨드를 사용하세요:
php artisan vendor:publish --provider="Laravel\Tinker\TinkerServiceProvider"WARNING
dispatch 헬퍼 함수와 Dispatchable 클래스의 dispatch 메서드는 가비지 컬렉션에 의존하여 Job을 큐에 등록합니다. 따라서 Tinker 환경에서 Job을 디스패치할 때는 dispatch() 대신 Bus::dispatch 또는 Queue::push를 사용해야 합니다.
커맨드 허용 목록
Tinker는 셸 내에서 실행을 허용할 Artisan 커맨드를 "허용 목록(allow list)"으로 관리합니다. 기본적으로 clear-compiled, down, env, inspire, migrate, migrate:install, up, optimize 커맨드를 실행할 수 있습니다. 추가로 허용할 커맨드가 있다면 tinker.php 설정 파일의 commands 배열에 등록하세요:
'commands' => [
// App\Console\Commands\ExampleCommand::class,
],자동 별칭 제외 클래스
Tinker는 상호작용 중에 사용된 클래스를 자동으로 별칭(alias) 처리합니다. 그러나 특정 클래스는 자동 별칭 처리를 원하지 않을 수 있습니다. tinker.php 설정 파일의 dont_alias 배열에 해당 클래스를 추가하면 됩니다:
'dont_alias' => [
App\Models\User::class,
],커맨드 작성
Artisan이 기본으로 제공하는 커맨드 외에도, 직접 커스텀 커맨드를 만들 수 있습니다. 커맨드 클래스는 보통 app/Console/Commands 디렉터리에 저장하지만, Artisan 커맨드 등록 설정을 통해 다른 위치를 사용해도 무방합니다.
커맨드 생성
새 커맨드를 만들려면 make:command Artisan 커맨드를 사용합니다. 이 명령을 처음 실행하면 app/Console/Commands 디렉터리가 없더라도 자동으로 생성됩니다.
php artisan make:command SendEmails커맨드 구조
커맨드 클래스를 생성한 후에는 signature와 description 속성에 적절한 값을 정의해야 합니다. 이 두 속성은 php artisan list 화면에 표시되며, signature는 커맨드가 받을 입력 값의 형태도 함께 정의합니다. 커맨드를 실행하면 handle 메서드가 호출되므로, 실제 처리 로직은 이 메서드 안에 작성합니다.
아래 예시를 살펴보겠습니다. handle 메서드의 파라미터에 타입을 지정하면 Laravel 서비스 컨테이너가 해당 의존성을 자동으로 주입해 줍니다.
<?php
namespace App\Console\Commands;
use App\Models\User;
use App\Support\DripEmailer;
use Illuminate\Console\Command;
class SendEmails extends Command
{
/**
* 콘솔 커맨드의 이름과 시그니처
*
* @var string
*/
protected $signature = 'mail:send {user}';
/**
* 콘솔 커맨드 설명
*
* @var string
*/
protected $description = '특정 사용자에게 마케팅 이메일을 발송합니다';
/**
* 콘솔 커맨드 실행
*/
public function handle(DripEmailer $drip): void
{
$drip->send(User::find($this->argument('user')));
}
}NOTE
커맨드 클래스는 가볍게 유지하고, 실제 비즈니스 로직은 서비스 클래스에 위임하는 것이 좋은 습관입니다. 위 예시에서도 이메일 발송의 핵심 처리는 DripEmailer 서비스 클래스가 담당하도록 구성되어 있습니다.
종료 코드
handle 메서드에서 아무것도 반환하지 않으면 커맨드는 성공을 의미하는 종료 코드 0으로 종료됩니다. 필요에 따라 정수를 직접 반환하여 종료 코드를 지정할 수도 있습니다.
$this->error('문제가 발생했습니다.');
return 1;커맨드 내 어느 메서드에서든 즉시 실패 처리를 하고 싶다면 fail 메서드를 사용하세요. 이 메서드는 커맨드 실행을 즉시 중단하고 종료 코드 1을 반환합니다.
$this->fail('문제가 발생했습니다.');클로저 커맨드
커맨드를 반드시 클래스로 만들 필요는 없습니다. 라우트에서 컨트롤러 대신 클로저를 사용하는 것처럼, 커맨드도 클로저로 정의할 수 있습니다.
routes/console.php 파일은 HTTP 라우트가 아닌 콘솔 기반의 진입점을 정의하는 파일입니다. 이 파일에서 Artisan::command 메서드를 사용해 클로저 방식의 커맨드를 정의할 수 있습니다. command 메서드는 커맨드 시그니처와 인수·옵션을 받는 클로저, 두 개의 인수를 받습니다.
Artisan::command('mail:send {user}', function (string $user) {
$this->info("이메일 발송 대상: {$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('특정 사용자에게 마케팅 이메일을 발송합니다');단일 실행 커맨드 (Isolatable)
WARNING
이 기능을 사용하려면 애플리케이션의 기본 캐시 드라이버가 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을 구현한 커맨드에는 --isolated 옵션이 자동으로 추가됩니다. 이 옵션과 함께 커맨드를 실행하면, Laravel은 애플리케이션의 기본 캐시 드라이버를 이용해 원자적 잠금(atomic lock)을 획득하려 시도합니다. 이미 같은 커맨드가 실행 중이라면 해당 커맨드는 실행되지 않으며, 성공 종료 코드(0)로 종료됩니다.
php artisan mail:send 1 --isolated실행되지 못했을 때 반환할 종료 코드를 직접 지정하고 싶다면, isolated 옵션에 값을 전달하면 됩니다.
php artisan mail:send 1 --isolated=12잠금 ID
기본적으로 Laravel은 커맨드 이름을 기반으로 원자적 잠금에 사용할 키를 생성합니다. 커맨드의 인수나 옵션을 키에 포함시키고 싶다면, isolatableId 메서드를 정의하여 커스텀 키를 반환하면 됩니다.
/**
* 커맨드의 격리 식별자를 반환합니다.
*/
public function isolatableId(): string
{
return $this->argument('user');
}잠금 만료 시간
기본적으로 격리 잠금은 커맨드가 완료되면 해제됩니다. 커맨드가 중단되어 정상 종료되지 못한 경우에는 1시간 후 자동으로 만료됩니다. 잠금 만료 시간을 직접 조정하려면 커맨드 클래스에 isolationLockExpiresAt 메서드를 정의하세요.
use DateTimeInterface;
use DateInterval;
/**
* 커맨드 격리 잠금의 만료 시간을 반환합니다.
*/
public function isolationLockExpiresAt(): DateTimeInterface|DateInterval
{
return now()->plus(minutes: 5);
}입력 정의
콘솔 커맨드를 작성할 때는 인수(argument)나 옵션(option)을 통해 사용자 입력을 받는 경우가 많습니다. Laravel에서는 커맨드 클래스의 signature 프로퍼티를 사용해 이를 간결하게 정의할 수 있습니다. signature는 커맨드 이름, 인수, 옵션을 라우트 정의와 유사한 표현식 문법으로 한 번에 선언할 수 있습니다.
인수 (Arguments)
사용자가 전달하는 인수와 옵션은 모두 중괄호 {}로 감쌉니다. 아래 예시는 user라는 필수 인수를 하나 정의한 커맨드입니다.
/**
* 콘솔 커맨드의 이름과 시그니처
*
* @var string
*/
protected $signature = 'mail:send {user}';인수를 선택적으로 만들거나 기본값을 지정할 수도 있습니다.
// 선택적 인수 (없어도 됨)
'mail:send {user?}'
// 기본값이 있는 선택적 인수
'mail:send {user=foo}'옵션 (Options)
옵션은 인수와 마찬가지로 사용자 입력을 받는 또 다른 방법입니다. 커맨드 라인에서 옵션을 전달할 때는 -- 두 개를 접두사로 붙입니다. 옵션에는 두 가지 유형이 있습니다. 값을 받는 옵션과 값 없이 스위치처럼 동작하는 옵션입니다.
아래는 값 없이 true/false 스위치로 동작하는 옵션 예시입니다.
/**
* 콘솔 커맨드의 이름과 시그니처
*
* @var string
*/
protected $signature = 'mail:send {user} {--queue}';이 예시에서 --queue 플래그를 전달하면 해당 옵션 값은 true가 되고, 전달하지 않으면 false가 됩니다.
php artisan mail:send 1 --queue값을 받는 옵션
옵션이 값을 요구하도록 하려면 옵션 이름 뒤에 = 기호를 붙입니다.
/**
* 콘솔 커맨드의 이름과 시그니처
*
* @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배열 입력 (Input Arrays)
여러 값을 받는 인수나 옵션을 정의하려면 * 문자를 사용합니다. 아래는 user 인수를 여러 번 받는 예시입니다.
'mail:send {user*}'이 경우 커맨드 라인에서 순서대로 여러 값을 전달할 수 있으며, user 인수는 [1, 2] 형태의 배열이 됩니다.
php artisan mail:send 1 2*를 선택적 인수 ?와 조합하면 0개 이상의 값을 받을 수 있습니다.
'mail:send {user?*}'배열 옵션
여러 값을 받는 옵션을 정의할 때는 각 값마다 옵션 이름을 반복해서 전달합니다.
'mail:send {--id=*}'이 커맨드는 아래처럼 --id를 여러 번 전달하는 방식으로 호출합니다.
php artisan mail:send --id=1 --id=2입력 설명 추가
인수나 옵션에 설명을 추가하려면 이름 뒤에 콜론(:)을 붙이고 설명을 작성합니다. 시그니처가 길어질 경우 여러 줄로 나눠 작성해도 됩니다.
/**
* 콘솔 커맨드의 이름과 시그니처
*
* @var string
*/
protected $signature = 'mail:send
{user : 메일을 받을 사용자 ID}
{--queue : 작업을 큐에 넣을지 여부}';누락된 입력 자동 프롬프트
필수 인수가 누락된 경우, 기본적으로 Laravel은 오류 메시지를 출력합니다. 하지만 PromptsForMissingInput 인터페이스를 구현하면, 필수 인수가 없을 때 사용자에게 자동으로 값을 물어보도록 동작을 바꿀 수 있습니다.
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Contracts\Console\PromptsForMissingInput;
class SendEmails extends Command implements PromptsForMissingInput
{
/**
* 콘솔 커맨드의 이름과 시그니처
*
* @var string
*/
protected $signature = 'mail:send {user}';
// ...
}인터페이스를 구현하면 Laravel이 인수 이름이나 설명을 기반으로 적절한 질문을 자동으로 생성해 사용자에게 묻습니다. 질문 내용을 직접 지정하고 싶다면 promptForMissingArgumentsUsing 메서드를 구현하고, 인수 이름을 키로 하는 배열을 반환하세요.
/**
* 누락된 인수를 수집할 때 사용할 질문을 반환합니다.
*
* @return array<string, string>
*/
protected function promptForMissingArgumentsUsing(): array
{
return [
'user' => '메일을 받을 사용자 ID를 입력하세요.',
];
}질문과 함께 플레이스홀더 텍스트를 지정하려면 튜플(배열) 형식을 사용합니다.
return [
'user' => ['메일을 받을 사용자 ID를 입력하세요.', '예: 123'],
];프롬프트 동작을 완전히 제어하려면 클로저를 사용할 수도 있습니다. 클로저는 사용자 입력을 직접 처리하고 값을 반환해야 합니다.
use App\Models\User;
use function Laravel\Prompts\search;
// ...
return [
'user' => fn () => search(
label: '사용자를 검색하세요:',
placeholder: '예: 홍길동',
options: fn ($value) => strlen($value) > 0
? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()
: []
),
];NOTE
사용 가능한 프롬프트 종류와 상세 사용법은 Laravel Prompts 문서를 참고하세요.
옵션에 대한 프롬프트는 커맨드의 handle 메서드 안에서 자유롭게 구현할 수 있습니다. 다만, 누락된 인수를 자동으로 물어본 직후에만 옵션 프롬프트를 실행하고 싶다면 afterPromptingForMissingArguments 메서드를 구현하세요.
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use function Laravel\Prompts\confirm;
// ...
/**
* 누락된 인수 프롬프트 완료 후 추가 동작을 수행합니다.
*/
protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output): void
{
$input->setOption('queue', confirm(
label: '메일을 큐로 처리하시겠습니까?',
default: $this->option('queue')
));
}Artisan 콘솔
커맨드 입출력 (Command I/O)
입력값 가져오기
커맨드가 실행되는 동안 인수(argument)와 옵션(option)에 전달된 값을 읽어야 할 때가 많습니다. argument와 option 메서드를 사용하면 됩니다. 해당 인수나 옵션이 존재하지 않으면 null이 반환됩니다.
/**
* 콘솔 커맨드 실행
*/
public function handle(): void
{
$userId = $this->argument('user');
}모든 인수를 배열로 한 번에 가져오려면 arguments 메서드를 호출하세요.
$arguments = $this->arguments();옵션도 동일한 방식으로 가져올 수 있습니다. option 메서드로 특정 옵션을, options 메서드로 전체 옵션을 배열로 가져옵니다.
// 특정 옵션 가져오기
$queueName = $this->option('queue');
// 모든 옵션을 배열로 가져오기
$options = $this->options();사용자 입력 받기
NOTE
Laravel Prompts는 CLI 애플리케이션에 아름답고 사용하기 편한 폼을 추가해 주는 PHP 패키지입니다. 플레이스홀더 텍스트, 유효성 검사 등 브라우저 폼과 유사한 기능을 제공합니다.
출력을 표시하는 것 외에도, 커맨드 실행 중에 사용자로부터 직접 입력을 받을 수 있습니다. ask 메서드는 질문 메시지를 출력하고 사용자의 입력을 받아 반환합니다.
/**
* 콘솔 커맨드 실행
*/
public function handle(): void
{
$name = $this->ask('이름이 무엇인가요?');
// ...
}ask 메서드의 두 번째 인수로 기본값을 지정할 수 있습니다. 사용자가 아무것도 입력하지 않으면 이 기본값이 반환됩니다.
$name = $this->ask('이름이 무엇인가요?', '홍길동');secret 메서드는 ask와 유사하지만, 사용자가 입력하는 내용이 콘솔에 표시되지 않습니다. 비밀번호처럼 민감한 정보를 입력받을 때 사용하세요.
$password = $this->secret('비밀번호를 입력하세요.');확인(Yes/No) 묻기
단순히 "예/아니오"로 대답할 수 있는 확인 메시지를 표시하려면 confirm 메서드를 사용하세요. 기본적으로 false를 반환하며, 사용자가 y 또는 yes를 입력하면 true를 반환합니다.
if ($this->confirm('계속 진행하시겠습니까?')) {
// ...
}두 번째 인수로 true를 전달하면, 기본값이 true로 바뀝니다. 즉, 사용자가 Enter만 눌러도 true로 처리됩니다.
if ($this->confirm('계속 진행하시겠습니까?', true)) {
// ...
}자동완성
anticipate 메서드를 사용하면 입력 가능한 선택지를 자동완성 힌트로 제공할 수 있습니다. 자동완성 힌트는 어디까지나 참고용이며, 사용자는 힌트에 없는 값도 자유롭게 입력할 수 있습니다.
$name = $this->anticipate('이름이 무엇인가요?', ['철수', '영희']);두 번째 인수로 클로저를 전달할 수도 있습니다. 사용자가 글자를 입력할 때마다 클로저가 호출되며, 현재까지 입력된 문자열을 인수로 받아 자동완성 후보 배열을 반환해야 합니다.
use App\Models\Address;
$name = $this->anticipate('주소를 입력하세요.', function (string $input) {
return Address::whereLike('name', "{$input}%")
->limit(5)
->pluck('name')
->all();
});다중 선택 질문
미리 정해진 선택지 중에서 고르게 하려면 choice 메서드를 사용하세요. 세 번째 인수로 기본 선택지의 배열 인덱스를 지정할 수 있으며, 사용자가 아무것도 선택하지 않으면 해당 인덱스의 값이 반환됩니다.
$name = $this->choice(
'이름을 선택하세요.',
['철수', '영희'],
$defaultIndex
);네 번째와 다섯 번째 인수로는 최대 재시도 횟수와 다중 선택 허용 여부를 지정할 수 있습니다.
$name = $this->choice(
'이름을 선택하세요.',
['철수', '영희'],
$defaultIndex,
$maxAttempts = null,
$allowMultipleSelections = false
);출력 작성하기
콘솔에 내용을 출력할 때는 line, newLine, info, comment, question, warn, alert, error 메서드를 사용할 수 있습니다. 각 메서드는 목적에 맞는 ANSI 색상을 자동으로 적용합니다. 예를 들어 info 메서드는 일반적으로 녹색 텍스트로 표시됩니다.
/**
* 콘솔 커맨드 실행
*/
public function handle(): void
{
// ...
$this->info('커맨드가 성공적으로 실행되었습니다!');
}오류 메시지를 출력할 때는 error 메서드를 사용하세요. 일반적으로 빨간색으로 표시됩니다.
$this->error('문제가 발생했습니다!');색상 없이 일반 텍스트를 출력하려면 line 메서드를 사용하세요.
$this->line('화면에 이 텍스트를 출력합니다.');빈 줄을 출력하려면 newLine 메서드를 사용하세요.
// 빈 줄 하나 출력
$this->newLine();
// 빈 줄 세 개 출력
$this->newLine(3);테이블
table 메서드를 사용하면 여러 행과 열로 구성된 데이터를 보기 좋게 출력할 수 있습니다. 컬럼명과 데이터만 전달하면 Laravel이 적절한 너비와 높이를 자동으로 계산합니다.
use App\Models\User;
$this->table(
['이름', '이메일'],
User::all(['name', 'email'])->toArray()
);진행 바
오래 걸리는 작업을 실행할 때 진행 상황을 시각적으로 보여주면 사용자 경험이 크게 향상됩니다. withProgressBar 메서드를 사용하면 반복 가능한 컬렉션을 순회하면서 자동으로 진행 바를 업데이트할 수 있습니다.
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();NOTE
더 고급 옵션이 필요하다면 Symfony Progress Bar 컴포넌트 문서를 참고하세요.
커맨드 등록
기본적으로 Laravel은 app/Console/Commands 디렉터리 안에 있는 모든 커맨드를 자동으로 등록합니다. 그러나 bootstrap/app.php 파일의 withCommands 메서드를 사용하면 다른 디렉터리도 스캔하도록 지정할 수 있습니다.
->withCommands([
__DIR__.'/../app/Domain/Orders/Commands',
])디렉터리 대신 클래스 이름을 직접 지정해 개별 커맨드를 수동으로 등록할 수도 있습니다.
use App\Domain\Orders\Commands\SendEmails;
->withCommands([
SendEmails::class,
])Artisan이 부팅될 때 등록된 모든 커맨드는 서비스 컨테이너를 통해 의존성이 해결된 뒤 Artisan에 등록됩니다.
Artisan 콘솔
프로그래밍 방식으로 명령 실행하기
CLI가 아닌 코드 내부에서 Artisan 명령을 직접 실행해야 할 때가 있습니다. 예를 들어, 라우트나 컨트롤러에서 특정 명령을 호출하고 싶은 경우가 있습니다. 이럴 때는 Artisan 파사드의 call 메서드를 사용합니다. 첫 번째 인자로 명령의 시그니처 이름이나 클래스 이름을, 두 번째 인자로 명령 파라미터 배열을 전달하면 됩니다. 메서드는 종료 코드(exit code)를 반환합니다.
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'
]);
// ...
});명령 전체를 문자열로 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 파사드의 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'
]);
// ...
});onConnection과 onQueue 메서드를 체이닝하면 명령을 디스패치할 커넥션이나 큐를 직접 지정할 수도 있습니다.
Artisan::queue('mail:send', [
'user' => 1, '--queue' => 'default'
])->onConnection('redis')->onQueue('commands');다른 명령에서 명령 호출하기
기존 Artisan 명령 내부에서 다른 명령을 호출해야 할 때가 있습니다. call 메서드를 사용하면 됩니다. 명령 이름과 인자/옵션 배열을 전달합니다.
/**
* 콘솔 명령 실행
*/
public function handle(): void
{
$this->call('mail:send', [
'user' => 1, '--queue' => 'default'
]);
// ...
}다른 명령을 호출하되 해당 명령의 출력을 모두 숨기고 싶다면 callSilently 메서드를 사용하세요. 시그니처는 call 메서드와 동일합니다.
$this->callSilently('mail:send', [
'user' => 1, '--queue' => 'default'
]);시그널 처리
운영체제는 실행 중인 프로세스에 시그널을 보낼 수 있습니다. 예를 들어 SIGTERM은 프로세스에게 "정상적으로 종료하라"고 요청하는 표준 시그널입니다. Artisan 커맨드에서 이러한 시그널을 수신하고 싶다면 trap 메서드를 사용하세요.
/**
* 콘솔 커맨드 실행
*/
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
});스텁 커스터마이징
Artisan의 make 명령어는 컨트롤러, Job, 마이그레이션, 테스트 등 다양한 클래스를 생성할 때 사용됩니다. 이 클래스들은 내부적으로 "스텁(stub)" 파일을 기반으로 생성되며, 입력한 값에 따라 스텁의 내용이 채워집니다.
기본 스텁이 아닌 프로젝트에 맞게 생성 결과물을 조정하고 싶다면, stub:publish 명령어로 자주 사용되는 스텁 파일들을 애플리케이션에 퍼블리시할 수 있습니다:
php artisan stub:publish퍼블리시된 스텁 파일들은 애플리케이션 루트의 stubs 디렉터리에 위치하게 됩니다. 이 파일들을 수정하면, 이후 Artisan make 명령어로 클래스를 생성할 때 변경된 스텁이 자동으로 반영됩니다.
NOTE
예를 들어, 모든 컨트롤러에 공통 주석이나 use 구문을 추가하고 싶다면, stubs/controller.stub 파일을 수정해두면 make:controller 실행 시마다 자동으로 포함됩니다.
이벤트
Artisan은 명령어 실행 시 세 가지 이벤트를 발생시킵니다: Illuminate\Console\Events\ArtisanStarting, Illuminate\Console\Events\CommandStarting, Illuminate\Console\Events\CommandFinished. ArtisanStarting 이벤트는 Artisan이 실행되는 즉시 발생하며, CommandStarting 이벤트는 명령어가 실행되기 직전에 발생합니다. 마지막으로 CommandFinished 이벤트는 명령어 실행이 완료되면 발생합니다.
이벤트
Artisan은 명령어 실행 과정에서 세 가지 이벤트를 발생시킵니다.
| 이벤트 | 발생 시점 |
|---|---|
Illuminate\Console\Events\ArtisanStarting | Artisan이 시작되는 즉시 |
Illuminate\Console\Events\CommandStarting | 개별 명령어가 실행되기 직전 |
Illuminate\Console\Events\CommandFinished | 명령어 실행이 완료된 직후 |
이 이벤트들을 활용하면 명령어 실행 전후에 로깅, 모니터링, 알림 전송 등의 부가 작업을 처리할 수 있습니다. 이벤트 리스너 등록 방법은 이벤트 문서를 참고하세요.