PHP function return value, how to check - php

First a simple example:
function doReturnSomething()
{
// some logic
if ($resultFromLogic) {
return Default_Model_Something;
}
return false;
}
As you can see, this functions returns a model or false. Now, let's call this function from some place else:
$something = doReturnSomething();
No, I want to put a if-statement to check the variable $something. Let's say:
if (false !== $something) {}
or
if ($something instanceof Default_Model_Something) {}
or
...
Is there a "best practice" for this situation to do? Check for false or use instance of. And are there any consequences for that particular way?
Thank is advance!

Depending on what it is returning, you could just do this:
if(doReturnSomething()) {}
It will return true when an object is returned (Default_Model_Something) and return false when false is returned or a null-value. Just don't use this way when working with numbers because "0" will evaluate to false.

I think that from PHP 5.4 on there is a special notice error for threating a function return in logical statements.
Good pratice is to save result of a function to variable and then use it in any logical statement.

<?php function my($a, $b ,$c){
$total = $a + $b - $c; return $total; }
$myNumber = 0;
echo "Before the function, myNumber = ". $myNumber ."<br />";
$myNumber = my(3, 4, 1); // Store the result of mySum in $myNumber
echo "After the function, myNumber = " . $myNumber ."<br />";
?>

Related

is it possible to simplify isset?

I have a lot of functions with parameter that can be either bool or null. If we simplify my functions I have somethings like this:
funtion ($param) {
if ($param) {
//true
} else {
//false
}
}
However, when I call function(null); it obviously goes into else part of condition. So I have to do
funtion ($param) {
if (isset($param)) {
if ($param) {
//true
} else {
//false
}
}
}
for every similar if condition, which is sort of annoying.
So my question is this:
Is there a possibility to do this type of condition with this type of parameter faster and/or without additional function?
To only validate on true and false, use strict type comparison (===):
function check($param)
{
if ($param === true) {
// It's true. :)
} else if ($param === false) {
// It's false.. :o
}
}
This will ignore it if it is null.
Please read the bottom code for the most useful (but least explanative) function.
The below function solves your dilemma. If $param is true or false then the return gives back the boolean version of the $param (useful for such instances as if $param is a sting or an integer etc).
else, nothing is returned by the function which is defined as a NULL value.
example with type clarity texts:
<?php
//Enter your code here, enjoy!
$test[] = NULL;
$test[] = true;
$test[] = false;
$test[] = "string";
$test[] = 45;
function tester($param) {
if(!is_null($param)){
return (boolean)$param?"true":"false";
}
return "null";
}
foreach($test as $row){
print $row . " :: ". tester($row)."\n";
}
Exampled Output:
:: null 1 :: true :: false string :: true 45 ::
true
If you want to return the actual type rather than the textual representation this can be easily achieved with a slimmed down version:
Solution:
function ($param) {
if(!is_null($param)){
return (boolean)$param;
}
// not required but useful to keep for code clarity.
//return null;
}
Possible results:
1 (true) 0 (false) null

How to make complete eval result as a return value of function

I know, eval is called 'evil' and it's seems to be the worst way for everything, but...
How to return complete result of eval outside of function? It is just hypotetic question, I've found easy better solution for me.
In database (want execute):
$var1 = "yes";
$var2 = "no";
include('file.php');
function:
function executeScriptData($id) {
$data = anydbhandler("SELECT `data` FROM `data` WHERE ID = $id");
if(trim($data['data']) != "") {
echo $data['data']; // echo data from database
return eval($data['data']);
}
}
calling function:
executeScriptData(someID);
echo $var1; // nothing happened :(, no result
Make sure the evalling happens in the scope you want it to (now $var1 is only available within the method executeScriptData()).
Possible solution:
function executeScriptData($id) {
$data = dbhandler("SELECT `data` FROM `data` WHERE ID = $id");
if(trim($data['data']) != "") {
return $data['data'];
}
}
$data = executeScriptData(SOMEID);
eval($data);
echo $var1;
This is impossible via return value as the docs are telling you:
http://php.net/manual/en/function.eval.php
Returnvalues:
eval() returns NULL unless return is called in the evaluated code, in which case the value passed to return is returned. If there is a parse error in the evaluated code, eval() returns FALSE and execution of the following code continues normally. It is not possible to catch a parse error in eval() using set_error_handler().
The return you are using there is in a subscope of eval, in an extra function. This scope cannot make your evaluation end. Otherwise eval() would not be able to define functions within its contents because every occurence of "return" would screw the code execution passed to eval().
All you can do is make a var global within your eval'ed code and overwrite it in context.
$a = true;
$myVar = "abc";
eval('global $a; global $myVar; if($a == true) { $myVar = "def"; } ');
echo $myVar;

Calling a PHP function by reference behaving unexpectedly

Iwonder why the out put is 0(zero) for below code snippet? Can anyone please clarify why below code output is zero.
<?php
function a($number)
{
return (b($number) * $number);
}
function b(&$number)
{
++$number;
}
echo a(5); // output 0(zero) ?
?>
You never return any value from the function, and you're trying to echo the return value.
function b(&$number)
{
return ++$number;
}
Note that this is a silly example for a function that takes its parameter by reference, since you don't have a reference to the original value 5. Something like this would be more appropriate:
function b( &$number) {
++$number;
}
$num = 5;
b( $num);
echo $num; // Prints 6
The function name is b, but you are calling a...
Also, you are echoing a function, that doesn't return a value. This means you are echoing a non-initialize variable.
You must either return a value:
return ++$number;
or echo the variable directly:
$number = 5;
b($number);
echo $number;

What do PHP closures return in IF statements?

My goal is to put some complex logic in an if() statement. Let's say I have an array of values and I'm going to execute a bit of code if everything in my array is nonzero. Normally, I could say, $valid = true, foreach my array, and set $valid = false when a zero is found. Then I'd run my code if ($valid). Alternatively, I could put my loop into a function and put the function intop my if().
But I'm lazy, so I'd rather not muck about with a bunch of "valid" flags, and I'd rather not write a whole new function that's only being used in one place.
So let's say I have this:
if ($q = function() { return 'foo'; }) {
echo $q;
}
else {
echo 'false';
}
I was expecting that the if gets 'foo', which evaluates to true. My closure is committed to $q and the statement executes. $q returns string foo, and 'foo' is printed.
Instead, I get the error Object of class Closure could not be converted to string.
So let's try this instead:
if (function() { return false; }) {
echo 'foo';
}
else {
echo 'true';
}
I was expecting that my function would return false and 'true' would be printed. Instead, 'foo' is printed.
What is wrong about the way that I'm going about this? It seems like it's saying, "Yep, that sure is a function!" instead of "No, because the function evaluated to false." Is there a way to do what I'm trying to do?
function() { return false; } creates an object of type Closure, similar to new with other class-types, compare the following code:
$func = function() { return false; };
$func now is an object. Each object returns true in an if clause. So
if ($func)
{
# true
} else {
# will never go here.
}
You might want to do this instead:
if ($func())
{
# true
} else {
# false
}
which will invoke the Closure object $func and give it's return value.
Both of those evaluate to true.
You need to make the function execute to use it in the if statement.
Try this:
$q = function() { return false; };
if ($q()) { //should not go here.
echo $q();
}
else {
echo 'false';
}
Demo: http://codepad.viper-7.com/Osym1s
PHP's closures are implemented as a hack - objects of type Closure. Your code is actually instantiating an object of this class, and assigning it to $q. In PHP, the result of assignment is the value being assigned, so in effect you code boils down to
if (new Closure()) { ... }
You're not executing the closure when you call echo, thus it's trying to print out the closure, not the result of the closure:
echo $q();
You are creating an anonymous function, but never executing it. When you test $q = function() { return 'foo'; }, what you're saying is "Assign a reference to this anonymous function to $q, and pass this test if $q is not null" (isn't PHP fun?)
You need to invoke the closure and assign its result to $q before testing and echoing $q.

What does & before the function name signify?

What does the & before the function name signify?
Does that mean that the $result is returned by reference rather than by value?
If yes then is it correct? As I remember you cannot return a reference to a local variable as it vanishes once the function exits.
function &query($sql) {
// ...
$result = mysql_query($sql);
return $result;
}
Also where does such a syntax get used in practice ?
Does that mean that the $result is returned by reference rather than by value?
Yes.
Also where does such a syntax get used in practice ?
This is more prevalent in PHP 4 scripts where objects were passed around by value by default.
To answer the second part of your question, here a place there I had to use it: Magic getters!
class FooBar {
private $properties = array();
public function &__get($name) {
return $this->properties[$name];
}
public function __set($name, $value) {
$this->properties[$name] = $value;
}
}
If I hadn't used & there, this wouldn't be possible:
$foobar = new FooBar;
$foobar->subArray = array();
$foobar->subArray['FooBar'] = 'Hallo World!';
Instead PHP would thrown an error saying something like 'cannot indirectly modify overloaded property'.
Okay, this is probably only a hack to get round some maldesign in PHP, but it's still useful.
But honestly, I can't think right now of another example. But I bet there are some rare use cases...
Does that mean that the $result is returned by reference rather than by value?
No. The difference is that it can be returned by reference. For instance:
<?php
function &a(&$c) {
return $c;
}
$c = 1;
$d = a($c);
$d++;
echo $c; //echoes 1, not 2!
To return by reference you'd have to do:
<?php
function &a(&$c) {
return $c;
}
$c = 1;
$d = &a($c);
$d++;
echo $c; //echoes 2
Also where does such a syntax get used in practice ?
In practice, you use whenever you want the caller of your function to manipulate data that is owned by the callee without telling him. This is rarely used because it's a violation of encapsulation – you could set the returned reference to any value you want; the callee won't be able to validate it.
nikic gives a great example of when this is used in practice.
<?php
// You may have wondered how a PHP function defined as below behaves:
function &config_byref()
{
static $var = "hello";
return $var;
}
// the value we get is "hello"
$byref_initial = config_byref();
// let's change the value
$byref_initial = "world";
// Let's get the value again and see
echo "Byref, new value: " . config_byref() . "\n"; // We still get "hello"
// However, let’s make a small change:
// We’ve added an ampersand to the function call as well. In this case, the function returns "world", which is the new value.
// the value we get is "hello"
$byref_initial = &config_byref();
// let's change the value
$byref_initial = "world";
// Let's get the value again and see
echo "Byref, new value: " . config_byref() . "\n"; // We now get "world"
// If you define the function without the ampersand, like follows:
// function config_byref()
// {
// static $var = "hello";
// return $var;
// }
// Then both the test cases that we had previously would return "hello", regardless of whether you put ampersand in the function call or not.

Categories