PHP 애플리케이션에서 시스템 명령을 호출하는 올바른 방법에 대한 간략한 분석

青灯夜游
풀어 주다: 2023-04-11 09:14:01
앞으로
4999명이 탐색했습니다.

PHP 애플리케이션에서 시스템 명령을 호출하는 올바른 방법에 대한 간략한 분석

때로는 PHP 애플리케이션에서 운영 체제 수준 명령을 사용해야 할 때가 있습니다. 이를 수행하는 방법을 살펴보고 개발자 경험을 더 좋게 만들 수 있는지 살펴보겠습니다.

지난 몇 년 동안 저는 코드 작성 방법과 코드 개선 방법의 모든 측면에 집중해 왔습니다. 저는 HTTP와의 통합을 보다 효율적이고 보다 객체 지향적으로 만드는 방법을 조사하는 것부터 시작했습니다. 저는 이것을 달성할 수 있는 방법을 찾았다고 믿으며 이제는 다른 곳에 관심을 집중하고 있습니다. [관련 추천: laravel 비디오 튜토리얼]

어떤 경우에는 애플리케이션에서 OS CLI를 사용하고 싶을 수도 있습니다. 웹 애플리케이션 또는 다른 CLI 애플리케이션에서. 과거에는 exec, passthru, shell_execsystem과 같은 메서드를 사용했습니다. 그런 다음 Symfony Process 구성 요소가 등장했고 우리는 구원을 받았습니다. execpassthrushell_execsystem 的方法。然后出现了 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

Symfony 프로세스 구성 요소를 사용하면 운영 체제 프로세스와 통합하고 출력을 얻는 것이 매우 쉽습니다. 하지만 이 라이브러리와 통합하는 방법은 여전히 ​​약간 실망스럽습니다. 실행하려는 명령에 대한 인수 배열을 전달하여 새 프로세스를 만듭니다. 살펴보겠습니다.

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에서 svn으로 전환한다고 가정해 봅시다(저는 잘 모르겠습니다).

개발자 경험을 향상하려면 먼저 OS 명령을 생성하는 데 논리적으로 사용되는 구성 요소를 이해해야 합니다.

  • 실행 파일
  • 매개 변수

실행 파일은 php, git, Brew 등과 같이 우리가 직접 상호 작용하는 것입니다. 우리 시스템에 설치된 다른 바이너리. 그러면 인수는 하위 명령, 옵션, 플래그 또는 매개변수가 될 수 있습니다.

그래서 조금 추상화하면 매개변수를 허용하는 프로세스명령이 있습니다. 인터페이스/계약을 사용하여 워크플로 작동 방식을 제어하는 ​​구성 요소를 정의합니다. 프로세스 계약부터 시작해 보겠습니다.

$git = new Git();
$command = $git->push(
    branch: 'main',
);

$result = $command->run();
로그인 후 복사
여기서 말하는 것은 모든 프로세스가 구축 가능해야 하며 생성된 프로세스의 결과는 Symfony 프로세스여야 한다는 것입니다. 우리 프로세스는 우리가 실행할 명령을 작성해야 하므로 이제 명령 계약을 살펴보겠습니다. 🎜rrreee🎜 명령에서 우리가 원하는 가장 중요한 것은 이를 매개변수로 반환할 수 있다는 것입니다. 이를 Symfony에 명령으로 전달할 수 있습니다. 프로세스. 🎜🎜아이디어는 충분하고 실제 사례를 살펴보겠습니다. 우리 대부분은 git 명령과 관련될 수 있어야 하므로 git을 예로 사용하겠습니다. 🎜🎜먼저 방금 설명한 프로세스 계약을 구현하는 Git 프로세스를 만들어 보겠습니다. 🎜rrreee🎜 우리 프로세스는 계약을 구현하고 프로세스가 원활하게 구축되고 실행될 수 있도록 하는 데 사용할 명령 속성을 갖습니다. Git 프로세스를 구축하고 만드는 방식에 집중할 수 있는 기능이 있습니다. 살펴보겠습니다: 🎜rrreee🎜 따라서 우리의 특성은 프로세스 계약 자체의 구현을 보여주고 프로세스를 구축하는 방법에 대한 지침을 제공합니다. 또한 빌드 명령을 추상화할 수 있는 메서드도 포함되어 있습니다. 🎜🎜지금까지 우리는 프로세스를 생성하고 잠재적인 명령을 구축할 수 있습니다. 그러나 우리는 아직 명령을 내리지 않았습니다. Git 클래스를 유형으로 사용하여 특성에 새로운 Git 명령을 만듭니다. 열거형인 또 다른 Git 클래스를 살펴보겠습니다. 그러나 간단한 버전을 보여드리겠습니다. 기본적으로 지원하려는 모든 git 하위 명령에 매핑되기를 원합니다. 🎜rrreee🎜 그런 다음 이를 Git 명령에 전달합니다. 🎜rrreee🎜 이 수업에서는 요청을 수락합니다. 현재 HandledGitCommands 특성에 의해 처리되는 프로세스 매개변수에서. 그런 다음 이를 Symfony 프로세스가 이해할 수 있는 매개변수로 변환할 수 있습니다. 경로 오류를 최소화하기 위해 Symfony 패키지의 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
php
원천:learnku.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿