[OOP] Vererbung einer Klasse / Wert lässt sich nicht überschreiben

Parantatatam

mag Cookies & Kekse
Hallo,

ich zweifle gerade ein wenig an mir selber, aber ich bastle gerade an einem CMS und das basiert auf der MVC-Struktur. Jedenfalls will ich den Controller und View sowohl für die öffentlich zugänglichen Bereiche nutzen, wie auch für den Administrationsbereich. Da aber der Controller für den Administrationsbereich mit Dateien aus einem anderen Verzeichnis gespeist wird, erstelle ich für diesen Bereich einen Admin_Controller, welcher seine Struktur vom eigentlichen Controller erbt. Damit ich das Verzeichnis ändern kann, habe ich eine Variable $this->__directory als protected definiert um sie zu überschreiben können. Allerdings funktioniert das nicht. Wenn sich jemand meiner annehmen und sich meine Dateien mal anschauen könnte, dann fände ich das äußerst nett.

Controller
PHP:
<?php
    class Controller {
        
        /**
         * Singletoninstanz der Klasse
         * Ermoeglicht, dass nur eine Instanz dieser Klasse zur Laufzeit existieren kann
         */
        private static $instance = NULL;
        
        /**
         * Enthaelt den Dateinamen des Controllers (ohne Suffix)
         */
        private $__page = '';
        
        /**
         * Gibt das Verzeichnis an, aus dem die entsprechenden Dateien geladen werden sollen
         * 
         * Dieser Wert kann veraendert werden, wenn er beispielsweise fuer den Controller des
         * Administrationsbereiches genutzt wird
         */
        protected $__directory = 'core/controller/';
        
        /**
         * Erstellt den Controller
         */
        final public static function start($page = 'default') {
                        
            /**
             * Erstellt den Controller, wenn die Instanz der Klasse noch nicht existiert
             */
            if(self::$instance === NULL) {
                /**
                 * Ruft den Konstruktor der Klasse auf, welcher nur auf diesem Weg geladen werden kann
                 */
                self::$instance = new self($page);
            }
            
            /**
             * Gibt die Instanz der Klasse zurueck
             */
            return self::$instance;
        }
        
        /**
         * Klonen der Klasse von aussen verbieten
         */
        final private function __clone() { }
        
        /**
         * Zugriff auf die internen Daten verhindern
         */
        final public function __set($name, $value) { return; }
        final public function __get($name) { return; }
        final public function __unset($name) { return FALSE; }
        final public function __isset($name) { return; }
        
        /**
         * Startet den Controller
         * @param (string) $page: Dateiname des Controllers (ohne Suffix)
         */
        final private function __construct($page) {
                        
            /**
             * Wenn die Konstante schon belegt ist
             */
            if(defined('SYS_CONTROLLER_FILENAME') === TRUE)
                throw new Exception('Could not create Controller! <b>SYS_CONTROLLER_FILENAME</b> is already defined!');
                
            /**
             * Dateinamen des Kontrollers in Konstante speichern
             */
            define('SYS_CONTROLLER_FILENAME', $page);
            
            /**
             * Dateinamen klassenintern verfuegbar machen
             */
            $this->__page = $page;
                                    
            /**
             * Controller laden
             */
            $this->load();
        }
        
        /**
         * Controller laden
         */
        final private function load() {
            
            /**
             * Wenn die Datei existiert
             */
            if(file_exists($this->__directory.$this->__page.'.php') === TRUE) {
                /**
                 * Controller laden
                 */
                require $this->__directory.$this->__page.'.php';
            }
            else {
                /**
                 * Controller konnte nicht geladen werden
                 */
                throw new Exception('Datei existiert nicht!');
            }
        }
    }
?>

Admin_Controller
PHP:
<?php
    class Admin_Controller extends Controller {
        
        protected $__directory = 'admin/controller/';
    }
?>
 
PHP:
if (self::$instance === NULL)
{
	self::$instance = new Controller($page);
}

Wobei: Es steht zwar so in den Büchern, ein (verrdammt guter) Programmierer sagte mir aber mal, das es so falsch wäre

Der 2. Punkt ist (gerade bei Singleton) das holen der Referenz:

Gwöhnlich sollte es ja:

PHP:
$var = &klasse::getInstance();

Die Instance geholt werden. Zend Studio schnallt es so und will es auch so haben, der PHP Strict-Mode jedoch bemängelte jedes dieser Vorkommen mit einer Notice-Meldung, aber wenn man sich etwas in die Sache hinwein denkt, kann man dem Strict-Mode nur recht geben und ein:

PHP:
$var = klasse::getInstance();

wäre richtiger, denn das was die Klasse da zurück gibt, ist ja sschon die Referenz der Instance, im 1. Fall würde man ja eine Referenz der Referenz bekommen, welche gewöhnlich Null wäre (in deinem Fall) ;)

Ich denke, in deinem Fall kommst du mit der Übergabe des Verzeichnis weiter:

PHP:
private function load($dir = '')
{
	/**
     * Wenn die Datei existiert
     */
	if (!empty($dir) && file_exists($dir . $this->__page . '.php'))
	{
		/**
         * Controller laden
         */
        require ($this->__directory . $this->__page . '.php');
	}
	elseif (file_exists($this->__directory . $this->__page . '.php'))
	{
		/**
         * Controller laden
         */
        require ($this->__directory . $this->__page . '.php');
	}
	else
	{
		/**
         * Controller konnte nicht geladen werden
         */
        throw new Exception('Datei existiert nicht!');
	}
}
 
Zuletzt bearbeitet:
Wie soll ich denn die Variable in den Konstruktor setzen, wenn ich diesen doch nicht verändern will? Ich habe da momentan meine Vorstellungsprobleme.
 
Ich habe gerade eine Lösung für das Problem gefunden:
In der Ursprungsklasse habe ich folgendes geändert:

  • $instance als protected gekennzeichnet
  • bei start() das final entfernt
  • __construct() als protected gekennzeichnet
und in der erbenden Klasse habe ich noch eine eigene start()-Methode erstellt, welche letztendlich die Originalmethode überschreibt und eine Instance der neuen Klasse erzeugt.
 
Zurück