I'm seeing some slightly odd behaviour, and i'm wondering if anyone feels like poking their nose in it with me...

Basic premise is this. I'm storing the string "$randicon" in a db field, and this string is retrieved and stored in the variable $items[1]->image. I'm trying to eval it, as $randicon is set as, well, a random image name earlier in the script. So far, this works fine for me:

$image = $items[1]->image; 
eval ("\$image = \"$image\";");
echo $image;

All of which is a little bit too much to place in-line 100 times or more in my site - so I decided to make it a function, for that extra bit of clarity:

function evalImage($image) {
        eval ("\$image = \"$image\";");
        print $image;
}

Then, of course, to call it as this:

evalImage($items[1]->image);

yet it doesn't work. The string "$randicon" gets passed to the function alright, but $image ends up being blank. I'm a little confused as to this, it seems like a fairly straight forward thing to do, yet it's not working. I've tried the ob_ series of functions aswell, all to no avail. Anyone seen this behaviour before or have some light to possibly shed on it?

    Any variables or arrays that are used in $image, will need to included in the global variables for the function. That might be the issue...

      i think you have to define $items[1]->image
      in the function, $image isn't assigned to something in the function... from what i can see.

        I'll be honest here, i come from the world of perl, and i'm clearly misunderstanding how php functions work if this is the case...

        When calling a function, you pass it a value, and that value should get taken as, well, $image, right? I mean, that's how it seems to be working. If i go "print $image;" in the function before calling the eval, it DOES print the string "$randicon", so I think i'm on the right path... it just seems to disappear into thin air once it gets eval()'d

          a function can't access outside variables if its not a global variable, globalizing a variable means it can be used throughout the script, and within functions..

          try this.

          function evalImage($image) { 
          global $image;
                  eval ("\$image = \"$image\";"); 
                  print $image; 
          }
          

            Are you using objects and classes? What does $items[1]->image pull from?

              nup, didn't work. it still prints nothing. if i go like this:

              function evalImage($image) {  
              print $image; eval ("\$image = \"$image\";");
              print "Hii!" . $image;
              }

              then it prints the string "$randiconHii!". The weird thing is that the eval works fine if i don't pass the string to a function. Odd indeed!

                Originally posted by sarah
                Are you using objects and classes? What does $items[1]->image pull from?

                it's built like this:

                for($i = 0; $i < 3; $i++)
                {
                        $row = mysql_fetch_object($res);
                        $items[$i] = new item;
                        $items[$i]->title = fixtxt($row->title);
                        $items[$i]->abstract = fixtxt($row->abstract);
                        $items[$i]->id = $row->id;
                        $items[$i]->image = $row->img_small;
                }
                

                so basically, it's the first 3 rows returned from a select. i'm using the [1] cause, well, that's just the first piece of code i tried using.

                  What happens when you add $items to the global variables? (Just curious...)

                  function evalImage($image) { 
                  global $items;
                          eval ("\$image = \"$image\";"); 
                          print $image; 
                  }
                  

                    OK... why that wasn't working didn't make sense to me either, but i think I got it...

                    ok, the problem isn't that $image isn't avialable globally... you passed a variable to a function, and the function received it and called it $image. No problem there. No need for global. But, then you want to use eval() to chage $image from the string '$randicon' to $image = $randicon, right?

                    Well, $randicon was never made available to the function, which is why it showed up blank.

                    you'd need to do something like this:

                    function evalImage($image) { 
                      global eval($image);
                      eval ("\$image = \"$image\";"); 
                      print $image; 
                    }
                    

                    That should make it so that if $image is the string '$randicon' or the string '$obscurevariablename' the variable will be made available to that function.

                    EDIT: Ok, that doesn't work either. I'm working on it though... It is an intesting problem.

                      Ok, this is how you do it... for sure... I actually tested this one:

                      $randicon = 'sucess!';
                      $image = '$randicon';
                      evalImage($image);
                      
                      function evalImage($image) {
                      	eval("GLOBAL $image;");
                      	eval ("\$image = \"$image\";"); 
                      	print "Test output: " . $image;
                      }
                      

                      make sense?

                        ah HAH! yes, that DOES work 🙂 i get it, i guess i'm just not familiar enough with scoping rules under php - as i said earlier, i'm a perl monkey by trade, and yeah... i guess i assumed $randicon was global, as perl would have globalised the variable when set in this kind of context... essentially, i just have another php include above all this code that has a line going:

                        $randicon = "icon" . rand(1, 23) . ".jpg";

                        it's not embedded in another subroutine or anything, really, it's just there - case in point, it was in scope if i called it from the other page... and the include order is certainly "right", ie. the $randicon variable is set before the function is defined (although i don't think that should matter...)

                        aaanyway, thank you all for your help, it was certainly an interesting problem for me, and i think now it's time to go find some good documentation on variable scope under php 🙂

                          Write a Reply...