때로는 PHP 애플리케이션에서 운영 체제 수준 명령을 사용해야 할 때가 있습니다. 이를 수행하는 방법을 살펴보고 개발자 경험을 더 좋게 만들 수 있는지 살펴보겠습니다.
지난 몇 년 동안 저는 코드 작성 방법과 코드 개선 방법의 모든 측면에 집중해 왔습니다. 저는 HTTP와의 통합을 보다 효율적이고 보다 객체 지향적으로 만드는 방법을 조사하는 것부터 시작했습니다. 저는 이것을 달성할 수 있는 방법을 찾았다고 믿으며 이제는 다른 곳에 관심을 집중하고 있습니다. [관련 추천: laravel 비디오 튜토리얼]
어떤 경우에는 애플리케이션에서 OS CLI를 사용하고 싶을 수도 있습니다. 웹 애플리케이션 또는 다른 CLI 애플리케이션에서. 과거에는 exec
, passthru
, shell_exec
및 system
과 같은 메서드를 사용했습니다. 그런 다음 Symfony Process 구성 요소가 등장했고 우리는 구원을 받았습니다. exec
或 passthru
或 shell_exec
和 system
的方法。然后出现了 Symfony Process 组件,我们得救了。
Symfony 进程组件使得与操作系统进程集成并获得输出变得非常容易。但是我们如何与这个库集成仍然有点令人沮丧。我们创建一个新进程,传入一个参数数组,使我们希望运行的命令。让我们来看看:
$command = new Process( command: ['git', 'push', 'origin', 'main'], ); $command->run();
这种方法有什么问题?好吧,老实说,什么都没有。但是有没有办法改善开发人员的体验?假设我们从 git 切换到 svn(我不太可能知道)。
为了改善开发人员的体验,首先,我们需要了解逻辑上用于创建 OS 命令的组件。我们可以将它们分解为:
我们的可执行文件是我们直接与之交互的东西,例如 php、git、brew 或我们系统上任何其他已安装的二进制文件。然后争论是我们如何互动;这些可以是子命令、选项、标志或参数。
因此,如果我们稍微抽象一下,我们就会有一个process
和一个command
, 它接受参数。我们将使用接口/契约来定义我们的组件来控制我们的工作流程应该如何工作。让我们从流程契约开始:
declare(strict_types=1); namespace JustSteveKing\OS\Contracts; use Symfony\Component\Process\Process; interface ProcessContract { public function build(): Process; }
我们这里是说每个进程都必须能够被构建,并且创建的进程的结果应该是一个 Symfony 进程。我们的流程应该构建一个命令供我们运行,所以现在让我们看看我们的命令契约:
declare(strict_types=1); namespace JustSteveKing\OS\Contracts; interface CommandContract { public function toArgs(): array; }
我们希望从命令中得到的主要内容是能够作为参数返回,我们可以将这些参数作为命令传递给 Symfony 进程。
想法已经够多了,让我们来看一个真实的例子。我们将使用 git 作为示例,因为我们大多数人应该能够与 git 命令相关联。
首先,让我们创建一个 Git 进程来实现我们刚刚描述的 Process Contract:
class Git implements ProcessContract { use HandlesGitCommands; private CommandContract $command; }
我们的流程实现了合约,并有一个命令属性,我们将使用它允许我们的流程被流畅地构建和执行。我们有一个特点,可以让我们集中精力为我们的 Git 流程构建和制造事物的方式。让我们看一下:
trait HandlesGitCommands { public function build(): Process { return new Process( command: $this->command->toArgs(), ); } protected function buildCommand(Git $type, array $args = []): void { $this->command = new GitCommand( type: $type, args: $args, ); } }
因此,我们的 trait 展示了流程契约本身的实现,并提供了有关如何构建流程的说明。它还包含一个允许我们抽象构建命令的方法。
到目前为止,我们可以创建一个流程并建立一个潜在的命令。但是,我们还没有下达命令。我们在 trait 中创建一个新的 Git 命令,它使用 Git 类作为类型。让我们看看另一个 Git 类,它是一个枚举。不过,我将展示一个精简版本 - 实际上,你希望它映射到你希望支持的所有 git 子命令:
enum Git: string { case PUSH = 'push'; case COMMIT = 'commit'; }
然后我们将它传递给 Git 命令:
final class GitCommand implements CommandContract { public function __construct( public readonly Git $type, public readonly array $args = [], public readonly null|string $executable = null, ) { } public function toArgs(): array { $executable = (new ExecutableFinder())->find( name: $this->executable ?? 'git', ); if (null === $executable) { throw new InvalidArgumentException( message: "Cannot find executable for [$this->executable].", ); } return array_merge( [$executable], [$this->type->value], $this->args, ); } }
在这个类中,我们接受来自 Process 的参数,当前由我们的 HandledGitCommands trait 处理。然后我们可以把它变成 Symfony 进程可以理解的参数。我们使用 Symfony 包中的 ExecutableFinder
use JustSteveKing\OS\Commands\Types\Git as SubCommand; class Git implements ProcessContract { use HandlesGitCommands; private CommandContract $command; public function push(string $branch): Process { $this->buildCommand( type: SubCommand:PUSH, args: [ 'origin', $branch, ], ); return $this->build(); } }
$git = new Git(); $command = $git->push( branch: 'main', ); $result = $command->run();
ExecutableFinder
를 사용합니다. 그러나 실행 파일을 찾을 수 없는 경우에도 예외를 발생시키고 싶습니다. 🎜🎜Git 프로세스에 넣으면 다음과 같이 보입니다. 🎜rrreee🎜이제 남은 일은 PHP 애플리케이션에서 git을 훌륭하게 사용할 수 있도록 코드 자체를 실행하는 것입니다. 🎜rrreee🎜결과 Push 메소드를 사용하면 심포니 프로세스와 상호 작용할 수 있습니다. 즉, 반대쪽 끝에서 명령을 사용하여 모든 정렬을 수행할 수 있다는 의미입니다. 우리가 변경한 유일한 것은 이 프로세스 생성을 중심으로 객체 지향 래퍼를 구축하는 것이었습니다. 이를 통해 컨텍스트를 잘 개발 및 유지하고 테스트 가능하고 확장 가능한 방식으로 확장할 수 있습니다. 🎜🎜애플리케이션에서 운영 체제 명령을 얼마나 자주 사용하시나요? 사용 사례를 생각해 볼 수 있나요? 여러분이 직접 사용해 보고 OS 통합을 개선할 수 있는지 확인할 수 있도록 GitHub 저장소에 🎜샘플 코드를 게시🎜했습니다. 🎜좋은 예로는 SSH, MySQL, Anable 또는 Terraform이 있습니다! 항상 타사 패키지를 사용할 필요 없이 일정에 따라 Laravel Artisan에서 MySQL 덤프를 효율적으로 실행할 수 있다고 상상해 보십시오!
원본 주소: https://laravel-news.com/working-with-os-process-in-php
번역 주소: https://learnku.com/laravel/t/71422
더 보기 프로그래밍 관련 지식은 프로그래밍 비디오를 방문하세요! !
위 내용은 PHP 애플리케이션에서 시스템 명령을 호출하는 올바른 방법에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!