gpt4 book ai didi

php - 如何让脚本在后台运行 - 不工作

转载 作者:行者123 更新时间:2023-12-04 16:14:32 26 4
gpt4 key购买 nike

我正在尝试启动 Ratchet 的 chat-server.php 文件,该文件需要从 php 文件启动套接字服务器,以便每当客户端访问该页面时,服务器都会启动,但不会发生。这个 chat-server.php 文件需要从终端运行,但我试图在用户访问时从主页运行它。

文件结构

./index.php

./config.php

./vendor/(all vendor files)

./src/MyApp/Chat.php

./js/app.js

./inc/connect.php <--Database connection file

./inc/send-message.php

./inc/startServer.php

./inc/bg.php

./inc/serverStatus.txt

./css/index.css

./css/reset.css

./bin/chat-server.php



config.php
<?php
include_once ("./inc/startServer.php");
?>

聊天服务器.php
<?php

use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;


if(isset($startNow)){

require dirname(__DIR__) . '/vendor/autoload.php';

$server = IoServer::factory(
new HttpServer(
new WsServer(
new Chat()
)
),
8080
);

$server->run();

}

?>

bg.php
<?php
$startNow = 1;
include_once ("../bin/chat-server.php");
?>

startServer.php
<?php

$statusFile = dirname(__FILE__).'/serverStatus.txt';
$status = file_get_contents($statusFile);
if($status == "0"){

function execInBackground($cmd) {
if(substr(php_uname(), 0, 7) == "WINDOWS") {
pclose(popen('start /B ' . $cmd, 'r'));
file_put_contents($statusFile, 1);
}
else {
exec($cmd . ' > /dev/null &');
file_put_contents($statusFile, 1);
}
}

execInBackground("php " . dirname(__FILE__) . "/bg.php");

}

?>

serverStatus.txt

其默认值已设置为 0

注意:相应地更新了代码,但现在仍然无法使用。

加号我不知道在发生任何故障时重新启动服务器,或者在所有客户端离开时如何关闭服务器。

最佳答案

当您使用 包含文件时相对路径 你必须记住它们是相对于 当前运行文件 ,不只是为了当前文件 .

在你的情况下。当您访问 index.php并包括在其中 config.php从那时起 startServer.php没关系,因为你包括 ./inc/startServer.php这是正确的,相对于 index.php .
但比你包括 ../inc/serverStatus.txt ,这是不对的,因为你还在运行 index.php并且该相对路径解析为 /../inc/serverStatus.txt换句话说,您正试图访问比您的 DOCUMENT_ROOT 高一级的文件。 .所以你永远不会进入你的if陈述。
您可以使用 __FILE__始终解析为 的绝对路径的常量当前文件 .所以你可以改变你的$statusFile

$statusFile = dirname(__FILE__) . '/serverStatus.txt';

接下来是关于您的 exec()popen(pclose())命令。如果你想执行一些不在你的 PATH 中的命令环境变量,比你 必须指定文件的绝对路径。因为你不知道它会从哪个文件夹启动。它可能是从 Apache 开始的主目录或者可能从您用户的主目录开始。这取决于您的 PHP 的设置是吗 sapi模块还是它 fcgi .无论如何,您需要更改您的 execInBackground()
execInBackground("php " . dirname(__FILE__) . "/bg.php");

并在您的命令中添加一些空格,如下所示:
pclose(popen('start /B ' . $cmd, 'r'));
exec($cmd . ' > /dev/null &');

这样你就不会出现一些奇怪的错误。

在您的 bg.php 您需要更改当前工作目录,如下所示:
<?php
$startNow = 1;
chdir(dirname(__FILE__));
include_once ("../bin/chat-server.php");
?>

这样, PHP会找到 chat-server.php无论您从哪个文件夹运行它。

BTW,你是怎么打算停止你的服务器的? =)

更新 : 你还有一个 变量范围 您的函数中的问题 execInBackground() .您的函数依赖于变量 $statusFile , 但是这个变量定义在 全局范围并且在函数内部不可见。要使其可见,您必须包含声明 global $statusFile;在访问 $statusFile 之前在您的函数中.像这样:
    function execInBackground($cmd) {
global $statusFile;
if (false !== stripos(PHP_OS, 'win')) {
pclose(popen('start /B ' . $cmd, 'r'));
file_put_contents($statusFile, 1);
} else {
exec($cmd . ' > /dev/null &');
file_put_contents($statusFile, 1);
}
}

我已经改变了你检查操作系统的方式,因为你的方法包含一个错误。

更新2 :

经过一系列测试,我发现当 php-script 在后台(在 Windows 下)运行时,它不能使用“echo()”来写入 STDOUT。当它发生时,php-script 将无声无息地死去,没有错误。所以改变所有 echo()是一些日志功能。

将监听端口更改为其他的,这肯定是免费的,例如 50000。因为,8080 经常可能已经被某些 Web 服务器或其他服务占用。

记住!只有当您拥有自己的服务器(如 VPS/VDS 或专用服务器)时,您才能在 上启动您的聊天服务器。公共(public)托管出于安全原因,没有人会允许您为传入连接打开某个端口。在公共(public)服务器上经常有禁用的功能,如 exec() , popen()出于同样的原因,类似。

关于php - 如何让脚本在后台运行 - 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38290749/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com