PHP アプリケーションでオペレーティング システム レベルのコマンドを使用する必要がある場合があります。これをどのように行うかを見て、開発者のエクスペリエンスを向上できるかどうかを見てみましょう。
過去数年間、私はコードの書き方とコードの改善方法のあらゆる側面に焦点を当ててきました。私は、HTTP との統合をより良く、よりオブジェクト指向にする方法を検討することから始めました。これを達成する方法を見つけたと信じており、今は別のことに注意を集中しています。 [関連する推奨事項: laravel ビデオ チュートリアル ]
場合によっては、アプリケーションで OS CLI を使用したいことがあります。 Web アプリケーションまたは別の CLI アプリケーション内。これまでは、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 プロセスを作成しましょう:
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, ); } }
つまり、私たちのトレイトはプロセス コントラクト自体の実装を示し、プロセスを構築する方法についての指示を提供します。また、ビルド コマンドを抽象化できるメソッドも含まれています。
これまでのところ、プロセスを作成し、潜在的なコマンドを構築できます。ただし、まだ命令は出していません。 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, ); } }
in このクラスでは、現在 HandledGitCommands トレイトによって処理されている Process からパラメーターを受け取ります。次に、これを Symfony プロセスが理解できるパラメーターに変換できます。パス内のエラーを最小限に抑えるために、Symfony パッケージの ExecutableFinder
を使用します。ただし、実行可能ファイルが見つからない場合には例外をスローすることも必要です。
これらを 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(); } }
あとはコード自体を実行して、PHP アプリケーションで実行できるようにするだけです。プログラムでの git の上手な使い方:
$git = new Git(); $command = $git->push( branch: 'main', ); $result = $command->run();
Push メソッドの結果により、symfony プロセスと対話できるようになります。つまり、反対側でコマンドを使用してすべてのソートを実行できることになります。私たちが変更した唯一の点は、このプロセスの作成に関するオブジェクト指向ラッパーを構築することです。これにより、コンテキストを適切に開発および維持し、テスト可能でスケーラブルな方法で拡張できるようになります。
アプリケーションでオペレーティング システム コマンドをどのくらいの頻度で使用しますか?何か使用例は考えられますか? サンプル コードを 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 中国語 Web サイトの他の関連記事を参照してください。