Call a recursive function from another function in PHP - php

I have created a recursive function which returns the array value. So I am calling that function from another function. but it doesn't return any values. The function is given below,
public function sitemapAction() {
$sites = self::getNavigation();
foreach(self::recursiveSitemap($sites) as $url) {
...
...
}
}
public function recursiveSitemap($sites)
{
$result = array();
foreach ($sites as $site) {
$result[]= array($site['DFA']);
if (is_array($site['items'])) {
return recursiveSitemap($site['items']);
}
}
}
Please help me on this.

If you look carefully at your recursive method, you will see that it actually does not return anything at all:
public function recursiveSitemap($sites)
{
$result = array();
foreach ($sites as $site) {
$result[]= array($site['DFA']);
if (is_array($site['items'])) {
return recursiveSitemap($site['items']);
}
}
}
If your variable $site['items'] is an array you call your method again, going deeper, without doing anything with the returned value.
And if not?
It would seem you would need to add the result you get back from your recursive function call to your $result array and return that, but I don't know exactly what output you expect.
Apart from that you have a small typo, you need self::recursiveSitemap($site['items']) if you want to call the same method recursively.
A simple example:
public function recursiveSitemap($sites)
{
$result = array();
foreach ($sites as $site) {
if (is_array($site['items'])) {
// do something with the result you get back
$result[] = self::recursiveSitemap($site['items']);
} else {
// not an array, this is the result you need?
$result[]= array($site['DFA']);
}
}
// return your result
return $result;
}
Assuming that $result is the thing you want to get back...

Related

Recursion on subarrays with "child" key

I have array of arrays - tree structure of main menu.
I try to find in this tree one node with needed slug and return this node with all it's childs.
I write little recurcive function
<?php
$tree = '[{"id":1,"structure":1,"parent":0,"slug":"medicinskaya-ge","child":{"2":{"id":2,"structure":1.1,"parent":1,"slug":"dnk-diagnostika","child":{"3":{"id":3,"structure":"1.1.1","parent":2,"slug":"dnk-diagnostika","datafile":"ssz","template":"ssz"},"4":{"id":4,"structure":"1.1.2","parent":2,"slug":"dnk-diagnostika","child":{"5":{"id":5,"structure":"1.1.2.1","parent":4,"slug":"dnk-diagnostika"},"6":{"id":6,"structure":"1.1.2.2","parent":4,"slug":"testirovanie-ge"},"7":{"id":7,"structure":"1.1.2.3","parent":4,"slug":"dnk-diagnostika"}}},"8":{"id":8,"structure":"1.1.3","parent":2,"slug":"dnk-diagnostika"},"9":{"id":9,"structure":"1.1.4","parent":2,"slug":"texnologiya-kol"}}}}}]';
$tree = json_decode($tree, true);
function getSlugData(string $slug, array $data)
{
foreach ($data as $row) {
if ($row['slug'] == $slug) {
return $row;
}
if (isset($row['child'])) {
//return $this->getSlugData($slug, $row['child']);
}
}
return [];
}
$result = getSlugData('testirovanie-ge', $tree);
print_r($result);
But as a result I have an empty array. If I print_r($row) when $row['slug'] == $slug - It appears on screen.
if ($row['slug'] == $slug) {
exit(print_r($row));
return $row;
}
What's my mistake?
In programming, recursion is a useful and powerful mechanism that allows a function to call itself directly or indirectly, that is, a function is said to be recursive if it contains at least one explicit or implicit call to itself.
I modified your code a bit and got the solution below.
$tree = '[{"id":1,"structure":1,"parent":0,"slug":"medicinskaya-ge","child":{"2":{"id":2,"structure":1.1,"parent":1,"slug":"dnk-diagnostika","child":{"3":{"id":3,"structure":"1.1.1","parent":2,"slug":"dnk-diagnostika","datafile":"ssz","template":"ssz"},"4":{"id":4,"structure":"1.1.2","parent":2,"slug":"dnk-diagnostika","child":{"5":{"id":5,"structure":"1.1.2.1","parent":4,"slug":"dnk-diagnostika"},"6":{"id":6,"structure":"1.1.2.2","parent":4,"slug":"testirovanie-ge"},"7":{"id":7,"structure":"1.1.2.3","parent":4,"slug":"dnk-diagnostika"}}},"8":{"id":8,"structure":"1.1.3","parent":2,"slug":"dnk-diagnostika"},"9":{"id":9,"structure":"1.1.4","parent":2,"slug":"texnologiya-kol"}}}}}]';
$tree = json_decode($tree, true);
//print_r($tree);
//die();
function getSlugData(string $slug, array $data, string $key = 'slug')
{
$result = [];
foreach ($data as $row) {
// Checks if the key exists and is the desired value for that key in the array
if (isset($row[$key]) && $row[$key] === $slug) {
return $row;
}
// If it is an array, apply recursion by calling getSlugData again
if (is_array($row)) {
$result = getSlugData($slug, $row, $key);
if ($result !== []) {
return $result;
}
}
}
return $result;
}
print_r(getSlugData('testirovanie-ge', $tree));
print_r(getSlugData('texnologiya-kol', $tree));
print_r(getSlugData('nothing-here', $tree));
die();
In the recursive function, you must not break the loop early unless you find your slug match. If a non-slug-match has a child element, you must iterate it and potentially pass up a match in subsequent recursive calls.
Code: (Demo)
function getSlugData(string $slug, array $data): array
{
foreach ($data as $row) {
if ($row['slug'] === $slug) {
return $row;
}
if (isset($row['child'])) {
$deeper = getSlugData($slug, $row['child']);
if ($deeper) {
return $deeper;
}
}
}
return [];
}
P.s. you aren't calling a class method, so $this-> is inappropriate.

PHP Retrieve array values from foreach loop and pass individual values to function

I have a function which contains a foreach loop that loops through an array and brings back each value using $row['COLORS']. The goal is to pass the value into a function that is called. Here is my problem. I cannot use the 'return' to pass the value. Due to the foreach loop, I cannot use a return in order to keep the loop going. Below code works for 1 record only.
function __construct() {
parent::__construct();
$this->myColors = $this->getColors();
}
public function getColors() {
sql = $this->buildSQL();
$query = $this->db->query($sql)->result_array();
foreach ($query as $row) {
$theColor = $row['COLOR'];
return $theColor;
}
}
I need to do the same for each of the colors in the array, not just one value. I have tried passing the value to another function with a return but it doesn't return where I need it in the __construct.
...
foreach ($query as $row) {
$theColor = $row['COLOR'];
$this->returnColor($passColor);
}
public function returnColor($passColor) {
return $passColor;
}
I also tried a function with a switch statement (which is not a viable solution due to hundreds of values) but again the return does not work in this situation. Any help would be very much appreciated.

what's wrong with my php code with recursive method?

Here is my php code, the test method not giving wanted output, and the other weird thing is var_dump('a') print 3 times;
my wanted output is array('qtggccc','qtff23sdf');
public function main()
{
$serverIds = array('ff23sdf','ggccc');
$res = $this->test($serverIds);
var_dump($res);
}
public function test($serverIds,$imgArray = array())
{
if(count($serverIds) > 0){
$media_id = array_pop($serverIds);
$imgUrl= $this->hh($media_id);
array_push($imgArray,$imgUrl);
var_dump($serverIds);
var_dump($imgArray);
$this->test($serverIds,$imgArray);
}
var_dump('a');
return $imgArray;
}
public function hh($m)
{
return 'qt'.$m;
}
Try this:
class MyClass{
private $imgArray = array();
public function main(){
$serverIds = array('ff23sdf','ggccc');
$res = $this->test($serverIds);
print_r($this->imgArray);
}
public function test($serverIds){
if(count($serverIds) > 0){
$media_id = end($serverIds);
$imgUrl= $this->hh($media_id);
array_push($this->imgArray,$imgUrl);
//remove last element
array_pop($serverIds);
$this->test($serverIds);
}
return;
}
public function hh($m){
return 'qt'.$m;
}
}
$obj = new MyClass();
echo '<pre>';
$obj->main();
Why use recursion? You are using a complicated solution for a simple problem.
public function main()
{
$serverIds = array('ff23sdf','ggccc');
$res = array();
//These three lines replace an entire recursive function, making the code easier and saving a chunk of memory once you start using real arrays
foreach ($serverIds as $media_id){
array_unshift($res, $this->hh($media_id));
}
var_dump($res);
}
public function hh($m)
{
return 'qt'.$m;
}

PHP: Need help in writing a method that stores all GET variables in a array and returns it

So I am building a helper class that would store all get variables from a url, remove trailing spaces and return it so that other methods can use them.
The problem is that only the first value gets stored.
The url looks like:
https://pay.paymentgateway.com/index.php?name=xyz&amount=10.30&checksum=abcd
My code outputs:
Array
(
[name] => xyz
)
My code:
class helperboy
{
protected $cleanvariables = array();
public function store_get_variables($_GET)
{
foreach ($_GET as $key => $value)
{
return $this->cleanvalues[$key] = trim($value);
}
}
protected function display_variables()
{
echo "<pre>";
print_r($this->cleanvalues);
}
}
I know I am doing something silly and I would appreciate any help.
Also, how can I access specific variables like this in my other methods.:
$this->cleanvalues['name'];
$this->cleanvalues['amount'];
$this->cleanvalues['checksum'];
your return statement is the problem....
class helperboy
{
protected $cleanvariables = array();
public function store_get_variables($_GET)
{
foreach ($_GET as $key => $value)
{
$this->cleanvalues[$key] = trim($value);
}
return $this->cleanvalues;
}
protected function display_variables()
{
echo "<pre>";
print_r($this->cleanvalues);
}
}
Well, the problem is that...
public function store_get_variables($_GET)
{
foreach ($_GET as $key => $value)
{
return $this->cleanvalues[$key] = trim($value);
}
}
... the loop here will be executed just once. As soon as function hits return statement, it will abort this loop - and return immediately.
Yet I think there are some bigger problems here. First, I don't buy the idea of some omnipotent helper class that knows everything about everyone. If you intend to work with some cleaner request params, why don't just 'objectize' this instead:
class My_Http_Request
{
private $request;
protected function fillGetParams() {
$this->request['get'] = array_map('trim', $_GET);
}
public function getTrimmedParam($name) {
return $this->request['get'][$name];
}
public function __construct() {
$this->fillGetParams();
}
}
That's just an idea, not ready-made implementation (no checks for missing elements, no returning all params if 'getTrimmedParam' method is called without any arguments, etc.

how to travel through the array in php?

i am having one key list
for example
$key_list=array("list"=>array("task","duration"));
function array_key_fun($key_list,$test_input){
//(is_array($test_input)){
return array_map('myfunction',$test_input,$key_list);
//}
}
//$va=array_map("myfunction",$test_input);
//print_r(array_key_fun($key_list,$test_input));
function myfunction($arr)
{
if(is_array($arr))
{
$get_array= get_childs($arr);
return $get_array;
}
}
function get_childs($arr){
$newarr=array();
$newarr_en='';
foreach($arr as $key=>$value)
{
if(is_array($value)){
$newarr[$key]=get_childs($value);
}else{
if (in_array($key,$key_list)) //here im facing the problem with key_list
{
..............
}
else
{
...............
}
}
}
return $newarr;
}
Either pass in function or declare as global
function abc($a,$key_list){
OR
function abc($a){
global $key_list;
//rest of code
EDIT:
When you pass the array as parameter of function you have to pass the value in call as well
when you call this function this should be
//array should be declared before calling function
$key_list=array("list"=>array("task","duration"));
abc($a,$key_list); //pass this array
http://php.net/manual/en/function.array-walk.php
array_walk
try this
You have to bring the variable into scope, within your code you have ......... if you replace that with global $key_list this will allow the function to Read / Write to that stack.

Categories