【发布时间】:2017-04-06 10:36:51
【问题描述】:
我在使用 Raspberry Pi 3 中用于配置 WiFi 网络的 PHP 脚本时遇到问题。它应该从 POST 获取 SSID 和 PW 变量,对 ajax 调用回答“ok”,然后然后执行脚本(按此顺序,然后 RPi 重新启动,因此连接丢失)。问题是在发送“ok”响应之前正在执行脚本。代码如下:
<?php
header('Access-Control-Allow-Origin: *');
header('content-type: text/html; charset:utf-8');
require_once "chkSession.php";
ini_set('display_errors', 1);
$servername = "localhost";
$username_db = "xxx";
$password_db = "xxx";
$dbname = "xxx";
$conn = new mysqli($servername, $username_db, $password_db, $dbname);
if ($conn->connect_error) {
die("died" . $conn->connect_error);
}
$username = $_POST['username'];
$sessionKey = $_POST['sessionKey'];
if (chkSession($conn,$username,$sessionKey)){
$ssid = $_POST['ssid'];
$wifipwd = $_POST['wifipwd'];
echo json_encode(["auth"=>"ok"]);
sleep(5);
exec("sudo /var/www/scripts/configwifi.sh \"".$ssid."\" \"".$wifipwd."\"");
} else {
echo json_encode(["auth"=>"skErr"]);
}
?>
如您所见,exec 是......好吧,在发送“ok”响应后 5 秒执行。或者应该是,但是响应没有到达。
我搜索了类似的问题,但没有真正找到任何有用的(或类似的)。
编辑:
我尝试了@steven-jackson 的回答,但没有结果:
echo json_encode(["auth"=>"ok"]);
flush();
ob_flush();
sleep(5);
exec("sudo /var/www/scripts/configwifi.sh \"".$ssid."\" \"".$wifipwd."\"");
编辑 2:
尝试将sleep从php脚本更改为shell脚本,以exec("sudo /var/www/scripts/configwifi.sh \"".$ssid."\" \"".$wifipwd."\" &");执行,但也没有成功。
【问题讨论】:
-
这是意料之中的。 ok 消息将被发送到缓冲区,然后直到脚本结束才释放。
-
我猜你正在经历会话锁定,我在你的脚本中没有看到
$_SESSION变量,但我会假设它在chkSession.php文件中,所以......解决这个地方session_write_close();上面的代码echo声明。 -
@cmorrissey 实际上我没有使用 PHP 会话进行用户验证,
chkSession.php是我为简单会话验证编写的脚本(基本上它只是检查用户发送的会话密钥是否匹配存储在服务器中的那个)。 -
@RossWilson 有没有办法绕过这个?我不知道所有脚本的输出在发送之前都被缓冲了,我认为它可以发送单独的回声。
-
@StevenJackson 确实如此,
www-data可以在/var/www/scripts/中使用 sudo 命令(其他任何地方都没有)。它确实执行得很好,问题是它在执行前没有回答“ok”。