MB: Alternativen für Restriktiven Property-Zugriff im Model (OOP)

moin,

wie kann man den Zugriff auf Properties im Model beschränken ohne auf Methoden im Model zurück zu greifen z.B. $model->qux und nicht $model->getQux()?

Ich möchte Methoden im Model nicht unbedingt verwenden wenn es nur ein paar zusammengehaltende Strings sein sollen.

Meine Lösung:

trait TraitStaticInstance {

  public function __set( $property, $value ) : void {};

  public function __get( $property ) : void {};
}
class FoobarModel {

  use TraitStaticInstance;

  public $qux;

  public $tuk;

  public function __construct ( string $qux, string $tux ) {
    $this->qux = $qux;
    $this->tux = $tux;
  }
}

Output:

$fb = new FoobarModel();

$fb->qux = 'hello world'; // geht leider
$fb->tux = 'hello world'; // geht leider
$fb->hi  = 'hello world'; // geht nicht

echo $fb->qux;
echo $fb->tuk;
echo $fb->by;  // geht nicht

Etwas bessere habe ich im Internet nicht gesehen 😕. Habt ihr mehr Erfolg???

lgmb

akzeptierte Antworten

  1. Lieber MB,

    ich verstehe Dein Problem nicht.

    wie kann man den Zugriff auf Properties im Model beschränken ohne auf Methoden im Model zurück zu greifen z.B. $model->qux und nicht $model->getQux()?

    was ist ein Model? Sprichst Du von MVC "Model"?

    Meine Lösung:

    Du definierst eine Klasse mit öffentlichen Eigenschaften. Es kommt (wie immer) darauf an, ob man das tatsächlich wollen möchte. Machst Du sie public, kannst Du mit $obj->qux direkt schreibend und lesend zugreifen. Die Sache mit den Traits hilft da überhaupt nicht.

    Machst Du $obj->qux dagegen private, benötigt $obj jeweils eine Methode, um den Wert in $obj->qux zu lesen und zu schreiben. Wenn man das Geheimnisprinzip anwendet, soll das auch so sein.

    Liebe Grüße

    Felix Riesterer

    1. moin,

      was ist ein Model? Sprichst Du von MVC "Model"?

      Ja meine ich als Beispiel.

      Die Sache mit den Traits hilft da überhaupt nicht.

      Fals ich Dich richtig verstehe, meinst du, dass zur Laufzeit hinzufügbare Instanz Properties nichts aus machen z.B. $obj->hi = 'by';. Ich hingegen möchte die Instanz so beschränkt wie möglich halten und es das machen was es soll und nix anderes. Nur darum habe ich ja auch diese Interzeptor-Methoden im Trait ergänzt. Oder verstehe ich dich da miss???

      Machst Du […] dagegen private, benötigt […] jeweils eine Methode, um den Wert in […] zu lesen und zu schreiben.

      Die Datenkapselung wollte ich erst zur Veranschaulichung meines Problemes hacken, habs aber dann verworfen, weil es offensichtlich ist - schien mir so. Da habe ich den Platz in der Selfhtml Datenbank eingespart.

      lgmb

  2. Hallo MB,

    Du hast beim Schreiben auf existierende Properties ein leider gesetzt.

    Suchst du ein Objekt mit readonly-Properties?

    Rolf

    --
    sumpsi - posui - clusi
    1. moin,

      Suchst du ein Objekt mit readonly-Properties?

      Ja stimmt, meine ich. Sorry, war gestern spät und ein kurzes Zeitfenster 😕.

      lgmb

  3. Eigene Methoden sollten nicht mit __ beginnen. Warum steht im Handbuch. MFG

    1. Tach!

      Eigene Methoden sollten nicht mit __ beginnen. Warum steht im Handbuch.

      Du meinst diesen Satz?

      Caution PHP reserves all function names starting with __ as magical. It is recommended that you do not use function names with __ in PHP unless you want some documented magic functionality.

      Nun, die Einschränkung beginnend ab "unless" ist das, was für den vorliegenden Fall gewünscht ist.

      dedlfix.

    2. moin,

      Eigene Methoden sollten nicht mit __ beginnen. Warum steht im Handbuch. MFG

      @dedlfix hat die Referenz siehe hier

      lgmb

      1. moin,

        Eigene Methoden sollten nicht mit __ beginnen. Warum steht im Handbuch. MFG

        @dedlfix hat die Referenz siehe hier

        Ich würde dieser Empfehlung auch folgen und das generell so machen, also eigene Methoden eben nicht mit führenden Unterstrichen notieren. Im Übrigen gibt es solche Reservierungen ja nicht nur in PHP. Und auch keinen Grund diese zu mißachten.

        Und wie gesagt, das ist auch eine Erfahrung die ich hier weitergebe. MFG

        1. Tach!

          Ich würde dieser Empfehlung auch folgen und das generell so machen, also eigene Methoden eben nicht mit führenden Unterstrichen notieren. Im Übrigen gibt es solche Reservierungen ja nicht nur in PHP. Und auch keinen Grund diese zu mißachten.

          Es gibt keinen Grund, weiterhin zu missachten, dass die vorliegenden Methodennamen keine eigenen Erfindungen sind, sondern eine genau definierte Funktionalität haben und für diese vom Entwickler verwendet werden können, was bei MB der Fall ist.

          dedlfix.

  4. Tach!

    Habt ihr mehr Erfolg???

    Dein Beispiel enthält Syntaxfehler und die beiden Methoden __set() und __get() enthalten keinen Code. Deswegen ist "geht nicht" erklärlich.

    Der Zugriff bei "geht leider" ist auch normal, denn vorhandene und zugängliche (public) Eigenschaften triggern nicht den Aufruf von __set()/__get().

    dedlfix.

    1. moin,

      Dein Beispiel enthält Syntaxfehler und die beiden Methoden __set() und __get() enthalten keinen Code. Deswegen ist "geht nicht" erklärlich.

      war auch nur als beispiel gedacht, ich dachte das wäre klar 😉.

      Der Zugriff bei "geht leider" ist auch normal, denn vorhandene und zugängliche (public) Eigenschaften triggern nicht den Aufruf von __set()/__get().

      Schon klar. Ich hab ja in der Vergangenheit die Instance Properties mit private deklariert und hab mit der magic method __get() in der Instance drauf zugegriffen. Geht wie am Schnürchen, aber Du oder ein anderer hast mich drauf hingewiesen, dass das mit private bezüglich intellisense nicht geht. Schade 😕. Und deswegen suche ich im der neuste version nach alternativen.

      lgmb

      1. Tach!

        Dein Beispiel enthält Syntaxfehler und die beiden Methoden __set() und __get() enthalten keinen Code. Deswegen ist "geht nicht" erklärlich.

        war auch nur als beispiel gedacht, ich dachte das wäre klar 😉.

        Wenn die beiden Methoden Inhalt haben, dann ist mir nicht klar, was du mit "geht nicht" meinst. "Geht" und "geht nicht" sind zu allgemein, um Probleme nachvollziehbar zu beschreiben.

        Der Zugriff bei "geht leider" ist auch normal, denn vorhandene und zugängliche (public) Eigenschaften triggern nicht den Aufruf von __set()/__get().

        Schon klar. Ich hab ja in der Vergangenheit die Instance Properties mit private deklariert und hab mit der magic method __get() in der Instance drauf zugegriffen. Geht wie am Schnürchen, aber Du oder ein anderer hast mich drauf hingewiesen, dass das mit private bezüglich intellisense nicht geht. Schade 😕. Und deswegen suche ich im der neuste version nach alternativen.

        Die Code-Analyse kann selbstverständlich auch nicht-öffentliche Mitglieder lesen und der Autovervollständigung zur Verfügung stellen. Dann aber nur, wenn man sich im Code innerhalb der Klasse befindet. Eigenschaften, die nur über die Magic Methods __set()/__get() erreichbar sind, sind nicht statisch sondern erst zur Laufzeit verfügbar, denn dein Code kann beliebig auf angefragte Namen reagieren. Kennst du die verfügbaren Namen doch schon zur Entwicklungszeit, dann kannst du diese mit PHPDoc-Syntax bekanntgeben.

        Intellisense ist der Name der Programmiererunterstützung in Microsoft-Produkten, kein allgemeiner Begriff für Autovervollständigung.

        dedlfix.

        1. moin,

          […] sind nicht statisch sondern erst zur Laufzeit verfügbar, denn dein Code kann beliebig auf angefragte Namen reagieren.

          schon klar.

          […] Kennst du die verfügbaren Namen doch schon zur Entwicklungszeit, dann kannst du diese mit PHPDoc-Syntax bekanntgeben.

          Wow. habe ich nicht bedacht! Danke Dir 😀!!!

          lgmb

          1. Tach!

            […] sind nicht statisch sondern erst zur Laufzeit verfügbar, denn dein Code kann beliebig auf angefragte Namen reagieren.

            schon klar.

            Ich meinte damit, dass das der Grund ist, warum die Hilfen der IDE hier nicht (richtig) ziehen können, weil sie den Code nur statisch analysieren und nicht laufen lassen können.

            dedlfix.