如何在我的网站上的 shell 中 运行 一个 php 脚本?
How to run a php script in a shell on my website?
我有一个 PHP 脚本位于 /var/www/site/update.php full
。该脚本从 cron 自动启动:
/usr/bin/php /var/www/site/update.php full
但是当我从我的网站启动相同的脚本时:
<?php exec("/usr/bin/php /var/www/site/update.php full") ?>
它 运行 持续了大约 20 分钟,然后开始显示大量错误消息。同时页面停止加载并在屏幕上写入 error 504 Gateway Time-out
。
我想 curl 也无济于事。还有其他选择吗?
问题是如何 运行 以便它可以独立于浏览器工作。该代码已经存在并已制定。现在它 运行 每小时通过 cron。但需要 运行 通过按按钮或在网站上 link 取消计划。
你可以修改PHP脚本中的set_time_limit(-1);
来防止PHP死掉但是504听起来像是你有nginx 运行ning,所以你也必须使用 location
配置节点(或主 ngix 配置)修改特定资源的时间限制以设置 *_timeout 设置
如果您不需要每秒刷新一次输出,我会这样做:
按下按钮时,将标志"pressed"存储在某个文件中
if($_POST['schedule_script_button']){
touch(DIR."/script_is_scheduled.flag");
}
每分钟使用 cron 运行 脚本
* * * * * php /var/www/example.com/my-long-script.php
脚本必须检查是否设置了该标志,否则终止
if(!file_exists(DIR."/script_is_scheduled.flag")){
出口;
}
//完整的脚本逻辑在这里执行
如果设置了标志,运行 脚本,并将输出保存到文件中。如果你使用crontab,你可以在脚本中使用echo,并且crontab应该修改如下:
* * * * * php /var/www/example.com/my-long-script.php > /var/www/example.com/my-script-output.txt
- 允许 Web 界面从另一个 URL 读取 "output file"。也就是说,您现在可以使用
file_get_contents
PHP 函数读取 my-script-output.txt
并简单地回显其内容。
我反对将 web-url 的执行限制设置为高值,这可能会被攻击者用来通过执行长脚本获取资源来降低您的站点
您试图实现的目标无法在 PHP Web 范例中完成:您的脚本 运行s 在 HTTP 请求的上下文中;当您的访问者中断请求(关闭选项卡或浏览器、关闭 WiFi 等)时,它的执行将始终终止。
为了从 HTTP 请求(点击按钮或程序化的 curl 调用)触发长时间的后台任务的执行,您的服务器必须由更多成分组成:通常是消息队列(例如如 RabbitMQ).
单击按钮只会触发作业消息:将(字符串)消息放入消息队列中,描述 运行 的执行类型和参数(例如 PHP-序列化方式,或 JSON) — 然后立即 returns。您的访问者会收到一个快速的 HTTP 响应,上面写着 "Your job has been queued successfully".
然后,除了 Message Queue 成分之外,您还必须 运行 一个连续 运行ning 进程(在 PHP 具有无限时间限制的 CLI 中,或任何语言的守护进程你的选择)。这个无限循环脚本将自身置于消息队列服务的监听模式(订阅者),每次有消息进来时,它都会执行您需要的任何长时间处理。
您的访问者可以在其 运行ning 作业的专用页面上查询长作业的状态,他们还可以在该页面上获取结果以供下载或查看等(例如:各种 "Convert YouTube to Mp3" 网络服务)
这是处理在线触发的长时间后台任务的唯一可靠方法。
您可以使用多种替代中间件来实现此目的:RabbitMQ、Redis、Kafka、是一些示例,具体取决于您的具体情况(根据诸如守护进程实例的数量、队列中未决消息的优先级管理需求或发生故障时队列的持久性等考虑因素)
您可以在 RabbitMQ 操作指南中找到 detailed guide with PHP。
我按照讨论中的建议做了 php execute a background process。页面仍未加载,但结果是。它可能不是最好的解决方案,但它确实有效。我期待更好的解决方案。
我有一个 PHP 脚本位于 /var/www/site/update.php full
。该脚本从 cron 自动启动:
/usr/bin/php /var/www/site/update.php full
但是当我从我的网站启动相同的脚本时:
<?php exec("/usr/bin/php /var/www/site/update.php full") ?>
它 运行 持续了大约 20 分钟,然后开始显示大量错误消息。同时页面停止加载并在屏幕上写入 error 504 Gateway Time-out
。
我想 curl 也无济于事。还有其他选择吗? 问题是如何 运行 以便它可以独立于浏览器工作。该代码已经存在并已制定。现在它 运行 每小时通过 cron。但需要 运行 通过按按钮或在网站上 link 取消计划。
你可以修改PHP脚本中的set_time_limit(-1);
来防止PHP死掉但是504听起来像是你有nginx 运行ning,所以你也必须使用 location
配置节点(或主 ngix 配置)修改特定资源的时间限制以设置 *_timeout 设置
如果您不需要每秒刷新一次输出,我会这样做:
按下按钮时,将标志"pressed"存储在某个文件中
if($_POST['schedule_script_button']){ touch(DIR."/script_is_scheduled.flag"); }
每分钟使用 cron 运行 脚本
* * * * * php /var/www/example.com/my-long-script.php
脚本必须检查是否设置了该标志,否则终止
if(!file_exists(DIR."/script_is_scheduled.flag")){ 出口; } //完整的脚本逻辑在这里执行
如果设置了标志,运行 脚本,并将输出保存到文件中。如果你使用crontab,你可以在脚本中使用echo,并且crontab应该修改如下:
* * * * * php /var/www/example.com/my-long-script.php > /var/www/example.com/my-script-output.txt
- 允许 Web 界面从另一个 URL 读取 "output file"。也就是说,您现在可以使用
file_get_contents
PHP 函数读取my-script-output.txt
并简单地回显其内容。
我反对将 web-url 的执行限制设置为高值,这可能会被攻击者用来通过执行长脚本获取资源来降低您的站点
您试图实现的目标无法在 PHP Web 范例中完成:您的脚本 运行s 在 HTTP 请求的上下文中;当您的访问者中断请求(关闭选项卡或浏览器、关闭 WiFi 等)时,它的执行将始终终止。
为了从 HTTP 请求(点击按钮或程序化的 curl 调用)触发长时间的后台任务的执行,您的服务器必须由更多成分组成:通常是消息队列(例如如 RabbitMQ).
单击按钮只会触发作业消息:将(字符串)消息放入消息队列中,描述 运行 的执行类型和参数(例如 PHP-序列化方式,或 JSON) — 然后立即 returns。您的访问者会收到一个快速的 HTTP 响应,上面写着 "Your job has been queued successfully".
然后,除了 Message Queue 成分之外,您还必须 运行 一个连续 运行ning 进程(在 PHP 具有无限时间限制的 CLI 中,或任何语言的守护进程你的选择)。这个无限循环脚本将自身置于消息队列服务的监听模式(订阅者),每次有消息进来时,它都会执行您需要的任何长时间处理。
您的访问者可以在其 运行ning 作业的专用页面上查询长作业的状态,他们还可以在该页面上获取结果以供下载或查看等(例如:各种 "Convert YouTube to Mp3" 网络服务)
这是处理在线触发的长时间后台任务的唯一可靠方法。
您可以使用多种替代中间件来实现此目的:RabbitMQ、Redis、Kafka、是一些示例,具体取决于您的具体情况(根据诸如守护进程实例的数量、队列中未决消息的优先级管理需求或发生故障时队列的持久性等考虑因素)
您可以在 RabbitMQ 操作指南中找到 detailed guide with PHP。
我按照讨论中的建议做了 php execute a background process。页面仍未加载,但结果是。它可能不是最好的解决方案,但它确实有效。我期待更好的解决方案。