tags:

views:

40

answers:

1

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.

+1  A: 

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.

mario
The inadvisability I mention usually comes down to 1. Spawning a new process is an expensive operation and 2. There's usually a native PHP extension that will handle things for you
Alan Storm