最近做一个PHP导入csv文件数据到mysql数据库的项目,做好了后测试是没有问题的,测试的时候都是小文件,最大1M的csv文件都没问题,但是今天突然来了个5M多,5w多条数据的csv文件,就一直说是取不到文件名,不然就是解析不到数据,求大神看看,要说代码有问题,但是小文件都可以上传,遇到大文件就歇菜了,
报错: fgetcsv() expects parameter 1 to be resource, boolean given in
以下是我的处理代码,
$filename = $_FILES['file']['tmp_name'];
$handle = fopen($filename, 'r');
$result = input_csv($handle); //解析csv
$len_result = count($result);
if($len_result==0){
echo '没有任何数据!';
exit;
}
$data_values=null;
for ($i = 1; $i < $len_result; $i++) { //循环获取各字段值
$mac = $result[$i][1]; //中文转码
$int1= $result[$i][2];
$field = $result[$i][3];
$channel = $result[$i][4];
$int2= $result[$i][5];
$sta = $result[$i][6];
$int3 = $result[$i][7];
$int4= $result[$i][8];
$int5= $result[$i][9];
$time1 = $result[$i][10];
$time2 = $result[$i][11];
$time3 = $result[$i][12];
$time4 = $result[$i][13];
$hostmac =$result[$i][14]; //中文转码
$data_values .= "('$mac',$int1,$field,$channel,$int2,$sta,$int3,$int4,$int5,FROM_UNIXTIME($time1),FROM_UNIXTIME($time2),FROM_UNIXTIME($time3),FROM_UNIXTIME($time4),'$hostmac'),";
// $sql = "insert into macdata (m_mac,m_int1,m_field,m_channel,m_int2,m_sta,m_int3,m_int4,m_int5,m_time1,m_time2,m_time3,m_time4,m_hostmac) values ('$mac',$int1,$field,$channel,$int2,$sta,$int3,$int4,$int5,FROM_UNIXTIME($time1),FROM_UNIXTIME($time2),FROM_UNIXTIME($time3),FROM_UNIXTIME($time4),'$hostmac')";//批量插入数据表中
// $result2 = $conn->query($sql);
// if($result2){
// echo '导入成功!';
// }else{
// echo '导入失败!';
// }
}
$data_values = substr($data_values,0,-1); //去掉最后一个逗号
fclose($handle); //关闭指针
$sql = "insert into macdata (m_mac,m_int1,m_field,m_channel,m_int2,m_sta,m_int3,m_int4,m_int5,m_time1,m_time2,m_time3,m_time4,m_hostmac) values $data_values";//批量插入数据表中
$result2 = $conn->query($sql);
if($result2){
echo '<script>window.location.href = "Mactest.php";alert("导入成功!")</script>';
}else{
echo '<script>window.location.href = "Mactest.php";alert("导入失败,请重试!")</script>';
}
function input_csv($handle) {
$out = array ();
$n = 0;
while ($data = fgetcsv($handle,100000)) {
$num = count($data);
for ($i = 0; $i < $num; $i++) {
$out[$n][$i] = $data[$i];
}
$n++;
}
return $out;
}
while ($data = fgetcsv($handle,100000)) { 这行 fgetcsv 报错 $handle参数应该是个资源,但是你给了一个布尔值。
$handle = fopen($filename, 'r');
是不是$filename文件太大了。
fgetcsv(file,length,separator,enclosure)
file 必需。规定要检查的文件。
length 可选。规定行的最大长度。必须大于 CVS 文件内最长的一行。
在 PHP 5 中该参数是可选的。在 PHP 5 之前是必需的。
如果忽略(在 PHP 5.0.4 以后的版本中设为 0)该参数的话,那么长度就没有限制,不过可能会影响执行效率。
直接从数据库中直接导出csv,给你我的源码,供你参考
$t=time();
$filepath= getcwd().'/';
$filename=$t.'.csv';
$where='1=1';
$sql=" SELECT filed1,filed2,filed3 FROM db.table where $where into outfile '$filepath$filename' CHARACTER SET gbk fields terminated by ',' optionally enclosed by '\"' escaped by '\"' lines terminated by '\r\n'";
//
$query = DB::query($sql);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=业务日志.csv');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($filepath.$filename));
readfile($filepath.$filename);
unlink($filepath.$filename);
谢谢大家了,这个问题解决了,说一下方案吧,以便于以后遇到同样问题的同学参考一下,
小文件上传导入没有问题,遇到大文件就获取不到文件名称,这是因为php设置里的上传单个最大文件设置没有设置,php默认是5M(反正我的就是5M)
, 而恰巧我的文件就是5点几M,到php.ini里改一下配置就可以了,
原因
解析csv文件的方法报错,传入了一个布尔类型的参数1,
1就是代表: 超过了文件大小php.ini中即系统设定的大小。
修改php.ini
修改 upload_max_filesize的值,
意思是上传文件最大值
改一下就好了
参考这位伟大博主的博客:http://blog.csdn.net/zhanghw0917/article/details/46793847