Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern for Wrapping Shell Commands in a Class

Despite its inadvisability, using PHP's shell commands to interact with non-php system commands remains a common way of quickly achieving certain results in web applications.

Has anyone abstracted out the common use cases into a class library (something in Zend maybe?) that offers a more sane/common way of handling this? Every time I encounter (or have to produce) this kind of code it's a bunch of procedural spaghetti, copy-pasted over and over again. I was wondering if (hoping that) the PHP community had come up with a better way of handling using command line applications in your web/php applications.

like image 826
Alan Storm Avatar asked Jun 23 '10 21:06

Alan Storm


Video Answer


1 Answers

Executing commandline applications is nothing dirty. In fact, it's the Unix way. And most mostly it's saner than trying to reimplement e.g. ImageMagick in pure PHP code. (Due to the disparity of its cmdline args, imagemagick is a bad example case if you look for a nice exec() abstraction.)

There isn't much wrapping up you can do. At best you can summarize in-/output to your external binary in a method:

function exec($args) {
    $args = implode(" ", array_map("escapeshellcmd", func_get_args()));
    $opts = $this->opts();
    return `{$this->bin} {$args} {$opts}`;
}

So you just call ->exec("-o", "$file") where needed. Your code can only be gneralized further with specialized exec submethods, if the particular cmdline app has an inherent system in its --argument naming scheme.

Depending on your actual use case, you might be able to stash a few standard options away. I did this for pspell, where you have an almost 1:1 relationship of option names to --cmdline=args:

function opts() {
    $map = array(
       "--ignore" => $this->ignore,
       "--verbose" => $this->verbose,
       "--dir={$this->dir}" => isset($this->dir),
    );
    return implode(" ", array_keys(array_intersect($map, array(1=>1))));
}

A very generic abstraction class for exec/popen (for a wide range of cmdline programs) probably doesn't exist.

like image 166
mario Avatar answered Oct 13 '22 23:10

mario