1

背景:

现在,在我们公司,我们有一个基于 PHP 的应用程序来自动化我们的报告构建。它是这样工作的:

  1. 带有表单的网页会生成一个带有一些配置的 ini 文件,这些配置保存在本地
  2. PHP CLI 脚本接受在步骤 1 中生成的 ini 文件,并基于它创建一个目录,其中包含从 Internet 获取数据的文档。(需要 5 到 10 分钟才能完成)
  3. 另一个 Web 表单探索文件夹的内容,进行一些验证并将目录的内容显示为预览。

在这些步骤之间,需要用户输入,有时用户需要中断脚本 2 以更正一些 ini 值。


问题:

我们希望在网络浏览器中运行 cli 脚本,以便在用户单击“构建”按钮后,生成 ini 文件(或数组)并自动传递给第二个脚本。但想法是让该脚本独立运行(模拟另一个“线程”),详细说明它在此过程中所做的一切,以便让用户在需要时中断。类似于在命令行中运行脚本,其中每个步骤都是详细的。


我们虽然使用 AJAX,但它会等待服务器完成其响应,然后再在 Web 浏览器中打印任何内容。iFrame 也不起作用,因为我们无法使用 javascript 操作它的 src 属性和内容。

那么,我们如何“模拟”命令 shell 输出呢?任何正确方向的提示将不胜感激。

注意:该脚本将始终在“localhost”中使用,无需远程访问!


解决方案

根据以下建议,我最终做了一些更简单的事情:

  • 将表单 ($_POST) 的内容转储到会话变量 $_SESSION['FORM']。
  • 创建了一个 $_SESSION[form-complete] 标志,当用户单击“构建”按钮时该标志将设置为 true。
  • 如果 $_SESSION[form-complete] 为真,服务器将显示一个指向“CLI SCRIPT”的 iframe,其参数是先前转储的会话变量。
  • CLI 脚本也有ob_implicit_flush(true); ob_end_flush();这样的输出不会被缓存。
  • 在脚本结束时 $_SESSION 变量是干净的并且会话被破坏
4

3 回答 3

3

iFrame 也不起作用,因为我们无法使用 javascript 操作它的 src 属性和内容。

您可以,只要 iframe 与父页面位于同一主机上(例如localhost)。AJAX 自然也不支持跨域请求,所以如果你有 AJAX 工作,iframe 也会随之而来。

您最简单的选择是将输出通过管道传输到一个临时文件,然后让您的“单独线程”成为检索输出的 iframe/AJAX 调用。如果它在 localhost 上运行,那么为此进行的带宽优化将毫无意义(除非日志变得非常长)。


一个小例子:

假设我们要运行./long_script. 这就是我们可以做到的。

  1. system('./long_script > /tmp/file 2>&1 &');(将所有输出通过管道传输到 /tmp/file,然后在后台运行)

  2. 制作一个执行类似操作的 PHP 脚本(您需要一种安全的方式来获取文件名,最好是会话变量或经过清理的$_GET变量):

    <pre><?php echo file_get_contents('/tmp/file'); ?></pre><script>setTimeout("window.location.reload()", 1000);</script>

  3. 将该 PHP 脚本放在 iframe 中。Javascript 将导致每 1 秒自动重新加载一次。


选择:

您可以使用popen来拥有一个进程句柄,然后fread将数据(set)刷新ob_implicit_flush(true)到浏览器(因此它不会等待从进程中获取所有输出,然后一次全部推送)。

于 2012-06-30T19:17:36.123 回答
1

那么,第 2 步可以是这样的页面:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title></title>
</head>
<body>

<button onclick="javasctipt:ajaxCall('stop')">Stop</button>
<button onclick="javasctipt:ajaxCall('pause')">Pause</button>
...
<iframe src="step2cli.php">Output of cli here</iframe>

</body>
</html>

调用ajax(对PHP)将您的命令(停止,暂停)或一些新信息(例如:新信息文件)写入“控制”文件。

定期您的 step2cli.php 检查“控制”文件。如果存在,解析并删除它,然后当然应用新信息。

于 2012-06-30T19:31:24.613 回答
0

bash中的这段代码工作

url="google.com"
content=$(curl -L $url)
echo $content
于 2021-05-29T15:35:01.040 回答