Skip to content

Instantly share code, notes, and snippets.

@7audio
Created August 17, 2019 13:54
Show Gist options
  • Save 7audio/61b85fb33a95a0e7dd364626a78ae166 to your computer and use it in GitHub Desktop.
Save 7audio/61b85fb33a95a0e7dd364626a78ae166 to your computer and use it in GitHub Desktop.
<?php
/*
Структура таблицы для сохранения дерева:
CREATE TABLE `tree` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`title` varchar(512) NOT NULL,
`position` varchar(32) NOT NULL,
`value` int NOT NULL,
`currency` varchar(8) NOT NULL,
`parentId` int NULL
);
*/
const DSN = 'mysql:host=localhost;dbname=tree';
const USER = '';
const PASS = '';
const TABLE = '';
function insertChild(array &$tree, array $child) {
$path = explode('.', $child['position']);
$node = &$tree;
while ($path) {
$i = (int) array_shift($path);
$node['children'][$i] = $node['children'][$i] ?? ['children' => []];
$node = &$node['children'][$i];
if (!$path) $node += $child;
}
}
function orderNodes(array &$node) {
ksort($node['children']);
array_walk($node['children'], 'orderNodes');
}
function persistNode(PDO $dbh, array $node, int $parentId = null) {
preg_match('/(\d+\.\d{2})\s(.+)/', $node['value'], $matches);
$query = "INSERT INTO ".TABLE." (title, position, value, currency, parentId) VALUES (?,?,?,?,?)";
$dbh->prepare($query)->execute([
$node['title'],
$node['position'],
(int) $matches[1] * 100,
$matches[2],
$parentId,
]);
$lastId = (int) $dbh->lastInsertId();
foreach ($node['children'] as $child) {
persistNode($dbh, $child, $lastId);
}
}
$input = [
[
'position' => '1.3.2',
'title' => 'грунт, грунт замусоренный (техн.)',
'value' => '223.10 ₽',
],
[
'position' => '1.2.1',
'title' => 'до 10 км',
'value' => '344.10 ₽',
],
[
'position' => '1',
'title' => 'Земляные работы',
'value' => '43.00 ₽',
],
[
'position' => '2.1.2',
'title' => 'песок',
'value' => '123.00 ₽',
],
[
'position' => '1.2.4',
'title' => 'до 40 км',
'value' => '1045.00 ₽',
],
[
'position' => '2.1.8',
'title' => 'щебень фр.5-20',
'value' => '6783.00 ₽',
],
[
'position' => '2.1.5',
'title' => 'основание из щебня',
'value' => '1345.00 ₽',
],
[
'position' => '1.2.2',
'title' => 'до 20 км',
'value' => '567.43 ₽',
],
[
'position' => '1.3.1',
'title' => 'грунт, грунт замусоренный (экологич.чистый)',
'value' => '654.40 ₽',
],
[
'position' => '2.1.4',
'title' => 'ПГС',
'value' => '735.00 ₽',
],
[
'position' => '2.1.7',
'title' => 'щебень фр.20-40',
'value' => '4112.00 ₽',
],
[
'position' => '2',
'title' => 'Устройство основания ("пирога")',
'value' => '534.50 ₽',
],
[
'position' => '1.2.3',
'title' => 'до 30 км',
'value' => '979.00 ₽',
],
[
'position' => '2.1.6',
'title' => 'щебень фр.40-70',
'value' => '983.00 ₽',
],
[
'position' => '1.2',
'title' => 'Вывоз грунта',
'value' => '3554.00 ₽',
],
[
'position' => '1.4',
'title' => 'Засыпка',
'value' => '7648.56 ₽',
],
[
'position' => '2.1.3',
'title' => 'основание из ПГС',
'value' => '7895.00 ₽',
],
[
'position' => '2.2',
'title' => 'Устройство бетонной подготовки',
'value' => '113.00 ₽',
],
[
'position' => '1.2.5',
'title' => 'до 50 км',
'value' => '1287.00 ₽',
],
[
'position' => '2.1.1',
'title' => 'основание из песка',
'value' => '673.00 ₽',
],
[
'position' => '1.1',
'title' => 'Разработка грунта комплексная (с учетом погрузки в автомобили-самосвалы, доработки вручную, планировки и т.п.), вывоз до 1 км',
'value' => '4123.00 ₽',
],
[
'position' => '1.3',
'title' => 'Утилизация грунта',
'value' => '1000.00 ₽',
],
[
'position' => '2.1',
'title' => 'Устройство основания',
'value' => '1123.00 ₽',
],
];
// creating tree
$tree = [];
foreach ($input as $row) {
insertChild($tree, $row);
}
orderNodes($tree);
// saving to DB
try {
$dbh = new PDO(DSN, USER, PASS);
foreach ($tree['children'] as $child) {
persistNode($dbh, $child, null);
}
} catch(PDOException $e) {
echo "Ошибка при сохранении: ".$e->getMessage()."\n";
}
// output
foreach ($tree['children'] as $i => $parent) {
echo "$i {$parent['title']}\n";
foreach ($parent['children'] as $j => $child1) {
echo "$i.$j {$child1['title']}\n";
foreach ($child1['children'] as $k => $child2) {
echo "$i.$j.$k {$child2['title']}\n";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment