在PHP中读取CSV文件,删除空格和特殊字符,并将其存储在db中
我用php编写了这段代码。它是从一个简单的csv文件中读取和存储数据库中的数据。 但当我试图读取一个带有特殊字符空格和多个逗号的csv文件时,它并没有读取值在PHP中读取CSV文件,删除空格和特殊字符,并将其存储在db中,php,Php,我用php编写了这段代码。它是从一个简单的csv文件中读取和存储数据库中的数据。 但当我试图读取一个带有特殊字符空格和多个逗号的csv文件时,它并没有读取值 <?php include_once 'connection.php'; if(isset($_POST['submit'])){ if($_FILES['csv_data']['name']){ $arrFileName = explode('.',$_FILES['csv_data']['name']);
<?php
include_once 'connection.php';
if(isset($_POST['submit'])){
if($_FILES['csv_data']['name']){
$arrFileName = explode('.',$_FILES['csv_data']['name']);
if($arrFileName[1] == 'csv'){
$handle = fopen($_FILES['csv_data']['tmp_name'], "r");
while (($data = fgetcsv($handle, 10000, ",")) !== FALSE) {
echo $arrFileName;
$hr = mysqli_real_escape_string($conn,$data[1]);
$min = mysqli_real_escape_string($conn,$data[2]);
$day = mysqli_real_escape_string($conn,$data[3]);
$month = mysqli_real_escape_string($conn,$data[4]);
$year = mysqli_real_escape_string($conn,$data[5]);
$castno = mysqli_real_escape_string($conn,$data[14]);
$si = mysqli_real_escape_string($conn,$data[27]);
$su = mysqli_real_escape_string($conn,$data[30]);
$mng = mysqli_real_escape_string($conn,$data[33]);
$phos = mysqli_real_escape_string($conn,$data[36]);
$import="INSERT into hm(hr,min,day,month,year,castno,si,su,mng,phos) values('$hr','$min','$day','$month','$year','$castno','$si','$su','$mng','$phos')";
mysqli_query($conn,$import);
}
fclose($handle);
print "Import done";
}
}
}
我在日常生活中经常这样做,毫无疑问,如果您是在linux机箱上托管,并且能够在机器上访问sed和tr,那么最简单的方法就是:
// clean bad characters that are not detected by the tr below
shell_exec("sed -i '{s/\\x0C/ /g; s/\\x1A/ /g; s/\\xA0/ /g; s/\\x00/ /g;}' $filePath");
// clean the tmp file and place the clean file back in the original file path
shell_exec("tr '\\200-\\377' ' ' < $filePath > $cleanFilePath");
// remove any blank/empty lines in the file
shell_exec("sed -i '/^$/d' $cleanFilePath");
//清除下面的tr未检测到的错误字符
shell_exec(“sed-i'{s/\\x0C//g;s/\\x1A//g;s/\\xA0//g;s/\\x00//g;}'$filePath”);
//清理tmp文件并将清理后的文件放回原始文件路径
shell_exec(“tr'\\200-\\377'<$filePath>$cleanFilePath”);
//删除文件中的所有空行/空行
shell_exec(“sed-i'/^$/d'$cleanFilePath”);
这会查找十六进制字符,如果它们无效(匹配或超出某些范围),则会将其从文件中删除<据我所知,code>tr
没有就地功能(自从我查看以来已经有很长一段时间了),因此您最终将结果输出到$cleanFilePath
中,它可以是您想要的任何位置。这也比PHP中的实现快得多(这些工具是为大型文本文件(也称为csv文件)构建的),所以为什么不利用它们呢
在我的日常工作中,我们在几秒钟内处理200万行的文件,这是一个巨大的提升。您可以在PHP中实现这一点,但根据我的经验(我最初在PHP中实现这一点的错误),我会避开该解决方案,因为它更复杂,速度也慢得多。我可能建议您重构上述内容,以使用预先准备好的语句-它将更健壮、更高效,特别是在任何时候,如果一个不受信任的用户能够发布数据
<?php
if( $_SERVER['REQUEST_METHOD']=='POST' && !empty( $_POST['submit'] ) && !empty( $_FILES['csv_data'] ) ){
try{
include_once 'connection.php';
/* the sql query with placeholders ~ 10 columns, 10 placeholders */
$sql='insert into `hm` ( `hr`,`min`,`day`,`month`,`year`,`castno`,`si`,`su`,`mng`,`phos` ) values(?,?,?,?,?,?,?,?,?,?);';
/* Get various properties of the uploaded file */
$obj=(object)$_FILES['csv_data'];
$ext=strtolower( pathinfo( $obj->name, PATHINFO_EXTENSION ) );
$name=$obj->name;
$tmp=$obj->tmp_name;
$err=$obj->error;
/* If there are no errors and the file is a .csv proceed */
if( $err== 0 && $ext=='csv' ){
printf('Begin importing %s',$name);
/* create the prepared statement object - exit if it fails */
$stmt=$conn->prepare( $sql );
if( !$stmt )throw new Exception('Failed to prepare query');
/* Not know if these should be integers or strings... */
$stmt->bind_param( 'ssssssssss', $hr,$min,$day,$month,$year,$castno,$si,$su,$mng,$phos );
/* read the csv file */
$data = new SplFileObject( $tmp );
$data->setFlags( SplFileObject::READ_CSV );
/* process each line - create variables */
foreach( $data as $i => $line ) {
list( $hr,$min,$day,$month,$year,$castno,$si,$su,$mng,$phos )=$line;
/* insert the record */
$stmt->execute();
}
$stmt->close();
printf( '<br />Importing %d lines from %s complete', $i, $name );
}
}catch( Exception $e ){
exit( $e->getMessage() );
}
}
?>
你能举一个CSV文件不起作用的例子吗(最好是几行,而不是一个完整的文件)。NA,16,53,04,08,18,HMSMS_CM,ARL,,,,,,,,,,,,,,,,4,Si,,,1.23,S,,,0.046,Mn,(,0.139,P,,,0.122,我试过读取这些数据,它看起来读起来不错,当你说不读取时,你是说没有创建记录还是字段位于错误的位置?如果你尝试打印($data)在循环中,是否显示此记录?请尝试使用仅包含这一行的文件。但它没有读取格式中所需的值。因为CSV文件数据类似于.NA、16、53、04、08、18、HMSMS_CM、ARL、1、1、0、09532/3 T5 S1、、、、、、、、、、4、Si、、1.23、S、、0.046、Mn、,(,0.139,P,,,0.122,你能创建一个数据的pastebin粘贴吗?从这里给出的例子很难理解格式