生成器的核心是一个 yield 关键字,使用yield php会返回一个属于Generator类的对象,这个对象可以使用foreach()函数进行迭代,
官方文档解释:yield提供了一种更容易的方法来实现简单的迭代对象,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低。
<?php
declare (strict_types = 1);
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use think\facade\Db;
use think\facade\Log;
class Test extends Command
{
protected function configure()
{
// 指令配置
$this->setName('test')
->setDescription('the test command');
}
protected function execute(Input $input, Output $output)
{
set_time_limit(0);
ini_set("memory_limit", "-1");
$dir = app()->getRuntimePath() . '资源文件夹';
try {
// 获取遍历的全部文件
$list = $this->openAllDir($dir);
$i = 1;
foreach ($list as $item) {
if (file_exists($item) && is_file($item)) {
// 这里开始读取文件内容
$output->writeln("正在读取第 {$i} 个文件 {$item}");
$res = $this->readImportFile($item);
$is_err = false;
// 处理读取到的数据并插入数据库
foreach ($res as $k => $re) {
if (empty($re[0])) {
continue;
}
foreach ($re as &$v) {
$v = $v && is_string($v) ? addslashes($v) : '';
}
unset($v);
if (isset($re[15])) {
$re[15] = intval($re[15]);
}
// 去掉重复名称数据
$exists = Db::name('xxx')->where('name', $re[0])->count();
if ($exists) {
continue;
}
$sql = "INSERT INTO `xxx`(`id`, `name`, `business_status`, `legal_representative`, `registered_capital`, `paid_in_capital`, `date_of_incorporation`, `approval_date`, `business_term`, `province`, `city`, `county`, `credit_code`, `identification_number`, `registration_no`, `organization_code`, `number_of_insured_persons`, `company_type`, `industry`, `name_used_before`, `registered_address`, `new_report_address`, `website`, `contact_number`, `other_number`, `email`, `other_email`, `nature_of_business`) VALUES (null , '{$re[0]}', '{$re[1]}', '{$re[2]}', '{$re[3]}', '{$re[4]}', '{$re[5]}', '{$re[6]}', '{$re[7]}', '{$re[8]}', '{$re[9]}', '{$re[10]}', '{$re[11]}', '{$re[12]}', '{$re[13]}', '{$re[14]}', '{$re[15]}', '{$re[16]}', '$re[17]', '$re[18]', '$re[19]', '$re[20]', '$re[21]', '$re[22]', '$re[24]', '$re[25]', '$re[26]', '$re[27]');";
$res = Db::execute($sql);
if (!empty($res)) {
$output->writeln("{$item} 文件添加第 ". ($k+1) ." 条记录成功!" . PHP_EOL);
} else {
$is_err = true;
$output->writeln("{$item} 文件添加第 ". ($k+1) ." 条记录添加失败!记录log" . PHP_EOL);
}
}
if ($is_err) {
$output->writeln("读取第 {$i} 个文件 {$item} 失败!");
}
$i++;
}
}
} catch (\Exception $e) {
$output->writeln('error:'. $e->getMessage());
}
// 指令输出
$output->writeln('end');
}
// 读取文件
protected function readImportFile($file)
{
$inputFileType = IOFactory::identify($file);
$objReader = IOFactory::createReader($inputFileType);
$worksheetNames = $objReader->listWorksheetNames($file);
// 只读取表格数据,忽略里面的各种格式,否则会内存耗尽
$objReader->setReadDataOnly(TRUE);
$objReader->setLoadSheetsOnly($worksheetNames[0]);
$objPHPExcels = $objReader->load($file);
$maxCol = $objPHPExcels->getSheet(0)->getHighestColumn(); // 总列数
$maxRow = $objPHPExcels->getSheet(0)->getHighestRow(); // 总行数
for ($i = 4; $i <= $maxRow; $i++) {
// 读取一行
yield $objPHPExcels->getSheet(0)->rangeToArray('A' . $i . ':' . $maxCol . $i)[0];
}
}
// 遍历文件夹,因为 yield 好像无法递归所以一个一个文件夹遍历
protected function openAllDir($dir)
{
// 读取文件夹下全部文件
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if ($file != '.' && $file != '..') {
$name = $dir . '/' . $file;
if (is_dir($name)) {
if ($dh2 = opendir($name)) {
while (($file2 = readdir($dh2)) !== false) {
if ($file2 != '.' && $file2 != '..') {
$name2 = $name . '/' . $file2;
if (is_dir($name2)) {
if ($dh3 = opendir($name2)) {
while (($file3 = readdir($dh3)) !== false) {
if ($file3 != '.' && $file3 != '..') {
$name3 = $name2 . '/' . $file3;
if (is_dir($name3)) {
if ($dh4 = opendir($name3)) {
while (($file4 = readdir($dh4)) !== false) {
if ($file4 != '.' && $file4 != '..') {
$name4 = $name3 . '/' . $file4;
if (is_dir($name4)) {
// end
} else {
if (strrchr($name4, '.') == '.xlsx') {
yield $name4;
}
}
}
}
}
} else {
if (strrchr($name3, '.') == '.xlsx') {
yield $name3;
}
}
}
}
}
} else {
if (strrchr($name2, '.') == '.xlsx') {
yield $name2;
}
}
}
}
}
} else {
if (strrchr($name, '.') == '.xlsx') {
yield $name;
}
}
}
}
closedir($dh);
}
}
}
}