Home Backend Development PHP Tutorial A brief analysis of the correct method of calling system commands in PHP applications

A brief analysis of the correct method of calling system commands in PHP applications

Dec 19, 2022 pm 07:41 PM
php

A brief analysis of the correct method of calling system commands in PHP applications

Sometimes you need to use operating system level commands in your PHP application. Let's look at how we do this and see if we can make the developer experience better.

Over the past few years I have been focusing on every aspect of how I write code and how to improve it. I started by looking into how to make the integration with HTTP better and more object-oriented. I believe I found a way to achieve this and now I'm focusing my attention elsewhere. [Related recommendations: laravel video tutorial]

In some cases, you want to use the OS CLI in your application. In a web application or another CLI application. In the past, we have used methods like exec or passthru or shell_exec and system. Then along came the Symfony Process component and we were saved.

The Symfony process component makes it very easy to integrate with operating system processes and obtain output. But how we integrate with this library is still a bit frustrating. We create a new process, passing in an array of arguments for the command we wish to run. Let’s take a look:

$command = new Process(
    command: ['git', 'push', 'origin', 'main'],
);

$command->run();
Copy after login

What’s wrong with this approach? Well, honestly, nothing. But is there a way to improve the developer experience? Let's say we switch from git to svn (which I'm unlikely to know).

To improve the developer experience, first, we need to understand the components that are logically used to create OS commands. We can break them down into:

  • Executable
  • Parameters

Our executable is something we interact with directly, e.g. php, git, brew or any other installed binary on our system. The argument then is how we interact; these can be subcommands, options, flags or parameters.

So if we abstract a little bit, we have a process and a command, which takes arguments. We will use interfaces/contracts to define our components to control how our workflow should work. Let's start with the process contract:

declare(strict_types=1);

namespace JustSteveKing\OS\Contracts;

use Symfony\Component\Process\Process;

interface ProcessContract
{
    public function build(): Process;
}
Copy after login

What we are saying here is that every process must be able to be built, and the result of the created process should be a Symfony process. Our process should build a command for us to run, so now let's look at our command contract:

declare(strict_types=1);

namespace JustSteveKing\OS\Contracts;

interface CommandContract
{
    public function toArgs(): array;
}
Copy after login

The main thing we want from the command is to be able to return it as parameters, which we can pass as The command is passed to the Symfony process.

Enough with the ideas, let’s look at a real-life example. We'll use git as an example since most of us should be able to relate to the git command.

First, let's create a Git process to implement the Process Contract we just described:

class Git implements ProcessContract
{
    use HandlesGitCommands;

    private CommandContract $command;
}
Copy after login

Our process implements the contract and has a command attribute that we will use to allow our Processes are structured and executed smoothly. We have a feature that allows us to focus on the way we build and make things for our Git process. Let's take a look:

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,
        );
    }
}
Copy after login

So our trait shows the implementation of the process contract itself and provides instructions on how to build the process. It also contains a method that allows us to abstract the build command.

So far we can create a process and build a potential command. However, we have not given the order yet. We create a new Git command in the trait, using the Git class as the type. Let's look at another Git class, which is an enumeration. However, I'll show a stripped down version - essentially, you want it to map to all the git subcommands you wish to support:

enum Git: string
{
    case PUSH = 'push';
    case COMMIT = 'commit';
}
Copy after login

Then we pass it to the Git command:

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,
        );
    }
}
Copy after login

in In this class, we accept parameters from Process, currently handled by our HandledGitCommands trait. We can then turn this into a parameter that the Symfony process can understand. We use ExecutableFinder from the Symfony package to minimize errors in the path. However, we also want to throw an exception if the executable is not found.

When we put them in our Git process, it looks a little like this:

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

Now all that's left to do is run the code itself so that we can run it in the PHP application Nice use of git in your program: The result of the

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

$result = $command->run();
Copy after login

Push method will allow you to interact with the symfony process - meaning you can perform all the sorting using commands on the other end. The only thing we changed was to build an object-oriented wrapper around the creation of this process. This allows us to develop and maintain the context well and extend things in a testable and scalable way.

How often do you use operating system commands in applications? Can you think of any use cases? I've published the sample code in a repository on GitHub so that you can play with it and see if you can improve your operating system integration.

A good example would be SSH, MySQL, or even Anable or Terraform! Imagine if you could efficiently run MySQL dumps from Laravel Artisan on a schedule without having to use third-party packages all the time!

Original address: https://laravel-news.com/working-with-os-process-in-php

Translation address: https://learnku.com/ laravel/t/71422

For more programming-related knowledge, please visit: Programming Video! !

The above is the detailed content of A brief analysis of the correct method of calling system commands in PHP applications. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
1 months ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
1 months ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
1 months ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
1 months ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

How To Set Up Visual Studio Code (VS Code) for PHP Development How To Set Up Visual Studio Code (VS Code) for PHP Development Dec 20, 2024 am 11:31 AM

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

7 PHP Functions I Regret I Didn't Know Before 7 PHP Functions I Regret I Didn't Know Before Nov 13, 2024 am 09:42 AM

If you are an experienced PHP developer, you might have the feeling that you’ve been there and done that already.You have developed a significant number of applications, debugged millions of lines of code, and tweaked a bunch of scripts to achieve op

How do you parse and process HTML/XML in PHP? How do you parse and process HTML/XML in PHP? Feb 07, 2025 am 11:57 AM

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

PHP Program to Count Vowels in a String PHP Program to Count Vowels in a String Feb 07, 2025 pm 12:12 PM

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

Explain late static binding in PHP (static::). Explain late static binding in PHP (static::). Apr 03, 2025 am 12:04 AM

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? Apr 03, 2025 am 12:03 AM

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.

See all articles