Statische Aufrufe an Objekt weitergeben

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Statische Aufrufe an Objekt weitergeben

    N Abend,

    ich dachte eigentlich, dass ich OOP relativ gut verstanden hätte, wurde aber eines besseren belehrt. Deswegen suche ich jemanden, der mir hier ein bisschen helfen kann.
    Ich teste gerade ein wenig mit Models ala Laravel, d.h. Aufrufe sehen so aus:

    PHP-Quellcode

    1. <?php
    2. User::find(1); // liefert den User mit der ID = 1
    3. User::where('name', 'Horst')->orderBy('id')->get(); // liefert alle User mit name = Horst.
    Ich dachte mir, das kann ich auch und hab munter losprogrammiert und aktuell sieht die Klasse auch recht gut aus (Unsauberkeiten sind zu entschuldigen). Allerdings scheitere ich an dem statischen Aufruf, der (zumindest bei Laravel) irgendwie keiner ist. Da ich mich die letzten Stunden vergeblich durch den Laravel-Code gekämpft habe um die Logik zu verstehen, bräuchte ich Hilfe von jemanden mit mehr Ahnung.
    Ich weiß es ist eigentlich nur eine Spielerei, aber ich würde gern das Konzept verstehen.

    PHP-Quellcode

    1. abstract class Model {
    2. protected $query;
    3. protected $table;
    4. protected $columns = ['*'];
    5. protected $whereCondition;
    6. public function __construct() {
    7. $this->getTable();
    8. }
    9. public function find($int) {
    10. return $this->where('id', $int)->get();
    11. }
    12. public function select($columns) {
    13. $this->columns = is_array($columns) ? $columns : func_get_args();
    14. return $this;
    15. }
    16. public function where($key, $value, $operator = '=') {
    17. $this->whereCondition = $key . ' ' . $operator . ' ' . $value;
    18. return $this;
    19. }
    20. public function get() {
    21. $this->query = 'SELECT ' . implode(', ', $this->columns) . ' FROM ' . $this->table . ' WHERE ' . $this->whereCondition;
    22. return $this;
    23. }
    24. }
    25. class User extends Model {}
    26. // klappt wunderbar
    27. $user = new User();
    28. $user->select('id', 'name')->where('mail', 'asdf@asdf.de')->get();
    29. // so hätte ichs gern
    30. $user = User::select('id', 'name')->where('mail', 'asdf@asdf.de')->get();
    Alles anzeigen
    Konkret müsste ich also den statischen Aufruf an das Objekt durchreichen, da die anderen Funktionen dann ja auf diesem Objekt arbeiten können, allerdings stirbt PHP bereits beim Aufruf (logischerweise). Wie kann ich das abfangen?
  • Habe zwar von Laravel konkret keinen blassen Schimmer, bin aber eigentlich in der OOP an sich recht bewandert. Daher wage ich es mal zu antworten.

    Ich würde vorschlagen dem Model eine statische "instance" Variable zu geben. Beim Aufruf von den Methoden fragst du dann ab, ob diese Instanz existiert. Wenn nicht, erstellst du sie erst und arbeitest dann weiter. Am Ende dann logischerweise statt return this ein return self::instance<
    Drasko@easy-scripting.net since 31.12.2011
    [Blockierte Grafik: http://files.tzdev.de/banner.png]
  • Okay,
    ich habs jetzt im ersten Moment so verstanden, dass ich in allen Methoden $this durch self::$instance ersetzen muss, aber das funktioniert nur beim ersten Aufruf User::select('name');, sobald ein zweiter Parameter dazu kommt, scheitert PHP wieder.
    Vermutlich stehe ich komplett auf dem Schlauch, aber ich kriegs grad nicht gebacken.

    PHP-Quellcode

    1. abstract class Model {
    2. protected static $instance = null;
    3. public static function instance() {
    4. if (is_null(self::$instance)) {
    5. self::$instance = new self();
    6. }
    7. return self::$instance;
    8. }
    9. // aktualisiert
    10. public function select($columns) {
    11. self::$instance->columns = is_array($columns) ? $columns : func_get_args();
    12. return self::$instance;
    13. }
    14. }
    Alles anzeigen
    Noch dazu mault PHP, dass man non-static Methoden nicht statisch aufrufen soll (und dass das Objekt leer ist), was aber ja eigentlich ein Zeichen von schlechtem OOP ist?!