riferimenti di variabili

salve,

ho un dubbio sui riferimenti delle variabili.

ho scritto un codice simile al seguente:

mia_funz($_SESSION["test"]);
FUNCTION mia_funz(&$par) { $par="valore"; }
var_dump($_SESSION["test"]);
//output: "valore"

ho anche provato così:

mia_funz(&$_SESSION["test"]);
FUNCTION mia_funz($par) { $par="valore"; }
var_dump($_SESSION["test"]);
//output: "valore"

il risultato è stato il medesimo, indi vorrei capire meglio come funziona l'operatore &.

grazie

inviato 8 anni fa
larchitetto
X 0 X

L'operatore & (ampersand, E commerciale) quando è anteposto al nome di una variabile restituisce il suo indirizzo anziché una sua copia.

Capirai meglio con questo esempio:

<?php
    $a = "vecchio";
    
    /**
     * Copio $a in $b
     *
     */
    $b = $a;
    
    /**
      * Creo un alias di $a e lo chiamo $c, praticamente prendo il riferimento di $a e lo metto in $c
      * in questo modo $c puntera' ad $a
      */
    $c = &$a;
    
    echo 'a:';
    var_dump($a);    
    
    /**
     * $b e' una COPIA di $a
     */
    echo 'b:';
    var_dump($b);
    
    /**
     * $c e' un riferimento alla locazione di memoria di $a
     */
    echo 'c:';
    var_dump($c);
    
    /**
     * vediamo cosa succede ora modificando il valore di $a
     */
    $a = "nuovo";  
    

    echo 'a:';
    var_dump($a);    
    
    /**
     * $b ha ancora il vecchio valore di $a, questo avviene perche' e' una sua copia!
     */
    echo 'b:';
    var_dump($b);
    
    /**
     * $c si comporta come se fosse $a perche' continua a fare riferimento alla locazione di memoria di $a
     * in questo modo, modificando $a, $c rispecchiera' il nuovo valore di $a.
     */
    echo 'c:';
    var_dump($c);
    
   

prova ad eseguirlo e vedrai le differenze :P

:bye:

risposto 8 anni fa
Andrea Turso
Andrea Turso
86
modificato 8 anni fa
X 0 X

nell'ultimo commento hai scritto:

   
    /**
     * $c si comporta come se fosse $a perche' continua a fare riferimento alla locazione di memoria di $a
     * in questo modo, modificando $a, $b rispecchiera' il nuovo valore di $a.
     */
    echo 'c:';
    var_dump($c);

anzichè $b, ti riferivi forse a $c, cisto che $c era il riferimento di $a, mentre $b una copia; o erro io?

cmq la situazione era chiara nel caso "semplice" delle variabili. il mio problema nasce con le funzioni e il relativo passaggio di parametri.

potrei risolvere il mio problema con un return <valore> alla variabile, anzichè metter su il riferimento della memoria, ma ormai son curioso di capire.

dunque, ragionando un altro minutino, sarebbe più logico passare alla funzione un riferimento come parametro. se facessi al contrario (e il risultato era sempre quello, da quello che ho visto), significa che nella dichiarazione della funzione creo un riferimento alla variabile passata come parametro? ha senso quello che ho scritto?

grazie

risposto 8 anni fa
larchitetto
X 0 X

Perdonami, hai perfettamente ragione ho sbagliato a scrivere nel commento, comunque ho corretto.

Quello a cui tu ti riferisci è il passaggio di parametri per valore o per riferimento.

<?php
/**
 * Prende come argomento un array ($array) e lo copia nella variabile
 * locale $array.
 *
 * Aggiunge poi un nuovo elemento ad $array;
 */
function paramValore(array $array) {
    $array[] = "nuovo elemento";
}
/**
 * Prende come argomento il riferimento ad un array ($array) e lo memorizza nella variabile locale
 * $array.

 */
function paramRiferimento(array &$array) {
    $array[] = "nuovo elemento";
}
$a = array("lol", "rofl");

paramValore($a);
var_dump($a);

paramRiferimento($a);
var_dump($a);

Il vantaggio del passaggio di parametri per riferimento è visibile soprattutto quando passi ad una funzione array o oggetti decisamente pesanti.

Passando il parametro per valore dovresti attendere che tutti gli elementi dell'array passato come parametro siano copiati nella nuova variabile locale prima che possa iniziare ad essere eseguita la tua funzione.

Passando il parametro per riferimento invece il problema non si pone in quanto la tua funzione andrà a lavorare direttamente sull'array in memoria.

Ovviamente come per gli array, il discorso vale per tutti gli altri tipi di dato.

Quando passi un parametro ad una funzione che accetta argomenti passati per riferimento (quindi ha & prima del parametro) essa copierà il riferimento (ovvero l'indirizzo della locazione di memoria nella quale risiede la variabile passata come parametro [parametro attuale]) nella variabile locale della funzione.

Nel caso dell'esempio la funzione paramRiferimento(array &$array) all'atto della chiamata essa prende l'indirizzo del parametro attuale e lo copia in $array che è una variabile locale della funzione di tipo array.

In questo modo quando tu accedi a $array dall'interno della funzione paramRiferimento ti starai riferendo a quello che è contenuto all'interno della cella di memoria che si trova a quell'indirizzo.

:P è complesso, dovresti aver studiato un pò di informatica prima ^^

per approfondimenti Parametri attuali e formali, vedi anche paragrafi 1.1.3 e 1.1.4.

perdonami per le spiegazioni "stupide" ma oggi ho frettissima!

:bye:

risposto 8 anni fa
Andrea Turso
Andrea Turso
86
modificato 8 anni fa
X 0 X

ehm, ti dirò...

tutto quello che hai scritto è stato chiaro ed ho pure ripassato qualche concetto appreso un po' di tempo fa.

studiai i puntatori in c (indi il concetto di base c'è), e grazie alla tua spiegazione ho soddisfatto la mia curiosità sul php.

grazie

risposto 8 anni fa
larchitetto
modificato 8 anni fa
X 0 X

Faccio notare che il passaggio di parametri per riferimento dovrebbe avvenire solo mettendo la & nella firma della funzione (o metodo di classe) e non usando la & nella chiamata di funzione:

CORRETTO:

<?php
function foo(&$var)
{
    $var++;
}

$a=5;
foo($a);
// $a is 6 here
?>

DEPRECATO:

<?php
function foo($var)
{
    $var++;
}

$a=5;
foo(&$a);
// $a is 6 here
?>

Questa seconda modalità, detta "call-time pass-by-reference", attualmente genera un Warning e non sarà più disponibile in PHP 6

 :bye:

risposto 8 anni fa
Gianni Tomasicchio
X 0 X

perfetto grazie :)

ah un'altra cosa, escludendo la sintassi, che differenze hanno i due modi (corretto e deprecato)?

risposto 8 anni fa
larchitetto
X 0 X

nel primo metodo è esplicitato all'atto della definizione della funzione che l'argomento è un indirizzo.

nel secondo metodo viene utilizzato l'operatore "indirizzo di" per fornire il riferimento della variabile alla funzione.

:bye:ù

risposto 8 anni fa
Andrea Turso
Andrea Turso
86
X 0 X

ok grazie =D

risposto 8 anni fa
larchitetto
X 0 X
Effettua l'accesso o registrati per rispondere a questa domanda