PHP - Recursion In Php
Hi there,
I don't know if this is the correct part of the forum but I am wanting to figure out something about recursion, kind of questioning someone elses code. It's just a general rule though so there's no real need to display it I don't think. However when I say I want to get a function to call another function, would I need to declare (write) the 2nd function within the function that called it? I just am questioning what I saw in another book whereby what I create does not work on my own basis but does when someone else shows an example in a book, where the author created a function that called a function that was written within another, is this legal syntax though is my main question? Kind of looked somewhat like this (very basic and no actual commands or instructions here): Code: [Select] <?php function myfunction() { // if whatever condition is true, call the second function just below me: function mysecondfunction() { } } Does that make any sense to you? Or would I just go off the book I am reading now where the 2 of them are completely seperated and the first function calls the 2nd, but not actually putting a function within another? Any advice is much helpful, Jez. Similar TutorialsThis topic has been moved to Miscellaneous. http://www.phpfreaks.com/forums/index.php?topic=349780.0 the function keeps returning 1. if i echo $i within the function then it counts up to six. the function should return 6, because there are 6 results from the mysql_query, so $i iterates upto 6. please any help solving this? Code: [Select] $i=0; $thewidth = $database->width($theid, $i); echo $thewidth; Code: [Select] function width($theid,$i) { $get = mysql_query("SELECT * FROM block WHERE sid='$theid'",$this->connect); $i++; while($row = mysql_fetch_assoc($get)) { $number = $row['id']; $this->width($number, $i); return $i; } } Hi, I wrote a piece of code for doing a recursive printing of all the leaf nodes. But it is not moving beyond one or two levels. Here is the code: $root = array( "paa" => array ( "adi1" => array ( "cir1" => array ( "aka", "ra", "vinodh","dkido" ), "cir2" => array ( "muta", "la" ), "cir3" => array ( "ezut", "telAm" ), "cir4" => array ( "ati" ) ), "adi2" => array ( "cir1" => array ( "paka", "vaV" ), "cir2" => array ( "mutaR", "RE" ), "cir3" => array ( "ula", "ku" ) ) ) ); function traverse($ar) { foreach($ar as $key=>$value) { echo "inside loop of ".$key."<br/>"; if(is_array($value)) { return traverse($value); } else { echo $key."==>".$value."<br/>"; } } } traverse($root); The output I get is: inside loop of paa inside loop of adi1 inside loop of cir1 inside loop of 0 0==>aka inside loop of 1 1==>ra inside loop of 2 2==>vinodh inside loop of 3 3==>dkido It does not seem to visit the other nodes. Anything I missed here ? V I am trying to work through an array of people links and return a certain person based on some comparisons. This is a multidimensional array with some levels having more links than others so you could have it would look more like a tree structure. I have a function Code: [Select] public function handlelinkL1Links($linkLinksArray) { foreach($linkLinksArray as $key=>$value) { if(array_search($key,$this->linkProcessed)===false && $this->compareKey($key)==true) { $linkToAdd = $key; } $this->handlelinkL1Links($value); } return $linkToAdd; } No matter how I have defined linkToAdd it is always null. How can I do this without it being global? Code: [Select] function width2($noid) { $getwidth = mysql_query("SELECT * FROM block WHERE sid='$theid'",$this->connect); while($row1 = mysql_fetch_assoc($getwidth)) { $this->width2($noid); } } how do i count how many times the function loops? It's not usual I ask questions on here - I usually help rather than be helped but alas, this is really confusing ! Short Story (You can skip this to "Your Mission") Without going into unnecessary detail i'll try to explain what i'm trying to do; Take an array (example provided...) Array( // These must be here, they are initially read by the template parser to get a starting point. "data"=>Array( "template"=>"main", // Template to start from (base template) "content"=>"%custom_topmenu% <Br/>Table<Br/> %bigtablecustom1%", // replace %content% tag,Shows 2 Examples, A Custom Menu, and Main Table with Smaller Tables inside ), // Below is numerically indexed arrays of content that will replace tags in the above "content" item 0=>Array( "data"=>Array( "rkey"=>"%bigtablecustom1%", // MUST have this item "template"=>"bigtable_single", // MUST have this item 0=>Array( "%title%"=>"Some Table Heading", "%footer%"=>"Some Table Footer Message (author?)", "%content%"=>"Some Content for the table with another rkey: %smalltablecustom1% --- %smalltablecustom2%", "%title_note%"=>"Some Time and Date" ) ), 0=>Array( "data"=>Array( "rkey"=>"%smalltablecustom1%", "template"=>"smalltable_single", 0=>Array( "%title%"=>"Small Title", "%content%"=>"Some Small Content or Note" ) ) ), 1=>Array( "data"=>Array( "rkey"=>"%smalltablecustom2%", "template"=>"smalltable_single", 0=>Array( "%title%"=>"Small Title 2", "%content%"=>"Some Small Content or Note" ) ) ) ) 1=>Array( // The menu is dynamically created by the module using it's inherited protected methods. "data"=>Array( "rkey"=>"%custom_topmenu%", "template"=>"custom_topmenu", 0=>Array( "%item1_name%"=>"Sub-Link 1", "%item1_link%"=>"#", "%item2_name%"=>"Sub-Link 2", "%item2_link%"=>"#", "%item3_name%"=>"Sub-Link 3", "%item3_link%"=>"#", "%item4_name%"=>"Sub-Link 4", "%item4_link%"=>"#" ) ) ) ) Turn this array into a single document, basically collpase all items with their children in the parent code. The Problem (You can skip this to "Your Mission") Now to make it easier and to (try) to prevent cross-tag contamination (so templates dont replace content that is supposed to be there from other template files...) I have wrote a recursion function that fills out all the content and removes the content sub-array from the data arrays (half the job). So now I have a multi-dimensional array that needs collapsing into a single document (variable), I am getting confused with how to go through this array (below - not above) so that all the template items are "inserted" inside their parent array items. The Function I made // Recursive, goes through an array and converts any "data" into actual templates. (Puts the content into a template) private function parse_template_data_array($array){ // First let's count how many items are in the array that was passed to us $item_count = count($array); // This should never happen, each array should have at least a "data" array inside. if($item_count < 1){ // Template Parser Fatal Object Syntax Error exit("FATAL PARSER ERROR1"); // If there is only one item, we don't need to recurse (There are no "child" elements) and so we skip the recursive section. }else if($item_count == 1){ // No items to parse, move on // So there are some child elements we must recurse through. }else{ // So this loops each "Child" element and passes that array to this function (recurse), Once it's finished it saves the array (result). for($i=0;$i<($item_count-1);$i++){ // -1 from the count, 1 to get rid of the data array. $array[$i] = $this->parse_template_data_array($array[$i]); } } // This part does the initial "template expansion", it finds the template needed for this item and saves it with the content to this item. // So we count how many data items we have $dcount = count($array['data']); // Count Data Items (minimum of 2 - Each data array must have "rkey" and "template") // If there isn't at least two items then someone made a booboo. if($dcount < 2){ // Template Parser Fatal Object Syntax Error exit("FATAL PARSER ERROR2"); // Otherwise let's sort this content out (We don't check if we only have the 2 minimum items since templates might not have Tags to replace). }else{ // Load Template file using the "template" item in the data array. $template = $this->get_file($array['data']['template']); // Count the amount of data items (content) to replace tags inside the loaded template (If there is no content sub-array then put to 0 to skip the below part). $dstrcount = (isset($array['data'][0]))? count($array['data'][0]) : 0; // No template content, maybe no tags, just give the template content back. if($dstrcount < 1){ // No items to parse // We have some content to replace. }else{ // We need the keys of the content sub-array so we can use (a neat feature of) the str_replace function. $akeys = array_keys($array['data'][0]); $template = str_replace($akeys ,$array['data'][0],$template); } // Save the result into this array item so we can pass the whole item back (This is also what happens when it recurses above) $array['data']['content'] = $template; } // Return the result array. return $array; } The Array returned by the above function Array ( [data] => Array ( [rkey] => %cdb_res_tpl_blk% [template] => main [content] => <html><head></head><body>%custom_topmenu%<br />%bigtablecustom1%</body></html> ) [0] => Array ( [data] => Array ( [rkey] => %bigtablecustom1% [template] => bigtable_single [content] => "Some Table Heading"=>"Some Table Heading", "Some Table Footer Message (author?)"=>"Some Table Footer Message (author?)", "Some Content for the table with another rkey: %smalltablecustom1% --- %smalltablecustom2%"=>"Some Content for the table with another rkey: %smalltablecustom1% --- %smalltablecustom2%", "Some Time and Date"=>"Some Time and Date" ) [0] => Array ( [data] => Array ( [rkey] => %smalltablecustom1% [template] => smalltable_single [content] => "Small Title"=>"Small Title", "Some Small Content or Note"=>"Some Small Content or Note" ) ) [1] => Array ( [data] => Array ( [rkey] => %smalltablecustom2% [template] => smalltable_single [content] => "Small Title 2"=>"Small Title", "Some Small Content or Note"=>"Some Small Content or Note" ) ) ) [1] => Array ( [data] => Array ( [rkey] => %custom_topmenu% [template] => custom_topmenu [content] => "Sub-Link 1"=>"Sub-Link 1", "#"=>"#", "Sub-Link 2"=>"Sub-Link 2", "#"=>"#", "Sub-Link 3"=>"Sub-Link 3", "#"=>"#", "Sub-Link 4"=>"Sub-Link 4", "#"=>"#" ) ) ) Your mission (Should you choose to accept ofc ), is to take the above array and turn it into a single html variable, with all the child elements inside their parent templates by replacing the tags in the array. All the data required is in the array, all that is needed is to "collapse" the array. Things to bear in mind: %cdb_res_tpl_blk% - This is in the original template file, so the result of a successfull collapse will replace this tag with the result. Dont worry about this one [rkey] - This is the "Tag" to replace in the "parent" content. [template] - This is the template file. [content] - This is the content that needs to go inside the parent item. Expected Result <html><head></head><body>"Sub-Link 1"=>"Sub-Link 1", "#"=>"#", "Sub-Link 2"=>"Sub-Link 2", "#"=>"#", "Sub-Link 3"=>"Sub-Link 3", "#"=>"#", "Sub-Link 4"=>"Sub-Link 4", "#"=>"#"<br />"Some Table Heading"=>"Some Table Heading", "Some Table Footer Message (author?)"=>"Some Table Footer Message (author?)", "Some Content for the table with another rkey: "Small Title"=>"Small Title","Some Small Content or Note"=>"Some Small Content or Note" --- "Small Title 2"=>"Small Title","Some Small Content or Note"=>"Some Small Content or Note""=>"Some Content for the table with another rkey: %smalltablecustom1% --- %smalltablecustom2%", "Some Time and Date"=>"Some Time and Date"</body></html> I will be working on this myself and if I find a solution I will post here. It is just that the way I code is I put my idea in my head, then try to code it in my head categorically, but when I think I find a solution it seems there is a bug, such as it will only collpase the main element, the bigtable, and the first small table, it wont do the other small table and not the menu either so basically it doesnt recurse items in the same array, only those underneath it. I'm so close but yet...so far... THANK YOU for ANY light you can shed on this situation it's been bugging me for a few days now (admittely have not coded since my first attempt - so tired.) My Code I won't provide the code I've done for it now since it just flat-out doesn't work, I've lost the code that I mentioned earlier that was bugged I modified and to be perfectly honest can't be bothered to reproduce it (it won't get me anywhere). Hello all, I'm trying to change the way the output look like from Recursion instead of it looking like this and make it look like this here is my code Code: [Select] <?php $user = $_GET['id']; echo '<hr>'; function display_mptt($user) { global $db; $id = $_GET['id']; // retrieve the left and right value of the $root node $sql2 = "SELECT * from mptt where id= ".$id.""; $result2 = mysql_query($sql2 ,$db); if(!$row2 = mysql_fetch_array($result2)) echo mysql_error(); echo '<h1>Your Tree</h1>'; // start with an empty $right stack $right = array(); // now, retrieve all descendants of the $root node $sql = "SELECT * from mptt WHERE `left` BETWEEN ".$row2['left']." AND ".$row2['right']." ORDER BY 'left' ASC"; $result = mysql_query($sql ,$db); // display each row while ($row = mysql_fetch_array($result)) { // only check stack if there is one if (count($right)>0) { // check if we should remove a node from the stack while ($right[count($right)-1]<$row['right']) { array_pop($right); } } // display indented node title // add this node to the stack $right[] = $row['right']; } echo str_repeat(' ',count($right)).$row['title']."<br>"; } display_mptt(1); ?> |