tags:

views:

305

answers:

7

In other words, can fn() know that it is being used as $var = fn(); rather than as fn();?

A use case would be to echo the return value in the latter case but to return it in the former.

Can this be done without passing a parameter to the function to declare which way it is being used?

A: 

No, there is no way to find it out. The unique thing you could do, is to grab the call stack (http://it2.php.net/debug_backtrace) and inspect it.

andy.gurin
Got a code example?
eyelidlessness
That's a pretty bad thing to do, unless it's for debugging.
troelskn
Why? I've used it for an error handler for example
andy.gurin
Because it's a very magic and non-standard way to change the behaviour of a function. Besides, mocking with a stacktrace in production code, is asking for trouble. An errorhandler would qualify as "for debugging", in my mind.
troelskn
A: 

No, it can't.

Konrad Rudolph
A: 

It can't be easily done but, so what if you just passed an extra boolean variable to the function? That way, the end of the function would look like:

if (namespace) {
    return $output;
} else {
    echo $output;
}

Seems a pretty simple workaround.

Stephen
I specified in the question: "Can this be done without passing a parameter to the function to declare which way it is being used?"
eyelidlessness
Scanned the question quick and didn't see that. Edited to reflect.
Stephen
The downside of passing a parameter is that it's more code, it's code that has to change everywhere it's used in order to change parameter length or order. More than that, I asked the question because I genuinely want to know more about PHP language/syntax features.
eyelidlessness
When you put it like that, it's something I'd like the answer to as well. I've always looked at that solution as the time-saving solution and, you're right, after a while, it starts to look like a scotch tape solution. If there's a better way, I'd love to hear about it.
Stephen
+3  A: 

No, and it shouldn't. It's a pretty basic premise of the language that functions are unaware of the context in which they are used. This allows you to decompose your application, because each part (function) is completely isolated from its surroundings.

That said, what you can do about this particular use-case, is to tturn on output buffering. By default echo will send data to stdout, but you can set a buffer, which will capture the output into a variable instead. For example:

function foo() {
  echo "Hello World";
}
foo(); // will output "Hello World"
ob_start();
foo();
$foo = ob_get_clean(); // will assign the string "Hello World" into the variable $foo

In addition to that, it is generally considered bad style to have functions output directly. You should generally return a string and leave it for the top level of your script to output. Ideally there should be just one single echo statement in your entire application.

troelskn
+6  A: 

Many PHP functions do this by passing a boolean value called $return which returns the value if $return is true, or prints the value if $return is false. A couple of examples are print_r() and highlight_file().

So your function would look like this:

function fn($return=false) {
    if ($return) {
        return 'blah';
    } else {
        echo 'blah';
    }
}

Any other way will not be good programming style.

yjerem
A: 

This is a response to troelskn. I know this isn't really the preferred use of SO, but I really want to find out more and I have more to say than can fit in short comments.

It's a pretty basic premise of the language that functions are unaware of the context in which they are used.

Really? Is this something the PHP language developers have specified, or are you inferring this from the fact that it can't be done?

This allows you to decompose your application, because each part (function) is completely isolated from its surroundings.

Isn't this why problems occur when backwards-incompatible changes are made to the language? If you can just up and change the behavior of any function, wouldn't any other function that depends on it break? Wouldn't having more insight into the context be a tool to help avoid that?

In addition to that, it is generally considered bad style to have functions output directly.

Considered by whom?

Ideally there should be just one single echo statement in your entire application.

Er. That's severely limiting. In order to achieve this, it requires having functionality that isn't built into the language and can be buggy as implemented, like a templating abstraction. Why is <someTag><?php echo sanitize($var); ?></someTag> inferior to echo someTemplateFunction($someHugeCompiledTemplate);?

Besides the fact that the latter has more overhead and room for bugs, doesn't it also make it harder to isolate problems (thus negating the assertion that "each part (function) is completely isolated from its surroundings")?

eyelidlessness
Downvoting instead of answering, thanks! 9_9
eyelidlessness
While I'd like to, it's equally hard for me to answer your questions in 300 characters. How about you post the question on a public forum, and I'll try to reply to you there?
troelskn
For example on Sitepoint: http://www.sitepoint.com/forums/forumdisplay.php?f=147
troelskn
I think I agree *sort of* with what troelskn. I think he is trying to say the front controller of your web app should echo a response only, after dealing with headers and all other PHP handling. However, this isn't to say don't use echo... use it in templates, and capture the output with output buffering.
alex
+2  A: 

Just think about how the interpreter executes this statement:

$var = fn();

The interpreter evaluates operands right-to-left with the assignment operator, so first it will evaluate the expression on the right hand side (fn() in this case) and will then assign the result to $var. Every expression returns a value, and it's your choice of what to do with this value.

yjerem