- Recursion Fail..
WT форуми -> PHP MySQL ASP.NET -> Recursion Fail..
Създайте нова тема Напишете отговор 
Автор Съобщение
xlebabarov
Нов
Нов

Регистриран на: 10/11/2009 8:24 am

Support: 5
Bonus: 10
Мнения: 161
Мнение 06/09/2018 9:33 pm     Recursion Fail.. Отговорете с цитат


Здравейте, боря се с проблема за рекрусията:

SQL code:
-- phpMyAdmin SQL Dump
-- version 4.8.2
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Sep 06, 2018 at 09:20 PM
-- Server version: 10.1.34-MariaDB
-- PHP Version: 7.2.7

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES cp1251 */;

--
-- Database: `blank_website`
--

-- --------------------------------------------------------

--
-- Table structure for table `user_product_categories`
--

CREATE TABLE `user_product_categories` (
`id` int(11) NOT NULL,
`name` varchar(225) COLLATE cp1251_bulgarian_ci NOT NULL,
`main` int(11) NOT NULL,
`level` int(11) NOT NULL,
`orders` int(11) NOT NULL,
`user_added` int(11) NOT NULL,
`user_edited` int(11) NOT NULL,
`time_added` int(11) NOT NULL,
`time_edited` int(11) NOT NULL,
`user_ip` varchar(225) COLLATE cp1251_bulgarian_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=cp1251 COLLATE=cp1251_bulgarian_ci;

--
-- Dumping data for table `user_product_categories`
--

INSERT INTO `user_product_categories` (`id`, `name`, `main`, `level`, `orders`, `user_added`, `user_edited`, `time_added`, `time_edited`, `user_ip`) VALUES
(1, 'Electronics', 0, 0, 1, 1, 0, 1533326058, 0, '1'),
(2, 'Computers & Tablets', 1, 1, 1, 1, 0, 1533326058, 0, '1'),
(3, 'Cameras & Photos', 1, 1, 2, 1, 0, 1533326058, 0, '1'),
(4, 'TV Audio & Surveillance', 1, 1, 3, 1, 0, 1533326058, 0, '1'),
(5, 'Video Games & Consoles', 1, 1, 4, 1, 0, 1533326058, 0, '1'),
(6, 'Cell phones & Accessories', 1, 1, 5, 1, 0, 1533326058, 0, '1'),
(7, 'Fashion', 0, 0, 2, 1, 0, 1533326058, 0, '1'),
(8, 'Home & Garden', 0, 0, 3, 1, 0, 1533326058, 0, '1'),
(9, 'Shop Cellphones & Accessories', 6, 2, 1, 1, 0, 1533326058, 0, '1'),
(10, 'Cellphones & Smartphones', 6, 2, 2, 1, 0, 1533326058, 0, '1');

-- --------------------------------------------------------

--
-- Table structure for table `user_product_categories_lang`
--

CREATE TABLE `user_product_categories_lang` (
`id` int(11) NOT NULL,
`cat_id` int(11) NOT NULL,
`lang_id` int(11) NOT NULL,
`name` varchar(225) COLLATE cp1251_bulgarian_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=cp1251 COLLATE=cp1251_bulgarian_ci;

--
-- Dumping data for table `user_product_categories_lang`
--

INSERT INTO `user_product_categories_lang` (`id`, `cat_id`, `lang_id`, `name`) VALUES
(1, 1, 1, 'Електроника'),
(2, 1, 2, 'Electronics'),
(3, 2, 2, 'Computers & Tablets'),
(4, 3, 2, 'Cameras & Photos'),
(5, 4, 2, 'TV Audio & Surveillance'),
(6, 5, 2, 'Video Games & Consoles'),
(7, 6, 2, 'Cell phones & Accessories'),
(8, 2, 1, 'Компютри и таблети'),
(9, 3, 1, 'Камери и снимки'),
(10, 4, 1, 'ТВ Аудио и Охранителна техника'),
(11, 5, 1, 'Видео игри и конзоли'),
(12, 6, 1, 'Мобилни телефони & Аксесоари'),
(13, 7, 2, 'Fashion'),
(14, 8, 2, 'Home & Garden'),
(15, 7, 1, 'Мода'),
(16, 8, 1, 'Дом & Градина'),
(17, 9, 2, 'Shop Cellphones & Accessories'),
(18, 10, 2, 'Cellphones & Smartphones'),
(19, 9, 1, 'Клетъчни телефони & Аксесоари'),
(20, 10, 1, 'Клетъчни телефони & Смартфони');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `user_product_categories`
--
ALTER TABLE `user_product_categories`
ADD PRIMARY KEY (`id`);

--
-- Indexes for table `user_product_categories_lang`
--
ALTER TABLE `user_product_categories_lang`
ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `user_product_categories`
--
ALTER TABLE `user_product_categories`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11;

--
-- AUTO_INCREMENT for table `user_product_categories_lang`
--
ALTER TABLE `user_product_categories_lang`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=21;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;


PHP code:
$url = 'http://localhost/starniko/';
$homec = '\\';
$home = 'E:\xampp\htdocs\starniko'.$homec;

$c = array(0 => $url,
1 => $homec,
2 => $home);

// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
}
mysqli_query($conn, "SET CHARACTER SET utf8");



А в случая Glang e това:

PHP code:
<?php
$glang = array(
//'' => '',
'does_not_match_mysql_add' => 'Посочените стойности не съвпадат. Моля, уравновесете.',
'mysql_add_table_not_null' => 'Посочените стойности в таблицата за добавяне не могат да са празни. Моля, изберете стойност.',
'mysql_add_value_not_array' => 'Стойностите, value0 or value1 не са масив. Моля, предоставете масив.',
'mysql_select_table_not_null' => 'Посочените стойности в таблицата за селектиране не могат да са празни. Моля, изберете стойност.',
'mysql_select_what_not_null' => 'Стойността какво не може да е нула. Моля, изберете стойности.',
'mysql_select_is_not_array_where' => 'Стойността where не е масив. Моля, изберете масив.',
'mysql_select_is_not_array_where0' => 'Стойността where0 не е масив. Моля, изберете масив.',
'mysql_select_is_not_array_where1' => 'Стойността where1 не е масив. Моля, изберете масив.',
'mysql_select_is_not_the_same_where' => 'Стойността where0 и where1 не са равни. Моля, уравновесете.',
'mysql_update_table_not_null' => 'Таблицата в стойности за ъпдейт не може да бъде празна. Моля, изберете стойност.',
'mysql_update_update_not_null' => 'Ъпдейта в стойности за ъпдейт не може да бъде празен. Моля, изберете стойност.',
'mysql_update_update_not_array'> 'Ъпдейта в стойности за ъпдейт не може да не бъде масив. Моля, изберете стойност.',
'mysql_update_update_not_equal' => 'Ъпдейта или където в стойности за ъпдейт не може да бъдат празни или неравни. Моля, изберете стойност.',
'mysql_update_where_not_array' => 'Където в стойности за ъпдейт не може да не бъдат масив. Моля, изберете стойност.',
'Close_menu' => 'Затвори менюта',
'log_out' => 'Изход',
'' => '',
'' => '',// BB Code
'quoted' => 'Цитат',
'said' => 'каза',
'Image' => 'Изображение',
//Profile
//'' => '',
'Username' => 'Потребителско име',
'Password' => 'Парола',
'Email' => 'E-mail',
'Level' => 'Ниво',
'Country' => 'Държава',
'Countries' => 'Държави',
'Language' => 'Език',
'Credits' => 'Кредити',
'Gender' => 'Пол',
//Products
'Name' => 'Име',
'Store_id' => 'Име на магазин',
'Cat_id' => 'Категория',
'User_ip' => 'IP на потребител',
'Description' => 'Описание',
'Images' => 'Изображения',
'' => '',
'Time_added' => 'Добавено на',
//Register
'Check' => 'Провери',
'Change' => 'Промени',
'username_free' => 'Потребителското име е свободно.',
'username_not_free' => 'Потребителското име е заето.',
'select_an_option' => 'Моля изберете',
'Register' => 'Регистрация',
'email_not_free' => 'E-mail-ът вече се използва',
'email_free' => 'E-mail-ът е свободен',
'Lang' => 'Език',
'Address' => 'Адрес',
'Mobile_phone' => 'Мобилен телефон (код/телефон)',
'could_not_be_empty' => ' не може да бъде празен.',
'username_cannot_contain_extra_characters' => 'Потребителското име не може да съдържа допълнителни знаци. Може да съдържа само букви от аА до zZ и _.',
'not_valid' => ' е невалидно.',
'username_not_less' => 'Потребителското име трябва да бъде между 4 и 12 символа',
'password_not_less' => 'Паролата трябва да бъде между 4 и 12 символа',
'country_not_less' => 'Държавата трябва да е под или 10 символа',
'gender_not_less' => 'Полът трябва да е под или 10 символа',
'language_not_less' => 'Езикът трябва да е под или 10 символа',
'address_not_less' => 'Адресът трябва да е под или 10 символа',
'phone_code_not_less' => 'Телефонен код трябва да е под или 10 символа',
'phone_num_not_less' => 'Телефонен номер трябва да е под или 20 символа',
'registration_success' => 'Регистрацията успешна!',
// Add Product
'Product_name' => 'Име на продукта',
'Pictures' => 'Снимки',
'Categorie' => 'Категория',
'Send' => 'Изпрати',
'Submit' => 'Изпращане',

'' => ''
);
?>


Просто за изпълненнието на файла за да ме разберете давам и функцията си mysql_select която е добро мое изобретение, служещо ми вярно като идеята на функцията е да избере от

    table - Името на селектираната таблица
    where - WHERE заявката на таблицата array('id') = array(1) под кода $where = array(array(), array())
    order - Реда на селектирането да речем array('id')=array('ASC') под кода $order = array(array(), array())


PHP code:
function mysql_select($table, $what = array('*'), $where = array(array(), array()), $order = array(array(), array())){
global $conn;
global $glang;


$sql = 'SELECT ';
if(!$table){
die($glang['mysql_select_table_not_null']);
}
switch(count($what)){
case 0:
die($glang['mysql_select_what_not_null']);
break;
case 1:
if($what[0]=='*'){
$sql.= '*';
}else{
$sql.= '`'.$what[0].'`'; }
break;
}
if((count($what)>=2)&&(count($what)!=1)){
for($i=0;$i<=count($what)-1;$i++){
$sql.='`'.$what[$i].'`';
if($i!=count($what)-1){
$sql.=', ';
}else{
$sql.=' ';
}
}

}

$sql.= 'FROM `'.$table.'` ';

if(!is_array($order)){die('Order must be array. Please, select value.');}
if(!is_array($order[0])){die('Order0 must be array. Please, select value.');}
if(!is_array($order[1])){die('Order1 must be array. Please, select value.');}
if(count($order[0])!=count($order[1])){die('Order count must be equal. Please, select value.');}

if((count($where[0])==0)&&(count($where[1])==0)){
if(count($order[0])>=1){
$sql .= 'ORDER BY ';
for($i=0;$i<=count($order[0])-1;$i++){
$sql.='`'.$order[0][$i].'` '.$order[1][$i];
if($i!=count($order[0])-1){
$sql.=', ';
}
}
}


$result = mysqli_query($conn, $sql);
$rezult = array();
if (mysqli_num_rows($result) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($result)) {
array_push($rezult, $row);
}
return $rezult;
} else {
return false;
}

}else{

if(!is_array($where)){ die($glang['mysql_select_is_not_array_where']);}
if(!is_array($where[0])){ die($glang['mysql_select_is_not_array_where0']);}
if(!is_array($where[1])){ die($glang['mysql_select_is_not_array_where1']);}
if(count($where[0])!=count($where[1])){ die($glang['mysql_select_is_not_the_same_where']);}
$sql.='WHERE ';
for($i=0;$i<=count($where[0])-1;$i++){
if($i!=count($where[0])-1){
$sql.= '`'.$where[0][$i].'` = \''.$where[1][$i].'\' AND ';
}else{
$sql.= '`'.$where[0][$i].'` = \''.$where[1][$i].'\'';

}
}
if(count($order[0])>=1){
$sql .= 'ORDER BY ';
for($i=0;$i<=count($order[0])-1;$i++){
$sql.='`'.$order[0][$i].'` '.$order[1][$i];
if($i!=count($order[0])-1){
$sql.=', ';
}
}
}

$result = mysqli_query($conn, $sql);
$rezult = array();
if (mysqli_num_rows($result) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($result)) {
array_push($rezult, $row);
}
return $rezult;
} else {
return false;
}

}



}


Рекрусията съм я включил ей тук но за съжаление скрипта не се изпълнява:

PHP code:
function has_children($cat, $id){
if(!$cat){die('Please, select cat.');}
if(!$id){die('Please, select id.');}
if(!is_numeric($id)){die('Please, select numeric values.');}


for($i=0;$i<=count($cat)-1;$i++){
foreach($cat[$i] as $key => $val){
if($key=='main'){
if($val==$id){return true;}
}
}
}
}

function make_menu_rows($array = array(), $level = 0){
$rez = mysql_select('user_product_categories', array('id', 'name', 'main', 'level', 'orders'), array(array('level'), array($level)), array(array('orders'), array('ASC')));
$rez1 = mysql_select('user_product_categories', array('*'));
$array1 = array();

foreach($rez as $var){
$array_key = array_pop(array_keys($array));
if(isset($array_key)){$array_var = $array_key+1;}else{$array_var = 0;}
$array[$array_var] = array('Main' => $var);


if(has_children($rez1, $var['id'])){
$rez2 = mysql_select('user_product_categories', array('id', 'name', 'main', 'level', 'orders'), array(array('main'), array($var['id'])), array(array('orders'), array('ASC')));
foreach($rez2 as $var1){
if(has_children($rez1, $var1['id'])){
array_push($array[$array_var], array('Sub' => $var1));
make_menu_rows($array, $var1['level']);
}else{
array_push($array[$array_var], array('Sub' => $var1));
}
}
}else{
}
}
return $array;
}


$make = make_menu_rows();
print_r($make);


резултатът е:
Array
(
    [0] => Array
        (
            [Main] => Array
                (
                    [id] => 1
                    [name] => Electronics
                    [main] => 0
                    [level] => 0
                    [orders] => 1
                )

            [0] => Array
                (
                    [Sub] => Array
                        (
                            [id] => 2
                            [name] => Computers & Tablets
                            [main] => 1
                            [level] => 1
                            [orders] => 1
                        )

                )

            [1] => Array
                (
                    [Sub] => Array
                        (
                            [id] => 3
                            [name] => Cameras & Photos
                            [main] => 1
                            [level] => 1
                            [orders] => 2
                        )

                )

            [2] => Array
                (
                    [Sub] => Array
                        (
                            [id] => 4
                            [name] => TV Audio & Surveillance
                            [main] => 1
                            [level] => 1
                            [orders] => 3
                        )

                )

            [3] => Array
                (
                    [Sub] => Array
                        (
                            [id] => 5
                            [name] => Video Games & Consoles
                            [main] => 1
                            [level] => 1
                            [orders] => 4
                        )

                )

            [4] => Array
                (
                    [Sub] => Array
                        (
                            [id] => 6
                            [name] => Cell phones & Accessories
                            [main] => 1
                            [level] => 1
                            [orders] => 5
                        )

                )

        )

    [1] => Array
        (
            [Main] => Array
                (
                    [id] => 7
                    [name] => Fashion
                    [main] => 0
                    [level] => 0
                    [orders] => 2
                )

        )

    [2] => Array
        (
            [Main] => Array
                (
                    [id] => 8
                    [name] => Home & Garden
                    [main] => 0
                    [level] => 0
                    [orders] => 3
                )

        )

)


Като тук

            [4] => Array
                (
                    [Sub] => Array
                        (
                            [id] => 6
                            [name] => Cell phones & Accessories
                            [main] => 1
                            [level] => 1
                            [orders] => 5
                        )

                )

Би трябвало да се включи рекрусията понеже в таблицата Cell Phones & Accessories е с main 1 и включени 2 подменюта които не излизат ID 9 и 10

Shop Cellphones & Accessories
и
Cellphones & Smartphones
с level 2 и main 6

Ако схващате идеята моля помогнете Question
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
raiden
Активен
Активен

Регистриран на: 08/12/2006 10:13 am

Support: 188
Bonus: 462
Мнения: 2170
Мнение 08/09/2018 3:10 am      Отговорете с цитат


Ако използваш MySQL 8 можеш да си направиш рекурсията в заявката:
https://www.db-fiddle.com/f/se4UTULGTUbVT6Lmwy33x5/1
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
xlebabarov
Нов
Нов

Регистриран на: 10/11/2009 8:24 am

Support: 5
Bonus: 10
Мнения: 161
Мнение 12/09/2018 1:46 pm      Отговорете с цитат


raiden написа:
Ако използваш MySQL 8 можеш да си направиш рекурсията в заявката:
https://www.db-fiddle.com/f/se4UTULGTUbVT6Lmwy33x5/1


За съжаление не ползвам 8 а някъкви идеи защо не работи кода?
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
raiden
Активен
Активен

Регистриран на: 08/12/2006 10:13 am

Support: 188
Bonus: 462
Мнения: 2170
Мнение 12/09/2018 9:43 pm      Отговорете с цитат


Функцията ти вика сама себе си, но това извикване не променя нищо в резултата. Трябва да имаш нещо от рода на
$array = make_menu_rows($array, $var1['level']);

или директно да правиш
return make_menu_rows($array, $var1['level']);

за да работиш при всяко следващо извикване с резултата от предишното. Иначе функцията не е рекурсивна. Предвид че имаш нивото на всяка категория в йерархията, рекурсията не е наложителна и можеш да минеш с нещо такова:
PHP code:
<?php
$array = [
0 => ['id' => 1, 'name' => 'Electronics2', 'main' => 0, 'level' => 0],
1 => ['id' => 2, 'name' => 'Electronics1', 'main' => 0, 'level' => 0],
2 => ['id' => 3, 'name' => 'Electronics11', 'main' => 2, 'level' => 1],
3 => ['id' => 4, 'name' => 'Electronics12', 'main' => 3, 'level' => 2]
];

function nestSubs($array) {
$result = array_reduce(
$array,
function ($result, $i) {
$result[$i['level']][$i['id']] = $i;
return $result;
},
[]
);
$maxLevel = max(array_keys($result));
for ($i = $maxLevel; $i > 0; $i--) {
foreach($result[$i] as $sub) {
$result[$i - 1][$sub['main']]['subs'][$sub['id']] = $sub;
}
unset($result[$i]);
}

return $result[0];
}

print_r(nestSubs($array));
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
Покажи мнения от преди:    
Създайте нова тема   Напишете отговор    web-tourist.net Форуми -> PHP MySQL ASP.NET Часовете са според зоната GMT + 2 Часа
Страница 1 от 1


 
Идете на:  
Не Можете да пускате нови теми
Не Можете да отговаряте на темите
Не Можете да променяте съобщенията си
Не Можете да изтривате съобщенията си
Не Можете да гласувате в анкети