如何使用cakepp应用程序中的gearman扩展来运行exec()/linux命令


How to run exec()/ linux commands using gearman extension from cakephp application?

我还安装了gearman扩展和gearman命令行工具。我尝试使用gearman从简单的php文件中反转一个字符串。

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

与我尝试运行exec('ls-l')的方式相同,我能够使用webroot目录中cakepp应用程序中的简单php文件执行。文件路径:cakehp/app/webroot/worker.php,cakehp-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);
?>

如何使用cakepp中的View、Controller实现相同类型的执行?工作流程:使用ajax方法将数据从View发布到Controller,并执行"来自gearman的exec()",将输出作为ajax Post方法的响应发送回View。

为什么要使用exec?!这带来了巨大的安全风险。请改用DirectoryTerator。

您的客户端代码应该是控制器的一部分。

<?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;
    }
}

然后从视图中使用requestAction。

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

工人可能是这样的:

<?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;
}

这是伪代码不要在生产中使用它请参阅Gearman文档,了解更多高级工人设置。

为了真正利用负载分布,Gearman服务器当然不应该在本地主机上。

您的worker.php需要已经在服务器上运行才能运行。为了进行测试,打开一个新的终端窗口到您希望worker.php运行的服务器。在命令行上启动工作程序:php worker.php。(在生产服务器上,您可能希望在没有终端的情况下查看主管来运行您的工作人员。)

client.php中的代码将进入控制器,但将结果保存到变量中,而不是print语句。

事实上,这将来自AJAX调用是无关紧要的,它将像普通网页一样工作。当控制器执行时,gearman客户端代码将从worker获得响应,您可以将结果输出到视图。