PHP - Recursive Iterator Iterator Tree Problem ??
Hi
consider I have following type of directory structure inside /root folder1 -fileName1.1 -folder1.2 --fileName1.2.1 $dirItr = new RecursiveDirectoryIterator('/root'); $itr = new RecursiveIteratorIterator($dirItr); $structure ; // the type of structure i want to build store inside it foreach($itr as $object) { //magic happens here } //in the end I want folowing type of structure $structure = array('label'=>'folder1','children'=>array(array('label'=>'fileName1.1'),array('label'=>'folder1.2','children'=>array(array('label'=>'fileName1.2.1'))))); Importan observations; a)children key is an array which contains arrays of other folder or filename; b) filename does not have children attribute because they are leafs of tree c) a folder without any files will be represented as array('label'=>'emptyFolderName',children=>array()) ; //children attribute with empty array. I wd be really thankfull to the user whoever solved this problem , wasted a month already on it !! thanks in Advance. Similar TutorialsHello my good people
I'm doing a content manager system in PHP and mySQLi, following a serie of video tutorials.
But in my project I am using a tree menu.
In the front office all works smoothly (the tree menu displays all results - menu and submenus - and each button carries the information of the respective page). I have a database table with categories and subcategories, with the structure of :: categoryid, categoryname, parentid I have found numerous examples of printing out a tree structure of the table, and it works, but I would like to get all the data into an array, ultimately to print the array to a listbox to select from. The array structure would be categoryid => categoryname. The basic query I have now is as follows :: Code: [Select] function createCatTree($thisParentCatID=0,$depth=0) { $catIDQ = mysql_query("SELECT * from category WHERE parentcatid = $thisParentCatID;"); while ( $catIDQRow = mysql_fetch_array($catIDQ) ) { $thisCatName = $catIDQRow['categoryname']; $thisCatID = $catIDQRow['categoryid']; for($i = 0; $i < $depth; $i++) $spcstr.= " "; // create spaces to mimic a tree structure $value = $spcstr.$thisCatName; // add spaces echo $value; createCatTree($thisCatID,$depth+1); } } I was hoping to send the categoryid and categoryname to an array, like Code: [Select] $arr[$thisCatID] = $value;then change my function call to be Code: [Select] createCatTree($thisCatID,$depth+1,$arr);to send the array as a variable back to the function to hold the data going forward. Also, I added a section at the top of the function to see if the array needed to be initialized, like Code: [Select] if ($arr == "") { $arr = array(); } but this does not work. Is there any way to use this basic recursive code and save all the data to an array to be worked on at a later time? Hi there, hope one of you can help me with a problem im just having. Ok, lets start with the explanation what i want to to: I'd like to collect headlines from a html site, and get the test results in an array, so that the array structure represents the dom-levels of the site. Small Example: <h1>test1.1<h1/> <h2>test2.1</h2> <h2>test2.2</h2> <h3>test3</h3> <h1>test1.2<h1/> Shoul end in a array structure like: Code: [Select] array('level 1' => array ( 'sibble1' => array ( 'headline' => 'test1.1', 'level2' => array( 'sibble1' => array ( 'headline' => 'test2.1', 'level3' => array(), // empty data, needs to be processed anyway to find gaps, to maybe a h4 headline would be existing ), 'sibble2' => array ( 'headline' => 'test2.2', 'level3' => array ( 'sibble1' => array ( 'headline' => 'test3.1', 'level4' => array(), // empty data, needs to be processed anyway to find gaps, to maybe a h4 headline would be existing ), ), ), ), ), 'sibble2' => array ( 'headline' => 'test1.1', 'level2' => array(), ), ), ); So i hope out of this example you can see what i want to do. level represents the healdine level 1-9, sibblin is as name for the childs on the headline level. Ok, so to extract the herefore needed data out of the html, i build a class with a recursive function, that filters the html by a regex from one headline to the next, first iteratin all childs, if there are no more childs i go tho ne nextsibbling element. as an running example code look he Code: [Select] <?php class Application_Model_DomParser { const PREG_MATCH_ONE_ELEMENT_TO_MUCH_LENGTH = 4; private $slicedFields = array(); public function __construct() { } public function sliceFirstSectionToDataFields($level = 1, $haystack) { preg_match_all("#(.*?)<h$level>(.*?)</h$level>(.*?)(<h$level>|$)#s", $haystack, $data); // prepare the chunkData $pageText = ''; if (isset($data[1][0])) { $pageText = $data[1][0]; } $headline = ''; if (isset($data[2][0])) { $headline = $data[2][0]; } $dataToProcessNextLevel =''; if (isset($data[3][0])) { $dataToProcessNextLevel = $data[3][0]; } // @todo dirty warnings compression, search why warning occures @$posOfNextChild = strlen($data[0][0]) - self::PREG_MATCH_ONE_ELEMENT_TO_MUCH_LENGTH; // from here goes the debug... echo $headline ."::" .strlen($dataToProcessNextLevel). "<br>"; if (strlen($dataToProcessNextLevel) <= self::PREG_MATCH_ONE_ELEMENT_TO_MUCH_LENGTH) { if ($level < 9) { $dataToProcessNextLevel = $haystack; } else { return; } } //recursive check for next level in $dataToProcessNextLevel $nextLevel = $level + 1; $this->sliceFirstSectionToDataFields($nextLevel, $dataToProcessNextLevel); $haystack = substr($haystack, $posOfNextChild); // slized To The End if (self::PREG_MATCH_ONE_ELEMENT_TO_MUCH_LENGTH == strlen($haystack)) { // die("slized To The End"); return; } // recursive check for other childs in actuall level... $this->sliceFirstSectionToDataFields($level, $haystack); } } $htmlString = 'test<h1>headkline1.1</h1> <p>test test</p> <h2>headline 2.1</h2>test test <h2>headline 2.2</h2> <p>tes test test</p> <h3>headline 3.1</h3>test <h3>headline 3.2</h3>test <h2>headline 2.3</h2> <p> </p> <p>test</p> <h1>headline 1.2</h1> <h2>headline 2.4</h2> <p>11111111111112222222222222222222222</p> <p> ewfwrefg upowmdg w3q09umq09wrt n3q089ty 3q0898943ty -98 41</p> <h3>headline 3.3</h3> <p>test</p> <p>test</p> <p>test</p> <h1>1.3 testtest</h1> <p>test</p> <h3>head 3.4</h3> <p>sadfsadfsadf asdfsda f sdaas saf saddas</p> <h3>head 3.4</h3> <h3>test 1.3</h3> <p>test;</p> '; $model = new Application_Model_DomParser(); $result = $model->sliceFirstSectionToDataFields(1, $this->htmlString); So letting this piece of code run, you can se via the debug echo, every headline is found, even in the right order of its occurence. My problem now is dont get it how to return the extracted values, and collect them to get a result as my above shown structure shows. So i spent ours to solve this problem but didnt come to a result. I know its a hard problem, and to help me takes time, cause its a complex situation. Allthough i hope someone knows a anser. I need this problem solved, to get my mind rested! Thanks, and greetings Selma Something bothers me: I am writing a PHP code to implement "step by step" form. In order to do that, I copied a method which looks like: Program name: doit.php : if (!isset($_SESSION['para_stage'])) { ... first time to the code .... initialize variables ...display first form which calls doit.php when submit.....} else {already been to this code, variables are initialized, do what you have to do and recall doit.php ....} It works fine, but: isn't there a problem with calling the same program again and again from itself? isn;t it like a recursive, which means the stack will be used until overflow? Hello! Maybe I'm a bit ashamed to question some little kind of thing, but I tested 3 hours and couldn't let this function. It's like the most easiest possible recursiv function...: Code: [Select] function recursiv($s){ $s.="b"; if(strlen($s)>30){return $s;} //else return 0; else recursiv($s); } echo recursiv("h"); The result is a blank page... Thanks a lot for your help !! Hello,
Here is my code:
<?php require 'vendor/autoload.php'; $client = new Elasticsearch/Client(); $root = realpath('~/elkdata/for_elk_test_2014_11_24/Agencies'); $iter = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($root, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD); $paths = array($root); foreach ($iter as $path => $dir) { if ($dir -> isDir()) { $paths[] = $path; } } //Create the index and mappings $mapping['index'] = 'rvuehistoricaldocuments2009-2013'; //mapping code $mapping['body'] = array ( 'mappings' => array ( 'documents' => array ( '_source' => array ( 'enabled' => true ), 'properties' => array( 'doc_name' => array( 'type' => 'string', 'analyzer' => 'standard' ), 'description' => array( 'type' => 'string' ) ) ) ) ); $client ->indices()->create($mapping) //Now index the documents for ($i = 0; $i <= count($paths); $i++) { $params ['body'][] = array( 'index' => array( 'type' => 'documents' 'body' => array( 'foo' => 'bar' //Document body goes here ) ) ); //Every 1000 documents stop and send the bulk request. if($1 % 1000) { $responses = $client->bulk($params); // erase the old bulk request $params = array(); // unset the bulk response when you are done to save memory unset($responses); } } ?>I am looking to index a large amount of documents using elastic search and php. I have a very complex directory filled with other directories that i need to index into an array. I wanted to see if my code looked right, and if not what am I doing wrong? Thanks, Austin Harmon Code: [Select] public function getBonusChildren($userID) { if($userID != NULL) { $sql = 'SELECT COUNT(*) AS count, userID FROM jos_backoffice_users WHERE parentID= ' . $userID . ';'; $stmt = conn::getInstance()->prepare($sql); $stmt->execute(); $obj = $stmt->fetchAll(PDO::FETCH_ASSOC); if(is_object($obj)) { $obj->count += $this->getBonusChildren($obj->userID); } } return $obj->count; } I get no error. It just always return null. How can I get this done? I'm really fond of your coding and need some help too I'm also trying to make a tree and save it in an xml file such that parent_id of one node is inserted in as pages key to the father node.By running this query $sql = "Select * from category order by parent_id ASC"; I'm getting the following result. Array ( => Array ( [category_id] => 2 [parent_id] => 0 [category_name] => Clothes ) [1] => Array ( [category_id] => 5 [parent_id] => 1 [category_name] => T-shirts ) [2] => Array ( [category_id] => 6 [parent_id] => 1 [category_name] => Cotton-Shirts ) [3] => Array ( [category_id] => 1 [parent_id] => 2 [category_name] => Upper ) [4] => Array ( [category_id] => 4 [parent_id] => 2 [category_name] => Lower ) [5] => Array ( [category_id] => 3 [parent_id] => 4 [category_name] => Pants ) ) My code is as follows but not executing correctly function searchTree($arr,$node,$i){ if(!in_array($node['parent_id'],$arr[$i])) { $stmt = '<pages_'.$i.'>'; $stmt .=$node; $stmt .='</pages_'.$i.'>'; return $stmt;} else{ //print_r($returnTree); print_r ($arr[$i]);//['category_id']; $returnTree = ($arr[$i]['category_id']==$node['parent_id'])? searchTree($arr,$node,$i++): searchTree($arr,'',$i++); } } $i=0; foreach($links as $link){ $myArr = searchTree($links,$link,$i);} The result should be as follows: <page_1> <label>Clothes</label> <uri>#</uri> <pages> <page_1_1> <label>Upper</label> <uri>#</uri> <pages> <label>T-Shirt</label> <uri>#</uri> <page_1_1> <page_1_1_1> <label>Short Sleaves</label> <uri>#</uri> </page_1_1_1> <page_1_1_2><label>Long Sleaves</label><uri>#</uri> </page_1_1_2></page_1_1></page_1> <page_1_2> <label>Lower</label> <uri>#</uri> <pages>....</page_1_2> Hopefully you can unsderstand this problem. Please help me. If i have a list of categories like: 1. Billboards and advertisement section 1(a)City Clock 1(a)(i)Application fee (has columns for approved price and proposed price) 1(a)(ii)Advertisement Per year (has columns for approved price and proposed price) 1(b)Billboards 1(b)(i)Application fee for construction (has columns for approved price and proposed price) 1(b)(ii)Charge per year without advertisement (has columns for approved price and proposed price) 1(c)Something here..... 1(c)(i) something here...(has columns for approved price and proposed price) 1(c)(ii)something here...(has columns for approved price and proposed price) 1(c)(iii) something here... (has columns for approved price and proposed price) e.t.c THEN SOME CATEGORIES LOOK LIKE:category 2 2. Category name 2(a)something here..(has columns for approved price and proposed price) 2(b)something here.. 2(b)(i)something here..(has columns for approved price and proposed price) 2(b)(ii)something here..(has columns for approved price and proposed price) NOW: i have categories without sub categories and others with sub-sub categories , a main category doesn't does have a column for prices ( or lets just say other columns) , a sub category WITHOUT its sub category will have columns for prices, if a sub category has its sub category, then its subcategory should have columns for prices (this is where my problem is - how do i handle such a situation in php Mysql?? ) Hey guys, I've got a problem. I need a function, that gives me a menue like that: parent_page1 page1 page2 page3 parent_page2 page1 page2 page3 So.. here is my database structu All what I need, is a function, that gives me a menu like that on top. Do you need some more information? Let me know.. I have a function that searches first for a line in a file and then for a string in that line. If the string is not found, it concatenates the line with the next line and so on until it finds the string. The following script works but it is time consuming. I want to put a "break" somewhere so that if the line is found, the foreach will break. Can someone please help and tell me how to do this? If I put the break before the recursive call, it wont do the call. If I put it after, it wont get to the break. Thanks! function findEndTag($file, $line, $consolidatedLine) { $endTagFound = strstr($consolidatedLine,"/>"); if (!$endTagFound) { $fileContent = file($file); foreach ($fileContent as $i => $lineArray) { if ($lineArray == $line) { $consolidatedLine = $consolidatedLine." ".$fileContent[$i+1]; return (findEndTag($file, $fileContent[$i+1], $consolidatedLine)); } } } else { return $consolidatedLine; } } Hi, I am using a separate class for all the functions. And using using the following function "objectToArray" to convert the JSON decoded object to Array. Class file: class xyz { . . . . . function objectToArray($d) { if (is_object($d)) { $d = get_object_vars($d); } if (is_array($d)) { return array_map(__FUNCTION__, $d); } else { return $d; } } . . . } Main page: $obj = new xyz(); $arr = $obj->objectToArray($json_obj); Because the function "objectToArray" is recursive, array_map(__FUNCTION__, $d) is not able to applies the callback. And throws the warning "array_map() expects parameter 1 to be a valid callback". Need help! Girish Dear all, Hello, i'm a newbie programmer. I want to implement the concept about recursive descent parser for natural language (english). The concept was found in http://nltk.sourceforge.net/doc/en/ch07.html#rdparser. But my problem is, how to implementation the concept/theory to PHP code ? Anyone would to help me to give the advice or tutorial or maybe anyone has to make script before? Thank you very much in advance. i have the below script but it doesn't work it just refreshes the page anyone know what is wrong Code: [Select] <?php $path = "../../gallery/gallery_files/gallery/"; if(isset($_POST['file']) && is_array($_POST['file'])) { foreach($_POST['file'] as $file) { $dirname = $path; //Recursive Delete Function function DELETE_RECURSIVE_DIRS($dirname) { // recursive function to delete // all subdirectories and contents: if(is_dir($dirname))$dir_handle=opendir($dirname); while($file=readdir($dir_handle)) { if($file!="." && $file!="..") { if(!is_dir($dirname."/".$file))unlink ($dirname."/".$file); else DELETE_RECURSIVE_DIRS($dirname."/".$file); } } closedir($dir_handle); rmdir($dirname); return true; } } } ?> Hi there, I have written a recursive function that basically generates a tree structure for my site pages (kind of like a sitemap). It all worked fine until yesterday, I started getting error messages telling me that I have exhausted the amount of memory available. There are only about 30 pages in the site (parent, child, sub-child etc), so I dont think that I should be using up that much memory. This was my first attempt at a recursive function so I am pretty sure that it may not have been optimised properly. If anyone could take a look and offer any feed back that would be great. (written in codeigniter framework) function getAllPages() { $this->tmp_arr = array(); $this->buildPageStructure(0, 0); return $this->tmp_arr; } function buildPageStructure($parent_id, $counter) { $CI = & get_instance(); $query = $CI->db->query("SELECT page_id, title, page_url, status FROM pages WHERE parent_page='$parent_id' ORDER BY sort_order ASC"); $counter++; if($query->num_rows() > 0) { foreach($query->result() as $row) { $new_arr = new Page(); $new_arr->page_id = $row->page_id; $new_arr->title = $row->title; $new_arr->level = $counter; $new_arr->page_url = $row->page_url; $new_arr->status = $row->status; $this->tmp_arr[] = $new_arr; $this->buildPageStructure($row->page_id, $counter); } } } Cheers Jon Hello Community, maybe I'm a little bit over-worked, but I'm stucked in a problem with recursive database queries. I have a DB table with from/to relations. Here is an excerpt for only one relation (from rel_item_id_from=3 to rel_item_id_to=3): rel_id rel_item_id_from rel_item_id_to 1 52 3 2 3 17 My question is: How can I get a recursive solution to get the upward and downward children? It is also possible to have multiple relations (1:n or n:m). Thanks for your assistance - OLK Hi, I am trying to recursively build another array based on the one I get back from our CRM api. The array I get back looks like this: Code: [Select] [1] => stdClass Object ( [description] => Description Text [label] => Product [name] => Product [sobject] => KnowledgeArticleVersion [topCategories] => stdClass Object ( [childCategories] => Array ( [0] => stdClass Object ( [childCategories] => Array ( [0] => stdClass Object ( [childCategories] => Array ( [0] => stdClass Object ( [label] => Apple [name] => Apple ) [1] => stdClass Object ( [label] => Orange [name] => Orange ) [2] => stdClass Object ( [label] => lemon [name] => lemon ) ) [label] => Templates [name] => Templates ) [1] => stdClass Object ( [label] => Connector [name] => Connector ) [2] => stdClass Object ( [label] => AeroView [name] => AeroView ) ) [label] => AeroWare [name] => AeroWare ) [1] => stdClass Object ( [label] => BackOffice [name] => BackOffice ) [2] => stdClass Object ( [label] => OutWare [name] => OutWare ) [3] => stdClass Object ( [childCategories] => Array ( [0] => stdClass Object ( [label] => ERA [name] => ERA ) [1] => stdClass Object ( [label] => Kairos [name] => Kairos ) ) [label] => InWare [name] => InWare ) ) [label] => All [name] => All ) ) The child categories could be any level deep. I would like put it in an array something like this: Code: [Select] Array ( [label] => Cat 1 [level] => 0 [children] => Array ( [label] => Sub Cat 1 [level] => 1 [children] => Array ( [label] => Sub Sub Cat 1 [level] => 2 ) ) ) I have tried so many things but I just can't get it right. Any assistance would be greatly appreciated. Thanks Peter I've got a dev server which, for reasons I won't go into, needs to have different .htaccess files for each site (and subfolders within them) within it. But not always. What I need to do is: - For the folder I put the PHP script in, and every folder under it (the whole tree under it): - If there's a .htaccess file an no .htaccess.dev file, copy .htaccess and name the copy .htaccess.dev (and look in subfolders) If there's a .htaccess file and also a .htaccess.dev file, do nothing (but keep looking for subfolders) If there's neither a .htaccess or .htaccess.dev file, do nothing (but keep looking for subfolders)I'd try to come up with something myself, but getting it wrong will be fairly catastrophic! I'm sure the conditional copy / rename bit is relatively straightforward, but it's the recursive searching of the whole file-system under the script's location that I'm not sure about... Any help greatly appreciated, as always! I have SSH access, if it's easier done that way maybe I'm approaching it wrong?
Hey there I just started out with PHP so it might be a trivial problem. I want to populate an array with values by a recursive function but i don't get it the way i want it to have. Target array (written in python syntax): myArray = { key : [ [a1, a2, a3, a4], [b1, b2, b3 ,b4] ], key2 : [ [c1, c2, c3, c4], [d1, d2, d3, d4] ] } So far i created a recursive function to collect all data i need for the array but i don't get the right syntax to achieve my target array. What i have so far is following code (snippet): function get_data($main_dir, $items=[], $myArray=[], $depth=0) { global $items; if ($myArray == NULL && depth == 0) { $myArray = array(); } $depth++; $dirHandle = opendir($main_dir); while ($file = readdir($dirHandle)){ if(is_dir($main_dir.$file) && $file != "." && $file != "..") { $new_dir = $main_dir.$file."/"; $items = get_data($new_dir, $items, $myArray, $depth); $myArray = $items[1] $items = $items[0] } else { splitted_dir = preg_split("/\//", $main_dir); key = splitted_dir[2]; file_information = read_out_file($main_dir.$file); information_1 = file_information[0]; information_2 = file_information[1]; myArray = array_merge($myArray, array($key, array($key, $information_1, $information_2, $main_dir, $file)) } } } The array contains all informations i need but the structure of it is not useable. Current output: Array ( [0] => key1 [1] => Array ( [0] => key1 [1] => information_1 [2] => information_2 [3] => ./path/ [4] => filename ) [2] => key1 [3] => Array ( [0] => key1 [1] => information_1 [2] => information_2 [3] => ./path/ [4] => filename ) [4] => key1 [5] => Array ( [0] => key1 [1] => information_1 [2] => information_2 [3] => ./path/ [4] => filename ) [6] => key2 [7] => Array ( [0] => key2 [1] => information_1 [2] => information_2 [3] => ./path/ [4] => filename ) [8] => key2 [9] => Array ( [0] => key2 [1] => information_1 [2] => information_2 [3] => ./path/ [4] => filename ) ) 1 ## IDK why this "1" at the end gets printed out... But what i want to get is this: Array ( [key1] => Array ( Array ( [0] => key1 [1] => information_1 [2] => information_2 [3] => ./path/ [4] => filename ) ) Array ( [0] => key1 [1] => information_1 [2] => information_2 [3] => ./path/ [4] => filename ) ) ) [key2] => Array ( Array ( [0] => key2 [1] => information_1 [2] => information_2 [3] => ./path/ [4] => filename ) ) Array ( [0] => key2 [1] => information_1 [2] => information_2 [3] => ./path/ [4] => filename ) ) ) )
At the end i want to sort the output by alphabetic order of the keys which i should achieve with sort() i guess?
Greetings Edited August 10, 2019 by Sandy_85 if ($template->load($maintemplatefile,$values)) { //load every php file in the plugin folder //Handle invalid page Requests } else { echo '404 File Not Found'; //exit; } //print page code echo $template->html(); } I call the above code it prints out the template file but it does not recursively replace the <TEMPLATE_LOADTEMPLATE_$1> that is in the file even though it properly parses both the $tag and $value variables going to the $this->replace($tag,$value); line. Any idea why this does not work? <?php class Template { var $code=''; function load($file,$values) { if (file_exists($file)) { //get template directory $dir=substr($file,0,strrpos($file,'/')) . '/'; //get template $this->code=file_get_contents($file); //check if any recurseve templates to add $tags=$this->tags(); //process all internal template tags $newValues=array_slice($values,1); foreach ($tags as $tag) { //handle inserting new template file if (substr($tag,0,13)=='LOADTEMPLATE_') { $file=substr($tag,13); if ($file[0]=='$') { $file=$values[(substr($file,1)-1)]; } $temp=new Template; $filename=$dir . $file . '.xhtml'; if ($temp->load($filename,$newValues)) { $value=$temp->html(); } else { $value='File Not Found'; } $this->replace($tag,$value); } } return true; } else { return false; } } function tags() { preg_match_all('/<TEMPLATE_[^<]+?>/', $this->code, $tags); $tags=$tags[0]; foreach ($tags as $key=>$value) { $tags[$key]=substr($value,10,-1); } return array_unique($tags); } function replace($tag,$value) { $this->code = ereg_replace('<TEMPLATE_' . $tag . '>',$value . '',$this->code); } function replaceSection($tag,$value) { $replace='~<TEMPLATE_' . $tag . '>[\s\S]*?</TEMPLATE_' . $tag . '>~'; $this->code = preg_replace($replace,$value . '',$this->code); } function compress() { $this->code = ereg_replace("\n",'',$this->code); $this->code = ereg_replace(" ",' ',$this->code); $this->code = ereg_replace("\r",'',$this->code); } function html() { //remove <TEMPLATE_*> & </TEMPLATE_*> tags then return html. return preg_replace('/(<\/?)TEMPLATE_[^<]+?>/','',$this->code); } } ?> All code listed is available for use under GNU public license. |