Php амперсанд перед названием функции

How to Start a PHP Function with an Ampersand

In PHP, an ampersand ( & ) is put before the function name for returning a reference to the variable instead of returning the value. To return by reference is handy for using a function to detect a variable a reference to be bound to.

An Example of Using Ampersand

For a better perception, let’s consider a detailed example of using an ampersand to start a PHP function.

Instead of a copy, it is necessary to set the property of the object that is returned by getValue() .

In contrast to passing a parameter, here, you should put the ampersand in both of the places for specifying that you want to return by reference.

The example will look as follows:

 class pupil < public $value = 42; public function &getValue( ) < return $this->value; > > $obj = new pupil(); // $myValue is a reference to // $obj->value, which is 42. $myValue = &$obj->getValue(); $obj->value = 2; // Printing the new value of // $obj->value, i.e. 2. echo $myValue; ?>

References and Ampersands in PHP

Two variables can be referred to the same content with the help of references.

Otherwise saying, a variable specifies its content instead of becoming that content.

Passing by reference gives an opportunity to two variables to specify the same content under distinct names. To be referenced an ampersand should be put before the variable.

Источник

Php амперсанд перед названием функции

To experiment on performance of pass-by-reference and pass-by-value, I used this script. Conclusions are below.

#!/usr/bin/php
function sum ( $array , $max ) < //For Reference, use: "&$array"
$sum = 0 ;
for ( $i = 0 ; $i < 2 ; $i ++)#$array[$i]++; //Uncomment this line to modify the array within the function.
$sum += $array [ $i ];
>
return ( $sum );
>

$max = 1E7 //10 M data points.
$data = range ( 0 , $max , 1 );

$start = microtime ( true );
for ( $x = 0 ; $x < 100 ; $x ++)$sum = sum ( $data , $max );
>
$end = microtime ( true );
echo «Time: » .( $end — $start ). » s\n» ;

/* Run times:
# PASS BY MODIFIED? Time
— ——- ——— —-
1 value no 56 us
2 reference no 58 us

3 valuue yes 129 s
4 reference yes 66 us

1. PHP is already smart about zero-copy / copy-on-write. A function call does NOT copy the data unless it needs to; the data is
only copied on write. That’s why #1 and #2 take similar times, whereas #3 takes 2 million times longer than #4.
[You never need to use &$array to ask the compiler to do a zero-copy optimisation; it can work that out for itself.]

2. You do use &$array to tell the compiler «it is OK for the function to over-write my argument in place, I don’t need the original
any more.» This can make a huge difference to performance when we have large amounts of memory to copy.
(This is the only way it is done in C, arrays are always passed as pointers)

3. The other use of & is as a way to specify where data should be *returned*. (e.g. as used by exec() ).
(This is a C-like way of passing pointers for outputs, whereas PHP functions normally return complex types, or multiple answers
in an array)

5. Sometimes, pass by reference could be at the choice of the caller, NOT the function definitition. PHP doesn’t allow it, but it
would be meaningful for the caller to decide to pass data in as a reference. i.e. «I’m done with the variable, it’s OK to stomp
on it in memory».
*/
?>

Источник

Php амперсанд перед названием функции

Ссылки в PHP позволяют ссылаться на область памяти, где расположено значение переменной или параметра. Для создания ссылки перед переменной указывается символ амперсанда — & . Но перед рассмотрением ссылок сначала рассмотрим простой пример копирования переменных:

"; // tom = Tom echo "sam = $sam"; // sam = Sam ?>

Здесь переменной $sam присваивается значение переменной $tom («Tom»). Затем той же переменной $sam присваивается новое значение — «Sam». Результат программы ожидаем — обе переменные имеют различные значения:

Теперь при копировании значения переменных передадим ссылку:

"; // tom = Sam echo "sam = $sam"; // sam = Sam ?>

Здесь нас интересует выражение

В данном случае переменной $sam передается не копия значения переменной $tom , как в предыдущем случае, а ссылка на область в памяти, которую занимает переменная $tom . То есть после выполнения инструкции

Обе переменных будут указывать на один и тот же адрес в памяти. Это приведет к тому, что изменение значения одной из этих переменных приведет к изменению значения другой переменной. Потому что они ссылаются на один и тот же участок в памяти и соответственно имеют одно общее значение:

Присвоить ссылку на переменную можно двумя способами:

Передача по ссылке

В примере в прошлых темах мы передавали параметры по значению . Но в PHP есть и другая форма передачи параметров — по ссылке . Рассмотрим два этих способа передачи параметров и сравним. Стандартная передача параметра по значению:

 $number = 5; square($number); echo "
number = $number"; ?>

В данном случае внутри функции square() значение параметра $a возводится в квадрат. То есть значение параметра внутри функции изменяется. Однако после вызова функции square() значение переменной $number , которое передается параметру $a, не изменится. Это и есть передача по значению, она никак не затрагивает переменную $number .

Теперь рассмотрим передачу параметра по ссылке:

 $number = 5; square($number); echo "
number = $number"; ?>

При передаче по ссылке перед параметром ставится знак амперсанда: function square(&$a) . Теперь интерпретатор будет передавать не значение переменной, а ссылку на эту переменную в памяти. То есть теперь и переменная $number и параметр $a будут указывать на одну и ту же область в памяти. В итоге, значение переменной $number после передачи параметру &$a также будет изменено.

Возвращение ссылки из функции

Функция также может возвращать ссылку. В этом случае при определении и вызове функции перед ее именем ставится знак амперсанда:

 $userName = "admin"; $checkedName = &checkName($userName); echo "
userName: $userName"; echo "
checkedName: $checkedName"; ?>

В данном случае функция checkName() получает параметр по ссылке и возвращает ссылку — фактически ссылку, которая передается в функции. Для этого перед определением функции указан символ амперсанда:

Для имитации работы функция проверяет имя пользователя и изменяет его на некоторое стандартное, если оно равно «admin».

При вызове функции перед ее именем указывается символ амерсанда:

После выполнения функции переменная $checkedName фактически будет содержать ссылку на переменную $userName .

Источник

Объекты передаются по ссылке или нет?

Часто можно услышать фразу, что в PHP «объекты всегда передаются по ссылке». На самом деле всё немного сложнее.

Как выглядит работа с ссылками в PHP? Для этого используется специальный синтаксис – перед именем переменной или параметра функции ставится символ амперсанда (&). В том случае, когда амперсанд проставлен в сигнатуре функции – это называют передачей параметра по ссылке. Изменяя такую переменную-параметр внутри функции, после выхода из функции мы обнаружим, что значение поменялось и в месте вызова. Думаю, с этим знакомы все.

А что с объектами? Объекты, переданные внутрь какой-то функции в качестве аргументов, ведут себя точно также – если внутри функции мы меняем внутреннее состояние объекта, то снаружи увидим это изменённое состояние. Отличие в том, что в сигнатуре функции не нужно ставить амперсанд перед параметром-объектом.

Отсюда можно сделать ошибочный вывод, что объекты всегда передаются по ссылке, просто синтаксис попроще, не надо обмазываться амперсандами.

А что, если в сигнатуре функции, принимающей объект всё-таки поставить амперсанд? После небольшой проверки, на первый взгляд, ничего не поменяется! Кажется очередной фрактал плохого дизайна: скалярные типы данных можно передать двумя способами, и по ссылке, и по значению, а объекты всегда по ссылке, при этом амперсанд хочешь ставь, хочешь не ставь.

На самом деле, это заблуждение. Разберёмся что здесь происходит.

Упрощённо, механику можно представить так: когда мы создаём объект с помощью оператора new и присваиваем какой-то переменной, в эту переменную помещается не сам объект, а некий идентификатор объекта, id.

Передавая переменную в качестве аргумента внутрь какой-то функции, мы передаём значение этого идентификатора, т.е. передача происходит по значению . Важно понимать, что значением является не сам объект, а его идентификатор.

Таким образом снаружи функции и внутри мы, имея одинаковое значение идентификатора объекта, работаем с одним и тем же объектом.

Но если внутри функции мы присвоим переменной, например null – повлияет ли это на объект снаружи функции? Никак! Мы обнулили переменную содержащую id объекта внутри функции, но снаружи функции, внешняя переменная всё ещё содержит id объекта и сам объект никуда не делся из памяти.

Теперь ставим в сигнатуре функции амперсанд. В этом случае переменная, содержащая идентификатор объекта, передастся по ссылке. Поменяв такую переменную внутри функции, например, присвоив null , мы обнаружим что поменялась и переменная снаружи – она тоже стала null . А объект в памяти стал ничьим и он будет удалён сборщиком мусора.

Подводим итог.

  1. Формулировка «объекты всегда передаются по ссылке» не корректна. Впрочем, с практической точки зрения такое упрощение не приводит к проблемам в общении с другими разработчиками, все воспринимают эту фразу примерно одинаково: изменив состояние объекта внутри функции мы увидим это и снаружи.
  2. Есть существенная разница между синтаксисом с амперсандом и без него. Но на практике не припомню, чтобы мне требовалось использовать вариант с амперсандом перед переменной-объектом.

Источник

Читайте также:  Python list child classes
Оцените статью