php - PHP - 我的用于获取文件名和查找新文件的脚本可以更快吗?
问题描述
我可以通过 FTP 访问 1 个目录,该目录包含供应商所有产品的所有图像。1 个产品有多个图像:尺寸变化和产品显示变化。
没有“列表”(XML、CSV、数据库..)可以让我知道“什么是新的”。目前我看到的唯一方法是获取所有文件名并将它们与我的数据库中的文件名进行比较。
最后一次检查计算了该目录中的998.283 个文件。1 个产品有多种变体,并且没有关于它们如何命名的文档。
我对文件名进行了初步抓取,将它们与我的产品进行了比较,并将它们的文件名和修改日期(来自文件)保存在“图像”的数据库表中。
下一步是检查“新的”。
我现在正在做的是:
// get the file list /
foreach ($this->getFilenamesFromFtp() as $key => $image_data) {
// I extract data from filenames (product code, size, variation number, extension..) so I can store them in table and later use that as reference (ie. I want to use only large images of variation, not all sizes
$data=self::extractDataFromImage($image_data);
// checking if filename already exists in DB images
// if there is DB entry (TRUE) it will do nothing, and if there is none it will continue with insertion in DB
if($this->checkForFilenameInDb($data['filename'])){
}
else{
$export_codes=$this->export->getProductIds();
// check if product code is in export table - that is do we really need this image
if($this->functions->in_array_r($data['product_code'],$export_codes)){
self::insertImageDataInDb($data);
} // end if
} // end if check if filename is already in DB
} // end foreach
我的方法getFilenamesFromFtp()
如下所示:
$filenames = array();
$i=1;
$ftp = $this->getFtpConfiguration();
// set up basic connection
$conn_id = ftp_ssl_connect($ftp['host']);
// login with username and password
$login_result = ftp_login($conn_id, $ftp['username'], $ftp['pass']);
ftp_set_option($conn_id, FTP_USEPASVADDRESS, false);
$mode = ftp_pasv($conn_id, TRUE);
ftp_set_option($conn_id, FTP_TIMEOUT_SEC, 180);
//Login OK ?
if ((!$conn_id) || (!$login_result) || (!$mode)) { // || (!$mode)
die("FTP connection has failed !");
}
else{
// I get all filenames and store them in array
$files=ftp_nlist($conn_id, ".");
// I count the number of files in array = the number of files on FTP
$nofiles=count($files);
foreach($files as $filename){
// the limit I implemented while developing or testing, but in production (current mode) it has to run without limit
if(self::LIMIT>0 && $i==self::LIMIT){ //!empty(self::LIMIT) &&
break;
}
else{
// I get date modified from from file
$date_modified = ftp_mdtm($conn_id, $filename);
// I create new array for filenames and date modified so I can return it and store it in DB
$filenames[]= array(
"filename" => $filename,
"date_modified" => $date_modified
);
} // end if LIMIT empty
$i++;
} // end foreach
// close the connection
ftp_close($conn_id);
return $filenames;
}
问题是脚本需要很长时间。我现在检测到的最长时期是在getFilenamesFromFtp()
我创建数组时:
$filenames[]= array(
"filename" => $filename,
"date_modified" => $date_modified
);
到目前为止,该部分持续了 4 小时,但仍未完成。
在写这篇文章时,我有一个想法,从一开始就删除“修改日期”,然后仅在我打算将该图像存储在数据库中时才使用它。
完成此更改和测试后,我将立即更新此问题:)
解决方案
处理一百万个文件名需要时间,但是,我认为没有理由将这些文件名(和date_modified
)存储在数组中,为什么不直接处理文件名呢?
此外,与其完全处理文件名,不如先将其存储在数据库表中?然后您可以稍后进行真正的处理。通过将任务一分为二,检索和处理,它变得更加灵活。例如,如果您想更改处理,则不需要进行新的检索。
推荐阅读
- asp.net-mvc - TagHelper 永远不会在 .NET Core 2.2 中执行
- sql-server - 如何确保使用 SMO 恢复 alla 数据?
- c - 无效影响程序的输出
- javascript - 我如何在 Jest 中等待 React Hook?
- netsuite - 在 SuiteLet 上显示 Map/Reduce 脚本错误
- node.js - how to fetch seller order from multiple collection data
- c# - 如何使用实时图表在条形图中的每一列上都有标签
- c++ - 基类中的唯一指针禁止实例化并出现错误“试图引用已删除的函数”
- c# - 如果存在验证错误,也要更新 ViewModel 中的属性
- java - getXmlEncoding() 给出错误的输出