Co do nazw plików, wciąż mam zastrzeżenia. Ale nie to jest teraz ważne. Ogólnie rzecz biorąc Twój sposób podejścia do wzorca MVC nie odpowiada pewnym standardom i mylisz kilka pojęć. Ale to nic, pewnie nie zaglądałeś jeszcze pod maskę żadnego frameworka.
Postaram się wytłumaczyć na czym to wszystko polega w skrócie:
Otóż, jak już pewnie wiesz - w modelu MVC mamy do czynienia z trzema elementami:
- Modelem - a więc warstwą, która bezpośrednio wykonuje wszystkie operacje na danych w bazie lub w innej postaci (której na razie w swoim kodzie nie masz)
- Widokiem - a więc warstwą prezentacji - plikami HTML (lub ogólniej szablonami, które w rezultacie są wyświetlane jako HTML) w przypadku stron i aplikacji internetowych. (który nie jest klasą, tak jak w Twoim przypadku, gdzie za widok odpowiedzialna jest klasa View.php, a nie zwykły plik HTML lub jakiś szablon)
oraz
- Kontrolerem - a więc warstwą, która łączy widok i model dostarczając danych z modelu do widoku w celu umożliwienia prezentacji właściwych informacji
Aby to wszystko połączyć w całość, trzeba utworzyć pewien system, najlepiej złożony z klas (jak już sam wiesz, programowanie strukturalne to przeżytek).
Zacząć należy od samej koncepcji. Wiadomo, do aplikacji musi być jakiś punkt wejścia - zazwyczaj jest to po prostu plik index.html w którym ładowany jest silnik i parsowane są dane z zapytania (zmienna $_GET) i na tej podstawie jest ładowany określony kontroler. Te dwa zadania (parsowanie $_GET i wyznaczanie kontrolera do załadowania) to w istocie tak zwany "routing", który dalej przedstawię w bardzo uproszczonej formie.
Wyznaczony kontroler, który w naszym przykładzie będzie klasą jest ładowany i wykonywana określona metoda, wyznaczana najczęściej także w procesie routingu

Przykładowo założmy, że w zapytaniu istnieją dwie zmienne: "controller" i "action" - moduł jaki ma być załadowany i akcja, jaką ten moduł ma wykonać, tak, że w rezultacie zapytanie do serwera ma formę:
"www.example.com/index.php?controller=jakisKontroller&action=jakasakcja"
To w index.php uzyskamy coś takiego:
////////////////////////////////////////
// Tutaj będzie kod ładujący silnik.
////////////////////////////////////////
// Parsowanie danych z get:
// Nazwa kontrolera i akcji
$controllerName = $_GET["controller"];
$actionName = $_GET["action"];
// Routing:
// Tablica routingu, w przyszłości warto umieścić ją w innym pliku php i ladować w tym miejscu.
// W tablicy routingu znajdują się informacje na temat jaki kontroler jest w jakim plilku oraz nazwa
// klasy w tym pliku którą należy utworzyć
"file" => "klienci.php",
"class" => "Clients",
"kontakt" => "contact",
)
),
"file" => "services.php",
"class" => "Services",
"wyswietl" => "show"
)
)
)
// Odczytywanie nazwy pliku z klasą kontrolera z tablicy routingu
$fileName = $routes[$controllerName]["file"];
// Odczytywanie nazwy klasy kontrolera z tablicy routingu na podstawie nazwy kontrollera
$className = $routes[$controllerName]["class"]();
// Odczytywanie nazwy metody kontrolera z tablicy routingu na podstawie nazwy akcj
$methodName = $routes[$kontrollerName][$actionName];
// Koniec routingu
// Ładowanie klasy kontrolera, tworzenie instancji klasy kontrolera i wykonanie metody na tej instancji.
include "/controllers/" . $fileName ;
$controller = new $className();
$controller->$methodName();
Najważniejsze, żebyś przyjrzał się tablicy routingu i jak wygląda odczytywanie nazw: pliku, klasy i akcji kontrolera. Zauważ też jak tworzę nowe obiekty - przy pomocy zmiennych, za którymi stawiam "()" (tak, tak można w PHP).
Jest to przykład banalny w zasadzie. W rzeczywistości routing jest nieco bardziej zaawansowany. Dodatkowo poza wymienionymi danymi w $_GET[] często są jeszcze inne parametry - sama nazwa kontrolera i akcji często może nie wystarczyć. Bo przypuścmy, że chcemy na przyklad pokazać pojedynczą usługę. Wtedy musielibyśmy stworzyć na przykład metodę showOne, która przyjmuje jakiś
identyfikator usługi (np. liczbę). Wtedy w get musielibyśmy mieć nazwe kontrolera, nazwę akcji i parametr, np:
"www.example.com/index.php?controller=jakisKontroller&action=jakasakcja&
id=1"
Jednak na razie pozostanę przy tym co jest, bo chodzi aby omówić mechanizm, jak to zazwyczaj działa.
Kolejnym etapem jest zdefiniowanie abstrakcyjnej klasy kontrolera, z której dziedziczą wszystkie konkretne kontrolery.
Kontroler powinien móc robić dwie rzeczy, o których już mówiłem:
- posługiwać się modelem
- wyświetlać widok
Do wyświetania widoku użyjemy prostej metody, która będzie korzystała z buforowania wyjścia, natomiast model narazie
będzie tylko polem wewnątrz klasy kontrolera, które będzie inicjalizowane w konstruktorze klas pochodnych (konkretnych kontrolerach):
abstract class Controller {
private $model;
protected function displayView($view, $variables) {
echo $this->getView($view, $variables); }
protected function getView($view, $variables){
// Załadowanie zmiennych z tablicy $variables
include $this->$view;
return $contents;
}
}
Teraz możemy utworzyć już przykładowy kontroler (klienci.php):
class Clients extends Controller() {
public function contact() {
this->displayView("contact_form.php"); // a w pliku contact_form.php - na przykład formularz kontaktowy.
}
}
Można teraz wywołać zapytanie:
www.example.com/index.php?controller=klienci&action=kontakt
co spowoduje wyświetlenie formularza kontaktowego.
Natomiast w kwestii modelu jest pewna dowolność, która zależy od tego jak zaawansowana ma być strona/aplikacja, którą tworzymy. W prostych przypadkach może to być zwykła klasa łącząca z bazą danych:
http://pastebin.com/fmDGtWZTW bardziej złożonych przypadach modele będą klasami z metodami pozwalającymi na wykonanie bardziej skomplikowanych zadań i prawdopodobnie cache'ującymi wyniki, a ich polem będzie odwołanie do instancji takiej klasy jak powyżej.
Mając przykładowo tę klasę "Services", w sytuacji gdy posługujemy się modelem w formie takiej klasy, umożliwiającej dostęp do bazy danych, będzie ona wyglądała tak:
class Services extends Controller{
__construct() {
$this->model = new Database();
}
public function show() {
$all = $this->model->getAll(); // pobiera wszystkie rekordy
this->loadView("services_list.php", $all); // wyswietla widok z listą wszystkich usług
}
}