我读过某个地方应该使用库salsify/jsonstreamingparser
打开一个大json文件,但这给了我与json_decode
相同的错误:
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in /data/www/default/database/vendor/salsify/json-streaming-parser/src/Listener/InMemoryListener.php on line 92
我必须在php中执行此操作,因为我正在使用没有python的免费托管。
基本上我想做的是下载一个大的json文件,将其解压缩并处理内容。我不知道为什么在php中我整天都无法做到,但是在python中我却在5分钟内做到了:
import os
import json
import urllib
import zipfile
json_file = 'AllSets-x.json'
zip_file = json_file + '.zip'
urllib.urlretrieve ("https://mtgjson.com/json/" + zip_file, zip_file)
dir_path = os.path.dirname(os.path.realpath(__file__))
zip_ref = zipfile.ZipFile(dir_path + "/" + zip_file, 'r')
zip_ref.extractall(dir_path)
zip_ref.close()
json_data = json.load(open(json_file, 'r'))
print json_data.keys()[0]
这就是我在php中的功能:
<?php
require_once __DIR__ . '/vendor/autoload.php';
include "../credentials.php";
error_reporting(E_ALL); # Reports all errors
ini_set('display_errors','Off'); # Do not display errors for the end-users (security issue)
ini_set('error_log','/tmp/php-errors.log'); # Set a logging file
// Override the default error handler behavior
set_exception_handler(function($exception) {
$logger->error($exception);
echo "Something went wrong!";
});
$logger = new Monolog\Logger('channel-name');
$logger->pushHandler(new Monolog\Handler\StreamHandler('/tmp/php-errors.log', Monolog\Logger::DEBUG));
$logger->info("Parsing json file");
$listener = new \JsonStreamingParser\Listener\InMemoryListener();
$json_file = __DIR__ . "/AllSets-x.json";
$stream = fopen($json_file, 'r');
try {
$parser = new \JsonStreamingParser\Parser($stream, $listener);
$parser->parse();
fclose($json_file);
} catch (Exception $e) {
fclose($json_file);
throw $e;
}
$logger->info("Json file parsed");
$json_data = $listener->getJson();
$logger->info("Displaying json data");
var_dump($json_data);
参考方案
使用InMemoryListener肯定会破坏流解析器的目的。这只会将所有内容解压缩到内存中(可能在内存方面比普通的json_decode
更差)。
如果要在这种约束下工作,则需要单独捕获每个JSON对象块。
有可能符合要求的SimpleObjectQueueListener。如果特定的JSON具有一堆要处理的[{…}, {…}, {…}]
对象:
$listener = new \JsonStreamingParser\Listener\SimpleObjectQueueListener("print_r", 0);
// would just print out each object block from the JSON stream
显然,您将使用类似“ process_my_json_blobs
”的回调。 (或者像[$pdo, "execute"]
这样的准备好的回调。)
顺便说一句,读取整个JSON输入仅适用于本地Python,因为通常的PHP设置通常没有memory_limit
。 (Python最多依赖于系统ulimit
。)
我相信这比标题听起来要难一些,但我可能完全错了。我有一个像这样的数组:[["londrina",15],["cascavel",34],["londrina",23],['tiradentes',34],['tiradentes',21]] 我希望能够采用通用…
PHP-MySQL结果转换为JSON - php我试图了解如何将MySQL结果转换为JSON格式,以便以后可以在Javascript中使用此JSON来构建HTML表。但是我的代码只是产生大量的空值,我还不明白为什么。$result = mysqli_query($con, "SELECT * FROM Customers"); $test = json_encode($result);…
json_encode网址失败 - php有人在this bug附近吗?echo json_encode(array('url'=>'/foo/bar')); {"url":"\/foo\/bar"} 我使用Zend_Json and Zend_Json_Expr以便我甚至可以在js对象中获取回调函数-但我无法获得…
json_encode的特定方式 - php所以这是我的PHP<?php include 'connect.php'; $sql = "SELECT name from startup_schema"; $result = mysqli_query($mysqli, $sql) or die("Error in Selecting " …
PHP JQuery复选框 - php我有以下片段。 var myData = { video: $("input[name='video[]']:checked").serialize(), sinopse: $("#sinopse").val(), dia: $("#dia").val(), quem: $(…