0

我有一个完整的 PHP 脚本,它处理上传的文本文件并将数据导入 MySQL 表。

每次上传文本文件时:

  1. 现有表被删除
  2. 创建一个同名的新表
  3. 并将所有新数据插入到新表中。

文本文件是由公司的内部数据库软件创建的,这就是这个过程的原因。

文本文件中的字段/值由反斜杠分隔,脚本成功地将其分解:

$this_array = explode("\\", $this_string);

然后它通过在每行末尾查找换行符来结束数组的该部分(数组该部分的末尾将是数据库行的末尾)。例如。在示例文本文件(如下)中,换行符出现在'Row1Data for colname4'. 数组的那部分应该成为数据库表中的一行。

然而问题是脚本吐出这个错误:

Error #1136:Column count doesn't match value count at row 1

这是由于文本文件中的多个段落在它们的末尾也有换行符(参见下面的示例文本文件)。

问题:我不知道如何避免将段落的结尾解释为数组的行/部分的结尾。如何继续对多段文本使用此过程,而不会将它们解释为数组该部分的结尾?

示例文本文件内容:

colname1name\colname2name\colname3name\colname4name
Data for colname1\Row1Data for colname2\This is a Row1 Paragraph to go in colname3
This is another Row1 Paragraph to go in colname3
This is yet another Row1 Paragraph to go in colname3\Row1Data for colname4
Row2Data for colname1\Row2Data for colname2\This is a Row2 Paragraph 1 to go in colname3
This is another Row2 Paragraph to go in colname3
This is yet another Row2 Paragraph to go in colname3\Row2Data for colname4

脚本中有很多代码,但我认为这是最相关的部分:

//
//---------------------------------------create table--------------------------------
//
$text_string="CREATE TABLE `area` (";
//loop thru names
for ($n=0; $n< count($name_array); $n++){
$name_array[$n]=trim($name_array[$n]);//trim needed here
if($name_array[$n]=='population'){//population field has to be INT

    $text_string.= "`".$name_array[$n]."` INT(8) NOT NULL,";    

}elseif($name_array[$n]=='towndescription'){//description field has to be TEXT

    $text_string.= "`".$name_array[$n]."` TEXT NOT NULL,";  

}else{
$text_string.= "`".$name_array[$n]."` varchar(250) NOT NULL default '',";
}
}
//remove last comma
$string_len=strlen($text_string);
$string_len=$string_len-1;
$text_string=substr($text_string,0,$string_len);
//
$text_string.= ") ENGINE=MyISAM ";
$db_sql_query = $text_string;
$db_result = @mysql_query($db_sql_query, $db_connection) or die ("Error #" . mysql_errno() . ":" . mysql_error());
print $text_string."<BR><BR>";//////////    
//
//----------------------------------------------------------------------------------------
//
//now loop thru $array
//

for ($n=1; $n<count($array) ; $n++){

    $text_string= "INSERT INTO `area` VALUES (";
    //for each line explode
    $this_string=$array[$n];
    $this_array = explode("\\", $this_string);
    for ($i=0; $i< count($this_array); $i++){
        //replace ' with html code - &#8217;
        $this_item=$this_array[$i];
        $this_item=trim($this_item);//trim needed here
        $this_item = str_replace("&", "and","$this_item" );
        $this_item = str_replace("'", "&#8217;","$this_item" );
        $this_item = str_replace("\"", "","$this_item" );//escaped "    

        //$this_item = str_replace(" ", "%20","$this_item" );
        $text_string.= " '".$this_item."' ,";
    }
    //remove last comma
    $string_len=strlen($text_string);
    $string_len=$string_len-1;
    $text_string=substr($text_string,0,$string_len);
    //
    $text_string.= ") ";
    $db_sql_query = $text_string;

    $db_result = @mysql_query($db_sql_query, $db_connection) or die ("Error #" . mysql_errno() . ":" . mysql_error());
print $text_string;//////////   
}

任何帮助将不胜感激!

4

2 回答 2

0

在我看来,您可以在反斜杠上爆炸,然后根据需要抓取每一列,假设所有列都将提供一行。因此,您抓住第 1、2、3 和 4 列 - 然后在第四列时,写入行,然后重新启动。

这是一些代码:

<?php

$text = "
Data for colname1\\Row1Data for colname2\\This is a Row1 Paragraph to go in colname3
This is another Row1 Paragraph to go in colname3
This is yet another Row1 Paragraph to go in colname3\\Row1Data for colname4\\
Row2Data for colname1\\Row2Data for colname2\\This is a Row2 Paragraph 1 to go in colname3
This is another Row2 Paragraph to go in colname3
This is yet another Row2 Paragraph to go in colname3\\Row2Data for colname4
";

$lines = explode('\\', $text);
$totalCols = 4;

$currentCol = 0;
$currentRow = 0;
foreach ($lines as $line)
{
    echo $currentCol . '/' . $currentRow . ': ' . $line . "\n";
    $currentCol++;
    if ($currentCol == $totalCols)
    {
        $currentCol = 0;
        $currentRow++;
    }
}

?>

这将因此输出:

0/0: Data for colname1
1/0: Row1Data for colname2
2/0: This is a Row1 Paragraph to go in colname3 This is another Row1 Paragraph to go in colname3 This is yet another Row1 Paragraph to go in colname3
3/0: Row1Data for colname4
0/1: Row2Data for colname1
1/1: Row2Data for colname2
2/1: This is a Row2 Paragraph 1 to go in colname3 This is another Row2 Paragraph to go in colname3 This is yet another Row2 Paragraph to go in colname3
3/1: Row2Data for colname4

这是您可以玩的现场演示。

我不得不调整您的数据以使其正常工作 - “Row1Data for colname4”没有反斜杠终止符。

于 2013-04-26T21:29:17.303 回答
0

感谢所有在这里提供帮助的人。经过更多的研究,我开始意识到,因为我正在导入一个文本文件,所以在将文本上传到数据库之前将其转换为 CSV 是有意义的(意味着摆脱所有这些斜线)。

一旦我确定文本文件中的文本是正确的 CSV 格式,我就使用Jay Williams的脚本将逗号分隔的文件转换为关联的数组。第一行应包含数组键。

这一切都意味着,因为多个文本段落都用一对引号括起来,所以我的脚本可以正确识别所有段落(稍作调整),而不会将它们解释为数组那部分的结尾.

于 2013-06-12T10:08:50.803 回答