淺析PHP應用程序中正確調(diào)用系統(tǒng)命令的方法-實時

          來源:php中文網(wǎng) | 2022-12-19 20:00:30 |

          有時你需要使用 PHP 應用程序中的操作系統(tǒng)級命令。讓我們看看我們?nèi)绾巫龅竭@一點,看看我們是否可以讓開發(fā)者體驗更好。

          在過去的幾年里,我一直專注于我如何編寫代碼以及如何改進它的各個方面。我首先研究如何使與 HTTP 的集成更好、更面向?qū)ο?。我相信我找到了實現(xiàn)這一目標的方法,現(xiàn)在我將注意力集中在其他地方。【相關(guān)推薦:laravel視頻教程】

          在某些情況下,你希望在應用程序中使用 OS CLI。在 Web 應用程序或另一個 CLI 應用程序中。過去,我們使用過類似 execpassthrushell_execsystem的方法。然后出現(xiàn)了 Symfony Process 組件,我們得救了。


          (資料圖)

          Symfony 進程組件使得與操作系統(tǒng)進程集成并獲得輸出變得非常容易。但是我們?nèi)绾闻c這個庫集成仍然有點令人沮喪。我們創(chuàng)建一個新進程,傳入一個參數(shù)數(shù)組,使我們希望運行的命令。讓我們來看看:

          $command = new Process(    command: ["git", "push", "origin", "main"],);$command->run();

          這種方法有什么問題?好吧,老實說,什么都沒有。但是有沒有辦法改善開發(fā)人員的體驗?假設我們從 git 切換到 svn(我不太可能知道)。

          為了改善開發(fā)人員的體驗,首先,我們需要了解邏輯上用于創(chuàng)建 OS 命令的組件。我們可以將它們分解為:

          可執(zhí)行的參數(shù)

          我們的可執(zhí)行文件是我們直接與之交互的東西,例如 php、git、brew 或我們系統(tǒng)上任何其他已安裝的二進制文件。然后爭論是我們?nèi)绾位?;這些可以是子命令、選項、標志或參數(shù)。

          因此,如果我們稍微抽象一下,我們就會有一個process和一個command, 它接受參數(shù)。我們將使用接口/契約來定義我們的組件來控制我們的工作流程應該如何工作。讓我們從流程契約開始:

          declare(strict_types=1);namespace JustSteveKing\OS\Contracts;use Symfony\Component\Process\Process;interface ProcessContract{    public function build(): Process;}

          我們這里是說每個進程都必須能夠被構(gòu)建,并且創(chuàng)建的進程的結(jié)果應該是一個 Symfony 進程。我們的流程應該構(gòu)建一個命令供我們運行,所以現(xiàn)在讓我們看看我們的命令契約:

          declare(strict_types=1);namespace JustSteveKing\OS\Contracts;interface CommandContract{    public function toArgs(): array;}

          我們希望從命令中得到的主要內(nèi)容是能夠作為參數(shù)返回,我們可以將這些參數(shù)作為命令傳遞給 Symfony 進程。

          想法已經(jīng)夠多了,讓我們來看一個真實的例子。我們將使用 git 作為示例,因為我們大多數(shù)人應該能夠與 git 命令相關(guān)聯(lián)。

          首先,讓我們創(chuàng)建一個 Git 進程來實現(xiàn)我們剛剛描述的 Process Contract:

          class Git implements ProcessContract{    use HandlesGitCommands;    private CommandContract $command;}

          我們的流程實現(xiàn)了合約,并有一個命令屬性,我們將使用它允許我們的流程被流暢地構(gòu)建和執(zhí)行。我們有一個特點,可以讓我們集中精力為我們的 Git 流程構(gòu)建和制造事物的方式。讓我們看一下:

          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 展示了流程契約本身的實現(xiàn),并提供了有關(guān)如何構(gòu)建流程的說明。它還包含一個允許我們抽象構(gòu)建命令的方法。

          到目前為止,我們可以創(chuàng)建一個流程并建立一個潛在的命令。但是,我們還沒有下達命令。我們在 trait 中創(chuàng)建一個新的 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 的參數(shù),當前由我們的 HandledGitCommands trait 處理。然后我們可以把它變成 Symfony 進程可以理解的參數(shù)。我們使用 Symfony 包中的 ExecutableFinder來最大程度地減少路徑中的錯誤。但是,如果找不到可執(zhí)行文件,我們也想拋出異常。

          當我們把它們放在我們的 Git 進程中時,它看起來有點像這樣:

          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();    }}

          現(xiàn)在剩下要做的就是運行代碼本身,以便我們可以在 PHP 應用程序中很好地使用 git:

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

          Push方法的結(jié)果將允許你與symfony進程交互-這意味著你可以在另一端使用命令執(zhí)行所有排序。我們唯一改變的是圍繞這個過程的創(chuàng)建構(gòu)建了一個面向?qū)ο蟮陌b器。這使我們能夠很好地開發(fā)和維護上下文,并以可測試和可擴展的方式擴展事物。

          你多久在應用程序中使用操作系統(tǒng)命令?你能想到任何用例嗎?我已經(jīng) 在 GitHub 上的存儲庫中發(fā)布了示例代碼,以便你可以使用它并查看是否可以改進你的操作系統(tǒng)集成。

          一個很好的例子應該是SSH、MySQL,甚至Anable或Terraform!想象一下,如果你可以按計劃高效地運行來自Laravel Artisan的MySQL轉(zhuǎn)儲,而無需始終使用第三方程序包!

          更多編程相關(guān)知識,請訪問:編程視頻!!

          以上就是淺析PHP應用程序中正確調(diào)用系統(tǒng)命令的方法的詳細內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!

          關(guān)鍵詞:

          亚洲a在线视频视频| 亚洲精品9999久久久久无码| 亚洲国产欧美一区二区三区| 亚洲国产成人无码av在线播放| 久久综合亚洲色一区二区三区| 亚洲免费在线播放| 久久久久久亚洲av成人无码国产| 国产l精品国产亚洲区在线观看| 丝袜熟女国偷自产中文字幕亚洲| 亚洲综合在线另类色区奇米| 亚洲夜夜欢A∨一区二区三区| 亚洲精品无码鲁网中文电影| 亚洲中文字幕无码一久久区| 久久久久国产亚洲AV麻豆 | 亚洲精品A在线观看| 亚洲国产精品毛片av不卡在线| 亚洲成AⅤ人影院在线观看| 亚洲不卡无码av中文字幕| 一级毛片直播亚洲| 亚洲日韩中文字幕日韩在线| 中文字幕亚洲图片| 亚洲AV无码一区二区乱子伦| 亚洲图片在线观看| 亚洲午夜电影在线观看高清| 精品国产成人亚洲午夜福利| 亚洲AV成人一区二区三区观看| 亚洲AV无码成H人在线观看| 国产精品亚洲mnbav网站 | 亚洲午夜久久久久久久久久| 精品国产_亚洲人成在线高清| 亚洲AV人无码综合在线观看| 亚洲成人在线免费观看| 亚洲国产a级视频| 日本系列1页亚洲系列| 亚洲福利精品一区二区三区| 国产日韩成人亚洲丁香婷婷| 国产亚洲真人做受在线观看| 日韩亚洲Av人人夜夜澡人人爽| 亚洲一区二区三区在线观看蜜桃| 亚洲色成人WWW永久在线观看| heyzo亚洲精品日韩|