我面临的问题根本不应该解决,但我不知道如何解决。这是场景:
我想从SQL语句中获取结果到PHP数组中,看起来很简单吧?
问题是它给了我关于memory_limit的错误(致命错误:内存不足(已分配408944640)(试图分配805306376字节) )。
这是我的代码正在使用结果较少的语句(我需要使用的语句包含+/- 4000条记录)。
$connect = @new mysqli($host, $db_user, $db_password, $db_name);
if($connect->connect_errno!=0)
{
echo "Error: ".$connect->connect_errno."Why: ". $connect->connect_error;
}
else{
$query = "SELECT meta_value, post_date
FROM
wp_postmeta
INNER JOIN
wp_posts
ON wp_posts.ID=wp_postmeta.post_id
where wp_posts.post_type ='shop_order' AND wp_postmeta.meta_key = '_order_total'";
$sql_query=mysqli_query($connect,$query);
if ($sql_query->num_rows > 0){
while(($row = mysqli_fetch_assoc($sql_query))!== false){
$result[] = $row;
}} else {
echo "0 results";
}
}
echo json_encode($result);
不太清楚为什么要使用0.8 GB的内存(对于一个简单的语句来说,似乎差不多。但是要尝试一下,我已将php.ini文件中的memory_limit更改为: memory_limit = 8192M 。但这根本没有帮助(检查是否使用了memory_limit调用php_info()函数)。
谢谢你们!
答案 0 :(得分:1)
不要在内存中保存完整的结果表,否则您的服务器将很容易受到DOS攻击。服务器必须能够同时回复许多请求。一次只处理一行,然后释放分配的内存。
您应直接输出以逗号分隔的JSON块。
echo '[';
$sep = '';
while(($row = mysqli_fetch_assoc($sql_query))!== false){
echo $sep . json_encode($row);
$sep = ',';
}
echo ']';
或者,您可以将其缓存在临时文件中。
在较新的MySql版本上,您可以尝试:
SELECT JSON_OBJECT('meta_value', meta_value, 'post_date', post_date)
FROM wp_postmeta
INNER JOIN wp_posts ON wp_posts.ID=wp_postmeta.post_id
WHERE wp_posts.post_type ='shop_order'
AND wp_postmeta.meta_key = '_order_total'
INTO OUTFILE '/tmp/mysql-temp-GENERATED_UUID';
这将生成一个带有JSON行但没有逗号分隔的文件。
如mysqlserverteam.com所述,聚集函数JSON_ARRAYAGG
应该可以解决此问题。 (很遗憾,我的安装存在第三方存储库冲突,因此我无法对其进行测试。)
SELECT JSON_ARRAGG(JSON_OBJECT('meta_value', meta_value, 'post_date', post_date))
FROM wp_postmeta
INNER JOIN wp_posts ON wp_posts.ID=wp_postmeta.post_id
WHERE wp_posts.post_type ='shop_order'
AND wp_postmeta.meta_key = '_order_total'
INTO OUTFILE '/tmp/mysql-temp-GENERATED_UUID';
如果JSON_ARRAYAGG
由于某种原因导致问题,一种解决方法(至少在类似Unix的系统上)将是:
<?php
$guid = bin2hex(openssl_random_pseudo_bytes(16));
$tmp_filename = "/tmp/mysql-json-{$guid}.json";
/* let MySql generate the tempfile, then */
passthru('sed \'1 s/^/[/; $! s/$/,/ ; $ s/$/]/\' ' . $tmp_filename);
?>
答案 1 :(得分:0)
为什么不使用Wordpress这样查询和分页:
$args = array(
"post_type" => "shop_order",
"posts_per_page" => 1000,
"post_status" => array("any"),
"paged" => $paged, // pass your pagination here from javascript
"meta_query" => array(
"key" => "_order_total",
"compare" => "EXISTS"
)
);
$custom_posts = get_posts($args);
echo json_encode($custom_posts);