2010-06-23 3 views
7

Nonostante l'inavvisibilità, l'utilizzo dei comandi shell di PHP per interagire con i comandi di sistema non php rimane un modo comune per ottenere rapidamente determinati risultati nelle applicazioni Web.Pattern per il wrapping di comandi shell in una classe

Qualcuno ha estrapolato i casi di uso comune in una libreria di classi (qualcosa in Zend forse?) Che offre un modo più sano/comune di gestirlo? Ogni volta che incontro (o devo produrre) questo tipo di codice è un mucchio di spaghetti procedurali, copiati ripetutamente. Mi stavo chiedendo se (sperando che) la comunità di PHP avesse messo a punto un modo migliore di gestire usando le applicazioni a riga di comando nelle vostre applicazioni web/php.

+0

Ottima domanda. Le [note note dell'utente] (http://www.php.net/manual/en/function.exec.php) per exec() offrono una varietà di approcci, per lo più della qualità che descrivi anche se ... ci sono vari incarnazioni di funzioni lì, una delle quali funzionerà di solito. Esistono anche alcune implementazioni OOP più pulite, ma servono casi molto specifici (come l'avvio e l'arresto di processi in Linux). Sarebbe davvero bello avere l'implementazione "perfetta" per questo. –

+1

Quali sono i "casi di uso comune"? – Artefacto

+0

Beh, se potessi elencare tutti quelli e confidare di conoscerli, probabilmente li implementerei io stesso invece di chiedere se qualcuno l'avesse già implementato. In qualsiasi attività di programmazione che sembra semplice ci sono tonnellate di condizioni comuni a cui non pensi. Tutto ciò che intendevo per "casi di uso comune" era che volevo che la soluzione fosse già pensata, e non una singola classe di metodo che avvolge una chiamata di shell. –

risposta

3

L'esecuzione di applicazioni a riga di comando non è sporca. In effetti, è il modo Unix. E la maggior parte è più salutare che provare a reimplementare, ad es. ImageMagick in puro codice PHP. (A causa della disparità dei suoi argomenti di cmdline, caso imagemagick is a bad example se si cerca una bella astrazione exec().)

Non c'è molto da fare. Nella migliore delle ipotesi si può riassumere un input/output al binario esterno in un metodo:

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

Quindi basta chiamare -> exec ("- o", "$ file"), dove necessario. Il tuo codice può essere ulteriormente valorizzato con i metodi di esecuzione specializzati, se la specifica app di cmdline ha un sistema inerente nel suo schema di denominazione degli argomenti.

A seconda del caso di utilizzo effettivo, è possibile che siano disponibili alcune opzioni standard. Ho fatto questo per pspell, dove si ha quasi 1: 1 rapporto di nomi di opzione per --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)))); 
} 

Una classe di astrazione molto generico per exec/popen (per una vasta gamma di programmi cmdline) probabilmente non esiste.

+0

L'inadeguatezza che menziono di solito si riduce a 1. Generare un nuovo processo è un'operazione costosa e 2. Di solito c'è un'estensione PHP nativa che gestirà le cose per te –