arrays visualizzare - Gli array in PHP sono passati per valore o per riferimento?




elementi statico (7)

Per la seconda parte della tua domanda, vedi la pagina dell'array del manuale , che afferma (citando) :

L'assegnazione di array comporta sempre la copia di valore. Utilizzare l'operatore di riferimento per copiare una matrice per riferimento.

E l'esempio dato:

<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 is changed,
             // $arr1 is still array(2, 3)

$arr3 = &$arr1;
$arr3[] = 4; // now $arr1 and $arr3 are the same
?>


Per la prima parte, il modo migliore per essere sicuri è provare ;-)

Considera questo esempio di codice:

function my_func($a) {
    $a[] = 30;
}

$arr = array(10, 20);
my_func($arr);
var_dump($arr);

Darà questo risultato:

array
  0 => int 10
  1 => int 20

Il che indica che la funzione non ha modificato la matrice "esterna" che è stata passata come parametro: viene trasmessa come copia e non come riferimento.

Se vuoi passare per riferimento, devi modificare la funzione, in questo modo:

function my_func(& $a) {
    $a[] = 30;
}

E l'output diventerà:

array
  0 => int 10
  1 => int 20
  2 => int 30

Come, questa volta, la matrice è stata passata "per riferimento".


Non esitare a leggere la sezione Spiegazione dei riferimenti del manuale: dovrebbe rispondere ad alcune delle tue domande ;-)

Quando un array viene passato come argomento a un metodo o funzione, viene passato per riferimento?

Che ne dici di fare questo:

$a = array(1,2,3);
$b = $a;

$b un riferimento a $a ?


Questo thread è un po 'più vecchio ma qui qualcosa che ho appena incontrato:

Prova questo codice:

$date = new DateTime();
$arr = ['date' => $date];

echo $date->format('Ymd') . '<br>';
mytest($arr);
echo $date->format('Ymd') . '<br>';

function mytest($params = []) {
    if (isset($params['date'])) {
        $params['date']->add(new DateInterval('P1D'));
    }
}

http://codepad.viper-7.com/gwPYMw

Nota che non esiste un amplificatore per il parametro $ params e tuttavia cambia il valore di $ arr ['date']. Questo non corrisponde esattamente a tutte le altre spiegazioni qui e a ciò che ho pensato fino ad ora.

Se clone l'oggetto $ params ['date'], la seconda data in uscita rimane la stessa. Se l'ho appena impostato su una stringa, non ha alcun effetto sull'output.


In PHP gli array vengono passati alle funzioni in base al valore per impostazione predefinita, a meno che non vengano passati esplicitamente per riferimento, come mostrato dallo snippet seguente:

$foo = array(11, 22, 33);

function hello($fooarg) {
  $fooarg[0] = 99;
}

function world(&$fooarg) {
  $fooarg[0] = 66;
}

hello($foo);
var_dump($foo); // (original array not modified) array passed-by-value

world($foo);
var_dump($foo); // (original array modified) array passed-by-reference

Ecco l'output:

array(3) {
  [0]=>
  int(11)
  [1]=>
  int(22)
  [2]=>
  int(33)
}
array(3) {
  [0]=>
  int(66)
  [1]=>
  int(22)
  [2]=>
  int(33)
}

Quando un array viene passato a un metodo o funzione in PHP, viene passato per valore a meno che non lo passi esplicitamente per riferimento, in questo modo:

function test(&$array) {
    $array['new'] = 'hey';
}

$a = $array(1,2,3);
// prints [0=>1,1=>2,2=>3]
var_dump($a);
test($a);
// prints [0=>1,1=>2,2=>3,'new'=>'hey']
var_dump($a);

Nella tua seconda domanda, $b non è un riferimento a $a , ma una copia di $a .

Proprio come il primo esempio, puoi fare riferimento a $a facendo quanto segue:

$a = array(1,2,3);
$b = &$a;
// prints [0=>1,1=>2,2=>3]
var_dump($b);
$b['new'] = 'hey';
// prints [0=>1,1=>2,2=>3,'new'=>'hey']
var_dump($a);

Di default

  1. I primitivi vengono passati per valore. Improbabile per Java, la stringa è primitiva in PHP
  2. Le matrici di primitivi vengono passate in base al valore
  3. Gli oggetti vengono passati per riferimento
  4. Le matrici di oggetti vengono passate per valore (la matrice) ma ogni oggetto viene passato per riferimento.

    <?php
    $obj=new stdClass();
    $obj->field='world';
    
    $original=array($obj);
    
    
    function example($hello) {
        $hello[0]->field='mundo'; // change will be applied in $original
        $hello[1]=new stdClass(); // change will not be applied in $original
        $
    }
    
    example($original);
    
    var_dump($original);
    // array(1) { [0]=> object(stdClass)#1 (1) { ["field"]=> string(5) "mundo" } } 
    

Nota: come ottimizzazione, ogni singolo valore viene passato come riferimento fino alla sua modifica all'interno della funzione. Se è stato modificato e il valore è stato passato per riferimento, viene copiato e la copia viene modificata.


Per quanto riguarda la prima domanda, l'array viene passato per riferimento A MENO CHE sia stato modificato all'interno del metodo / funzione che stai chiamando. Se si tenta di modificare la matrice all'interno del metodo / funzione, viene eseguita prima una copia di essa, quindi viene modificata solo la copia. Questo fa sembrare che l'array sia passato per valore quando in realtà non lo è.

Ad esempio, in questo primo caso, anche se non si sta definendo la propria funzione per accettare $ my_array come riferimento (utilizzando il carattere & nella definizione del parametro), viene comunque passato per riferimento (ad esempio: non si spreca memoria con una copia non necessaria).

function handle_array($my_array) {  

    // ... read from but do not modify $my_array
    print_r($my_array);

    // ... $my_array effectively passed by reference since no copy is made
}

Tuttavia, se si modifica la matrice, viene prima creata una copia (che utilizza più memoria ma non altera la matrice originale).

function handle_array($my_array) {

    // ... modify $my_array
    $my_array[] = "New value";

    // ... $my_array effectively passed by value since requires local copy
}

FYI - questo è noto come "lazy copy" o "copy-on-write".


Ecco la semplice spiegazione (spero) del concetto pass by objectusato in Python.
Ogni volta che si passa un oggetto alla funzione, l'oggetto stesso viene passato (l'oggetto in Python è in realtà ciò che si chiamerebbe un valore in altri linguaggi di programmazione) e non il riferimento a questo oggetto. In altre parole, quando chiami:

def change_me(list):
   list = [1, 2, 3]

my_list = [0, 1]
change_me(my_list)

L'oggetto attuale - [0, 1] (che verrebbe chiamato un valore in altri linguaggi di programmazione) viene passato. Quindi in effetti la funzione change_meproverà a fare qualcosa come:

[0, 1] = [1, 2, 3]

che ovviamente non cambierà l'oggetto passato alla funzione. Se la funzione fosse simile a questa:

def change_me(list):
   list.append(2)

Quindi la chiamata risulterebbe in:

[0, 1].append(2)

che ovviamente cambierà l'oggetto. Questa risposta lo spiega bene.





php arrays reference pass-by-reference pass-by-value