Page 1 of 1
Call-time references deprecated
Posted: Fri Jul 13, 2007 6:18 pm
by alex.barylski
I'm porting some code over from PHP to PHP 5.2.3 under Deb Etch.
I received this warning:
Warning: Call-time pass-by-reference has been deprecated; If you would like to pass it by reference, modify the declaration of [runtime function name](). If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file
A quick jump to offending line number seems that a call like this is now no longer needed:
Code: Select all
$this->_objects[$key]->init(&$this->_page, $tmp[$key]['prop']);
I realize that PHP5 all objects, arrays, etc were passed by reference and admittedly I am not sure why I added the & prefix but under PHP4 I always used references just to avoid annoying bugs which were the result of working on a copy.
In anycase, can someone confirm whther my assumptions are correct in that I only need the & in the function declaration and not on the object being passed - will this prevent the deprecation warning?
It's weird cause, I was actually testing locally on PHP 5.2.0 and this error didn't ocur, so I assume this is recently deprecated?
Also, if objects are automatically referenced when passing as arguments to a function, how do you force 'pass by value' if the function only needs a copy of the object?
Would you simply make a copy of the object and pass the copy?
Code: Select all
$tmp = $obj;
myFunction($tmp); // Pass by value instead of by reference
Cheers

Re: Call-time references deprecated
Posted: Fri Jul 13, 2007 6:46 pm
by volka
Hockey wrote:In anycase, can someone confirm whther my assumptions are correct in that I only need the & in the function declaration and not on the object being passed - will this prevent the deprecation warning?
You could've easily tested it, but yes.
Hockey wrote:It's weird cause, I was actually testing locally on PHP 5.2.0 and this error didn't ocur, so I assume this is recently deprecated?
Not really

see
http://cvs.php.net/viewvc.cgi/ZendEngin ... 2=1.85.2.3
Hockey wrote:Also, if objects are automatically referenced when passing as arguments to a function, how do you force 'pass by value' if the function only needs a copy of the object?
You can
clone an object. But what do you mean by "
only needs a copy"?
Code: Select all
<?php
function myFunction($x) {
$x->foo = 'bar';
}
$obj = new StdClass;
$tmp = $obj;
myFunction($tmp);
echo $obj->foo;
prints
bar (php5)
Posted: Fri Jul 13, 2007 9:33 pm
by stereofrog
Objects in php5 are pointers (not references), that's why it's safe to pass them by value. All other types, including arrays, still should be passed by reference if you intend to modify them in a function (not the best idea anyways, so it's better to avoid references completely).
Posted: Sat Jul 14, 2007 3:37 am
by volka
stereofrog wrote:Objects in php5 are pointers (not references)
Are there any differences in php? What's a pointer in php?
Posted: Sat Jul 14, 2007 9:32 am
by stereofrog
volka wrote:stereofrog wrote:Objects in php5 are pointers (not references)
Are there any differences in php? What's a pointer in php?
During the execution php maintains the list of variables and their values (so-called symbol table). When you assign one variable to another
php allocates a new entry in the symbol table and copies the value from $a to $b. The symbol table looks then like this
$a and $b are not linked together in any way, if you assign something else to $b, $a won't be affected. This behaviour is common for php4 and 5, the key difference is that "object" values are stored immediately in php4, while php5 stores only the memory address of the object i.e. pointer.
in php4 symbol table will be
Code: Select all
a -> {source object}
b -> {copy of the object}
and in php5
Code: Select all
a -> 0x1234 \
|-> {source object}
b -> 0x1234 /
that is, "new X" returns the "whole object" in php4 and only a pointer in php5.
Pointer value is like any other, and there's no difference for the engine if you assign a pointer or an integer, however when you dereference the pointer and change the object itself
this also indirectly changes $b, just because $b happens to have the same pointer value as $a. But this doesn't mean $a and $b "know" of each other, they remain independent just like before.
Reference is somewhat completely different. References are aliases, assigning by reference
essentially means: "$c is another name for $a". Of course, $c and $a are then wired together, changing $c will also change $a.
This reasoning exactly applies to the function calls. When a function is being called, engine creates a new symbol table and copies arguments' values to the new variables. Arguments passed by value are independent from their "sources", but can affect them by dereferencing:
Code: Select all
function foo($copy) {
$copy->x = 123; // indirectly affects $source
$copy = 999; // doesn't affect $source
}
$source = new X;
foo($source);
When passing by reference, the function variable becomes an alias to the source and can change it directly:
Code: Select all
function bar(& $ref) {
$ref = 999; // changes $source
}
$source = new A;
bar($source);
// - source got a new value
References are harmful, because they change the calling scope in an often unobvious way, resulting in undesired side effects. In php4, passing by reference was basically a hack to let a function change a passed object, in php5 this is not needed, and it's better to forget about references completely. Most comparable languages doesn't support references, that doesn't make them less powerful.
Hope this was helpful.

Posted: Sat Jul 14, 2007 1:10 pm
by volka
Oops, that was supposed to be a rethorical question. I know what a pointer is. But if you search the php manual or the zend site you will find that for $obj = new XYZ; $obj isn't called a pointer, there is no such thing in php. $obj is an object reference, like in java.
$a = &$b; increases the reference count just like $a = $obj or passing objects to a function in php5.
Posted: Sat Jul 14, 2007 3:43 pm
by stereofrog
Well, I thought I explained that pretty clear. Obviously not. ;(
References and pointers are different things, please don't confuse them.
Posted: Sat Jul 14, 2007 3:46 pm
by Oren
PHP doesn't have pointers as far as I know.
Posted: Sat Jul 14, 2007 3:56 pm
by stereofrog
Zend engine is not written in php.
Posted: Sat Jul 14, 2007 5:03 pm
by volka
meaning

btw: Zend Engine has pointers, it's written in C.
---
I know what you mean. The difference between
Code: Select all
$a = 15;
$b = &$a;
$b = null;
echo gettype($a), "\n";
and
Code: Select all
$c = new StdClass;
$d = $c;
$d->prop = 'xyz';
$d = null;
echo gettype($c), "\n";
echo $c->prop, "\n";
They are simply not called pointers in php and don't exactly behave like pointers in e.g. C or other languages that provide pointer/pointer arithmetic. It's really more like object references in java.
And if you look up the manual at php.net and the docu at zend.com you find anything from object handle to object reference but no "pointer" mentioned.
Posted: Sat Jul 14, 2007 5:40 pm
by stereofrog
Exactly that. I just think that using the term "reference" for object pointers is utterly confusing, because unlike java this term is already loaded in php and stands for somewhat completely different. If you feel allergic to the word "pointer", feel free to say "object value" or "handle" or whatever, but for goodness sake, don't call them "references".

Posted: Sat Jul 14, 2007 5:49 pm
by volka
That was probably the problem of the writers of the manual, too. "Object handle" ... o..k..
php mixes C++ references without having pointers and java object references without e.g. outboxing.
Posted: Sat Jul 14, 2007 5:56 pm
by stereofrog
If you forgive me an argumentum ad verecundiam, this is what Bruce Eckel says in TIJ
...“Does Java have pointers?” Some have claimed that pointers are hard and dangerous and therefore bad, and since Java is all goodness and light and will lift your earthly programming burdens, it cannot possibly contain such things. However, it’s more accurate to say that Java has pointers; indeed, every object identifier in Java (except for primitives) is one of these pointers, but their use is restricted and guarded not only by the compiler but by the run-time system. Or to put it another way, Java has pointers, but no pointer arithmetic. These are what I’ve been calling “references,” and you can think of them as “safety pointers,” not unlike the safety scissors of elementary school—they aren’t sharp, so you cannot hurt yourself without great effort, but they can sometimes be slow and tedious.
This exactly applies to php as well.
Posted: Sat Jul 14, 2007 6:01 pm
by volka
exactly what I wrote

Posted: Sat Jul 14, 2007 6:03 pm
by stereofrog
glad we agreed
