Are There Pointers in PHP

How to use a pointer in a PHP function?

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

There is a good explanation of pointers on this page

References are not pointer in php?

In simple words, references are aliases.

A variable in PHP is stored in two pieces: the name and the value. The name points to the value.

$x = 2;
$y = $x;
$z = &$x;

When $x = 2; is executed, the name x is stored in the symbol table of the current scope and the value 2 is stored in a zval (don't ask, it's the internal name of a data structure that stores a value in PHP).

When $y = $x; is executed, the name y is stored in the symbol table of the current scope and the value of $x (2) is copied into a new zval structure.

When $z = &$x; is executed, the name z is stored in the symbol table of the current scope but a new zval is not created. Instead, z is set to point to the same zval as x.

The memory used by the variables $x, $y and $z looks like this:

+---------+                +---------+
| x | -------------> | 2 |
+---------+ +---------+
^
+---------+ | +---------+
| y | -------------------------> | 2 |
+---------+ | +---------+
|
+---------+ |
| z | --------------------+
+---------+

When a value is passed by reference to a function or a function returns a reference the same things happen, only the names are stored in different symbol tables (remark the "current scope" in the explanation above).

Let' see this code:

function f(& $z) {
$y = $z;
$z = $z + 2;
}
$x = 2;
f($x);

After $x = 2; the memory looks like this:

+---------+                +---------+
| x | -------------> | 2 |
+---------+ +---------+

During the execution of function f(), the memory looks like this:

+===== global ====+
| +---------+ | +---------+
| | x | -------------> | 4 |
| +---------+ | +---------+
+=================+ ^
|
+====== f() ======+ |
| +---------+ | | +---------+
| | y | -------------------------> | 2 |
| +---------+ | | +---------+
| | |
| +---------+ | |
| | z | --------------------+
| +---------+ |
+=================+

y and z are stored in a different symbol table than x and they are removed (together with the entire symbol table that contains them) when the call to f() returns.

When y is removed, its value is also removed because there is no name that points to it any more. But, because the value pointed by z is also pointed by x ($z is an alias), the value is not removed together with z and it survives the function call. f() modifies the value using $z; and this change is visible in the main program through the variable $x.

The things happen in a similar way when a function returns a reference. The function returns a value that is not copied but a new name that points to it is created into the symbols table of the calling code.

PHP behavior and arrays pointers

This behavior is characteristic of language?

The meaning of "pointer" in PHP arrays is not the same as the general meaning of "pointer" (in C/C++ or other languages that gives the programmer direct access to memory).

There are no pointers in PHP. The array data type keeps internally a cursor inside the list of values it contains. It is called the internal pointer of the array and it is modified by functions reset(), next(), prev(), end(), each() and maybe others. It can be used to iterate over the array like this:

$array = array(1, 2, 3);
while (list($key, $val) = each($array)) {
echo($key.' => '.$val."\n");
}

There is no reliable way to iterate the array using next() or prev() because they return FALSE when there are no more elements to iterate but they also return FALSE when the value FALSE is stored as an element in the array.

They could be useful if you need to analyze only several items from the beginning (or end) of the array. F.e. let's say we have an array of integers returned by a function and we need to get the first value that is not zero.

But this goal can be accomplished even easier using foreach():

$array = array(0, 0, 0, 2, 0, 1, 0, 3);
foreach ($array as $val) {
if ($val != 0) {
break;
}
}
echo($val); // prints "2"

or array_shift():

$array = array(0, 0, 0, 2, 0, 1, 0, 3);
do {
$val = array_shift($array);
if ($val != 0) {
break;
}
} while(count($array));
echo($val); // prints "2"

The result is expected: the pointer has been reset. My question is if the pointer is reset only after the end of the array?

The documentation of foreach() is wrong. Maybe it was correct on PHP 3 and PHP 4 but I think since the introduction of iterators in PHP 5 the behaviour of foreach() changed (to better).

It says:

When foreach first starts executing, the internal array pointer is automatically reset to the first element of the array. This means that you do not need to call reset() before a foreach loop.

As foreach relies on the internal array pointer, changing it within the loop may lead to unexpected behavior.

A simple test contradicts this statement:

$array = array(1, 3, 5, 7, 9);

foreach ($array as $val1) {
foreach ($array as $val2) {
echo('$val1='.$val1.'; $val2='.$val2.'; ');
}
echo("\n");
}

It works without problems. It should not work if foreach() is using the internal array pointer. It probably creates a copy of the pointer.

You can also try to use current(), next(), prev() or reset() inside the foreach() and you will get surprising and sometimes inconsistent results.

You better use foreach() to iterate over the arrays and do not rely on the internal pointer in any way.

The functions reset() and end() are, however, very handy when you need to get the first and the last element of the array without worrying about the keys.

PHP - can a method return a pointer?

PHP doesn't have pointers. PHP has reference. A reference in PHP is a true alias. But you don'tneed them. Objects are passed by handle (so they feel like references) for other data PHP uses a copy-on-write mechanism so there is no memory/performance penalty. The performance penalty comes when using references as they disable copy-on-write and therefore all the optimizations in the engine.

If you really want to return a reference youhave todeclare it in the signature:

public function &prepare( $query ) {
// bla bla bla

return $this->statement;
}

But as said: If $this->statement is an object there is no need.

See also http://php.net/references

PHP pointers vs references

In PHP, there are no pointers, only references. Your examples demonstrate pass by reference

The difference between your code snippets is only in syntax, where the first syntax is now deprecated.

Passing by reference vs. passing by value

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


Related Topics



Leave a reply



Submit