我有一个文件(200多行),其中包含以下设备类别。我需要将文件转换为sql才能将其插入数据库。
Video / Camera
Video / Camera / 4K
Video / Other
Other
Other / sub1
Other / sub2
Other / Camera
类别可以具有子类别(最多可以包含10个子类别),这些子类别可能具有与其他名称相同的名称,例如“视频”具有“摄像机”类别,“其他”也是如此(这不是真实数据)。我正在寻找的输出是:
INSERT INTO `category` (`id`, `name`, `parent`) VALUES
(1, 'VIDEO', NULL),
(2, 'CAMERA', 1),
(3, '4K', 2),
(4, 'OTHER', 1),
(5, 'OTHER', NULL),
(6, 'sub1', 5);
我没有指望我制作了多少个版本,但这是最后一个无法按需工作的版本,我还认为代码可以变得更轻巧...
<?php
$level = array();
function doesCategoryExist($data, $level, $prevlevel, $name, $prevname) {
if (empty($data)) {
return array(0, 'null');
}
foreach ($data as &$value) {
if ($name == $value['name']) {
if ($level == $value['level']) {
return array(1, 0);
} else {
return array(0, 'null');
}
} else {
if ($prevname == $value['name'] && $prevlevel == $value['level']) {
return array(0, $value['id']);
}
}
}
}
$data = array();
$counter = 1;
foreach (new SplFileObject('/home/username/categories5.txt') as $line) {
$tmp = explode(" / ", trim($line));
for ($x = 0; $x < count($tmp); $x++) {
if ($tmp[$x] != "") {
if ($x == 0) {
$data2 = doesCategoryExist($data, $x, 0, $tmp[$x], '');
} else {
$data2 = doesCategoryExist($data, $x, $x-1, $tmp[$x], $tmp[$x-1]);
}
if ($data2[0] == 0) {
$data[] = array('level'=>$x,'id'=>$counter,'name'=>$tmp[$x],'parent'=>$data2[1]);
$counter++;
} else {
if ($data2[1]!=0){
$data[] = array('level'=>$x,'id'=>$counter,'name'=>$tmp[$x],'parent'=>'null');
$counter++;
}
}
}
}
}
print_r($data);
?>
有什么建议吗?
答案 0 :(得分:0)
您可以使用以下内容作为起点。它有两个功能,一个用于解析输入文件(返回嵌套数组)。另一个将结构映射到有用的东西。
<?php
declare(strict_types=1);
error_reporting(-1);
ini_set('display_errors', 'On');
/**
* @param string $input
* @param string $branchSeparator
* @param string $lineSeparator
*
* @return array
*/
function buildMap(string $input, string $branchSeparator = '/', string $lineSeparator = "\n"): array {
$result = [
'id' => null,
'children' => [],
];
$id = 1;
foreach (explode($lineSeparator, $input) as $line) {
$path = array_map('trim', explode($branchSeparator, $line));
$parent =& $result;
foreach ($path as $branch) {
if (!array_key_exists($branch, $parent['children'])) {
$parent['children'][$branch] = [
'id' => $id++,
'parent' => $parent['id'],
'children' => [],
];
}
$parent =& $parent['children'][$branch];
}
}
return $result['children'];
}
/**
* Map the structure from `buildMap` to a flat array using a supplied render function.
*
* @param array $map
* @param callable $renderer
* @param array $result
*
* @return array
*/
function mapToValues(array $map, callable $renderer, array &$result = []): array {
foreach ($map as $key => $def) {
$result[] = $renderer($def['id'], $key, $def['parent']);
if (\count($def['children']) > 0) {
$result = mapToValues($def['children'], $renderer, $result);
}
}
return $result;
}
// $input = file_get_contents('/home/username/categories5.txt');
$input = <<<DATA
Video / Camera
Video / Camera / 4K
Video / Other
Other
Other / sub1
Other / sub2
Other / Camera
DATA;
$map = buildMap($input);
$sql = sprintf(
'INSERT INTO `category` (`id`, `name`, `parent`) VALUES %s',
implode(', ', mapToValues($map, function (int $id, string $name, ?int $parent = null) {
return sprintf(
"(%d, '%s', %s)",
$id,
$name, // do some escaping here!
$parent ?? 'NULL'
);
}))
);
echo $sql;