바닐라 PHP에서 CLI PHP 애플리케이션 부트 스트랩
본문
소개
PHP는 웹 응용 프로그램 및 CMS에서 널리 사용되는 것으로 잘 알려져 있지만 많은 사람들이 모르는 것은 PHP가 웹 서버가 필요 없는 명령줄 응용 프로그램을 작성하기 위한 훌륭한 언어라는 것입니다.
사용하기 쉽고 친숙한 구문으로 인해 API와 통신하거나 Crontab을 통해 예약 된 작업을 실행할 수 있지만 외부 사용자에게 노출 될 필요가 없는 무료 도구 및 작은 응용 프로그램을 위한 낮은 언어입니다.
원본 : https://dev.to/erikaheidi/bootstrapping-a-cli-php-application-in-vanilla-php-4ee
확실히, 당신은 당신의 요구에 부응하기 위해 하나의 파일 PHP 스크립트를 만들 수 있으며 작은 것들에 대해서는 합리적으로 잘 작동 할 것입니다; 그러나 앞으로 해당 코드를 유지 관리, 확장 또는 재사용 하기가 매우 어렵습니다.
우리가 더 이상 프론트 엔드를 사용하지 않는 것을 제외하고는 명령 줄 응용 프로그램을 구축 할 때 동일한 웹 개발 원칙을 적용 할 수 있습니다.
또한 외부 사용자가 응용 프로그램에 액세스 할 수 없으므로 보안이 강화되고 실험을 위한 더 많은 공간이 만들어집니다.
나는 웹 응용 프로그램이 조금 아프고 최근에 프론트 엔드 주변에 구축되는 복잡성 때문에 명령 줄에서 PHP를 사용하는 것은 개인적으로 매우 상쾌했습니다. 이 포스트 / 시리즈에서는 PHP에서 실험용 CLI 앱의 기본으로 사용할 수 있는 미니멀리스트 / 종속성이 없는 CLI AppKit (작은 프레임 워크를 생각 함) (minicli)을 함께 빌드 합니다.
추신 : 필요한 모든 것이 git clone 인 경우 여기로 이동하십시오.
이것은 minicli 빌딩 시리즈의 1 부입니다.
전제 조건
이 튜토리얼을 따르려면 로컬 컴퓨터 또는 개발 서버에 php-cli가 설치되어 있고 자동 로드 파일을 생성하려면 Composer가 필요합니다.
1. 디렉토리 구조 및 진입 점 설정
메인 프로젝트 디렉토리를 만들어 시작해 봅시다 :
mkdir minicli
cd minicli
다음으로 CLI 응용 프로그램의 진입 점을 만듭니다. 이것은 최신 PHP 웹 앱의 index.php 파일과 동일합니다.
여기서 단일 진입 점은 요청을 관련 컨트롤러로 리디렉션합니다. 그러나 애플리케이션은 CLI 전용이므로 다른 파일 이름을 사용하고 웹 서버에서의 실행을 허용하지 않는 몇 가지 안전 장치를 포함합니다.
자주 사용하는 텍스트 편집기를 사용하여 minicli라는 새 파일을 엽니다.
vim minicli
여기에 .php 확장자가 포함되어 있지 않습니다. 명령 행에서 이 스크립트를 실행하고 있으므로 쉘 프로그램에 PHP를 사용하여 이 스크립트를 실행하고 있음을 알려주는 특수 디스크립터를 포함 시킬 수 있습니다.
#!/usr/bin/php
<?php
if (php_sapi_name() !== 'cli') {
exit;
}
echo "Hello World\n";
첫 번째 줄은 응용 프로그램 shebang입니다. 이 스크립트를 실행하는 쉘에게 /usr/bin/php를 해당 코드의 인터프리터로 사용하도록 지시합니다.
chmod를 사용하여 스크립트를 실행 가능하게 만드십시오.
chmod +x minicli
이제 다음을 사용하여 응용 프로그램을 실행할 수 있습니다.
./minicli
Hello World가 출력으로 표시되어야 합니다.
2. 소스 디렉토리 및 자동로드 설정
여러 프레임 워크에서 이 프레임 워크를 쉽게 재사용 할 수 있도록 다음 두 가지 소스 디렉토리를 작성합니다.
- app :이 네임 스페이스는 응용 프로그램 별 모델 및 컨트롤러 용으로 예약됩니다.
- lib :이 네임 스페이스는 핵심 프레임 워크 클래스에서 사용되며 다양한 애플리케이션에서 재사용 할 수 있습니다.
다음을 사용하여 두 디렉토리를 작성하십시오.
mkdir app
mkdir lib
이제 자동 로드를 설정하기 위해 composer.json 파일을 만들어 봅시다. 이를 통해 PHP의 클래스 및 기타 객체 지향 리소스를 사용하면서 응용 프로그램을 보다 잘 구성 할 수 있습니다.
텍스트 편집기에서 새 composer.json 파일을 작성하고 다음 컨텐츠를 포함하십시오.
{
"autoload": {
"psr-4": {
"Minicli\\": "lib/",
"App\\": "app/"
}
}
}
파일을 저장하고 닫은 후 다음 명령을 실행하여 자동 로드 파일을 설정하십시오.
composer dump-autoload
자동 로드가 예상대로 작동하는지 테스트하기 위해 첫 번째 클래스를 작성합니다. 이 클래스는 명령 실행 처리를 담당하는 Application 객체를 나타냅니다. 우리는 간단하게 유지하고 이름을 App으로 지정합니다.
선택한 텍스트 편집기를 사용하여 lib 폴더 내에 새 App.php 파일을 작성하십시오.
vim lib/App.php
App 클래스는 이전에 minicli 실행 파일에서 설정 한 "Hello World"코드를 대체하는 runCommand 메소드를 구현합니다. 나중에 이 명령을 수정하여 여러 명령을 처리 할 수 있습니다. 지금은 스크립트를 실행할 때 전달 된 매개 변수를 사용하여 "Hello $ name"텍스트를 출력합니다. 매개 변수가 전달되지 않으면 $ name 변수의 기본값으로 world가 사용됩니다.
App.php 파일에 다음 내용을 삽입하고 완료되면 파일을 저장하고 닫습니다.
<?php
namespace Minicli;
class App
{
public function runCommand(array $argv)
{
$name = "World";
if (isset($argv[1])) {
$name = $argv[1];
}
echo "Hello $name!!!\n";
}
}
이제 minicli 스크립트로 이동하여 현재 내용을 다음 코드로 바꾸십시오.이 코드는 잠시 후에 설명합니다.
#!/usr/bin/php
<?php
if (php_sapi_name() !== 'cli') {
exit;
}
require __DIR__ . '/vendor/autoload.php';
use Minicli\App;
$app = new App();
$app->runCommand($argv);
여기서는 새 객체를 만들 때 클래스 파일을 자동으로 포함하기 위해 자동 생성 autoload.php 파일이 필요합니다. App 객체를 만든 후 runCommand 메서드를 호출하여 해당 스크립트를 실행할 때 사용되는 모든 매개 변수가 포함 된 전역 $ argv 변수를 전달합니다. $ argv 변수는 첫 번째 위치 (0)가 스크립트의 이름이고 후속 위치는 명령 호출에 전달 된 추가 매개 변수로 채워지는 배열입니다.
이것은 명령 행에서 실행되는 PHP 스크립트에서 사용 가능한 사전 정의 된 변수입니다.
이제 모든 것이 예상대로 작동하는지 테스트하려면 다음을 실행하십시오.
./minicli your-name
그리고 다음과 같은 결과가 나타납니다.
Hello your-name!!!
이제 스크립트에 추가 매개 변수를 전달하지 않으면 다음과 같이 인쇄됩니다.
Hello World!!!
3. 출력 도우미 만들기
명령 행 인터페이스는 텍스트 전용이므로 때때로 응용 프로그램의 오류 또는 경고 메시지를 식별하거나 사람이 읽을 수있는 방식으로 데이터를 형식화 하기가 어려울 수 있습니다. 이러한 작업 중 일부를 터미널로의 출력을 처리하는 도우미 클래스에 아웃소싱 합니다.
선택한 텍스트 편집기를 사용하여 lib 폴더 내에 새 클래스를 작성하십시오.
vim lib/CliPrinter.php
다음 클래스는 세 가지 공개 메소드를 정의합니다. 메시지를 출력하는 기본 출력 메소드; 새로운 라인을 인쇄하는 새로운 라인 방법; 텍스트를 강조하기 위해 이 두 가지를 결합하여 새 줄로 감싸는 표시 방법이 있습니다. 더 많은 서식 옵션을 포함하도록 이 클래스를 나중에 확장 할 것입니다.
<?php
namespace Minicli;
class CliPrinter
{
public function out($message)
{
echo $message;
}
public function newline()
{
$this->out("\n");
}
public function display($message)
{
$this->newline();
$this->out($message);
$this->newline();
$this->newline();
}
}
이제 CliPrinter 도우미 클래스를 사용하도록 App 클래스를 업데이트하겠습니다. CliPrinter 객체를 참조 할 $ printer라는 속성을 만듭니다. 개체는 앱 생성자 메서드에서 생성됩니다. 그런 다음 getPrinter 메소드를 작성하고 runCommand 메소드에서 이를 사용하여 echo를 직접 사용하는 대신 메시지를 표시합니다.
<?php
namespace Minicli;
class App
{
protected $printer;
public function __construct()
{
$this->printer = new CliPrinter();
}
public function getPrinter()
{
return $this->printer;
}
public function runCommand($argv)
{
$name = "World";
if (isset($argv[1])) {
$name = $argv[1];
}
$this->getPrinter()->display("Hello $name!!!");
}
}
이제 다음을 사용하여 애플리케이션을 다시 실행하십시오.
./minicli your_name
메시지를 둘러싼 줄 바꿈과 같이 다음과 같이 출력 되어야 합니다.
Hello your_name!!!
다음 단계에서는 명령 로직을 App 클래스 외부로 이동하여 필요할 때마다 새 명령을 쉽게 포함 시킬 수 있습니다.
4. 명령 레지스트리 작성
이제 일반적인 runCommand 메소드와 Command Registry를 통해 여러 명령을 처리하기 위해 App 클래스를 리팩터링 합니다. 일반적으로 인기 있는 PHP 웹 프레임 워크에서 경로가 정의 된 것처럼 새로운 명령이 등록됩니다.
업데이트 된 App 클래스는 이제 command_registry라는 새로운 속성 인 배열을 포함합니다. registerCommand 메소드는 이 변수를 사용하여 애플리케이션 명령을 이름으로 식별 되는 익명 함수로 저장합니다.
runCommand 메소드는 $argv [1]이 등록 된 명령 이름으로 설정되어 있는지 확인합니다. 명령이 설정되어 있지 않으면 기본적으로 도움말 명령을 실행하려고 시도합니다. 유효한 명령이 없으면 오류 메시지가 인쇄됩니다.
업데이트 된 App.php 클래스가 이러한 변경 후에 어떻게 보이는지 입니다. App.php 파일의 현재 내용을 다음 코드로 바꿉니다 :
<?php
namespace Minicli;
class App
{
protected $printer;
protected $registry = [];
public function __construct()
{
$this->printer = new CliPrinter();
}
public function getPrinter()
{
return $this->printer;
}
public function registerCommand($name, $callable)
{
$this->registry[$name] = $callable;
}
public function getCommand($command)
{
return isset($this->registry[$command]) ? $this->registry[$command] : null;
}
public function runCommand(array $argv = [])
{
$command_name = "help";
if (isset($argv[1])) {
$command_name = $argv[1];
}
$command = $this->getCommand($command_name);
if ($command === null) {
$this->getPrinter()->display("ERROR: Command \"$command_name\" not found.");
exit;
}
call_user_func($command, $argv);
}
}
다음으로 minicli 스크립트를 업데이트하고 hello와 help라는 두 가지 명령을 등록합니다. 새로 만든 registerCommand 메소드를 사용하여 App 객체 내에 익명 함수로 등록됩니다.
업데이트 된 minicli 스크립트를 복사하고 파일을 업데이트하십시오.
#!/usr/bin/php
<?php
if (php_sapi_name() !== 'cli') {
exit;
}
require __DIR__ . '/vendor/autoload.php';
use Minicli\App;
$app = new App();
$app->registerCommand('hello', function (array $argv) use ($app) {
$name = isset ($argv[2]) ? $argv[2] : "World";
$app->getPrinter()->display("Hello $name!!!");
});
$app->registerCommand('help', function (array $argv) use ($app) {
$app->getPrinter()->display("usage: minicli hello [ your-name ]");
});
$app->runCommand($argv);
이제 응용 프로그램에는 help와 hello라는 두 가지 작업 명령이 있습니다. 테스트하려면 다음을 실행하십시오.
./minicli help
인쇄됩니다 :
usage: minicli hello [ your-name ]
이제 hello 명령을 다음과 같이 테스트하십시오.'
./minicli hello your_name
Hello your_name!!!
이제 더 많은 명령과 기능을 구현하기 위한 기본 역할을 하는 미니멀리스트 구조를 사용하는 작동 중인 CLI 앱이 있습니다.
이 시점에서 디렉토리 구조는 다음과 같습니다.
.
├── app
├── lib
│ ├── App.php
│ └── CliPrinter.php
├── vendor
│ ├── composer
│ └── autoload.php
├── composer.json
└── minicli
이 시리즈의 다음 부분에서는 명령 논리를 응용 프로그램 별 네임 스페이스 내의 전용 클래스로 이동하여 minicli를 명령 컨트롤러를 사용하도록 리팩터링 합니다. 다음에 또 만나요!
이 튜토리얼에서 사용 된 모든 파일은 여기에서 찾을 수 있습니다 : erikaheidi minicli : v0.1.0
- 이전글커맨드 라인의 PHP : 커맨드 컨트롤러 구현 19.09.28
- 다음글양식에 버튼을 놓을 위치 19.09.27