2 Stimmen

Emulation einer Werttyp-Strukturklasse in PHP

Gibt es eine Möglichkeit, eine Strukturklasse in PHP zu emulieren? dh eine Klasse, die durch Wert und nicht durch Referenz übergeben, so dass es noch Typ angedeutet werden kann...

Und wenn ja, welche verschiedenen Techniken könnten eingesetzt werden? Was ist die beste Technik?

Wenn dies möglich ist, könnten Sie offensichtlich eine vollständig typsichere Schicht für PHP erstellen, gibt es solche Schichten? Hat jemand damit Erfahrungen gemacht?

1voto

Anonymous Punkte 7

Ich denke, der einfachste Weg ist es zu tun, wie Java tut - haben Sie Ihre Wertklassen unveränderlich sein, und lassen Sie alle "Änderung" Methoden ein neues Objekt stattdessen zurückgeben.

1voto

Nicolas Punkte 2126

Ich glaube nicht, dass man dieses Ziel nur mit PHP-Code erreichen kann.

Sie haben keine Kontrolle darüber, wie PHP-Funktionen mit Parametern umgehen, und ich sehe nicht, wie Sie sicherstellen können, dass alles so gehandhabt wird, wie Sie es wünschen, ohne den (untergeordneten) Code in der PHP-Binärdatei und den Modulen ändern zu müssen.

Es wäre aber ziemlich cool :)

1voto

ryeguy Punkte 62987

Objekte werden immer per Referenz übergeben. Die einzige Möglichkeit, sie als Kopie zu übergeben, ist die explizite Verwendung der clone Stichwort (ja, überall).

Meine Empfehlung wäre, ein Array zu verwenden, da es sich dabei um Werttypen handelt und somit immer kopiert wird. Da man es als assoziatives Array verwenden kann (z.B. String -> Wert), könnte es genauso gut ein Objekt sein. Der Nachteil ist natürlich, dass Sie keine Methoden verwenden können (aber das ist wie bei einer Struktur, so dass Sie vielleicht damit zufrieden sind). Es gibt jedoch keine Möglichkeit, Typsicherheit zu erzwingen.

Aber mit all Ihren Anforderungen klingt es so, als ob PHP nicht Ihre Art von Sprache ist, um ehrlich zu sein.

1voto

nickf Punkte 517253

Ich habe mit dem Vorschlag von anonymous herumgespielt, dass alle Mutationen des Objekts ein neues Objekt zurückgeben, und das funktioniert, aber es ist umständlich.

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

Und nun zum Test:

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"

Es funktioniert, aber man muss eine seltsame Methode verwenden, um das Objekt zu ändern:

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

Die einzige andere Möglichkeit, die mir einfällt, wäre die Verwendung der __set() Methode, aber das war noch schlimmer. Man musste dies tun, was verdammt verwirrend ist.

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

Letztendlich ist es wahrscheinlich einfacher, die Variablen privat zu machen und keine Mutatoren bereitzustellen, so dass die einzige Möglichkeit, den "enum"-Wert einer Variablen zu ändern, darin bestünde, eine neue zu erstellen:

echo $obj; // "banana"
$obj = new FruityEnum("cantaloupe");

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X