Gli array in PHP sono passati per valore o per riferimento?



2 Answers

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

Question

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 ?




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.




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.




Related