Could some one please explain to me what the difference in the following is:
$var = 'something';
function myFunc(){
global $var;
// do something
}
and (note: the reference sign &)
$var = 'something';
function myFunc(&$var){
// do something
}
I can't understand the difference between these two methods.
Update
Hmmm... I think i'm getting alittle confused here :)
$var = 1;
$var2 = 2;
function myFunction(){
global $var, $var2;
$var = $var + $var2;
}
// echo $var would return 3 here.
$var = 1;
$var2 = 2;
function myFunction(&$a, &$b){
$a = $a + $b;
}
// echo $var would return 3 here aswell.
I understand those part already, But what i don't understand is the difference between these two approaches, am i wrong to assume that these two approaches are technically the same thing, with different concept of how they are wrote by the coder and also how they are handled by PHP?
If i'm wrong to assume this, then it would really help if you could provide better examples, maybe something that can be accomplished using only one of the above approaches?
ok, i noticed one difference while writing This Update, which is that when doing references i can chose new variable names while keeping the pointer to the variable in the functions scope.
In the second code block, the external $var and the internal $var are the same element. On the other hand, the third code block behaves a lot more like the first -- but you can access and modify the variable from the sending function; in the first code block, any edits you make to the variable internally are not available outside of the scope of the function.
EDIT to match the edits to the question.
The & means we are passing the variable by reference. The best way to describe it is by example.
function test2(&$var) { $var = 2; }
function test() {
$abc = 1;
test2($abc);
echo $abc;
}
test();
This code will print a 2 to the screen.
$var = 0;
function test()
{
global $var;
$var = 1;
}
test();
echo $var;
This will print 1;
In the first example, the local $var variable inside myFunc() will be assigned by reference to the variable with the same name that exists in the global scope (accessible through the superglobal $GLOBALS). PHP translates that to something like:
$var = 'something';
$GLOBALS['var'] = &$var;
function myFunc(){
$var = &$GLOBALS['var'];
// do something
}
In the second example, you pass the variable explicitly to the function, thus it is not taken from the global scope.
$var = 'something';
$GLOBALS['var'] = &$var;
function myFunc(&$var){
// do something
}
myFunc($var);
Both examples will reference the exact same variable, but using different mechanisms.
There is no technical difference at all between your two examples; they will always behave in an identical manner.
That leaves us looking for other types of differences, and there is a pretty significant code quality difference here: In the first version, looking at the call site will not tell you that the function depends on the global. In the second one it will (it's being passed in as a parameter). So the second form is, in my book at least, superior.
In addition, another difference (although one that does not apply to this example) is that the first form can only be used if your variable is in the global scope to begin with; the second will work everywhere.
You should also take into account that both these methods have an in/out argument. Normally you would not be writing code like this if it were just one argument (since you can return the out value instead) so it's interesting to consider the case where more than one arguments are being given. This is a pretty rare, and it can be argued that it's better to just return an array with multiple values rather than take multiple arguments by reference to make the code even easier to follow.
So in conclusion:
They do the same thing
If you are going to use one of them, prefer the second form (clearer, more flexible)
Consider using none of them and doing things otherwise if it doesn't require writing a substantial amount of additional code
One passes by value and one passes by reference:
By value:
$var = 'something';
function myFunc($var){
$var = 'hello';
}
echo $var; //something
By reference:
$var = 'something';
function myFunc(&$var){
$var = 'hello';
}
echo $var; //hello
For more information, the PHP manual has a page on passing by reference: http://php.net/manual/en/language.references.pass.php
In the case of globals, you are essentially pulling a variable from the global scope and using it inside of the function. It's like implicitly passing by reference.
This page, in particular the global section explains: http://us.php.net/manual/en/language.variables.scope.php
Please note that globals should typically be avoided. The short version of why is because they make knowing the state of a program difficult, and later changes can cause unexpected side effects.
Related
Is it considered wrong to pass a variable to a function where the variable passed has the same name as the variable in the function itself? I never see anyone do this, but wondered if there was a reason why (other than readability). Example:
$variable = "value";
function myFunction($variable) {
return $variable;
}
No there is not problem with doing this except some naming confusion. Because,
$variable = "value"; // this declaration belong to a global scope
// but $variable passing through as argument, makes it scope within that function declaration only
function myFunction($variable) {
return $variable;
}
You might have expect that if you call the function like myFunction() i.e. without any parameter, it will return you "value", but absolutely not, cause $variable passed as argument is not the global one.
But if you try to use the global $variable within the myFunction, then it will cause some conflict, that is why no one do this.
Aside from making variables a bit confusing to track, there is nothing wrong with this. They exist in different scopes.
It is up to you but vice versa, if you want to pass intentionally a variable into a function.. then you have to use this:
$variable = "value";
function myFunction($variable) {
global $variable;
return $variable;
}
echo myFunction('another value');
One more point. When creating functions you may set a default value for your params to avoid errors:
function myFunction($variable="default value") {
return $variable;
}
echo myFunction();
There is nothing wrong with it at all, and I would have thought it's quite common.
However, you should always be choosing the best name for a variable, or a parameter, in each situation, not applying one rule to your whole code.
For instance, in a database lookup function, it might be obvious what $id refers to, so it would be a sensible parameter name; but where you are calling it, you will likely have lots of IDs of various sorts, so a more descriptive variable name should be used. On the other hand, each time you build an SQL string, it's probably the only such variable in scope, so giving it a consistent name keeps your code tidy and easy to read.
A common observation is that all code is read more often than it is written (yes, even your personal website that you wouldn't dare share with the world). Variable names should be chosen with that in mind: what makes this code easy to read, understand, and maintain?
You can use global and add default value in param variable.
$variable = "value";
function myFunction($variable = '') {
global $variable;
return $variable;
}
I started to learn OO a few days back, I'm quite OK with procedural coding but obviously that is not enough and I want to become a well versed coder with a lot of experience and knowledge, so first thing to learn completely must be OO followed by the right design patterns I think.
Anyhow, I have one thing where I'm stuck which I don't quite follow...
Static variables... I understand that a static variable doesn't lose it's value even if the containing function is finished executing, and will keep it's value if the same function is executed again, and again etc etc.
But what I don't understand is what exactly can you now assign to a static variable? The manual and also countless question on stackoverflow state you can not assign an expression to a static variable.
So I read the PHP manual, to find out exactly what is considered an expression? The manuals answer is (and I quote):
"In PHP, almost anything you write is an expression. The simplest yet most accurate way to define an expression is "anything that has a value"."
"When you type "$a = 5", you're assigning '5' into $a. '5', obviously, has the value 5, or in other words '5' is an expression"
http://php.net/manual/en/language.expressions.php
Now when you read about variable scope in the manual, they have exactly this example:
function test()
{
static $a = 0;
echo $a;
$a++;
}
So, the manual about variable scopes says static $a = 0; is fine, while the manual about expressions says $a = 5, would be an expression. Which is basically the same thing, just a 0 instead of a 5...
So I'm a bit confused now.
What exactly is an expression now and what exactly can I or can I not assign to static variables? :)
You cannot initialize a static variable using a non-constant expression. You can assign anything you like to it after it is initialized.
The difference is that static variables are initialized during the parsing phase, i.e. while PHP reads through the source code to figure out what's what. At that stage no code is executed, PHP just reads what you want it to do. Therefore, it will not execute code to initialize the variable.
static $foo = 'bar';
'bar' is a constant value which PHP can easily assign to the variable at parse time.
static $foo = Bar::baz();
Bar::baz() is an expression that needs to run, PHP needs to locate the class, load it if necessary, run the baz() method, which may do all sorts of different stuff... The same for 5 + 3, md5('bar') or anything that requires actual computation. PHP is simply not going to do all this dynamic stuff at parse time. Therefore you cannot initialize a static variable with anything but constant values.
At runtime, you can assign anything you like to a static variable. An often used pattern is this:
static $foo = null;
if ($foo === null) {
$foo = new SomeObject;
}
This keeps the instance of SomeObject in the static variable, but you cannot initialize the variable with it.
static keyword changes nothing. 0 is still an expression.
You can assign to static only constant values, that have determined value on parsing stage and have no any calculations.
So
static $a = 0;
is valid code;
static $b = $a + 1;
static $c = 1 + 5;
are not.
You have mixed up apples and oranges here. (Or/and the manual did a poor job explaining them.)
Static variables, as in your question, are not the same as static properies of a class.
See: http://php.net/manual/en/language.oop5.static.php
Setting variable values inside a function call - I don't see this a lot, is this considered good practice?
function myUpdate($status){
...
}
myUpdate($status = 'live');
I personally like it because it's more descriptive. I see it more frequently the other way around, ie., assigning a default value in the function definition.
That's a very bad idea, because it's basically code obfuscation. php does not support keyword arguments, and that can lead to weird stuff. Case in point:
function f($a, $b){
echo 'a: ' . $a . "\n";
echo 'b: ' . $b . "\n";
}
f($b='b-value', $a='a-value');
This program does not only output
a: b-value
b: a-value
but also defines the variables $b and $a in the global context. This is because
f($b='b-value', $a='a-value');
// is the same thing as ...
$b = 'b-value';
$a = 'a-value';
f($b, $a);
There are a few good practices one can do to make remembering method arguments easier:
Configure your editor/IDE to show the signature of functions on highlight.
If a function has lots of arguments that describe some kind of state, consider moving it into an *objec*t (that holds the state instead)
If your function just needs lots of arguments, make it take an array for all non-essential ones. This also allows the method caller not to worry at all about the multitude of options, she just needs to know the ones she's interested in.
All kidding aside, seriously why do you use it? You have to realize it's something totally different than assigning a default value. What you're doing here is assigning the value to a variable, and then passing that variable to the function. The result is, that after the function call, the $status varialbe is still defined.
myUpdate( $status = 'live' );
echo $status; // "live"
Even if this is what you want, I'd say it's less descriptive than just splitting it out in two lines.
No, it's not because it's extra code. Try:
myUpdate('live' /*status*/, 42 /*maxTries*/);
Or if you really wanted named parameters, you could use a map:
myUpdate(array(
'status' => 'live'
));
Normally it would kill type safety, but PHP doesn't have any, anyway.
Well, default value is different thing.
// if you call myUpdate without argument, it will have $status with value live
function myUpdate($status = 'live'){
}
Calling this:
myUpdate($status = 'live');
is equivalent to:
myUpdate('live');
with the only difference being that after the call, if you call it like myUpdate($status = 'live'); you will keep the $status var with value live in the scope where you called the function, not inside it.
But IMHO its much more readable to do it like this:
$status = 'live';
myUpdate($status);
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What's an actual use of variable variables?
i saw the concept of variable variables in php .
that is a variable whose name is contained in another variable .
like this
$name = ’foo’;
$$name = ’bar’;
echo $foo;
// Displays ’bar’
one advantage that i see is , you can create variable names with numbers or lettes which you can not use normally . like this
$name = ’123’;
/* 123 is your variable name, this would normally be invalid. */
$$name = ’456’;
// Again, you assign a value
echo ${’123’};
// Finally, using curly braces you can output ’456’
and also you can call some functions like this
function myFunc() {
echo ’myFunc!’;
}
$f = ’myFunc’;
$f(); // will call myFunc();
and in a book i saw this
Variable variables are a very powerful tool, and should be used with
extreme care, not only because they can make your code difficult to
understand and document, but also because their improper use can lead
to some significant security issues.
The problem i have is if using variable variables in the code can be that dangerous . why are we using it . and is there any major advantages using variable variables in my code , if any what are those advantages .
you can use it in case of not-user-input. Look
function getVar($gid){
$name = "gid".$gid;
global $$name;
$var = $$name;
return $var;
}
It's useful when you have a lot of variables (same start with ending number, etc...) which is probably save
Look at your example:
function myFunc() {
echo ’myFunc!’;
}
$f = ’myFunc’;
$f(); // will call myFunc();
It is powerful: $f can have a value dynamically and the function called based on this value.
At the same time: If the user was given limitless access to $f this could be a security threat
In some MVC Frameworks they use it to run a function which will vary depending on the URL:
http://www.domain.com/thecontroller/theaction
in PHP side they will parse the url, get the second segment which is the name of the function then run it, but how? they will assign to a variable like what you have mentioned:
$toRun = 'theaction';
$toRun();
I've used double and even treble indirect pointers in C, but have never explicitly used variable variables in PHP (but I have used variable functions and classes).
I think it's somehow reassuring that there's more functionality in PHP than I use - and that I can make informed choices about which constructs I do use (I often use explicit references for example).
A nice usage I saw in some framework is using them to access, easier, values passedfrom another script as an array:
$array['test'];
$array['other'];
$array['third_index'];
// or simply $array = array('test','other','third_index');
foreach($array as $k=>$v)
{
$$k = $v;
}
So you could then have $test, $other and $third_index being usable as variables. Pretty handy when dealing with views, for example.
What does this code mean? Is this how you declare a pointer in php?
$this->entryId = $entryId;
Variable names in PHP start with $ so $entryId is the name of a variable.
$this is a special variable in Object Oriented programming in PHP, which is reference to current object.
-> is used to access an object member (like properties or methods) in PHP, like the syntax in C++.
so your code means this:
Place the value of variable $entryId into the entryId field (or property) of this object.
The & operator in PHP, means pass reference. Here is a example:
$b=2;
$a=$b;
$a=3;
print $a;
print $b;
// output is 32
$b=2;
$a=&$b; // note the & operator
$a=3;
print $a;
print $b;
// output is 33
In the above code, because we used & operator, a reference to where $b is pointing is stored in $a. So $a is actually a reference to $b.
In PHP, arguments are passed by value by default (inspired by C). So when calling a function, when you pass in your values, they are copied by value not by reference. This is the default IN MOST SITUATIONS. However there is a way to have pass by reference behaviour, when defining a function. Example:
function plus_by_reference( &$param ) {
// what ever you do, will affect the actual parameter outside the function
$param++;
}
$a=2;
plus_by_reference( $a );
echo $a;
// output is 3
There are many built-in functions that behave like this. Like the sort() function that sorts an array will affect directly on the array and will not return another sorted array.
There is something interesting to note though. Because pass-by-value mode could result in more memory usage, and PHP is an interpreted language (so programs written in PHP are not as fast as compiled programs), to make the code run faster and minimize memory usage, there are some tweaks in the PHP interpreter. One is lazy-copy (I'm not sure about the name). Which means this:
When you are coping a variable into another, PHP will copy a reference to the first variable into the second variable. So your new variable, is actually a reference to the first one until now. The value is not copied yet. But if you try to change any of these variables, PHP will make a copy of the value, and then changes the variable. This way you will have the opportunity to save memory and time, IF YOU DO NOT CHANGE THE VALUE.
So:
$b=3;
$a=$b;
// $a points to $b, equals to $a=&$b
$b=4;
// now PHP will copy 3 into $a, and places 4 into $b
After all this, if you want to place the value of $entryId into 'entryId' property of your object, the above code will do this, and will not copy the value of entryId, until you change any of them, results in less memory usage. If you actually want them both to point to the same value, then use this:
$this->entryId=&$entryId;
No, As others said, "There is no Pointer in PHP." and I add, there is nothing RAM_related in PHP.
And also all answers are clear. But there were points being left out that I could not resist!
There are number of things that acts similar to pointers
eval construct (my favorite and also dangerous)
$GLOBALS variable
Extra '$' sign Before Variables (Like prathk mentioned)
References
First one
At first I have to say that PHP is really powerful language, knowing there is a construct named "eval", so you can create your PHP code while running it! (really cool!)
although there is the danger of PHP_Injection which is far more destructive that SQL_Injection. Beware!
example:
Code:
$a='echo "Hello World.";';
eval ($a);
Output
Hello World.
So instead of using a pointer to act like another Variable, You Can Make A Variable From Scratch!
Second one
$GLOBAL variable is pretty useful, You can access all variables by using its keys.
example:
Code:
$three="Hello";$variable=" Amazing ";$names="World";
$arr = Array("three","variable","names");
foreach($arr as $VariableName)
echo $GLOBALS[$VariableName];
Output
Hello Amazing World
Note: Other superglobals can do the same trick in smaller scales.
Third one
You can add as much as '$'s you want before a variable, If you know what you're doing.
example:
Code:
$a="b";
$b="c";
$c="d";
$d="e";
$e="f";
echo $a."-";
echo $$a."-"; //Same as $b
echo $$$a."-"; //Same as $$b or $c
echo $$$$a."-"; //Same as $$$b or $$c or $d
echo $$$$$a; //Same as $$$$b or $$$c or $$d or $e
Output
b-c-d-e-f
Last one
Reference are so close to pointers, but you may want to check this link for more clarification.
example 1:
Code:
$a="Hello";
$b=&$a;
$b="yello";
echo $a;
Output
yello
example 2:
Code:
function junk(&$tion)
{$GLOBALS['a'] = &$tion;}
$a="-Hello World<br>";
$b="-To You As Well";
echo $a;
junk($b);
echo $a;
Output
-Hello World
-To You As Well
Hope It Helps.
That syntax is a way of accessing a class member. PHP does not have pointers, but it does have references.
The syntax that you're quoting is basically the same as accessing a member from a pointer to a class in C++ (whereas dot notation is used when it isn't a pointer.)
To answer the second part of your question - there are no pointers in PHP.
When working with objects, you generally pass by reference rather than by value - so in some ways this operates like a pointer, but is generally completely transparent.
This does depend on the version of PHP you are using.
You can simulate pointers to instantiated objects to some degree:
class pointer {
var $child;
function pointer(&$child) {
$this->child = $child;
}
public function __call($name, $arguments) {
return call_user_func_array(
array($this->child, $name), $arguments);
}
}
Use like this:
$a = new ClassA();
$p = new pointer($a);
If you pass $p around, it will behave like a C++ pointer regarding method calls (you can't touch object variables directly, but that's evil anyways :) ).
entryId is an instance property of the current class ($this)
And $entryId is a local variable
Yes there is something similar to pointers in PHP but may not match with what exactly happens in c or c++.
Following is one of the example.
$a = "test";
$b = "a";
echo $a;
echo $b;
echo $$b;
//output
test
a
test
This illustrates similar concept of pointers in PHP.
PHP passes Arrays and Objects by reference (pointers). If you want to pass a normal variable Ex. $var = 'boo'; then use $boo = &$var;.
PHP can use something like pointers:
$y=array(&$x);
Now $y acts like a pointer to $x and $y[0] dereferences a pointer.
The value array(&$x) is just a value, so it can be passed to functions, stored in other arrays, copied to other variables, etc. You can even create a pointer to this pointer variable. (Serializing it will break the pointer, however.)