<?php
function sum($y) {
$y = $y + 5;
}
$x = 5;
sum($x);
echo $x;
?>
So I have this code. The questions are: What does it output? The answer: 5. How do I make it to output 10? The answer: sum(&$x).
The problem is that I don't understand why the answer to the first question is 5. When you make sum($x), shouldn't it replace the function with $x, so $x= 5+5=10? Why the answer is 5? I really don't understand. Someone explaind me something related to pointers and the adress, but I didn't understand. I never understood the concept of pointers, and I googled it and apparently there are no pointers in php, so I'm super confused. My friend said that a variable is formed of a value, and the memory adress of that value. Can someone explain me like I'm 5 years old why the answer is 5 and not 10? Please
Let's pretend $x is a piece of paper with 5 written on it.
function sum($y) {
$y = $y + 5;
}
Here $y is the value of what you have written. You add 5 to such value in your mind, but the note is left untouched.
function sum(&$y) {
$y = $y + 5;
}
With the reference operator (&$y), you pass the very paper to the function, and it overwrites what's written on it.
For primitive values like numbers, I wouldn't bother and always return the value you want:
function valuePlusFive($x) {
return $x + 5;
}
$x = 5;
$x = valuePlusFive($x);
This is not a very good explanation from theory point of view, but this should help you understand the concept:
when you declare function like this and then call it:
function ($argument) {...}
The argument you pass there is passed by value. This means that inside the scope of a function you will be working with a copy of an argument you passed. You can imagine that before the function is called the copy of argument has been made and inside the function you're working with the copy, while original remains untouched. Once the function is finished the copy is no more
However when you declare it like this:
function (&$argument) {...}
You are passing argument by reference, meaning that you are working directly with a variable you've passed. So in this case no copies are made, you took the argument from one place, put it inside the function and changed it.
In PHP, "The scope of a variable is the context within which it is defined." (according to the docs). So inside your function, $y (a copy of the value you passed in) is being operated on, but it is not returned by the function. So when the function ends, the value is no longer accessible outside the function.
If you want to pass the variable in by reference (similar to a pointer in C) then you can add a & like so:
function sum(&$y) {
$y = $y + 5;
}
Now when you call this code:
$x = 5;
sum($x);
echo $x;
it will output 10. Maybe a better way to do this would be to return a value from your function, and output that value:
function sum($y) {
return $y + 5;
}
$x = 5;
echo sum($x);
Related
This question already has answers here:
Accept function as parameter in PHP
(9 answers)
Closed 1 year ago.
I have two functions - the first function is complex and it takes around 15 seconds to load as it fetches data from third parties. The second one is a normal function. To illustrate this is what I have
<?php
class ComplexFunctions{
public function complexFunctionOne($x){
// do something
}
}
?>
<?php
function SimpleFunction($y, $z){
if($y){
// if $y is true use variable z
}else{
//if $y is false don't use variable z
}
return $a;
}
$cf = new ComplexFunctions();
$input_y = 'Y';
$input_y = 'Z';
$output = SimpleFunction($input_y, $cf->complexFunctionOne($input_y);
?>
I need to run the complex function $y only when the first variable $y is true. If it isn't I don't want to run it.
Unfortunately, regardless of whether $y is true or false - $cf->complexFunctionOne($input_y) is still loaded in any condition. This could take a lot of useless time for something that I do not want unless it's called specifically.
One solution could be to call $cf->complexFunctionOne($input_y) inside teh simple function, however, I have a hand full of complex functions e.g. complexFunctionTwo and I only want to use depending on the circumstance rather than have a Switch/Case statement.
well in order to pass a function, you can just:
$output = SimpleFunction($input_y, function() use ($input_y, $cf){
return $cf->complexFunctionOne($input_y);
};
so then you just need:
function SimpleFunction($y, $z){
if($y){
// if $y is true use variable z
$a = $z();
}else{
//if $y is false don't use variable z
$a = ...;
}
return $a;
}
In this way you will "lazy load" the result of $z
I saw this on W3Schools.
<?php
function myTest() {
static $x = 0;
echo $x;
$x++;
}
myTest();
myTest();
myTest();
?>
The output is 0, 1 and 2.
I wonder why it is not 0, 0 and 0.
Since each time the function is called, the variable x becomes 0 again.
I am a PHP beginner. Thanks!
If you declare a var static inside a function, the var keep it value over multiple calls. You could compare it to a static var inside of classes.
The code you post is a good example to see the actual effect. However I would only carefull use static inside functions, because most of the time, you need the static value somewhere else, reset the value, or something else which requires to much logic and makes the code really bad.
A good example would be a function, which returns a unique identifier for a given identifier. This could be simply achieved by using this code.
function unique_id($id) {
static $count = 0;
return $id . ($id++);
}
This example may clarify. static has a scope, thus is not a global variable. So I can define static $x outside the function and it will be defined there. Since static has scope, it wouldn't make any sense to keep on executing and resetting $x = 0. So, php will only acknowledge it the first time that line is called.
<?php
static $x = 1000;
function myTest() {
static $x = 0;
echo $x;
$x++;
}
myTest();
myTest();
myTest();
?>
I'm probably missing something simple here, but I have this function for finding the factors of a number.
function factor($n){
$factors_array = array();
for ($x = 1; $x <= sqrt(abs($n)); $x++)
{
if ($n % $x == 0)
{
$z = $n/$x;
array_push($factors_array, $x, $z);
}
}
return $factors_array;
}
I then want to do something like this...
factor(120);
print_r($factors_array);
This give me nothing though. Any ideas on where I'm going wrong?
You aren't assigning the variable to the return value of the function. As far as the PHP interpreter is concerned, $factors_array only exists if you're inside the factor() function. Try this:
$factors_array = factor(120);
print_r($factors_array);
Then you can reuse $factors_array in other areas of the code.
Have a look at this page for an explanation of why this happens.
just try this:
print_r(factor(120));
Because you can't access $factors_array; outside the function, this is called scope of variable, usually, variables that defined inside function are not available outside, also, variables that are defined outside function are not available inside function...
Read more Variable scope ΒΆ
I am looking to return an integer with a value of 50 or value of 25. Is this the correct way to do this or should I create a variable $temp1=50 and $temp2=25 and return the variable instead of just returning 50 and 25.
function somefunction($length)
{
if ($length > 50)
{
return 50;
} else {
return 25;
}
}
Sorry if duplicate, I looked.
It is perfectly fine the way you're doing it. Assigning a value to a variable to only return it makes no sense really.
As a better version to your alternative, for some more complicated cases, where you'd eventually need to return a variable, you could use only one variable instead of two as you suggested. Something more like
function somefunction($length)
{
$myVar = 0;
if ($length > 50) {
$myVar = 50;
}
else {
$myVar = 25;
}
return $myVar;
}
It is not necessary to assign a variable before. Just write
return ($length > 50 ? 50 : 25);
Assigning to a variable before returning is pointless. You're returning a value. 50 is a perfectly good value by itself, it does not need to be assigned to a variable before being returned.
In other words: you're doing it right already.
It depends on what you want to do :
if you just want to return a constant or if you want to parameter this constant.
in a case of a constant, for readability, you can name them :
define('RETURN_CONSTANT_SUP',50);
define('RETURN_CONSTANT_INF',25);
function somefunction($length)
{
if ($length > RETURN_CONSTANT_SUP)
{
return RETURN_CONSTANT_SUP;
} else {
return RETURN_CONSTANT_INF;
}
}
So you do it the right way, you can just use constant if, one day, you want to reuse those values.
I'd say the problem with your function is less the return but the input.
Anyway, your question is a bit theoretic. Because both returning a constant integer value as well as a variable would work. It wouldn't even make much of a difference. See the following example:
function somefunction($length)
{
return 25 + 25 * ($length > 50);
}
The problem with the code is that you have written it only for these specific values. So not using a variable can be a sign that the code is limited. But less because of the return and more because of the flow.
function integer_top_cut_drop($value, $top, $default)
{
$value = (int) $value;
$top = (int) $top;
$default = (int) $default;
if ($value > $top)
{
return $top;
}
return $default;
}
As this function shows, there are no numbers in there, but only variables. It pretty much does what your existing function does, but everything is variable. The numbers with their constant values have been removed and are now being passed as parameters:
function somefunction($length)
{
return integer_top_cut_drop($length, 50, 25);
}
So you normally never are concerned whether your return a variable, a constant, some other kind of expression or another functions return value.
More important is, that your code does what it has to do and you do it in a useful way.
That could mean in your code that your function already is totally fine.
But consider you enable yourself that you can re-use common parts, e.g. like shown here with a new function. That might be a bit over the top for your example, but just to show the picture.
A function can preserve the logic, so you don't need to write that part more than once. It also reduces the size of the other parts of the code using that function.
There is no correct way to do this.
This question is about style and preferences and you won't be able to get a definitive answer.
Just use what you like best (unless you are working in a team of course, in which case you should adapt the team's coding styleguide).
I am trying to set a reference in a function. But, I am not able to get this working.
Code I tried:
function set(&$x, &$y)
{
$x =& $y[2];
}
$y = array(
0,
1,
array('something')
);
$x = array('old_val');
print "1. inited, x is:\n";
print_r($x);
set($x, $y);
print "\n2. now, x is: ";
print_r($x);
Output:
1. inited, x is:
Array
(
[0] => old_val
)
2. now, x is: Array
(
[0] => old_val
)
I am expecting the value of $x to be same as $y[2]. Also, any further modification to $x should change $y[2]. (As in pointer assignment in C: x = &y[2]; )
What am I doing wrong? Any suggestions appreciated.
Edit:
actually, the function set() in the test code is a simplified one for my testing purpose. It is actually select_node(&$x, &$tree, $selector) : This will select a node from the tree which matches $selector and assigns it to $x.
References aren't pointers, and act slightly differently.
What's happening is that the $x variable inside the set() function is being bound to the same location as $y[2], but $x inside set() is not the same as $x outside of set(). They both point to the same location, but you have only updated the one inside of set(), which is no longer relevant once set() returns. There is no way to bind the $x in the calling scope, as it does not exist inside the function.
See: http://ca3.php.net/manual/en/language.references.arent.php
You may want to declare set() to return a reference:
function &set(&$x, &$y) {}
And call it like this:
$x =& set($x,$y);
See http://ca3.php.net/manual/en/language.references.return.php
There is nothing wrong here. The x in function set() is a local alias to the global variable x. In other words the global x and x in function set() point to the same value. After you do this:
$x =& $y[2];
Local x now points to the value of $y[2] but the global x still points to the old value. You need to read this page http://php.net/references