当通过$ argv传递JSON并包含特殊字符时,json_decode返回NULL

时间:2013-12-29 19:24:16

标签: javascript php json node.js child-process

我被迫在我的节点应用程序中使用遗留 PHP模块(完全没有文档的外部API包装器)。

我正在尝试通过命令行参数将一小块数据传递给我的PHP脚本,如:

var spawn = require('child_process').spawn;
//...
//later on:
var LegacyScript = spawn('php', ['bridge.php', JSON.stringify(someData)]);

在我的bridge.php中,我正在执行以下操作:

<?php
$data = json_decode($argv[1], TRUE);
# this logs the data just fine - i can use the string and lint it / parse it - everything perfect
file_put_contents('phpgot.txt', $argv[1]);
# this is empty
file_put_contents('phpprocessed.txt', $data);
# this is NULL
file_put_contents('phpreencoded.txt', json_encode($data));
# my node module gets plain null
echo json_encode($data);
?>

我采取的方法是否有效?我有点困惑,因为数据似乎在我的PHP桥接器中很好地到达,但它将在解析它时失败,尽管它是通过jsonlint等等的完全有效的JSON。

是否有另一种(更优雅的)将数据传递给衍生进程的方法?

编辑:所以我注意到只有在JSON字符串中存在特殊字符(ü,ö,ä等)时才会失败。当内容是普通的拉丁字符集时,它的工作方式与预期的一样。我虽然在UTF-8的所有环境中。

2 个答案:

答案 0 :(得分:3)

您的方法存在许多问题。

  1. 如果您只是在Windows上传递命令行参数,则必须注意命令的外观。因为你有一个JSON编码的字符串,所以它包含双引号,空格和其他字符,这些字符在传递时可能会被不同地解析。字符串可能会变成单个参数,最终会出现在其他数组索引中。这是一个很好的阅读:http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx

  2. 根据传递的数据,您的小型设置可能容易进行shell注入(命令行注入)。

  3. 您还必须在各种平台上测试您的代码;每个操作系统都有它自己的怪癖。

  4. 从外观上看,您可能会在每个请求中生成一个新进程。这是一个性能损失,你可能会发现这是不可接受的。


  5. <强>替代

    您可以使用PHP I / O流(stdin / stdout)。这些文档非常适合PHP和NodeJS,它是在进程之间传递数据的推荐方法。对于PHP,文档在这里:http://php.net/manual/en/features.commandline.io-streams.php 对于NodeJS,子进程可能会起作用:http://nodejs.org/api/child_process.html

    另一个合适的替代方案(虽然更复杂)是在随机端口上的Node中设置服务器,将端口号作为命令行参数传递给PHP,并使用PHP脚本通过{{连接到NodeJS服务器1}}并通过HTTP从那里获取数据。要放回数据,请通过PHP中的cURL函数使用POST请求。

    我记得有很多方法可以实现它;一个是FastCGI实现,另一个是memcached。我不太了解这些,但你可以做你的研究并不断提问。

答案 1 :(得分:0)

我的问题源于我的JSON中的特殊字符(如äöü等变音符号。)

在我的输入上使用utf_8_encode修复了json_decode的输出:

$data = json_decode(utf_8_encode($argv[1]), TRUE);

如果有人输入了为什么我还要感恩,因为这没有多大意义(一切都已经用UTF-8编码)。