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

时间:2016-05-12 06:57:46

标签: php shell cakephp command gearman

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

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目录的cakephp应用程序的简单php文件执行。 filepath:cakephp / app / webroot / worker.php,cakephp / 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);
?>

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

2 个答案:

答案 0 :(得分:3)

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

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

<?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 documentation以获取更多高级工作人员设置。

要实际利用负载分配当然,Gearman服务器不应该在localhost上。

答案 1 :(得分:0)

您的worker.php需要已在服务器上运行才能实现此功能。要进行测试,请打开一个新的终端窗口,指向要运行worker.php的服务器。在命令行上启动worker php worker.php。 (在生产服务器上,您可能希望查看supervisor以在没有终端的情况下运行您的工作人员。)

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

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