我在 Apache 服务器上通过 Ratche 运行 ZMQ“推送”接口,它在命令行上运行得很好,可以按照我想要的方式与我的服务器交互。以下是代码
//script1.php
<?php
echo exec('php script2.php');
?>
//script2.php
<?php
$entryData = array(
'category' => 'modelLmdap'
, 'job_id' => '1234'
, 'text' => ''
, 'status' => ''
);
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
$socket->connect("tcp://localhost:5555");
$socket->send(json_encode($entryData));
?>
当我执行 script1.php 时,我看到服务器窗口中弹出一个窗口,显示“请求已记录”。但是,如果我尝试通过浏览器运行它,我得到的是空白页,服务器上没有任何输出。
我查看了一下,这可能是由于 Apache 无法在命令行上运行,解决方案是将以下内容添加到我的 sudoers(使用 sudo visudo):
www-data ALL=NOPASSWD: ALL
仍然没有!空白页。我将命令切换为 exec(),然后出现此错误:
致命错误:在 /home/username/server/qap/v2/tools/push.php 第 8 行中未找到类“ZMQContext”
有任何想法吗?
编辑:有人问我为什么要做这一切,这是一个很实际的问题。
TL;DR 我想不出将另一个 php 脚本作为服务来执行的方法 - curl 无法在本地运行并且 include 也无法解决问题。
我正在执行大量复杂的统计计算,这些计算需要大量资源,并且需要花费太多时间才能产生任何输出,从而导致奇怪的脚本执行问题,包括无缘无故出现空白页(即使我延长了最大脚本执行时间)和 AJAX 错误(尽管超时已达到最大值)。因此,我将服务器端的计算外包给许多不同的后台进程,所有这些进程都是 php 脚本。这也允许我在执行此长脚本时更新用户。有问题的调用是执行控制计算场的“控制器”脚本(这是正确的术语吗?我不知道)。然后,脚本与推送服务器(通过 ZMQ)通信并将数据推送到客户端。原始代码是 AJAX 繁重的,我真的不想将其全部更新为使用 websockets,所以我决定使用 Ratchet 作为套接字服务器的“推送”类型样式。这意味着我可以进行原始 AJAX 调用来启动整个过程,然后页面单向接收来自服务器的更新。这有很多优点,我最喜欢的是通信本质上是单向的,这使我不得不在服务器端实现许多安全功能。不幸的是,为了使这一切正常工作,Ajax 脚本需要能够 shell_exec 'farm' 脚本,因为它们需要作为后台进程运行,这就是我遇到问题的原因。我试过 curl(),但它只抓取裸文本,而 include() 只会导致其他脚本作为 ajax 脚本的一部分运行,这完全违背了要点。我想从长远来看,我可以将“推送”服务器修改为完全双工,允许初始数据从网页直接传输到异步“farm 服务器”(我知道 ReactPHP 可以做到这一点,node.js 也可以),但作为套接字服务器编程的新手,我认为最好避免这样做,直到我完成一个工作模型。
如果我遗漏了什么,请告诉我,我和你一样讨厌不安全的网站!
答案1
好的,我已经解决了!
问题是由于系统上安装了许多不同的 PHP 版本(我将系统从共享托管域移植到私人服务器,并携带所有相关包袱)。Apache 使用的是 php5.4,而 ZMQ 安装在 5.6 上。
我将所有 php 5.4 文件夹重命名为 php54_old,并创建指向所有相关 php 5.6 文件夹的链接 (sudo ln -s /etc/php56 /etc/php54)。我相信这与其 sudo 权限 (上文) 结合使用使其能够正常工作,尽管我将在部署站点时测试它是否在没有 sudo 权限的情况下工作。出于多种原因,我不太喜欢 Apache 具有 sudo 权限 - 在此期间,我将 Apache 的 sudo 权限限制为仅执行 php。
编辑:哦,我还卸载并重新安装了 ZMQ PEAR 包和 zmq php 包装器。