2016-05-12 12 views
2

Ich habe auch das Befehlszeilentool von gamingman extension und von gearman installiert. Ich habe versucht, eine Zeichenfolge mit Gearman aus einfachen PHP-Datei umzukehren.Wie exec()/linux Befehle mit der gearman Erweiterung von CakePHP Anwendung ausführen?

Example: 
$gmclient= new GearmanClient(); 
$gmclient->addServer(); 
$result = $gmclient->doNormal("reverse", "Test the reverse string"); 
echo "Success: $result\n"; 
output: 
Success: gnirts esrever eht tseT 

In gleicher Weise habe ich versucht, exec (‚ls -l‘), ich bin in der Lage auszuführen mit einfachen PHP-Dateien aus CakePHP Anwendung von Webroot-Verzeichnis auszuführen. Dateipfad: cake.php/app/webroot/worker.php, cake.php/app/webroot/client.php.

worker.php 

<?php 
$worker= new GearmanWorker(); 
$worker->addServer(); 
$worker->addFunction("exec", "executeScript"); 
while ($worker->work()); 
function executeScript($job) 
{ 
    $param = $job->workload(); 
    $t = exec($param); 
    return $t; 
} 
?> 

client.php 

<?php 
$client= new GearmanClient(); 
$client->addServer(); 
$cmd = 'ls -l'; 
print $client->do("exec", $cmd); 
?> 

Wie implementiert man die gleiche Art der Ausführung mit View, Controller von CakePHP? Arbeitsablauf: Veröffentlichen Sie Daten von View to Controller mit der Ajax-Methode und führen Sie "exec() from gearman" aus, senden Sie die Ausgabe an View als Antwort von ajax POST method zurück.

Antwort

0

Ihre worker.php muss bereits auf einem Server laufen, damit dies funktioniert. Öffnen Sie zum Testen ein neues Terminalfenster für den Server, auf dem die Datei "worker.php" ausgeführt werden soll. Starten Sie den Worker: php worker.php in der Befehlszeile. (Auf einem Produktionsserver sollten Sie sich supervisor ansehen, um Ihren Mitarbeiter ohne Terminal auszuführen.)

Der Code in client.php würde in Ihrem Controller gespeichert werden, aber das Ergebnis in einer Variablen statt einer print-Anweisung speichern .

Die Tatsache, dass dies von einem AJAX-Aufruf wäre, ist irrelevant, es funktioniert genauso wie eine normale Webseite. Wenn der Controller ausgeführt wird, erhält der Code des Gearbman-Clients eine Antwort vom Worker, und Sie können das Ergebnis in der Ansicht ausgeben.

+0

Kris @ Thankyou für die Antwort. Aber ich brauche einige Daten, um den client.php-Code von der Ansicht zum Controller zu verarbeiten. Beispiel: Der Benutzer lädt Daten hoch und verwendet ajax Post-Daten zur Controller-Funktion und führt den client.php-Code aus. – Dollyh

2

Warum verwenden Sie exec?! Das bringt ein riesiges Sicherheitsrisiko mit sich. Verwenden Sie stattdessen DirectoryIterator.

Ihr Client-Code sollte Teil des Controllers sein.

<?php 
class UploadController extends AppController 
{ 
    public function directoryList() 
    { 
     $directory = ''; 
     // Get data 
     if (!empty($this->data['directory']) && is_string($this->data['directory'])) 
     { 
      $directory = $this->data['directory']; 
     } 
     $client= new GearmanClient(); 
     $client->addServer("localhost",4730); // Important!!! 

     $result = $client->do("fileList", serialize($data)); 

     return $result; 
    } 
} 

Dann aus Sicht verwenden requestAction.

$uploads = $this->requestAction(
     array('controller' => 'upload', 'action' => 'directoryList'), 
     array('return') 
    ); 

Worker könnte wie folgt aussehen:

<?php 
$worker= new GearmanWorker(); 
$worker->addServer("localhost",4730); // Important!!! 
$worker->addFunction("fileList", "getFileList"); 
while ($worker->work()); 

// From Art of Web 
// http://www.the-art-of-web.com/php/directory-list-spl/ 
function getFileList($dir) 
{ 
    // array to hold return value 
    $retval = array(); 
    $dir = $job->workload(); 
    // add trailing slash if missing 
    if(substr($dir, -1) != "/") $dir .= "/"; 

    // open directory for reading 
    $d = new DirectoryIterator($dir) or die("getFileList: Failed opening directory $dir for reading"); 
    foreach($d as $fileinfo) { 
    // skip hidden files 
    if($fileinfo->isDot()) continue; 
    $retval[] = array(
     'name' => "{$dir}{$fileinfo}", 
     'type' => ($fileinfo->getType() == "dir") ? 
      "dir" : mime_content_type($fileinfo->getRealPath()), 
     'size' => $fileinfo->getSize(), 
     'lastmod' => $fileinfo->getMTime() 
     ); 
    } 

    return $retval; 
} 

Dies ist Pseudo-Code. Nicht in der Produktion verwenden !!! Siehe Gearman documentation für mehr Vorarbeiter Setup.

Um Lastverteilung tatsächlich nutzen Gearman Server sollte nicht auf localhost natürlich sein.

+0

Goran @ Ich benutze Exec, um Python auszuführen, um dies auszuführen, brauche ich Benutzer hochgeladen Dateninformationen. Also benutze ich einen Ajax-Aufruf, um Python zu senden und auszuführen und eine Antwort an View zurückzusenden. Wie implementiert man Gearman in diesem Workflow? Gibt es einen anderen besseren Weg, um fortzufahren? – Dollyh

+0

Ich denke, das sollte eine andere Frage sein. Du hast Python überhaupt nicht erwähnt. Ihre Frage ist mit _shell_ markiert. Verwenden Sie stattdessen [Python-Worker] (https://pypi.python.org/pypi/gearman/) und rufen Sie Python-Befehle direkt auf. Alles andere bleibt gleich. –