Angular POST to PHP: file_put_contents not writing/wrong 提交订单
Angular POST to PHP: file_put_contents not writing/wrong submit order
我正在使用 angular http 将 post 数据从我的 Ionic 应用程序发送到 PHP 脚本。在该脚本中,一个 json 文件被读取和解码,以便可以附加传入的数据,然后将其写回文件。
这基本上工作正常,但在某些情况下 file_put_contents
不写入新的编码数组 and/or 提交顺序被弄乱了。
打字稿:
this.names.forEach(name => {
this.http.post("http://myServer.test/saveNames.php", {name: name["name"], mode: name["mode"]}).subscribe(
err => {
errors.push(name["name"]);
}
);
});
Typescript post 数据:
(3) [{…}, {…}, {…}]
0: {name: "User 1", mode: "namesM"}
1: {name: "User 2", mode: "namesW"}
2: {name: "User 3", mode: "namesJobs"}
length: 3
PHP 脚本:
$postData = file_get_contents("php://input");
if (isset($postData)) {
$request = json_decode($postData, true);
var_dump("Data after decode:");
var_dump($request);
$inp = file_get_contents('names.json');
if (($inp) == "") return; // Return so file does not get messed up
$allNames = json_decode($inp, true);
var_dump("File, no decode:");
var_dump($inp);
var_dump("File, decoded:");
var_dump($allNames);
$allNames[] = $request;
var_dump("File content + new data:");
var_dump($allNames);
var_dump("All data pretty printed:");
var_dump(json_encode($allNames, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
file_put_contents('names.json', json_encode($allNames, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); // mit UTF8s
}
names.json 任何写入前(初始状态):
[]
names.json post 完成后:
[
{
"name": "User 1",
"mode": "namesM"
},
null
]
该文件具有 777 权限,在此过程中未打开。如您所见,只写了一个名字,插入了一个空值,然后什么也没有发生。
当我检查 Chrome 网络选项卡时,我注意到在用户 1(其漂亮的打印 json 看起来不错)之后,顺序被弄乱了。在User 1之后,接下来是User 3,但是file_get_contents(names.json)
返回的是空数组,所以User 1实际上并没有被写入。用户 3 也产生了正确的 json,但紧接着用户 2 出现并且 file_get_contents('names.json')
为空(如空字符串),因此它在此处停止。
但是我不明白为什么文件中仍然有用户1,为什么其他两个没有写成一般。
这是我在 Chrome 网络选项卡中的 var_dumps():
用户 1(第一个):
string(18) "Data after decode:"
array(2) {
["name"]=>
string(6) "User 1"
["mode"]=>
string(6) "namesM"
}
string(16) "File, no decode:"
string(2) "[]"
string(14) "File, decoded:"
array(0) {
}
string(24) "File content + new data:"
array(1) {
[0]=>
array(2) {
["name"]=>
string(6) "User 1"
["mode"]=>
string(6) "namesM"
}
}
string(24) "All data pretty printed:"
string(66) "[
{
"name": "User 1",
"mode": "namesM"
}
]"
用户 3(第二个!?):
string(18) "Data after decode:"
array(2) {
["name"]=>
string(6) "User 3"
["mode"]=>
string(9) "namesJobs"
}
string(16) "File, no decode:"
string(2) "[]"
string(14) "File, decoded:"
array(0) {
}
string(24) "File content + new data:"
array(1) {
[0]=>
array(2) {
["name"]=>
string(6) "User 3"
["mode"]=>
string(9) "namesJobs"
}
}
string(24) "All data pretty printed:"
string(69) "[
{
"name": "User 3",
"mode": "namesJobs"
}
]"
用户 2(第三个!?)
string(18) "Data after decode:"
array(2) {
["name"]=>
string(6) "User 2"
["mode"]=>
string(6) "namesW"
}
对于冗长的文字,我真的很抱歉,但我尝试了几个小时后还是找不到解决方案。我希望我记录得足够好,感谢您的帮助!
在我看来,可能会出现以下任一问题:
您 运行 PHP 所在的网络服务器可能 运行 每个 POST 并行(多线程)请求,这会导致文件被一个请求部分打开或正忙于写入,而另一个请求正忙于尝试读取它。
您的网络服务器的文件系统告诉 PHP 文件已写入并且一切正常,但实际上,它仍在忙于在内部缓存数据,然后才实际写入磁盘.所以当下一个读取文件的请求来的时候,还没有完全写入
因此您可能尝试的解决方案是:
尝试使用带有 LOCK_EX
标志的 file_put_contents 和 file_get_contents 来独占读取和写入文件。参见 http://php.net/manual/en/function.file-put-contents.php
你为什么要从同一个客户端发送多个 POST 请求?你应该做这样的事情:
var allNames = [];
this.names.forEach(name => {
allNames.push({name: name["name"], mode: name["mode"]});
});
this.http.post("http://myServer.test/saveNames.php", allNames, ....);
所以一次发送整个名称数组,那么你将避免运行陷入这个问题。
磁盘操作非常慢,因此您不应该指望它们跟上来自客户的请求。您应该尽可能少地进行磁盘操作,并尽可能多地对数据进行批处理。
我正在使用 angular http 将 post 数据从我的 Ionic 应用程序发送到 PHP 脚本。在该脚本中,一个 json 文件被读取和解码,以便可以附加传入的数据,然后将其写回文件。
这基本上工作正常,但在某些情况下 file_put_contents
不写入新的编码数组 and/or 提交顺序被弄乱了。
打字稿:
this.names.forEach(name => {
this.http.post("http://myServer.test/saveNames.php", {name: name["name"], mode: name["mode"]}).subscribe(
err => {
errors.push(name["name"]);
}
);
});
Typescript post 数据:
(3) [{…}, {…}, {…}]
0: {name: "User 1", mode: "namesM"}
1: {name: "User 2", mode: "namesW"}
2: {name: "User 3", mode: "namesJobs"}
length: 3
PHP 脚本:
$postData = file_get_contents("php://input");
if (isset($postData)) {
$request = json_decode($postData, true);
var_dump("Data after decode:");
var_dump($request);
$inp = file_get_contents('names.json');
if (($inp) == "") return; // Return so file does not get messed up
$allNames = json_decode($inp, true);
var_dump("File, no decode:");
var_dump($inp);
var_dump("File, decoded:");
var_dump($allNames);
$allNames[] = $request;
var_dump("File content + new data:");
var_dump($allNames);
var_dump("All data pretty printed:");
var_dump(json_encode($allNames, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
file_put_contents('names.json', json_encode($allNames, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); // mit UTF8s
}
names.json 任何写入前(初始状态):
[]
names.json post 完成后:
[
{
"name": "User 1",
"mode": "namesM"
},
null
]
该文件具有 777 权限,在此过程中未打开。如您所见,只写了一个名字,插入了一个空值,然后什么也没有发生。
当我检查 Chrome 网络选项卡时,我注意到在用户 1(其漂亮的打印 json 看起来不错)之后,顺序被弄乱了。在User 1之后,接下来是User 3,但是file_get_contents(names.json)
返回的是空数组,所以User 1实际上并没有被写入。用户 3 也产生了正确的 json,但紧接着用户 2 出现并且 file_get_contents('names.json')
为空(如空字符串),因此它在此处停止。
但是我不明白为什么文件中仍然有用户1,为什么其他两个没有写成一般。
这是我在 Chrome 网络选项卡中的 var_dumps():
用户 1(第一个):
string(18) "Data after decode:"
array(2) {
["name"]=>
string(6) "User 1"
["mode"]=>
string(6) "namesM"
}
string(16) "File, no decode:"
string(2) "[]"
string(14) "File, decoded:"
array(0) {
}
string(24) "File content + new data:"
array(1) {
[0]=>
array(2) {
["name"]=>
string(6) "User 1"
["mode"]=>
string(6) "namesM"
}
}
string(24) "All data pretty printed:"
string(66) "[
{
"name": "User 1",
"mode": "namesM"
}
]"
用户 3(第二个!?):
string(18) "Data after decode:"
array(2) {
["name"]=>
string(6) "User 3"
["mode"]=>
string(9) "namesJobs"
}
string(16) "File, no decode:"
string(2) "[]"
string(14) "File, decoded:"
array(0) {
}
string(24) "File content + new data:"
array(1) {
[0]=>
array(2) {
["name"]=>
string(6) "User 3"
["mode"]=>
string(9) "namesJobs"
}
}
string(24) "All data pretty printed:"
string(69) "[
{
"name": "User 3",
"mode": "namesJobs"
}
]"
用户 2(第三个!?)
string(18) "Data after decode:"
array(2) {
["name"]=>
string(6) "User 2"
["mode"]=>
string(6) "namesW"
}
对于冗长的文字,我真的很抱歉,但我尝试了几个小时后还是找不到解决方案。我希望我记录得足够好,感谢您的帮助!
在我看来,可能会出现以下任一问题:
您 运行 PHP 所在的网络服务器可能 运行 每个 POST 并行(多线程)请求,这会导致文件被一个请求部分打开或正忙于写入,而另一个请求正忙于尝试读取它。
您的网络服务器的文件系统告诉 PHP 文件已写入并且一切正常,但实际上,它仍在忙于在内部缓存数据,然后才实际写入磁盘.所以当下一个读取文件的请求来的时候,还没有完全写入
因此您可能尝试的解决方案是:
尝试使用带有
LOCK_EX
标志的 file_put_contents 和 file_get_contents 来独占读取和写入文件。参见 http://php.net/manual/en/function.file-put-contents.php你为什么要从同一个客户端发送多个 POST 请求?你应该做这样的事情:
var allNames = [];
this.names.forEach(name => {
allNames.push({name: name["name"], mode: name["mode"]});
});
this.http.post("http://myServer.test/saveNames.php", allNames, ....);
所以一次发送整个名称数组,那么你将避免运行陷入这个问题。
磁盘操作非常慢,因此您不应该指望它们跟上来自客户的请求。您应该尽可能少地进行磁盘操作,并尽可能多地对数据进行批处理。