最近有个项目老是在周一自动关闭mysql,必须得手动启动,查询日志后发现是内存溢出造成LINUX优先关闭了mysql服务
查看具体方法,发现后台有个订单导出execl造成的
使用的是**CRMEB**商城,**TP6**框架,这个订单导出需要关联用户表和购物车表,三表联查后一次性导出1万条数据就会崩溃,当然也是服务器配置一般,内存只分了1G给PHP,导出速度也很慢,然后找了很久找到一个导出CSV的,用了下挺好用的,速度快,也不会早晨内存溢出,下面记录下具体使用
可以使用ajax请求
转载[原有压缩解压功能我没有使用](https://www.cnblogs.com/panziwen/p/12505170.html)
public static function excel_out($where)
{
//不限制执行时间,以防超时
set_time_limit(0);
//文件名
$xlsName = '订单导出' . date('YmdHis', time());
//表头
$xlsCell = ['编号', '订单号', '收货人', '收货人手机', '收货人地址', '支付金额', '使用积分', '备注', '购买人', '购买人手机', '订单状态', '下单时间', '商品信息'];
//统计总行数 getOderWhere是处理条件的,就不放了
$sqlCount = self::getOrderWhere($where, self::alias('a')
->join('user r', 'r.uid=a.uid', 'LEFT'), 'a.', 'r')
->count();
//每次取多少条
$sqlLimit = 1000;//每次只从数据库取1000条
// buffer计数器
$cnt = 0;
$fileNameArr = array();
//分段执行,以免内存写满
for ($i = 0; $i < ceil($sqlCount / $sqlLimit); $i++) {
$fp = fopen($xlsName . '_' . $i . '.csv', 'w'); //生成临时文件
$fileNameArr[] = $xlsName . '_' . $i . '.csv';//将临时文件保存起来
//第一次执行时将表头写入
if ($i == 0) {
fputcsv($fp, $xlsCell);
}
//查询出数据
$xlsData = self::getOrderWhere($where, self::alias('a')
->join('user r', 'r.uid=a.uid', 'LEFT'), 'a.', 'r')
->field('a.id,a.order_id,a.real_name,a.user_phone,a.user_address,a.pay_price,a.use_integral,a.remark,r.nickname,r.phone,a.add_time,a.status,a.shipping_type,a.goods_id,a.total_num')
->limit($i * $sqlLimit, $sqlLimit)
->select()->toArray();
foreach ($xlsData as $v) {
$cnt++;
//执行下一次循环之前清空缓冲区
if ($sqlLimit == $cnt) {
ob_flush();
$cnt = 0;
}
if ($v['status'] == 2 && $v['shipping_type'] == 2) {
$v['status_name'] = '未核销';
} else if ($v['status'] == 2) {
$v['status_name'] = '未发货';
} else if ($v['status'] == 3) {
$v['status_name'] = '待收货';
} else if ($v['status'] == 4) {
$v['status_name'] = '待评价';
} else if ($v['status'] == 5) {
$v['status_name'] = '已完成';
} else {
$v['status_name'] = '已取消';
}
//这里查询订单的商品详情信息
$goods = Db::name('store_product')->where('id', $v['goods_id'])->field('id,store_name,unit_name,price')->find();
$goods_str = '名称:' . $goods['store_name'] . "\r\n";
$goods_str .= '价格:' . $goods['price'] . "\r\n";
$goods_str .= '数量:' . $v['total_num'] . ' ' . $goods['unit_name'];
$v['add_time'] = date('Y-m-d H:i:s', $v['add_time']);
$v['goods_str'] = $goods_str;
$item = [
$v['id'],
$v['order_id'],
$v['real_name'],
$v['user_phone'],
$v['user_address'],
$v['pay_price'],
$v['use_integral'],
$v['remark'],
$v['nickname'],
$v['phone'],
$v['status_name'],
$v['add_time'],
$goods_str,
];
unset($v);
//每行写入到临时文件
fputcsv($fp, $item);
}
fclose($fp); //每生成一个文件关闭
}
//将所有临时文件合并成一个
foreach ($fileNameArr as $file) {
//如果是文件,提出文件内容,写入目标文件
if (is_file($file)) {
$fileName = $file;
//打开临时文件
$handle1 = fopen($fileName, 'r');
//读取临时文件
if ($str = fread($handle1, filesize($fileName))) {
//关闭临时文件
fclose($handle1);
//打开或创建要合并成的文件,往末尾插入的方式添加内容并保存
$handle2 = fopen($xlsName . '.csv', 'a+');
//写入内容
if (fwrite($handle2, $str)) {
//关闭合并的文件,避免浪费资源
fclose($handle2);
}
}
}
unlink($file); //删除csv临时文件
}
//输出压缩文件提供下载
header("Cache-Control: max-age=0");
header("Content-Description: File Transfer");
header('Content-disposition: attachment; filename=' . basename($xlsName.'.csv')); // 文件名
header("Content-Type: application/zip"); // zip格式的
header("Content-Transfer-Encoding: binary"); //
header('Content-Length: ' . filesize($xlsName.'.csv')); //
@readfile($xlsName.'.csv');//输出文件;
unlink($xlsName . '.csv'); //删除合并的临时文件
}
解决数据导出关闭mysql问题
最新推荐文章于 2023-02-16 23:09:08 发布
本文详细介绍了在PHP环境中遇到的MySQL数据导出时关闭的问题,包括可能的原因和解决方案,帮助开发者有效处理数据库导出过程中的突发状况。
摘要由CSDN通过智能技术生成