Question

Est-il possible d'imiter une classe de la structure en PHP? à-dire une classe qui passe par valeur et non par référence, donc il peut encore être de type ... laissé entrevoir

Et si oui, quelles sont les techniques différentes pourraient être utilisées? Quelle est la meilleure technique?

Si cela est possible, vous pouvez évidemment créer un type totalement sans danger pour la couche PHP, y at-il de telles couches? Quelqu'un at-il eu une expérience avec cela?

Était-ce utile?

La solution

Les objets sont toujours passés par référence. La seule façon de les faire passer comme une copie est d'utiliser explicitement le mot-clé clone (oui, partout).

Ma recommandation serait d'utiliser un tableau, qui sont des types de valeur et donc toujours copié. Comme vous pouvez l'utiliser comme un tableau associatif (par exemple, chaîne -> valeur), il pourrait aussi bien être un objet. L'inconvénient est, bien sûr, vous ne pouvez pas utiliser des méthodes (mais c'est comme un struct donc vous pouvez être heureux avec cela). Il n'y a pas moyen de faire respecter la sécurité de type, cependant.

Mais avec tous vos besoins il semble que PHP n'est pas votre genre de langage, pour être honnête.

Autres conseils

Je pense que la meilleure façon est de le faire comme Java -. Avoir vos classes de valeurs immuables, et que tous les « modifications » méthodes renvoient à la place un nouvel objet

Je ne pense pas que vous pouvez atteindre cet objectif, seul avec le code PHP.

Vous avez aucun contrôle sur la façon dont les paramètres handle de la fonction PHP, et je ne vois pas comment vous pouvez vous assurer que tout est géré comme vous le voulez, sans avoir à modifier le code (niveau inférieur) dans le binaire PHP et modules .

Il serait assez cool, mais:)

Je jouais avec la suggestion de l'anonymat pour faire des mutations de l'objet renvoient un nouvel objet, et cela fonctionne, mais il est maladroit.

<?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;
    }
}

Et maintenant pour le tester:

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"

Il fonctionne, mais vous devez utiliser une étrange façon de changer l'objet:

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

La seule autre façon que je pouvais penser de le faire serait d'utiliser la méthode de __set(), mais qui était encore pire. Il fallait faire, ce qui est source de confusion sanglante.

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

En fin de compte, il est probablement plus facile de faire les variables privées et ne fournissent aucune mutateurs, la seule façon de changer la valeur « ENUM » d'une variable serait de créer un nouveau:

echo $obj; // "banana"
$obj = new FruityEnum("cantaloupe");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top