MVC Model include

hoctar

Erfahrenes Mitglied
Hallo,
ich erstelle gerade ein kleines Framework.

Das MVC Modell wird hier angewandt.

Die Dateistruktur sieht wie folgt aus:

/var/www/components/news/
- controller/news.php
- models/news.php
- view/news.php

News ist hier die Kompunente.

Aus dem NewsController soll das NewsModel geladen werden. Dieses muss vorher includiert werden.

Wie finde ich den Komponentenname?

PHP:
// Pfad: /var/www/components/news/controller/news.php
class NewsController extends Controller {
    
        function __construct() {
            
                $model = $this->getModel(...);
            
                $model->getNews();
            
        }
    
}
PHP:
// Pfad: /var/www/lib/controller.php
class Controller {
    
        function getModel($name) {
            
                // Wie finde ich diesen Wert? In diesem Fall muss hier 'news' stehen.
                $component = ?
                
                include '/var/www/components/'.$component.'/models/'.$name.'.php';
                
                $model = new $model();
                
                ...        
            
        }
    
}
 
Zuletzt bearbeitet:
Hallo hoctar,

im Framework CakePHP wird es z.B. so gelöst, dass der Model-Name dem Controller-Namen entsprechen sollte. Dort gibt es auch den sog. Inflector, der z.B. ein Wort in den Singular oder Plural verwandeln kann.

Außerdem würde ich noch die Option anbieten, dass der Controller auch anders heißen kann.

PHP:
class Controller
{
  function _getComponentName()
  {
     if (isset($this->componentName))
       return $this->componentName;
     
     else
     {
        $fullName = __CLASS__;

        $name = substr($fullName, 0, strpos($fullName, "Controller"));
      }
   }
}
}
 
Warum machst Du die Ordnerstruktur so umständlich?
Reicht nicht:
Code:
/var/www/frameworkname/mvc/controllers/
/var/www/frameworkname/mvc/models/
/var/www/frameworkname/mvc/views/

Dann kannst Du auch easy mit autoload arbeiten und brauchst nicht alle klassen per Hand includen:
PHP:
function __autoload( $class ) {
    $root = '/var/www/frameworkname/mvc/';

    $paths = array(
        $root.'controllers/'.$class.'.php',
        $root.'models/'.$class.'.php',
        $root.'views/'.$class.'.php'
    );

    foreach ( $paths as $file ) {
        if ( is_file( $file ) ) {
            require $file;
            break;
        }
    }

    if ( !class_exists( $class, false ) &&
         !interface_exists( $class, false ) ) {
        die( "<h1>Error: Class '<em>$class</em>' not found!</h1>" );
    }
}

Gruß
 
Ich möchte die MVC Aufteilung gerne in jeder Komponente haben.

Zusätzlich kann man aus jedem Controller jedes beliebige Model laden das einer Komponente zugeordnet ist.

@ComFreak

Der Controller heist in diesem Fall 'NewsController'.
Man könnte nun einen zweiten Controller anlegen, der da heist 'CommentController', der dann auch auf das News Model zugriff hat.

PHP:
class CommentController extends Controller {

        function __construct() {
    
                $this->getModel('news');

        }

}
 
Also das hier ist aus meiner persönlichen Sammlung:

Benötig: 3 Ordner (model, view, controller) möglichst vom root zugänglich, ClassName und FileName bitte gleich benennen.

PHP:
function __autoload($file) {
     $filedir['model'] = 'model';
     $filedir['view'] = 'view';
     $filedir['controller'] = 'controller';
     foreach ($filedir as $dir) {
         if (file_exists('./' . $dir . '/' . $file.'.php')) {
            include_once './' . $dir . '/' . $file.'.php';
            break;
        }
    }
}

function getViews($view){
     __autoload($view);
}

//Aufruf:
//statischer Aufruf
EinAndererController_c::invoke();

$model = new XYZ_m();
$model->setModel($request);

getView('ViewContent_v');
#self::getView('ViewContent_v');

Nja, hoffe das hilft etwas :).

PS: Natürlich kannste dir die __autoload auf die Index hauen, und auf allen anderen Seiten arbeiten, als würde die Funktion oben stehen.
 
Zuletzt bearbeitet:
Also das hier ist aus meiner persönlichen Sammlung:

Benötig: 3 Ordner (model, view, controller) möglichst vom root zugänglich, ClassName und FileName bitte gleich benennen.

PHP:
function __autoload($file) {
     $filedir['model'] = 'model';
     $filedir['view'] = 'view';
     $filedir['controller'] = 'controller';
     foreach ($filedir as $dir) {
         if (file_exists('./' . $dir . '/' . $file.'.php')) {
            include_once './' . $dir . '/' . $file.'.php';
            break;
        }
    }
}

function getViews($view){
     __autoload($view);
}

//Aufruf:
//statischer Aufruf
EinAndererController_c::invoke();

$model = new XYZ_m();
$model->setModel($request);

getView('ViewContent_v');
#self::getView('ViewContent_v');

Nja, hoffe das hilft etwas :).

PS: Natürlich kannste dir die __autoload auf die Index hauen, und auf allen anderen Seiten arbeiten, als würde die Funktion oben stehen.
Da hab ich gleich mal zwei Fragen:
  1. Warum benutzt Du include_once in der autoload?
  2. Warum machst Du eine Funktion welche die autoloader aufruft?

Ich versteh die Logic dahinter grad nicht...

Gruß
 
Habe jetzt folgendes rausgefunden.

Mit ReflectionObject kann man folgende Info bekommen.

PHP:
class Controller {
    
        function getControllerFilename() {

                $reflection = new ReflectionObject($this);
                return $path = $reflection->getFileName();
            
        }
    
}

Danke an alle Poster für die Hilfe :)
 
Zurück