3

我有一个 php 脚本,它正在读取远程 CSV 文件,并根据 CSV 文件的内容将产品添加到数据库中。目前大约有 2800 行(产品),但脚本一直停在第 1388 行。

我使用的代码如下:

while(($data = fgetcsv($fopen, 0, ",")) !== false):
  //stuff is done here...
endwhile;

我已将 php 内存限制设置为 64M,甚至尝试了 128M。我还将 max_execution_time 设置为 60 分钟。我还尝试按如下方式更改代码:

while(($data = fgetcsv($fopen, 1000, ",", '\r')) !== false):
  //stuff is done here...
endwhile;

这确实导致更多的行被解析,但数据不正确,即图像列正在成为描述列等。我认为这与添加 \r 作为我的行尾有关。我试过\n,没有运气。最后,我还在 ini 中将 auto_detect_line_endings 添加为 true。

任何人都可以提出为什么我的数据被缩短的原因吗?

问候,西蒙

编辑

我注意到了一些有趣的事情。我在上面代码中循环的每一行都有一个 MySQL 插入。现在,我数据库中的最后一条记录是 CSV 文件中的第一行,这是否意味着文件是从最后一行开始解析的?

这些似乎是休息处或附近的行:

W-3066,  I Love Love Cheap And Chic,     Moschino, 3.4 oz,EDT Spray,Women,,"Introduced by the design house of Moschino, I love love has a blend of grapefruit, orange, lemon, red currant, tea rose, cinnamon leaves, musk, cedar and tonka wood. It is recommended for daytime wear.",http://www.perfume-worldwide.com/products/Women/Final/W-3066large.jpg,0,0,0,8011003991457
W-3070,  Adidas Floral Dream,            Adidas,   1.7 oz,EDT Spray,Women,,"Introduced in 2008, the notes are bergamot, lily, rose, tonka bean and vanilla.",http://www.perfume-worldwide.com/products/Women/Final/W-3070large.jpg,0,0,0,3412244310024
W-3071,  Adidas Fruity Rhythm,           Adidas,   1.7 oz,EDT Spray,Women,,"Introduced in 2008, the notes are black currant, raspberry, cyclamen, freesia and musk.",http://www.perfume-worldwide.com/products/Women/Final/W-3071large.jpg,0,0,0,3412244510004

解决方案

事实证明,将文件复制到我的服务器并处理副本对我来说效果要好得多。我遵循的步骤如下:

  • 我使用读取远程文件的内容file_get_contents()
  • 然后我使用iconv() 函数将数据重新编码为 UTF-8
  • 我使用和函数制作了一个临时文件fopen(),文件的内容是上面的编码数据fwrite()fclose()
  • 我使用该chmod()函数将文件的权限设置为 0750
  • 然后我将该fgetcsv()函数应用于我的临时文件
  • 做了所有需要做的事
  • 完成后删除临时文件,使用unlink()函数

那成功了。所以,我怀疑问题的一半实际上是远程服务器超时,另一半是编码问题。

感谢大家在正确方向上的所有推动

4

2 回答 2

2

文件格式是否正确?您是否尝试在某些 csv 阅读器中打开文件,您可以在其中指定分隔符和结束行)?由此判断:

这确实导致更多行被解析,但数据不正确,即图像列正在成为描述列等

我会假设数据可能已损坏(即某些描述有逗号、结束线等)如果数据是动态生成的并且格式不正确,则会发生这种情况。

也可以在 txt 编辑器中打开(即记事本 ++),看看它的运行/外观如何..

于 2011-04-07T10:45:04.993 回答
2

首先我有几个问题要问你:

  • 1388、13881389什么
  • 是否有任何错误被输出
  • 当你到达最后一行时,你得到一个 ( $data[0] === null)

您有关内存限制的信息可能不是导致它的问题,因为 fgetcsv 每次迭代读取一行,内存中一次只有 1 行的数据。

如果您继续将数据放入数组或将它们连接在一起,则在您的 lop 中。这可能会导致内存泄漏,但您必须显示更深入的代码

CSV 文件必须非常结构化fgetcsv才能正确解析,使用 CSV 文件时要记住一些规则:

  • 第一行必须始终是列名
  • 所有其他行都是数据线:
    • 每个元素应该用一个分隔,
    • 如果一个元素包含空格或逗号,, '\n', '\r','\r\n'它应该用双引号引起来

一个有效的 CSV 文件应该是这样的:

id, firstname, lastname, age, profile_description
0,  Robert,    Pitt,     22,  "this string has spaces, and has a comma"

您应该验证结构是否正确,如果不正确,则应修复此问题,直到解析能够正确读取数据,然后您可以将数据干净地放入新的 CSV 文件中,处理所有不正确的小结构.

于 2011-04-07T10:46:47.550 回答