Domanda

C'è un modo per emulare una classe di struttura in PHP? cioè una classe che passa per valore e non per riferimento, in modo che possa essere ancora tipo accennato ...

E se sì, quali tecniche diverse potrebbero essere utilizzati? Qual è la migliore tecnica?

Se questo è possibile, ovviamente, si potrebbe creare uno strato di sicurezza completamente digitare per PHP, ci sono tali strati? Qualcuno ha avuto esperienza con questo?

È stato utile?

Soluzione

Gli oggetti sono sempre passati per riferimento. L'unico modo per farli passare come una copia è utilizzare in modo esplicito la parola chiave clone (sì, in tutto il mondo).

La mia raccomandazione sarebbe quella di utilizzare una matrice, che sono i tipi di valore e quindi sempre copiato. Dal momento che è possibile utilizzarlo come un array associativo (per esempio stringa -> Valore), potrebbe anche essere un oggetto. Il rovescio della medaglia è, naturalmente, non è possibile utilizzare i metodi (ma questo è come una struct così si può essere soddisfatti di questo). Non c'è modo di far rispettare la sicurezza di tipo, tuttavia.

Ma con tutte le vostre esigenze suona come PHP non è il tuo tipo di linguaggio, ad essere onesti.

Altri suggerimenti

Credo che il modo più semplice è quello di farlo come java fa -. Avere le classi di valore siano immutabili, e lasciare che tutti i metodi di "modifica" restituiscono un nuovo oggetto, invece

Non credo che si può raggiungere questo obiettivo, solo con il codice PHP.

Non hai il controllo su come i parametri maniglia funzione PHP, e non vedo come si potrebbe fare in modo che tutto viene gestito nel modo desiderato, senza dover cambiare il (di livello inferiore) codice binario PHP e moduli .

Sarebbe abbastanza freddo, però:)

stavo giocando intorno con il suggerimento di anonimo di apportare eventuali mutazioni dell'oggetto restituiscono un nuovo oggetto, e questo funziona, ma è imbarazzante.

<?php
class FruityEnum {
    private $valid = array("apple", "banana", "cantaloupe");
    private $value;

    function __construct($val) {
        if (in_array($val, $this->valid)) {
            $this->value = $val;
        } else {
            throw new Exception("Invalid value");
        }
    }

    function __set($var, $val) {
        throw new Exception("Use set()!!");
    }
    function set(FruityEnum &$obj, $val) {
        $obj = new FruityEnum($val);
    }

    function __get($var) { //everything returns the value...
        return $this->value;
    }
    function __toString() {
        return $this->value;
    }
}

E ora di provarlo:

function mutate(FruityEnum $obj) { // type hinting!
    $obj->set($obj, 'banana');
    return $obj;
}

$x = new FruityEnum('apple');
echo $x; // "apple"
$y = mutate($x);
echo  $x // still "apple"
    . $y // "banana"

Funziona, ma è necessario utilizzare uno strano modo per modificare l'oggetto:

$obj->set($obj, 'foo');

L'unico altro modo avrei potuto pensare di farlo sarebbe quello di utilizzare il metodo __set(), ma che era anche peggio. Si doveva fare questo, che è sanguinosa confusione.

$obj = $obj->blah = 'foo';

Alla fine, è probabilmente più facile fare le variabili private e di fornire non mutatori, quindi l'unico modo per cambiare il valore "enum" di una variabile potrebbe essere quella di crearne uno nuovo:

echo $obj; // "banana"
$obj = new FruityEnum("cantaloupe");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top