Aliasing a variable in PHP - php

I have a library class class someClass{....}. I created an object for this class.
$objectA = someClass;
I would like to use an alias for $objectA to some thing like $objectB, hence my class is more meaningful.
PS: $objectB should point $objectA

$objectB = $objectA;
From the manual:
One of the key-points of PHP 5 OOP that is often mentioned is that
"objects are passed by references by default". This is not completely
true. This section rectifies that general thought using some examples.
A PHP reference is an alias, which allows two different variables to
write to the same value. As of PHP 5, an object variable doesn't
contain the object itself as value anymore. It only contains an object
identifier which allows object accessors to find the actual object.
When an object is sent by argument, returned or assigned to another
variable, the different variables are not aliases: they hold a copy of
the identifier, which points to the same object.
<?php
class A {
public $foo = 1;
}
$a = new A;
$b = $a; // $a and $b are copies of the same identifier
// ($a) = ($b) = <id>
$b->foo = 2;
echo $a->foo."\n";
$c = new A;
$d = &$c; // $c and $d are references
// ($c,$d) = <id>
$d->foo = 2;
echo $c->foo."\n";
$e = new A;
function foo($obj) {
// ($obj) = ($e) = <id>
$obj->foo = 2;
}
foo($e);
echo $e->foo."\n";
?>
The above example will output:
2
2
2

I like John Conde's answer. I would like to add the following (to make it more straightforward):
In PHP almost anything can be "referenced". It is a similar concept to a "pointer" for old folks like me who came from the roots of technology programming in C and ASM.
A "pointer" is the address of the physical location of something in memory. By knowing it, you can reference that content without using the variable in the context.
In PHP, if you precede objects, structures, or variables with the symbol "&" you are telling the interpreter that you want the reference of the content and not the content itself. When associating it to another object, structure, or variable, instead of making a copy of it in another memory allocation point, the PHP interpreter will reference it to the same memory location as the original. Mainly, you will end up with two items pointing to the same location in RAM.
You can reference variables, structures, and objects in PHP like this:
$variable = "Variable Content";
$alias = &$variable;
echo $alias;
The above code should print Variable Content.
Please, notice that $alias = &$variable; is NOT the same as $alias = $variable; (without the "&"). In the first case, PHP will duplicate the content of $variable in $alias, and you will have two identical values in different locations of RAM being pointed by different variables. The second case, using "&", is a single content with two pointers that are independent but reference to the same location in RAM.
Similarly with how it happens with two specific variables, if you unset either of them ($variable or $alias) it won't unset the reference, which means the other will continue working. But, if you modify any, it will modify the content for both variables because they are looking to the same physical location in RAM to retrieve the content when used.
Think about this as analogous to the Unix unlink call. The same rule applies to objects and structures. Everything is referenceable.
And, YES, you can have multiple references to the same single content.
If you are now suddenly thinking about a "garbage collection" (GC) nightmare, well, so you got it. :)
More at https://www.php.net/manual/en/language.references.php
Those are similar in concept, varying only in terms of implementation and language model:
Referecences = Alias = Pointer

Related

What exactly are the entities 'Object', 'Object Reference', 'Object Identifier', 'Object Accessors' in PHP? How they function?

Below is the text from PHP Manual :
PHP treats objects in the same way as references or handles, meaning
that each variable contains an object reference rather than a copy of
the entire object.
A PHP reference is an alias, which allows two
different variables to write to the same value. As of PHP 5, an object
variable doesn't contain the object itself as value anymore. It only
contains an object identifier which allows object accessors to find
the actual object. When an object is sent by argument, returned or
assigned to another variable, the different variables are not aliases:
they hold a copy of the identifier, which points to the same object.
After going through the above text I've following doubts in my mind:
What exactly the 'Object' is?
What exactly the 'Object Reference' is?
What exactly an 'Object Identifier' is?
Does the entity called 'Object Identifier' work implicitly/internally?
How to create a copy of the 'Object Identifier'?
Do the terms 'Object Reference' and 'Object Identifier' mean the same thing?
What exactly the 'Object Accessors' are?
Do the terms 'Instance of a class', 'Instance of an object', 'Object variable', 'Class instance', 'Object instance' mean the same thing? If yes, what these entities indicate? If no, what are the differences in between their meanings?
How all of the above entities function?
Can someone please clear the doubts I have in an easy to understand, simple and lucid language in short and step-by-step manner?
It would be great if someone can explain these concepts with some suitable, working code example having explanatory comments at appropriate places in the code.
If possible, someone can also explain with the help of pictorial representation of working of these concepts. It would be highly appreciated.
You can take up following example or specify your own suitable example to explain all of the above concepts.
<?php
class A {
public $foo = 1;
}
$a = new A;
$b = $a;
$b->foo = 2;
echo $a->foo."\n";
$c = new A;
$d = &$c;
$d->foo = 2;
echo $c->foo."\n";
$e = new A;
function foo($obj) {
$obj->foo = 2;
}
foo($e);
echo $e->foo."\n";
?>
Thank You.
Reference links from the PHP Manual :
https://secure.php.net/manual/en/oop5.intro.php#oop5.intro
https://secure.php.net/manual/en/language.oop5.references.php#language.oop5.references
An Object is an instance of a class that you create with new Classname.
An Object Reference is a PHP variable whose value is an Object.
An Object Identifier is a value internal to the PHP implementation that identifies a particular object. It's probably something like an index into an array that contains pointers to all the objects.
Yes, they're internal, not visible to PHP applications.
Assign a variable containing an object to another variable. Internally, both variables contain copies of the object identifier.
They're not the same thing, but closely related. An object reference is a PHP variable, the object identifier is the internal data that it contains.
Object accessors are operations that access the contents of objects, such as $d->foo.
Yes, they're all essentially synonyms.
This is all just implementation details for how you can have multiple variables referring to the same object without having to use reference variables explicitly.
$a = new A;
$b = $a;
$a->foo = 2;
echo $b->foo; // echoes 2
The assignment isn't making a copy of the object, it's just copying the object identifier. All copies of an object identifier refer to the same object. Think of it like a pointer in languages like C or C++ -- when you copy a pointer, both variables refer to the same memory.
To make a copy of an object, you have to use clone.
$c = clone $a;
This is different from how arrays work, which is that assignment makes a copy, unless you use an explicit reference variable. (As an optimization, PHP uses copy-on-write, so it doesn't actually copy the array memory unless you modify it.)
$x = array(1);
$y = $x;
$z = &$x;
$x[0] = 2;
echo $y[0]; // echoes 1
echo $z[0]; // echoes 2

When is it good to use pass by reference in PHP?

In C++ if you pass a large array to a function, you need to pass it by reference, so that it is not copied to the new function wasting memory. If you don't want it modified you pass it by const reference.
Can anyone verify that passing by reference will save me memory in PHP as well. I know PHP does not use addresses for references like C++ that is why I'm slightly uncertain. That is the question.
The following does not apply to objects, as it has been already stated here. Passing arrays and scalar values by reference will only save you memory if you plan on modifying the passed value, because PHP uses a copy-on-change (aka copy-on-write) policy. For example:
# $array will not be copied, because it is not modified.
function foo($array) {
echo $array[0];
}
# $array will be copied, because it is modified.
function bar($array) {
$array[0] += 1;
echo $array[0] + $array[1];
}
# This is how bar shoudl've been implemented in the first place.
function baz($array) {
$temp = $array[0] + 1;
echo $temp + $array[1];
}
# This would also work (passing the array by reference), but has a serious
#side-effect which you may not want, but $array is not copied here.
function foobar(&$array) {
$array[0] += 1;
echo $array[0] + $array[1];
}
To summarize:
If you are working on a very large array and plan on modifying it inside a function, you actually should use a reference to prevent it from getting copied, which can seriously decrease performance or even exhaust your memory limit.
If it is avoidable though (that is small arrays or scalar values), I'd always use functional-style approach with no side-effects, because as soon as you pass something by reference, you can never be sure what passed variable may hold after the function call, which sometimes can lead to nasty and hard-to-find bugs.
IMHO scalar values should never be passed by reference, because the performance impact can not be that big as to justify the loss of transparency in your code.
The short answer is use references when you need the functionality that they provide. Don't think of them in terms of memory usage or speed. Pass by reference is always going to be slower if the variable is read only.
Everything is passed by value, including objects. However, it's the handle of the object that is passed, so people often mistakenly call it by-reference because it looks like that.
Then what functionality does it provide? It gives you the ability to modify the variable in the calling scope:
class Bar {}
$bar = new Bar();
function by_val($o) { $o = null; }
function by_ref(&$o) { $o = null; }
by_val($bar); // $bar is still non null
by_ref($bar); // $bar is now null
So if you need such functionality (most often you do not), then use a reference. Otherwise, just pass by value.
Functions that look like this:
$foo = modify_me($foo);
sometimes are good candidates for pass-by-reference, but it should be absolutely clear that the function modifies the passed in variable. (And if such a function is useful, often it's because it really ought to just be part of some class modifying its own private data.)
In PHP :
objects are passed by reference1 -- always
arrays and scalars are passed by value by default ; and can be passed by reference, using an & in the function's declaration.
For the performance part of your question, PHP doesn't deal with that the same way as C/C++ ; you should read the following article : Do not use PHP references
1. Or that's what we usually say -- even if it's not "completely true" -- see Objects and references

In PHP can someone explain cloning vs pointer reference?

To begin with, I understand programming and objects, but the following doesn't make much sense to me in PHP.
In PHP we use the & operator to retrieve a reference to a variable. I understand a reference as being a way to refer to the same 'thing' with a different variable. If I say for example
$b = 1;
$a =& $b;
$a = 3;
echo $b;
will output 3 because changes made to $a are the same as changes made to $b. Conversely:
$b = 1;
$a = $b;
$a = 3;
echo $b;
should output 1.
If this is the case, why is the clone keyword necessary? It seems to me that if I set
$obj_a = $obj_b then changes made to $obj_a should not affect $obj_b,
conversely $obj_a =& $obj_b should be pointing to the same object so changes made to $obj_a affect $obj_b.
However it seems in PHP that certain operations on $obj_a DO affect $obj_b even if assigned without the reference operator ($obj_a = $obj_b). This caused a frustrating problem for me today while working with DateTime objects that I eventually fixed by doing basically:
$obj_a = clone $obj_b
But most of the php code I write doesn't seem to require explicit cloning like in this case and works just fine without it. What's going on here? And why does PHP have to be so clunky??
Basically, there are two ways variables work in PHP...
For everything except objects:
Assignment is by value (meaning a copy occurs if you do $a = $b.
Reference can be achieved by doing $a = &$b (Note the reference operator operates upon the variable, not the assignment operator, since you can use it in other places)...
Copies use a copy-on-write tehnique. So if you do $a = $b, there is no memory copy of the variable. But if you then do $a = 5;, the memory is copied then and overwritten.
For objects:
Assignment is by object reference. It's not really the same as normal variable by reference (I'll explain why later).
Copy by value can be achieved by doing $a = clone $b.
Reference can be achieved by doing $a = &$b, but beware that this has nothing to do with the object. You're binding the $a variable to the $b variable. It doesn't matter if it's an object or not.
So, why is assignment for objects not really reference? What happens if you do:
$a = new stdclass();
$b = $a;
$a = 4;
What's $b? Well, it's stdclass... That's because it's not writing a reference to the variable, but to the object...
$a = new stdclass();
$a->foo = 'bar';
$b = $a;
$b->foo = 'baz';
What's $a->foo? It's baz. That's because when you did $b = $a, you are telling PHP to use the same object instance (hence the object reference). Note that $a and $b are not the same variable, but they do both reference the same object.
One way of thinking about it, is to think of all variables which store an object as storing the pointer to that object. So the object lives somewhere else. When you assign $a = $b where $b is an object, all you're doing is copying that pointer. The actual variables are still disjoint. But when you do $a = &$b, you're storing a pointer to $b inside of $a. Now, when you manipulate $a it cascades the pointer chain to the base object. When you use the clone operator, you're telling PHP to copy the existing object, and create a new one with the same state... So clone really just does a by-value copy of the varaible...
So if you noticed, I said the object is not stored in an actual variable. It's stored somewhere else and nothing but a pointer is stored in the variable. So this means that you can have (and often do have) multiple variables pointing to the same instance. For this reason, the internal object representation contains a refcount (Simply a count of the number of variables pointing to it). When an object's refcount drops to 0 (meaning that all the variables pointing to it either go out of scope, or are changed to somethign else) it is garbaged collected (as it is no longer accessable)...
You can read more on references and PHP in the docs...
Disclaimer: Some of this may be oversimplification or blurring of certain concepts. I intended this only to be a guide to how they work, and not an exact breakdown of what goes on internally...
Edit: Oh, and as for this being "clunky", I don't think it is. I think it is really useful. Otherwise you'd have variable references being passed around all over the place. And that can yield some really interesting bugs when a variable in one part of an application affects another variable in another part of the app. And not because it's passed, but because a reference was made somewhere along the line.
In general, I don't use variable references that much. It's rare that I find an honest need for them. But I do use object references all the time. I use them so much, that I'm happy that they are the default. Otherwise I'd need to write some operator (since & denotes a variable reference, there'd need to be another to denote an object reference). And considering that I rarely use clone, I'd say that 99.9% of use cases should use object references (so make the operator be used for the lower frequency cases)...
JMHO
I've also created a video explaining these differences. Check it out on YouTube.
In Short:
In PHP 5+ objects are passed by reference. In PHP 4 they are passed by value (that's why it had runtime pass by reference, which became deprecated). So, you have to use the clone operator in PHP5 to copy objects:
$objectB = clone $objectA;
Also note that it's just objects that are passed by reference, not other variables. The following may clear you up more:
PHP References
PHP Object Cloning
PHP Objects and References
i've written a presentation to explain better how php manage memory with its variables:
https://docs.google.com/presentation/d/1HAIdvSqK0owrU-uUMjwMWSD80H-2IblTlacVcBs2b0k/pub?start=false&loop=false&delayms=3000
take a look ;)

Are there pointers in php?

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.)

Php By Reference

Can someone please explain what the "&" does in the following:
class TEST {
}
$abc =& new TEST();
I know it is by reference. But can someone illustrate why and when I would need such a thing? Or point me to a url where this is explained well. I am unable to grasp the concept.
Thank you very much.
As I understand it, you're not asking about PHP references in general, but about the $foo =& new Bar(); construction idiom.
This is only seen in PHP4 as the usual $foo = new Bar() stores a copy of the object. This generally goes unnoticed unless the class stored a reference to $this in the constructor. When calling a method on the returned object later on, there would be two distinct copies of the object in existence when the intention was probably to have just one.
Consider this code where the constructor stores a reference to $this in a global var
class Bar {
function Bar(){
$GLOBALS['copy']=&$this;
$this->str="hello";
}
}
//store copy of constructed object
$x=new Bar;
$x->str="goodbye";
echo $copy->str."\n"; //hello
echo $x->str."\n"; //goodbye
//store reference to constructed object
$x=&new Bar;
$x->str="au revoir";
echo $copy->str."\n"; //au revoir
echo $x->str."\n"; //au revoir
In the first example, $x and $copy refer to different instances of Foo, but in the second they are the same.
Firstly, you don't really need to use it if you are using PHP 5, in PHP 5 all objects are passed by reference by default.
Secondly, when you assign an object to a variable name, either by creation, passing in a parameter, or setting a variable value, you are either doing so by reference or value.
Passing by reference means you pass the actual memory reference for the object, so say you passed an object as a parameter to a function, any changes that function makes to that variable will be reflected in the parent method as well, you are actually changing the state of that object in memory.
The alternative, to pass by value means you pass a copy of that object, not the memory reference, so any changes you make, will not be reflected in the original.
The PHP Manual does a pretty decent job of explaining references.
I should note, that they are NOT the same thing as a pointer or a reference in many other languages, although there are similarities. And as for objects being "passed by reference" by default - that's not exactly true either.
I would recommend reading the manual section first (and probably then re-reading a couple of times until you get it), and then come back here if you still have more questions.
A simpler way to look at it may be like this:
$a = 'foo';
$b = 'bar';
$a =& $b;
$b = 'foobar';
echo $a . ' ' . $b;
will output
foobar foobar
It might be helpful to think of it like this: In PHP, all variables are really some sort of pointer: The entries in the symbol table - the thing which maps variable names to values - contain a zval * in the C implementation of the Zend Engine.
During assignment - this includes setting function arguments - magic will happen:
If you do $a = $b, a copy of the value pointed to by the symbol table entry of $b will be created and a pointer to this new value will be placed in the symbol table entry for $a. Now, $a and $b will point to different values. PHP uses this as its default calling convention.
If you do $a =& $b, the symbol table entry for $a will be set to the pointer contained in the symbol table entry for $b. This means $a and $b now point to the same value - they are aliases of each other with equal rights until they are rebound by the programmer. Also note that $a is not really a reference to $b - they are both pointers to the same object.
That's why calling them 'aliases' might be a good idea to emphasize the differences to C++' reference implementation:
In C++, a variable containing a value and a reference created from this variable are not equal - that's the reason why there are things like dangling references.
To be clear: There is no thing like a reference type in PHP, as all variables are already internally implemented as pointers and therefore every one of them can act as a reference.
PHP5 objects are still consistent with this description - they are not passed by reference, but a pointer to the object (the manual calls it an 'object identifier' - it might not be implemented as an actual C pointer - I did not check this) is passed by value (meaning copied on assignment as described above).
Check the manual for details on the relation between PHP5 objects and references.

Categories