Jump to content

Can't use $input->urlSegment1 in a function. Is this my PHP weakling status showing?


alan
 Share

Recommended Posts

Summary

It seems I cannot use the code $input->urlSegment1 in a function.

Pretty please, can anyone spare a PHP lite-weight like me an explanation as to why this (seems) OK to do outside of a function but not in a function? Thanks.

Detail

If I visit URL example.com/page/my-url-segment/ with the following code:

if(isset($input->urlSegment1)) echo ":)"; else echo ":(";

then as I expect I see a smiley face as I do indeed have a urlSegment1. But if I replace the above code with this:

echo fDtest();

where fDtest() is:

function fDtest() {
    if(isset($input->urlSegment1)) echo ":)"; else echo ":(";
}

then I get a sad face.

Confused.

Link to comment
Share on other sites

THANKS Adrian! That solves it.

Is this something known to PHP gurus or something I have missed in the PW docs? For example looking in the API it talks about urlSegment but with no mention of wire.

I don't think I have ever used wire in my code before and I feel like I missed a whole chapter on how to use PW somehow :(

Does anyone know where I go to learn what wire is, how I use it, when I use it, why I need it in the way Adrian kindly pointed out?

Thank you clever people for any pointers.

Link to comment
Share on other sites

Slightly longer explanation is that it's a problem with scope; you might want to take a closer look at PHP manual entry about variable scope.

Essentially you need to use wire() (which is a function) instead of $input (which is an object and thus subject to same scope rules as variables) when you're in the context of a function. You could also pass the function a copy of (or reference to) whatever object or variable you want:

function fDtest($input) {
    if(isset($input->urlSegment1)) echo ":)"; else echo ":(";
}
echo fDtest($input);

.. but that's probably not what you want here. Anyway, hope this helps clear things out a bit  :)

Edit: removed reference sign from function call, that way of using references has been deprecated in PHP 5.3.0 and removed from 5.4.0.. and it wasn't even necessary step here, since in PHP 5 objects are by default passed by reference (kind of.)

Because of this you need to be very careful when making any changes to objects such as $input inside a function since it'll affect global scope too. To pass an object by value you'd need to use clone instead. Variables, on the other hand, need to be prefixed with reference sign "&" in function definition in order to pass them by reference -- by default they're passed by value..

Thanks to @Nik for pointing these out, my information was outdated!

Edited by teppo
  • Like 5
Link to comment
Share on other sites

Well it is all about variable scope. None of the PW variables (http://processwire.com/api/variables/) are available inside a php function. So you can use the wire function for any of those PW variables inside a function. If you're going to be using a variable more than once inside the function, it can be worth doing this at the top of the function:

$input = wire('input');
 

and for any other PW variables you might need access to.

  • Like 2
Link to comment
Share on other sites

Thanks VERY much teppo and adrian; I am relieved to say I actually understand the concept of scope (a bit) and so I totally get the distinction.

I had just never realized until now that the PW API stuff such as $input->urlSegment1 were not somehow 'god-mode' things that worked everywhere, now I know they are (sensibly now I think about it) limited by scope in a similar way to variables I can totally see that some other construct such as wire is needed to show I need to look 'outside' the function.

Brilliant! I feel I have learnt something subtle but significant thanks to you helpful fellows, thanks again! :D

  • Like 4
Link to comment
Share on other sites

Note: added some clarifications and corrections to my post above, I'm still stuck to some bad habits learned from PHP 4. Posting here to notify anyone who's following this thread (plain edit's don't seem to cause notifications or make the thread show up in list of new content..) :)

  • Like 2
Link to comment
Share on other sites

I had just never realized until now that the PW API stuff such as $input->urlSegment1 were not somehow 'god-mode' things that worked everywhere, now I know they are (sensibly now I think about it) limited by scope in a similar way to variables I can totally see that some other construct such as wire is needed to show I need to look 'outside' the function.

It's worth mentioning that wire('input') or wire('any API variable') would in fact work everywhere. So if you only needed to remember one way of accessing API variables, that one would be the most portable. 

  • Like 1
Link to comment
Share on other sites

It's worth mentioning that wire('input') or wire('any API variable') would in fact work everywhere. So if you only needed to remember one way of accessing API variables, that one would be the most portable.

I think the benefits of portability might make me switch to always using the wire( version since that would indeed allow me to move stuff in or out of functions without breaking or needing re-writing. This also explains why I've often seen code examples with wire( — thanks for the tip Ryan! :D

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...