Передавать значения переменных php

Передавать значения переменных 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

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.

Читайте также:  Python как переименовать папку

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

» ;

Читайте также:  Java http upload server

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.

Читайте также:  Call python from excel

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

Источник

Оцените статью