Php передать данные через ссылку

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 передать данные через ссылку

beware unset() destroys references

$x = ‘x’;
change( $x );
echo $x; // outputs «x» not «q23» —- remove the unset() and output is «q23» not «x»

Within a class, passing array elements by reference which don’t exist are added to the array as null. Compared to a normal function, this changes the behavior of the function from throwing an error to creating a new (null) entry in the referenced array with a new key.

class foo <
public $arr = [ ‘a’ => ‘apple’ , ‘b’ => ‘banana’ ];
public function normalFunction ( $key ) return $this -> arr [ $key ];
>
public function & referenceReturningFunction ( $key ) return $this -> arr [ $key ];
>
>

$bar = new foo ();
$var = $bar -> normalFunction ( ‘beer’ ); //Notice Error. Undefined index beer
$var = & $bar -> referenceReturningFunction ( ‘beer’ ); // No error. The value of $bar is now null
var_dump ( $bar -> arr );
/**
[
«a» => «apple»,
«b» => «banana»,
«beer» => null,
],
*/

?>
This is in no way a «bug» — the framework is performing as designed, but it took careful thought to figure out what was going on. PHP7.3

Parameters passed by references can have default values.
You can find out if a variable was actually passed by using func_num_args():

function refault ( & $ref = ‘Do I have to be calculated?’ ) echo ‘NUM ARGS: ‘ . func_num_args (). «\n» ;
echo «ORI VALUE: < $ref >\n» ;
if( func_num_args () > 0 ) $ref = ‘Yes, expensive to calculate result: ‘ . sleep ( 1 );
else $ref = ‘No.’ ;
echo «NEW VALUE: < $ref >\n» ;
>

$result = ‘Do I have to be calculated?’ ;
refault ( $result );
echo «RESULT: < $result >\n» ;
// NUM ARGS: 1
// ORI VALUE: Do I have to be calculated?
// NEW VALUE: Yes, expensive to calculate result: 0
// RESULT: Yes, expensive to calculate result: 0

refault ();
// NUM ARGS: 0
// ORI VALUE: Do I have to be calculated?
// NEW VALUE: No.
?>

The notes indicate that a function variable reference will receive a deprecated warning in the 5.3 series, however when calling the function via call_user_func the operation aborts without fatal error.

This is not a «bug» since it is not likely worth resolving, however should be noted in this documentation.

This function internally swaps the contents between
two simple variables using ‘passing by reference’.

Some programming languages have such a swap function
built in, but PHP seems to lack such a function. So,
one was created to fill the need. It only handles
simple, single variables, not arrays, but it is
still a very handy tool to have.

No value is actually returned by this function, but
the contents of the indicated variables will be
exchanged (swapped) after the call.
*/

print «

Define:\na = $a \nb = ' $b '

» ;
swap ( $a , $b );
print «

After swap(a,b):\na = ' $a '\nb = $b

» ;

function swap (& $arg1 , & $arg2 )

// Swap contents of indicated variables.
$w = $arg1 ; $arg1 = $arg2 ; $arg2 = $w ;
>

For anyone wondering, the copy-on-write behaviour just does the Right Thing™ when an array is passed to a function not by-ref which then passes it through to another function by-ref without writing to it. For example:

function do_sort (array $array ) : array usort ( $array , function ( $a , $b ) return strnatcasecmp ( $a [ ‘name’ ], $b [ ‘name’ ]);
>);

var_dump ( $data );
do_sort ( $data ); // does not affect value of $data
var_dump ( $data );
$data = do_sort ( $data );
var_dump ( $data );

I designed a class that can easily pass references.

#### Problem 1
function problem (& $value )
>
problem ( 1 ); // cannot be passed by reference

#### Problem 2
class problem2
static function __callStatic ( $name , & $arguments ) // cannot take arguments by reference
>
>
?>

My solution 👇
class Reference
function __construct (public mixed & $data )
>

function test ( $value )
$value = & Reference :: get ( $value ); // values OR reference
$value = «test- $value » ;
return $value ;
>

echo test ( 1 ), PHP_EOL ; // test-1

$val = 2 ;
echo test ( Reference :: create ( $val )), PHP_EOL ; // test-2
echo $val , PHP_EOL ; // test-2

#### Problem solving 2 ####
class TestCall
static function __callStatic ( $name , $arguments )
$value = & Reference :: get ( $arguments [ 0 ]);
$value = » $name — $value » ;
return $value ;
>
>

echo TestCall :: test ( 3 ), PHP_EOL ; // test-3

$val = 4 ;
echo TestCall :: test ( Reference :: create ( $val )), PHP_EOL ; // test-4
echo $val , PHP_EOL ; // test-4

Some have noticed that reference parameters can not be assigned a default value. It’s actually wrong, they can be assigned a value as the other variables, but can’t have a «default reference value», for instance this code won’t compile :

function use_reference ( $someParam , & $param =& $POST )
.
>
?>

But this one will work :

function use_reference ( $someParam , & $param = null )
?>

So here is a workaround to have a default value for reference parameters :

$array1 = array ( ‘test’ , ‘test2’ );

AddTo ( «indirect test» , «test» , $array1 );
AddTo ( «indirect POST test» , «test» );

echo «Array 1 » ;
print_r ( $array1 );

echo «_POST » ;
print_r ( $_POST );

?>

And this scripts output is :

Array 1 Array
(
[0] => test
[1] => test2
[indirect test] => test
)
_POST Array
(
[indirect POST test] => test
)

Of course that means you can only assign default reference to globals or super globals variables.

If you changed a reference variable with a new `Address`, the variable it originally pointed to won’t change.

Beware of using references with anonymous function and «use» keyword :

If you have a PHP version between 5.3 and < 5.3.10, "use" keyword break the reference :

$arg = 1 ;
echo ‘withRef — BEFORE — ‘ . $arg . «\n» ; // 1
withRef ( $arg );
// in PHP 5.3 < 5.3.10 : display 1
// in PHP 5.3 >= 5.3.10 : display 2
echo ‘withRef — AFTER — ‘ . $arg . «\n» ;
?>

A workaround is to use a copy of the reference variable in «use» keyword :
.
$arg2 = $arg ;
$func = function() use( $arg2 ) < /* do nothing, just declare using $arg2 */ >;

Sometimes we need functions for building or modifying arrays whose elements are to be references to other variables (arrays or objects for instance). In this example, I wrote two functions ‘tst’ and ‘tst1’ that perform this task. Note how the functions are written, and how they are used.

array_push ( $arr , & $r );
// Alternatively, this also could be $arr[] = &$r (in this case)
>

$arr0 = array(); // an empty array
$arr1 = array( 1 , 2 , 3 ); // the array to be referenced in $arr0

// Note how we call the function:
tst ( $arr0 , & $arr1 ); // We are passing a reference to ‘$arr1’ in the call !

print_r ( $arr0 ); // Contains just the reference to $arr1

array_push ( $arr0 , 5 ); // we add another element to $arr0
array_push ( $arr1 , 18 ); // we add another element to $arr1 as well

print_r ( $arr1 );
print_r ( $arr0 ); // Changes in $arr1 are reflected in $arr0

function tst1 (& $arr , & $r ) <
// Both arguments ‘$arr’ and ‘$r» are declared to be passed by
// reference,
// again, in the function’s body, we use a reference to
// the ‘$r’ argument

array_push ( $arr , & $r );
// Alternatively, this also could be $arr[] = &$r (in this case)
>

$arr0 = array(); // an empty array
$arr1 = array( 1 , 2 , 3 ); // the array to be referenced in $arr0

// Note how we call the function:
tst1 ( $arr0 , $arr1 ); // ‘tst1’ understands ‘$r’ is a reference to ‘$arr1’

print_r ( $arr0 ); // Contains just the reference to $arr1

array_push ( $arr0 , 5 ); // we add another element to $arr0
array_push ( $arr1 , 18 );

print_r ( $arr1 );
print_r ( $arr0 ); // Changes in $arr1 are reflected in $arr0

I hope this is somehow useful

Источник

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».
*/
?>

Источник

Читайте также:  Css flex запретить сжатие элемента
Оцените статью