tutorials.de Buch-Aktion 05/2012
Seite 1 von 2 12 LetzteLetzte
ERLEDIGT
JA
ANTWORTEN
15
ZUGRIFFE
387
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    jannicars jannicars ist offline Mitglied Gold
    Registriert seit
    Jun 2011
    Beiträge
    219
    Hallo,

    Ich bin gerade dabei mein aktuelles Projekt OOP zu machen.
    Jetzt bin ich schon beim ersten Problem angelangt.

    Als erstes mal ein Beispiel Quellcode:
    PHP-Code:
    <?php
    class class1{
        public function 
    load(){
            
    $test "test";
            return 
    $test;
        }
    }

    class 
    class2 extends class1{
        public function 
    __construct(){
            
    $load $this->load();
            echo 
    "Construct Echo:" $load;
            
    $this->function1();
        }
        public function 
    function1(){
            echo 
    "Function1 Echo:" $load;
        }
    }

    new 
    class2;
    ?>
    Nun meine Frage: wie kann ich $load in meiner class2 Globalisieren?
    Also dass ich nicht immer nochmals die function2 in jeder Funktion nochmals aufrufen muss?
    (function2 ist ein SQL-Query - Es wäre unsinnig mit 20 Funktionen 20 Querys zu erzeugen)

    So würde es klappen; find ich aber nicht so elegant, da ich die variable zu jeder Funktion immer mitübergeben müsste:
    PHP-Code:
    <?php
    class class1{
        public function 
    load(){
            
    $test "test";
            return 
    $test;
        }
    }

    class 
    class2 extends class1{
        public function 
    __construct(){
            
    $load $this->load();
            echo 
    "Construct Echo:" $load;
            
    $this->function1($load);
        }
        public function 
    function1($load){
            echo 
    "Function1 Echo:" $load;
        }
    }

    new 
    class2;
    ?>
    Gibt es da noch eine elegantere Lösung?
    Ich hab es noch so funktioniert, hat aber auch nicht geklappt:
    PHP-Code:
    <?php
    class class1{
        public function 
    load(){
            
    $test "test";
            return 
    $test;
        }
    }

    class 
    class2 extends class1{
        public function 
    __construct(){
            
    $load $this->load();
            echo 
    "Construct Echo:" $load;
            
    $this->function1();
        }
        public function 
    function1(){
            global 
    $load;
            echo 
    "Function1 Echo:" $load;
        }
    }

    new 
    class2;
    ?>
    Geändert von jannicars (11.12.11 um 20:09 Uhr)
     

  2. #2
    jannicars jannicars ist offline Mitglied Gold
    Registriert seit
    Jun 2011
    Beiträge
    219
    So scheint es gut zu klappen:
    PHP-Code:
    <?php
    class class1{
        public function 
    load1(){
            
    $test "test";
            return 
    $test;
        }
    }

    class 
    class2 extends class1{
        var 
    $load;
        public function 
    __construct(){
            
    $this->load $this->load1();
            echo 
    "Construct Echo:" $this->load;
            
    $this->function1();
        }
        public function 
    function1(){
            echo 
    "Function1 Echo:" $this->load;
        }
    }

    new 
    class2;
    ?>
    Wenn es eine bessere Möglichkeit gibt, nur her damit!
     

  3. #3
    Avatar von saftmeister
    saftmeister saftmeister ist offline Der Saft sei mit dir
    tutorials.de Premium-User
    Registriert seit
    May 2006
    Ort
    There is no place like 127.0.0.1
    Beiträge
    3.521
    Genauso macht man "globale" Klassen-Variablen. Eigentlich sind das sog. Member-Variablen. Sie können entweder

    - nur innerhalb der Klasse sichtbar sein (private)
    - innerhalb der Klasse und allen abgeleiteten Klassen sein (protected)
    - oder öffentlich sein (public)

    Hier ein paar Beispiele:

    private:

    Code php:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    
    <?php
    class klasse1
    {
      // Diese Klassenmember ist nur innerhalb dieser Klasse verfügbar
      private $member;
     
      public function __construct()
      {
         $this->member = 42;
      }
     
      public function printOutMember()
      {
        echo "In Klasse " .get_class($this) .": " . $this->member . "<br/>";
      }
    }
     
    class klasse2 extends klasse1
    {
      // Diese Klassenmember ist nur innerhalb dieser Klasse verfügbar
      private $memberKlasse2;
     
      // Konstruktor wird überschrieben
      public function __construct()
      {
         $this->memberKlasse2 = 44;
      }
     
      // Print-Out-Methode wird überschrieben
      public function printOutMember()
      {
        // Das hier funktioniert nicht bzw. gibt einen leeren String aus, 
        // da auf die Elternklassen-private-Member nicht zugegriffen werden kann
        // echo $this->member;
        echo "In Klasse " .get_class($this) .": " . $this->memberKlasse2 . "<br/>";
      }
    }
     
    $a = new klasse1();
    $a->printOutMember();
     
    $b = new klasse2();
    $b->printOutMember();

    Protected-Member und Methoden:

    Code php:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    
    class klasse1
    {
        // Diese Klassenmember ist nur innerhalb dieser Klasse und Kindsklassen verfügbar
        protected $member;
     
        public function __construct()
        {
            $this->member = 42;
        }
     
        public function printOutMember()
        {
            echo "In Klasse " .get_class($this) .": " . $this->member . "<br/>";
        }
    }
     
    class klasse2 extends klasse1
    {
        // Diese Klassenmember ist nur innerhalb dieser Klasse verfügbar
        private $memberKlasse2;
     
        // Konstruktor wird überschrieben
        public function __construct()
        {
            // Das ist notwendig, damit der Konstruktor in der Eltern-Klasse auch aufgerufen werden kann
            parent::__construct();
            $this->memberKlasse2 = 44;
        }
     
        // Print-Out-Methode wird überschrieben
        public function printOutMember()
        {
            // Das hier funktioniert nicht bzw. gibt einen leeren String aus,
            // da auf die Elternklassen-private-Member nicht zugegriffen werden kann
            echo "In Klasse " .get_class($this) .": " . $this->member . "<br/>";
            // Wir können auch die Methode in der Eltern-Klasse aufrufen:
            parent::printOutMember();
            echo "In Klasse " .get_class($this) .": " . $this->memberKlasse2 . "<br/>";
        }
    }
     
    $a = new klasse1();
    $a->printOutMember();
     
    // Das funktioniert auch nicht:
    //echo $a->member;
     
    $b = new klasse2();
    $b->printOutMember();
    // Und das funktioniert auch nicht
    //echo $b->memberKlasse2;

    Öffentliche Zugriffe

    Code php:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    
    <?php
    class klasse1
    {
        // Diese Klassenmember ist nur innerhalb dieser Klasse und Kindsklassen verfügbar
        protected $member;
     
        public function __construct()
        {
            $this->member = 42;
        }
     
        public function printOutMember()
        {
            echo "In Klasse " .get_class($this) .": " . $this->member . "<br/>";
        }
    }
     
    class klasse2 extends klasse1
    {
        // Diese Klassenmember ist global verfügbar
        public $memberKlasse2;
     
        // Konstruktor wird überschrieben
        public function __construct()
        {
            // Das ist notwendig, damit der Konstruktor in der Eltern-Klasse auch aufgerufen werden kann
            parent::__construct();
            $this->memberKlasse2 = 44;
        }
     
        // Print-Out-Methode wird überschrieben
        public function printOutMember()
        {
            // Das hier funktioniert nicht bzw. gibt einen leeren String aus,
            // da auf die Elternklassen-private-Member nicht zugegriffen werden kann
            echo "In Klasse " .get_class($this) .": " . $this->member . "<br/>";
            echo "In Klasse " .get_class($this) .": " . $this->memberKlasse2 . "<br/>";
        }
    }
     
    $a = new klasse1();
    $a->printOutMember();
     
    // Das funktioniert nicht:
    //echo $a->member;
     
    $b = new klasse2();
    $b->printOutMember();
    // Das hier aber schon:
    echo "Im globalen Scope: " . $b->memberKlasse2 . "<br/>";

    Vielleicht hilft es dir ein bisschen

    Wenn du fragen hast, her damit
    Geändert von saftmeister (12.12.11 um 07:22 Uhr) Grund: Kommentare gefixt
     
    Grüße
    --
    Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)

  4. #4
    jannicars jannicars ist offline Mitglied Gold
    Registriert seit
    Jun 2011
    Beiträge
    219
    Hallo Saftmeister,

    Ich verstehe zwar schon jetzt diese 3 Eigenschaften Bedeutungen, erkenne aber leider nicht den Sinn, wo ich Public, protected und private wie am sinnvollsten einsetzen söllte...?
     

  5. #5
    Avatar von Maniac
    Maniac Maniac ist offline Mitglied Smaragd
    Registriert seit
    Apr 2007
    Ort
    Augsburg/Gersthofen (Bayern)
    Beiträge
    1.204
    Private zb dann wenn du nicht willst das Kind-Klassen diese Variable überschreiben können.

    Protected wenn sie von Kind-Klassen überschrieben werden darf.

    Public ist quasi komplett offen, dort kannst du sie auch ausserhalb der Klasse überschreiben:

    PHP-Code:
    class test
    {
       public 
    $var1;
       protected 
    $var2;
       private 
    $var3;

       public function 
    __construct(){
          
    $this->var1 'is public';
          
    $this->var2 'is protected';
          
    $this->var3 'is private';
       }

       public function 
    getVar1(){
          echo 
    $this->var1;
       }

       public function 
    getVar2(){
          echo 
    $this->var2;
       }

        public function 
    getVar3(){
          echo 
    $this->var3;
       }
    }

    $Test = new test();

    echo 
    $Test->var1// gibt Wert der Variable zurück

    echo $Test->var2// Fehler, da Member-Variable nicht von aussen zugreifbar ist. Das selbe auch bei $this->var3

    echo $Test->getVar1(); // gibt wert 'is public'
    echo $Test->getVar1(); // gibt wert 'is protected'
    echo $Test->getVar1(); // gibt wert 'is private' 
    Saftmeister hat es eigentlich schon perfekt erklärt.
     
    Die Schweine von heute sind unsere Schnitzel von morgen!

  6. #6
    Avatar von saftmeister
    saftmeister saftmeister ist offline Der Saft sei mit dir
    tutorials.de Premium-User
    Registriert seit
    May 2006
    Ort
    There is no place like 127.0.0.1
    Beiträge
    3.521
    Das kommt auf den Anwendungsfall an. Ich habe jetzt aus dem Stand kein Beispiel parat, wo man welche Variante einsetzen könnte. Außer vielleicht dem:

    Code php:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    
    <?php
    /**
     * Basis-Personen-Klasse
     * 
     * Unveränderliche Werte werden privat sein
     * Veränderliche Werte werden protected sein
     * 
     * @author saftmeister
     */
    class Person
    {
        /**
         * Die ID in z.B. der Datenbank
         * 
         * @var int
         */
        private $id;
        
        /**
         * Der Vorname der Person
         * 
         * @var string 
         */
        private $firstName;
        
        /**
         * Der Nachname der Person
         * 
         * @var string
         */
        protected $lastName;
        
        /**
         * Das Geburtsdatum der Person
         * 
         * @var DateTime
         */
        private $birthDate;
        
        /**
         * Die Adresse der Person
         * 
         * @var Address
         * @todo Adressenklasse schreiben
         */
        protected $address;
        
        /**
         * Neues Objekt vom Typ Person erzeugen
         * 
         * @param int $id
         * @param string $firstname
         * @param string $lastname
         * @param DateTime $birthdate
         * @param Adress $address
         * @throws Exception
         */
        public function __construct($id, $firstname, $lastname, DateTime $birthdate, $address)
        {
            $this->id = $id;
            
            if(!$this->id)
            {
                throw new Exception('Ungültige ID!');
            }
            
            $this->firstName = $firstname;
            $this->lastName  = $lastname;
            $this->birthDate = $birthdate;
            $this->address   = $address;
        }
        
        /**
         * Gibt die ID des Datensatzes zurück
         * 
         * @return int
         */
        public function getId()
        {
            return $this->id;
        }
        
        /**
         * Gibt den Vornamen zurück
         * 
         * @return string
         */
        public function getFirstName()
        {
            return $this->firstName;
        }
        
        /**
         * Gibt das Geburtsdatum zurück
         * 
         * @return DateTime
         */
        public function getBirthDate()
        {
            return $this->birthDate;
        }
    }
     
    /**
     * Mitarbeiter-Klasse
     * 
     * @author jannicars
     */
    class Employer extends Person
    {
        /**
         * Art der Mitarbeit
         * 
         * @var string
         */
        private $work;
        
        /**
         * Ein neues Objekt vom Typ Employer erzeugen
         * 
         * @param int $id
         * @param string $firstname
         * @param string $lastname
         * @param DateTime $birthdate
         * @param Adress $address
         * @param string $work
         */
        public function __construct($id, $firstname, $lastname, $birthdate, $address, $work)
        {
            // Eltern-Konstruktor aufrufen und Werte übergeben
            parent::__construct($id, $firstname, $lastname, $birthdate, $address);
            
            $this->work = $work;
        }
        
        /**
         * Mitarbeits-Art zurück geben
         * @return string
         */
        public function getWork()
        {
            return $this->work;
        }
    }
     
    $saftmeister = new Employer(1, 'saft', 'meister', new DateTime('1970-01-01'), '127.0.0.1', 'Coder');
     
    echo "ID: " . $saftmeister->getId() . "<br/>";
    echo "Work: " . $saftmeister->getWork() . "<br/>";

    Angenommen, die Klasse "Person" ist für dich nicht verfügbar, lediglich die öffentlichen Schnittstellen. Du kannst also maximal den Konstruktor aufrufen, um ein neues Objekt zu erzeugen und die ID abholen.

    Du sollst jetzt eine Klasse "Employer" schreiben, die "Person" erweitert, auf die veränderlichen Werte darfst du schreibend und lesend zu greifen. Veränderlich bedeutet, das man die Werte jederzeit anpassen können muss.

    Werte wie der Vorname, das Geburtsdatum und die ID definieren wir einfach mal unveränderlich. Daher kannst du nur über Getter auf die Werte zu greifen.

    Das ganze macht vor allem dort Sinn, wo mit Klassen gearbeitet werden soll, auf die ein weiterer Programmierer (saftmeister hat die Klasse "Person" geschrieben, jannicars die Klasse "Employer") keinen Zugriff haben braucht/soll/darf.

    Wie gesagt, das ist stark vom Anwendungsfall abhängig.
     
    Grüße
    --
    Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)

  7. #7
    jannicars jannicars ist offline Mitglied Gold
    Registriert seit
    Jun 2011
    Beiträge
    219
    Danke für das Beispiel!

    Ich werde einfach alles Public machen,
    da es ja sonst keine Vorteile gibt, außer das es eingegrenzt ist.
    Bringt denn das Eingrenzen was für die Sicherheit oder wie?

    Und da ich die Klassen eh nur für mein eigenes Projekt benutze,
    ist es doch egal und ich lass es einfach immer bei Public...?
    Geändert von jannicars (12.12.11 um 15:36 Uhr)
     

  8. #8
    Avatar von Yaslaw
    Yaslaw Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    5.205
    Sicherheit - Begrenzt.
    Aber es gibt manchmal Methoden innerhalb von Klassen, die öffentlich keinen Sinn machen oder gar einen Fehler generieren wenn sie von Ausserhalb aufgerufen wird.

    Gut, du programmierst für dich alleine. Dann gehts mit public. Aber wenn du mit anderen zusammen programmierst oder deinen Code weiter geben willst, so kannst du mit diesen Unterscheidungen dem Anwender der Klasse mitgeben welche Methoden für ihn sind und welche nicht.

    Nimm als Beispiel ein Auto. Der Anlasser ist public. Den kann jeder anwenden. Mit dieser Methode (das drehen des Zündschlüssels) werden im Auto aber diverse weitere Methoden aufgerufen (einlassen von Benzin, zünden, ankurbeln etc.) All diese Methoden sind private, da du sie von Aussen nicht anwenden kannst.
    jannicars bedankt sich. 
    ---------------------------------------------------------------------------------------------------
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements kann man formatieren!)
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Bitte zur besseren Lesbarkeit PHP-Code in [PHP]...[/PHP], SQL in [SQL]...[/SQL], Visual Basic in [VB]...[/VB] etc. schreiben

  9. #9
    Avatar von saftmeister
    saftmeister saftmeister ist offline Der Saft sei mit dir
    tutorials.de Premium-User
    Registriert seit
    May 2006
    Ort
    There is no place like 127.0.0.1
    Beiträge
    3.521
    Es ist vor allem für dich als Entwickler gedacht.

    Eine gut durchdachte Klassen-Architektur verringert Fehlerquellen. Angenommen, du hast zwei Klassen, beide haben nix mit einerander gemeinsam, außer einer public Membervariablen, die zufällig in beiden Klassen gleich heißt. In einem unachtsamen Moment schreibst du statt $a->membervar ein $b->membervar. Dann gehst du 2 Tage auf die Suche nach dem Fehler, weil das nicht unbedingt offensichtlich ist.

    Zugegeben, das könnte natürlich auch mit Settern passieren.

    Wenn du allerdings Member als private deklarierst, die nicht unbedingt von außen erreichbar sein müssen, förderst du deine eigene Hirnhygiene. Das ist ein nicht zu unterschätzendes Stil-Mittel.

    Sei's drum. Wenn du das public machen willst, weil es dir damit erstmal leichter fällt, dann mach es so. Ab einem gewissen Level, wenn du schon OOP gut beherrschst, wirst du es freiwillig anwenden

    Aber ich muss entschieden protestieren: Egal ist es nicht! Wenn es egal wäre, hätte man die drei Modifizierer nicht einführen brauchen

    Spätestens bei Singleton- oder Factory-Pattern wirst du merken, das es gut ist, sowas zu haben.

    Und ja, es hat was mit Sicherheit zu tun. Damit steuerst du Zugriffsmodi auf Member-Variablen und Methoden.

    Ich bin mir sicher, das du es eines Tages verwenden wirst
    jannicars bedankt sich. 
    Grüße
    --
    Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)

  10. #10
    jannicars jannicars ist offline Mitglied Gold
    Registriert seit
    Jun 2011
    Beiträge
    219
    Danke euch beiden für die sehr gute Erklärung
    (vor allem das Beispiel mit dem Auto war gut ).
     

  11. #11
    jannicars jannicars ist offline Mitglied Gold
    Registriert seit
    Jun 2011
    Beiträge
    219
    Noch eine Frage: muss man __construct auch eine Eigenschaft wie public, protected oder private zuweisen?
     

  12. #12
    Avatar von Maniac
    Maniac Maniac ist offline Mitglied Smaragd
    Registriert seit
    Apr 2007
    Ort
    Augsburg/Gersthofen (Bayern)
    Beiträge
    1.204
    Müssen nicht, wenn du allerdings bei einer Eigenschaft (Member-Variable) sowie einer Funktion (Klassen-Methode) nichts angibst, wird automaitsch angenommen das es "public" ist.

    Den Konstruktor musst du auf public stellen wenn du die Klasse von aussen instanzieren möchtest ala
    PHP-Code:
    $myClass = new MyClass(); 
    Es gibt aber noch andere Beispiele wo man den Konstruktor auf protected oder private setzen kann.
     
    Die Schweine von heute sind unsere Schnitzel von morgen!

  13. #13
    Avatar von saftmeister
    saftmeister saftmeister ist offline Der Saft sei mit dir
    tutorials.de Premium-User
    Registriert seit
    May 2006
    Ort
    There is no place like 127.0.0.1
    Beiträge
    3.521
    Hmm, warum probierst du es nicht einfach? Nur als Tipp: Wenn du den Constructor private deklarierst, was meinst du, was dann passiert? Ist es dann überhaupt noch möglich, ein Objekt von der Klasse zu erzeugen?
     
    Grüße
    --
    Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)

  14. #14
    jannicars jannicars ist offline Mitglied Gold
    Registriert seit
    Jun 2011
    Beiträge
    219
    Eigentlich wollte ich nur wissen ob man Public mit angeben muss oder nicht.
     

  15. #15
    Avatar von saftmeister
    saftmeister saftmeister ist offline Der Saft sei mit dir
    tutorials.de Premium-User
    Registriert seit
    May 2006
    Ort
    There is no place like 127.0.0.1
    Beiträge
    3.521
    Hat Maniac bereits geschrieben: Muss man nicht, wird bei nicht Angabe automatisch auf public gesetzt.

    EDIT:

    Das muss aber nicht heißen, dass das für immer so bleibt. Es könnte sein, dass das PHP-Core-Team sich von heute auf morgen entscheidet, dass aus Sicherheitsgründen um zu drehen und als "deprecated" einzustufen.
     
    Grüße
    --
    Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)

Ähnliche Themen

  1. PHP-Log-Klasse: neu oder global?
    Von suntrop im Forum PHP
    Antworten: 3
    Letzter Beitrag: 24.11.09, 18:47
  2. Klasse global für alle SWFs nutzen
    Von p-flash im Forum Flash Plattform
    Antworten: 2
    Letzter Beitrag: 24.09.07, 15:29
  3. Übergabe einer Variable und Variable=global?
    Von Master Flexi im Forum PHP
    Antworten: 16
    Letzter Beitrag: 11.04.07, 13:19
  4. C Klasse aus DLL benutzen
    Von jhunners im Forum .NET Archiv
    Antworten: 0
    Letzter Beitrag: 24.09.04, 12:33
  5. Global.php von wbb1.2 in anderem Ordner benutzen
    Von TodesengelAzrael im Forum PHP
    Antworten: 4
    Letzter Beitrag: 12.01.04, 12:55