2


I was working on an API for ustream which returns the following array

Array
(
[results] => Array
    (
        [0] => Array
            (
                [id] => 33756327
                [userName] => sachintaware
                [title] => Mobile record
                [protected] => 
                [description] => Recorded on my Android phone.
                [createdAt] => 2013-06-03 03:29:38
                [rating] => 0.000
                [lengthInSecond] => 371.544
                [totalViews] => 5
                [codecIsForLiveHttp] => 
                [url] => http://www.ustream.tv/recorded/33756327
                [embedTag] => 
                [liveHttpUrl] => 
                [imageUrl] => Array
                    (
                        [small] => http://static-cdn2.ustream.tv/videopic/0/1/33/33756/33756327/1_14659377_33756327_120x90_b_1:2.jpg
                        [medium] => http://static-cdn2.ustream.tv/videopic/0/1/33/33756/33756327/1_14659377_33756327_320x240_b_1:2.jpg
                    )

                [sourceChannel] => Array
                    (
                        [id] => 14659377
                        [url] => http://www.ustream.tv/channel/14659377
                    )

            )

        [1] => Array
            (
                [id] => 33756481
                [userName] => sachintaware
                [title] => gobiggitest
                [protected] => 
                [description] => gobiggitest
                [createdAt] => 2013-06-03 03:37:49
                [rating] => 0.000
                [lengthInSecond] => 647.580
                [totalViews] => 11
                [codecIsForLiveHttp] => 
                [url] => http://www.ustream.tv/recorded/33756481
                [embedTag] => 
                [liveHttpUrl] => 
                [imageUrl] => Array
                    (
                        [small] => http://static-cdn2.ustream.tv/videopic/0/1/33/33756/33756481/1_14659377_33756481_120x90_b_1:3.jpg
                        [medium] => http://static-cdn2.ustream.tv/videopic/0/1/33/33756/33756481/1_14659377_33756481_320x240_b_1:3.jpg
                    )

                [sourceChannel] => Array
                    (
                        [id] => 14659377
                        [url] => http://www.ustream.tv/channel/14659377
                    )

            )

This is the function I used to go through the array as I want to fetch the [id] => 14659377 which is inside sourceChannel.But I am getting an empty value as a return value.What is the mistake I am making? can anyone please help me with it?

$getUsername = array();
function recursion($array) {
foreach ($array as $key => $value) {
      if($key==='sourceChannel'){
            $getId = $value['id'];
            //print_r($getId);
            return $getId;
          }
      if (is_array($value))
         recursion($value);
     }
}

$getUsername=recursion($resultsArray);
print_r($getUsername);
coderunner
  • 925
  • 1
  • 18
  • 33

4 Answers4

12

Your code is flawed because you need to change

recursion($value);

into

return recursion($value);

The return will take the answer back to the caller until the first caller is reached.

edit: The lesson here is that your function should ALWAYS return a value. So here is some more elaboration:

function recursion($array) {
    if (!is_array($array)) // check if what you're getting is an array!
        return null;
    foreach ($array as $key => $value) {
        if($key==='sourceChannel') {
            return $value['id'];
        }
        if (is_array($value)) {
            $result = recursion($value);
            if ($result !== null) {
                return $result;
            }
        }
    }
    return null; // this happens if all recursions are done and sourceChannel was not found
}
nl-x
  • 11,762
  • 7
  • 33
  • 61
  • @coderunner please try my re-edited code. And if fails, update your question with your current code. It should work now. – nl-x Jun 05 '13 at 07:31
  • This doesnt work because you're blindly returning the first recursion you try in the loop. You should only be returning if your recursion call actually returns a non-null value - otherwise we want to continue through the loop. See my answer for a complete fix. – jcsanyi Jun 05 '13 at 07:36
  • @jcsanyi thanks, overlooked that indeed. I updated my answer. – nl-x Jun 05 '13 at 07:46
  • 1
    I also missed 'return' syntax right before calling rec function again. Thanks. – Jeaf Gilbert Apr 02 '16 at 09:35
  • 1
    return recursion() worked for me like a charm. Thanks @nl-x – Alvin Chettiar Jan 04 '18 at 08:42
  • oh! you are a life saver. return worked like a charm! – Chayan C May 08 '23 at 11:57
2

You're not doing anything with the return from your recursion call. It's a bit more complex than simply returning it, because you only want to cascade out if we actually found anything.

Try this:

function recursion($array) {
    foreach ($array as $key => $value) {
        if($key==='sourceChannel') {
            return $value['id'];
        }
        if (is_array($value)) {
            $rc = recursion($value);
            if (!is_null($rc)) return $rc;
        }
    }
    return null;
}

First, I added return null; to the end of the function - if we didn't find anything, we return null.

Then, when I recurse, I check the return value... if it's non-null, it means we found something and we want to return it. If it is null, we don't want to return - we want to continue the loop instead.

jcsanyi
  • 8,133
  • 2
  • 29
  • 52
1

Try like this

foreach ($array['results'] as $key => $value) {
   if($key == "sourceChannel"){
        $getId = $value['id'];
        //print_r($getId);
        return $getId;
   }       
}
GautamD31
  • 28,552
  • 10
  • 64
  • 85
  • This answer might suit this case. But doesn't have recursion, and thus does not really answer the question. `Why doesn't this PHP recursive function return the value?` – nl-x Jun 05 '13 at 07:20
  • Why iterate over the array if you can also use `isset()`? And what happened to the recursive step? – Ja͢ck Jun 05 '13 at 07:23
  • Depends on what is to be expected. For now it would do. But then FDL's comment will even be better... `$array['results'][0]['sourceChannel']['id']` – nl-x Jun 05 '13 at 07:24
  • It doesn't work,I believe I will need to modify my function call like this... `$getUsername=recursion($resultsArray['results']);` right? but still I get an error for either index 'result' or foreach argument! where am I wrong? – coderunner Jun 05 '13 at 07:28
  • call like $getUsername=recursion($resultsArray); only – GautamD31 Jun 05 '13 at 07:30
  • `'sourceChannel'` is not a key in `$array['results']`, so this code will never return anything other than undefined. – Ja͢ck Jun 05 '13 at 07:42
  • Then what will be the 'sourceChannel'..?? – GautamD31 Jun 05 '13 at 08:35
1

You could use iterators to make your function a whole lot easier:

function findSourceChannel($array)
{
    foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($array)) as $key => $value) {
        if ($key == 'sourceChannel') {
            return $value['id'];
        }
    }
    return null;
}

That said, I'm not sure why you can't just do a search like this:

foreach ($array['results'] as $result) {
    if (isset($result['sourceChannel'])) {
        return $result['sourceChannel']['id'];
    }
}
return null;
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
  • Hey,thanks Jack are these classes inbuilt with the PHP version?Can I directly use them?Haven't tried them yet. – coderunner Jun 05 '13 at 07:25
  • yup Jack that search did the trick.Also,if `sourceChannel` is not a `key`(as you said in the above post) in the array how can I do it using the `RecursiveIteratorIterator` method? – coderunner Jun 05 '13 at 08:03
  • @coderunner In the meantime I've expanded my answer to include a method that doesn't even need recursion. Do check that out. – Ja͢ck Jun 05 '13 at 08:19
  • Yes, I mentioned in the previous post that it works and I just didn't think about it!! – coderunner Jun 05 '13 at 08:24