Referenz in Klassen

  • Kann mir das jemand erklären:
    2 Klassen
    - User
    - UserController


    Aus User erzeuge ich ein object : $user = new User();
    Wenn ich jetzt $user in UserController schicke und dort als Eigenschaft setze (egal ob static oder nicht), dann wird eine Referenz aufgebaut :huh: ?


    Bsp:


    output:


    Wieso wird ne Referenz erstellt? Ich bin immer davon ausgegangen, dass das nur passiert, wenn ich "&" benutze oder vererbe.

  • Lösung:
    http://www.php.net/manual/de/language.oop5.references.php
    Siehe Beispiel #1 Referenzen und Objekte


    Also, falls es mal jemand braucht:


    Allgemein, also ohne Klassen kann man ja mit & Referenzen zwischen (zB) Variablen aufbauen.

    PHP
    $a = 1;
    $b =& $a; #  beide vars zeigen nun auf den gleichen inhalt (also 1) (php.net: "sind Referenzen")
    echo $a; # == 1
    echo $b; # == 1


    Klassen:


    Und genau deswegen,
    weil durch das bereits bestehende Object $a eine Kopie $b erzeugt wird, welche auf den gleichen Inhalt zeigt,
    deswegen also bekomme ich im Bsp vom ersten Post eine Referenz.


    Einfaches Bsp:


    und jetzt wirds interessant:
    Im oberen "einfachen Bsp" haben wir kopiert. Dabei haben beide auf den gleichen Bezeichner des Inhalts gezeigt, aber "das eine kann auch ohne dem anderen".
    Löscht man also eine Kopie, existiert immer noch die Andere.
    EDIT: wie auf php.net erwähnt:

    Zitat

    $a und $b sind Kopien des gleichen Bezeichners


    ich versuch das mal darzustellen:

    Code
    inhalt
           |
      bezeichner
      |	   |
    kopie $a   kopie $b




    Will man also beide referenzieren
    müssen wir & benutzen:


    Damit ist also sichergestellt, dass die Instatz von User in meinem Controller genau den gleichen Zustand hat wie die "originale" Instatz außerhalb =)


    sorry - viel, aber wertvoll =)


    EDIT: bsp entfernt, weil verwirrend

  • Da ich mir gerade C++ ansehe und Referenzen in PHP jetzt besser verstehe wollte ich das hier mal Teilen (PHP ist ja in C/C++ geschrieben):


    Eine Referenz ist ein Alias.
    Die Referenz (also der Alias) zeigt auf die gleiche Adresse im Speicher (RAM).


    Heißt:
    Wenn ich eine Variable in C++ erstelle die vom Typ int ist, dann belegt diese Variable 4 Bytes im RAM.
    Der RAM hat Byte für Byte Adressen - zB 0xfff1.


    Die Referenz ist also keine Kopie.
    Die Referenz geht nicht über Umwege.
    Sondern die Referenz zeigt direkt auf diese Speicheradresse im RAM.


    Das wiederum erklärt, warum Variablen die als Referenz in eine Funktion aufgenommen werden auch Auswirkungen auf draußen haben.
    Die Variable verfällt, sobald die Funktion beendet/verlassen wird.
    Die Änderungen wurden allerdings direkt im Speicher vorgenommen - dort, wo die Daten liegen.


    In wie weit das in PHP umgesetzt wird weiß ich nicht.
    Aber ich schätze das Verhalten wurde simuliert.
    Denn in C++ wird beim Löschen der Variable der Speicher freigeben. Das heißt, dass die Referenz auf nichts zeigt.
    In PHP hingegen:

    PHP
    $var = 1; 
    $ref = &$var; // referenz zu $var herstellen 
    unset($var); // var löschen
    echo $ref; // ausgabe: 1


    In der PHP Doku wir von Bezeichnern gesprochen.
    Logische Schlussfolgerung:
    beim Erstellen der $var werden die Daten im RAM hinterlegt
    PHP erstellt (denke ich) einen Bezeichner, der auf diese Speicheradresse zeigt.
    Der Bezeichner vermittelt dann zwischen PHP-$var und Speicheradresse.
    Wird eine Referenz $ref zu $var erstellt, dann wird wohl der Bezeichner kopiert und Beide - die Bezeichner von $var und $ref - zeigen beide auf die gleiche speicheradresse.

    Code
    inhalt (Speicheradresse)
      |           |
    bezeichner  bezeichner(kopie)
      |           |
    $var   =   &$ref;


    In PHP wird also kein Speicher freigegeben (wenn nicht doch intern geregelt/geklärt).


    Hoffe man kann es verstehen =)



    EDIT:
    PHP gibt doch Speicher wieder frei:

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!