Obrasci za početnike: MVC vs MVP vs MVVM. Opća pravila za odabir uzorka. Izbor korisnih poveznica na tu temu

Kontrolori

Svaki zahtjev koji dolazi u aplikaciju obrađuje kontroler. Kontrolor može obraditi zahtjev proizvoljno sve dok ne prelazi granicu odgovornosti modela-pogled. To znači da kontroleri ne bi trebali sadržavati niti pohranjivati ​​podatke, niti bi trebali generirati korisnička sučelja.

U ASP.NET MVC Frameworku, kontroleri su .NET klase koje sadrže logiku potrebnu za obradu zahtjeva. Uloga kontrolera je enkapsulirati logiku aplikacije. Drugim riječima, kontroleri su odgovorni za obradu dolaznih zahtjeva i izvođenje operacija na modelu predmetno područje i odabir prikaza za vizualizaciju korisniku.

Uzorak prijave

Za potrebe ovog i sljedeći članci stvorit ćemo novi projekt MVC je imenovao ControllersAndActions pomoću predloška Empty, označivši potvrdni okvir MVC ispod Add folders and core references for i projekt testiranja jedinice pod nazivom ControllersAndActions.Tests. Jedinični testovi koje ćete stvarati ne zahtijevaju lažne implementacije, tako da nećete morati instalirati Moq paket, ali ćete morati instalirati MVC paket kako bi testovi mogli pristupiti osnovnim klasama kontrolera.

U prozor konzole Visual Studio NuGet Package Manager unesite sljedeću naredbu:

Instalacijski paket Microsoft.Aspnet.Mvc -verzija 5.0.0 -naziv projekta ControllersAndActions.Tests

Nakon stvaranja projekta, odaberite ControllersAndActions Properties iz izbornika Project u Visual Studio, u dijaloškom okviru koji se otvori, idite na karticu Web i označite radio gumb Specific Page ( Određena stranica) u kategoriji Start Action. Nema potrebe za unosom vrijednosti - samo odaberite radio gumb.

Pojam kontrolera

Vidjeli ste slučajeve upotrebe kontrolera u gotovo svim prethodnim člancima o ASP.NET MVC. Vrijeme je da zavirimo iza kulisa.

Izrada kontrolera pomoću sučelja IController

U MVC okviru, klase kontrolera moraju implementirati IController sučelje iz imenskog prostora System.Web.Mvc prikazano u primjeru ispod:

Korištenje System.Web.Routing; prostor imena System.Web.Mvc ( javno sučelje IController ( void Execute(RequestContext requestContext); ) )

Da biste dobili definiciju ovog sučelja, morate preuzeti izvorni kod MVC Frameworka, koji je izuzetno koristan za odgonetanje unutarnjeg rada okvirnih alata.

Kao što vidite, sučelje IControllera je vrlo jednostavno. Njegov jedini Metoda Execute(). Poziva se kada je zahtjev poslan ovoj klasi kontrolera. MVC Framework utvrđuje koju klasu zahtjev cilja čitanjem vrijednosti svojstva kontrolera koju generiraju podaci o usmjeravanju ili putem posebnih klasa za usmjeravanje.

Možete stvoriti klase kontrolera implementacijom sučelja IController, ali budući da je ovo sučelje niske razine, morat ćete obaviti puno posla da biste dobili bilo što korisno. Međutim, sučelje IController je korisno za demonstraciju rada kontrolera i u tu svrhu kreira se nova datoteka klase pod nazivom BasicController.cs u mapi Kontroleri, čiji je sadržaj prikazan u primjeru ispod:

Korištenje System.Web.Mvc; koristeći System.Web.Routing; namespace ControllersAndActions.Controllers ( public class BasicController: IController ( public void Execute(RequestContext requestContext) ( string controller = (string)requestContext.RouteData.Values["controller"]; string action = (string)requestContext.RouteData.Values["action "]; requestContext.HttpContext.Response.Write(string.Format("Kontroler: (0), Metoda radnje: (1)", kontroler, radnja)); ) ) )

Metodi Execute() sučelja IController prosljeđuje se objekt RequestContext, koji pruža informacije o trenutnom zahtjevu i ruti koja mu odgovara (i uzrokuje pozivanje danog kontrolera za obradu tog zahtjeva). Klasa RequestContext definira dva svojstva, opisana u tablici u nastavku:

Objekt HttpContextBase omogućuje pristup skupu objekata koji opisuju trenutni zahtjev, koji se nazivaju objekti konteksta; vratit ćemo im se kasnije. Objekt RouteData opisuje rutu. Važna svojstva klase RouteData navedena su u donjoj tablici:

Članak Konfiguriranje sustava usmjeravanja pokazao je kako koristiti tipove RouteBase i IRouteHandler za konfiguriranje sustava usmjeravanja. U primjeru koji se razmatra, korištenjem svojstva Values ​​​​dobive se vrijednosti varijabli regulatora i akcijskog segmenta, koje se zatim upisuju u odgovor.

Dio problema sa stvaranjem prilagođenih kontrolera je nedostatak pristupa značajkama kao što su pogledi. To znači da morate raditi na nižoj razini, što objašnjava pisanje sadržaja izravno kao odgovor klijentu. Vlasništvo HttpContextBase.Response vraća objekt HttpResponseBase koji vam omogućuje da konfigurirate i dodate sadržaj u odgovor koji će se poslati klijentu. Ovo je još jedna dodirna točka između ASP.NET platforme i MVC Frameworka.

Ako pokrenete aplikaciju i odete na URL poput /Basic/Index, posebni kontroler će generirati izlaz prikazan na slici ispod:

Implementacija sučelja IController omogućuje stvaranje klase koju MVC Framework prepoznaje kao kontroler i šalje mu zahtjeve, bez ikakvih ograničenja u načinu na koji se zahtjev obrađuje ili koji se odgovor za njega generira. Ovaj dobar primjer jer pokazuje koliko MVC okvir može biti proširiv čak i za ključne građevne blokove poput kontrolera, ali pisanje složena primjena na taj način može biti ispunjen znatnim poteškoćama.

Klase s imenima koja završavaju na Base

MVC Framework oslanja se na ASP.NET okvir za obradu zahtjeva, što ima puno smisla jer... ova platforma je dokazana implementacija bogata značajkama koja se čvrsto integrira s IIS poslužiteljem aplikacija. Problem je u tome što klase koje ASP.NET koristi za pružanje informacija o zahtjevima nisu dobro prilagođene za jedinično testiranje, što je glavna prednost korištenja MVC okvira.

Microsoft je odlučio uvesti mogućnosti testiranja uz zadržavanje kompatibilnosti s postojeće aplikacije ASP.NET Web Forms, tako da je rezultat bio Bazne klase. Ove se klase nazivaju tako jer imaju iste nazive kao i osnovne klase okvira ASP.NET, nakon čega slijedi riječ Base.

Na primjer, okvir ASP.NET pruža kontekstualne informacije o trenutnom zahtjevu i nizu ključnih aplikacijskih usluga putem HttpContext objekta. Njegova odgovarajuća osnovna klasa je HttpContextBase, čija se instanca prosljeđuje metodi Execute() definiranoj u sučelju IController (ostale osnovne klase bit će prikazane u sljedećim primjerima). Izvorna i osnovna klasa definiraju ista svojstva i metode, ali osnovne klase uvijek apstraktno, što znači da ih je lako koristiti za jedinično testiranje.

Ponekad ćete završiti s instancom jedne od izvornih ASP.NET klasa, kao što je HttpContext. U ovom slučaju morate stvoriti osnovnu klasu prilagođenu MVC-u sličnu HttpContextBase. To se radi pomoću jednog od Wrapper klase, koji imaju ista imena kao izvorne klase, dodana riječju Wrapper, na primjer HttpContextWrapper. Klase omotači proizlaze iz osnovnih klasa i imaju konstruktore koji prihvaćaju instance originalnih klasa:

Izvorne klase, osnovne klase i klase Wrapper definirane su u prostoru imena System.Web, tako da okvir ASP.NET može glatko podržavati MVC okvir i starije aplikacije Web aplikacije Obrasci.

Kreiranje kontrolera nasljeđivanjem od klase Kontroler

Kao što je pokazano u prethodnom primjeru, MVC Framework omogućuje gotovo neograničenu prilagodbu i proširenje. Za pružanje bilo koje željene vrste obrade upita i generiranja rezultata, možete implementirati sučelje IController. Ne sviđaju vam se metode djelovanja? Ne želite brinuti o renderiranim prikazima? U ovom slučaju možete uzeti stvari u svoje ruke i implementirati bolji, brži i elegantniji način obrade zahtjeva. Alternativno, možete iskoristiti prednosti alata koje nudi tim MVC Framework u Microsoftu i naslijediti svoje kontrolere iz klase System.Web.Mvc.Controller.

Klasa Controller pruža podršku za obradu zahtjeva koja je poznata većini programera MVC aplikacija. Korišten je u svim primjerima o kojima se raspravljalo u prethodnim člancima. Klasa Controller pruža tri ključna sredstva koji su opisani u nastavku:

Metode djelovanja

Ponašanje kontrolera raspoređeno je na više metoda (umjesto da se implementira u obrazac jedina metoda Izvršiti()). Svaka radnja se preslikava na odgovarajući URL i poziva s parametrima dohvaćenima iz dolaznog zahtjeva.

Rezultati radnji

Možete vratiti objekt koji opisuje rezultat radnje (kao što je renderiranje prikaza ili preusmjeravanje na drugi URL ili metodu radnje), a zatim ga obraditi na bilo koji način. Razdvajanje između specificiranja rezultata i njihovog izvršavanja olakšava testiranje jedinice.

Filteri

Ponašanje za višekratnu upotrebu (kao što je provjera autentičnosti) može se enkapsulirati kao filtri, a zatim se svaki aspekt ponašanja kontrolera i metoda radnji može označiti atributom u izvornom kodu.

Osim ako se ne bavite posebnim zahtjevom, najbolji pristup stvaranju kontrolera je njihovo izvođenje iz klase Controller, što je ono što Visual Studio radi, kao što možete očekivati, kada stvara nova klasa kao odgovor na stavku izbornika Dodaj --> Skela (Dodaj --> Predložak).

Primjer u nastavku prikazuje kôd jednostavan kontroler pod nazivom DerivedController, stvoren na sličan način. Generira se pomoću opcije MVC 5 Controller - Empty s nekoliko jednostavne promjene, namijenjen za postavljanje svojstva ViewBag i odabir prikaza:

Korištenje sustava; koristeći System.Web; koristeći System.Web.Mvc; namespace ControllersAndActions.Controllers ( public class DerivedController: Controller ( public ActionResult Index() ( ViewBag.Message = "Pozdrav od kontrolera DerivedController action method Index"; return View("MyView"); ) ) )

Klasa Controller također omogućuje komunikaciju sa sustavom Razor view. U ovom primjeru vraćamo rezultat poziva metodi View(), kojoj se prosljeđuje kao parametar naziv prikaza koji se prikazuje klijentu. Da biste kreirali ovaj prikaz, kreirajte mapu Views/Derived, kliknite na nju desni klik mišem i odaberite unutra kontekstni izbornik item Add --> MVC 5 View Page (Razor) (Dodaj --> MVC 5 View Page (Razor)). Navedite naziv MyView.cshtml i kliknite U redu za izradu datoteke prikaza.

Uskladite sadržaj datoteke s primjerom:

@( ViewBag.Title = "Index"; } MyView Сообщение от контроллера: « @ViewBag.Message »!}

Nakon pokretanja aplikacije i navigacije do URL-a pogleda /Izvedeno/Indeks, poziva se ova radnja i MyView se renderira:

Nasljeđivanje od klase Controller rezultira potrebom za implementacijom akcijskih metoda, primanjem svih inputa potrebnih za obradu zahtjeva i generiranjem odgovarajućeg odgovora. Sljedeći članci opisuju mnoge pristupe za to.

Mnogi ljudi počinju pisati projekt da rade s jednim zadatkom, ne implicirajući da može prerasti u višekorisnički sustav upravljanja, na primjer, sadržajem ili, ne daj Bože, produkcijom. I sve se čini sjajno i cool, sve funkcionira, dok ne počnete shvaćati da se kod koji je napisan sastoji isključivo od štaka i tvrdog koda. Kod je pomiješan s izgledom, upitima i štakama, ponekad čak i nečitljiv. Pojavljuje se gorući problem: kada dodajete nove značajke, morate dugo petljati s ovim kodom, prisjećajući se "što je tamo napisano?" i proklinjite sebe u prošlosti.

Možda ste čak čuli za uzorke dizajna i čak listali ove prekrasne knjige:

  • E. Gamma, R. Helm, R. Johnson, J. Vlissides “Objektivne tehnike orijentirani dizajn. Dizajn obrasci";
  • M. Fowler "Arhitektura poslovnih softverskih aplikacija."
I mnogi su, neustrašivi golemim priručnicima i dokumentacijom, pokušali proučiti bilo koji od modernih okvira i, suočeni sa složenošću razumijevanja (zbog prisutnosti mnogih arhitektonskih koncepata koji su pametno međusobno povezani), odgodili proučavanje i korištenje suvremenih alata u sklonište."

Ovaj će članak biti koristan prvenstveno za početnike. U svakom slučaju, nadam se da ćete za nekoliko sati moći dobiti ideju MVC implementacije obrazac koji je temelj svih modernih web okvira, a također dobiti "hranu" za daljnje razmišljanje o "kako to učiniti". Na kraju članka nalazi se izbor korisni linkovi, koji će vam također pomoći razumjeti od čega se sastoje web okviri (osim MVC-a) i kako rade.

Iskusni PHP programeri vjerojatno neće pronaći ništa novo za sebe u ovom članku, ali njihovi komentari i komentari na glavni tekst bili bi od velike pomoći! Jer Bez teorije je praksa nemoguća, a bez prakse teorija je beskorisna, onda će prvo biti malo teorije, a onda ćemo prijeći na praksu. Ako ste već upoznati s MVC konceptom, možete preskočiti teorijski dio i odmah prijeći na praksu.

1. Teorija MVC obrazac opisuje jednostavan način strukturiranja aplikacije, čija je svrha odvojiti poslovnu logiku od korisničkog sučelja. Kao rezultat toga, aplikaciju je lakše skalirati, testirati, održavati i, naravno, implementirati.

Pogledajmo konceptualni dijagram MVC uzorka (po mom mišljenju, ovo je najuspješniji dijagram koji sam vidio):

U arhitekturi MVC model osigurava podatke i pravila poslovne logike, pogled je odgovoran za korisničko sučelje, a kontroler osigurava interakciju između modela i pogleda.

Tipičan tijek MVC aplikacije može se opisati na sljedeći način:

  • Kada korisnik posjeti web resurs, inicijalizacijska skripta stvara instancu aplikacije i pokreće je za izvršenje.
    Ovo prikazuje prikaz, recimo početna stranica mjesto.
  • Aplikacija prima zahtjev od korisnika i određuje traženi kontroler i akciju. U slučaju glavne stranice izvodi se zadana radnja ( indeks).
  • Aplikacija instancira kontroler i pokreće akcijsku metodu,
    koji npr. sadrži pozive modela koji čitaju informacije iz baze podataka.
  • Nakon toga, radnja stvara pogled s podacima dobivenim iz modela i prikazuje rezultat korisniku.
  • Model – sadrži poslovnu logiku aplikacije i uključuje metode za uzorkovanje (to mogu biti ORM metode), obradu (primjerice, validacijska pravila) i pružanje specifičnih podataka, što ih često čini vrlo gustim, što je sasvim normalno.
    Model ne bi trebao izravno komunicirati s korisnikom. Sve varijable koje se odnose na korisnički zahtjev moraju se obraditi u kontroleru.
    Model ne bi trebao generirati HTML ili drugi kod za prikaz koji se može mijenjati ovisno o potrebama korisnika. Takav kôd treba obraditi u pogledima.
    Isti model, na primjer: model autentifikacije korisnika može se koristiti iu korisničkom iu administrativnom dijelu aplikacije. U ovom slučaju, može se uzeti opći kod u zasebnu klasu i nasljeđuje od nje, definirajući metode specifične za podaplikacije u svojim potomcima.

    Pogled - koristi se za određivanje vanjskog prikaza podataka primljenih od kontrolera i modela.
    Pogledi sadrže HTML označavanje i male umetke PHP koda za kretanje, formatiranje i prikaz podataka.
    Ne bi trebao izravno pristupiti bazi podataka. To je ono što modeli trebaju raditi.
    Ne bi trebalo raditi s podacima dobivenim na zahtjev korisnika. Ovaj zadatak mora izvršiti upravljač.
    Može izravno pristupiti svojstvima i metodama kontrolera ili modela za dobivanje podataka spremnih za izlaz.
    Pogledi se obično dijele na zajednički predložak koji sadrži oznake zajedničke za sve stranice (na primjer, zaglavlje i podnožje) i dijelove predloška koji se koriste za prikaz izlaznih podataka iz modela ili prikaz obrazaca za unos podataka.

    Kontroler je ljepilo koje povezuje modele, prikaze i druge komponente radna aplikacija. Kontrolor je odgovoran za obradu zahtjeva korisnika. Kontroler ne bi trebao sadržavati SQL upite. Bolje ih je držati u modelima. Kontroler ne smije sadržavati HTML ili druge oznake. Vrijedi to staviti u obzir.
    U dobro dizajniranoj MVC aplikaciji, kontroleri su obično vrlo tanki i sadrže samo nekoliko desetaka redaka koda. Isto se ne može reći za Stupid Fat Controllers (SFC) u CMS Joomla. Logika regulatora prilično je tipična i većina se provodi u osnovne klase.
    Modeli su, naprotiv, vrlo debeli i sadrže većinu koda koji se odnosi na obradu podataka, jer struktura podataka i poslovna logika sadržana u njima obično su prilično specifične za određenu aplikaciju.

    1.1. Front Controller i Page Controller U većini slučajeva, interakcija korisnika s web aplikacijom događa se klikom na poveznice. Pogledajte sada adresnu traku vašeg preglednika - primili ste ovaj tekst s ove veze. Ostale poveznice, poput onih na desnoj strani ove stranice, pružit će vam drugačiji sadržaj. Dakle, poveznica predstavlja određenu naredbu web aplikaciji.

    Nadam se da ste već primijetili da različite stranice mogu biti savršene različite formate konstrukcija adresna traka. Svaki format može prikazati arhitekturu web aplikacije. Iako to nije uvijek slučaj, u većini slučajeva to je jasna činjenica.

    Razmotrimo dvije opcije za adresnu traku, koje prikazuju neki tekst i korisnički profil.

    Približan kod obrade u ovom slučaju:
    switch($_GET["action"]) ( case "about" : require_once("about.php"); // prijelom stranice "O nama"; case "contacts" : require_once("contacts.php"); // Prijelom stranice "Kontakti"; slučaj "povratne informacije" : require_once("feedback.php"); // Prijelom stranice "Povratne informacije"; zadano: require_once("page404.php"); // prijelom stranice "404"; )
    Mislim da su to već učinili gotovo svi.

    Koristeći URL mehanizam za usmjeravanje, možete konfigurirati svoju aplikaciju da prihvaća zahtjeve poput ovog za prikaz istih informacija:
    http://www.example.com/contacts/feedback

    Ovdje kontakti predstavljaju kontroler, a povratne informacije su metoda kontrolera kontakata koja prikazuje obrazac Povratne informacije itd. Ovom pitanju ćemo se vratiti u praktičnom dijelu.

    Također je vrijedno znati da usmjerivači mnogih web okvira omogućuju stvaranje proizvoljnih URL rute(naznačite što svaki dio URL-a znači) i pravila za njihovu obradu.
    Sada imamo dovoljno teorijskog znanja da prijeđemo na praksu.

    2. Vježbajte Prvo, krenimo sljedeća struktura datoteke i mape:


    Gledajući unaprijed, reći ću da će osnovne klase Model, View i Controller biti pohranjene u osnovnoj mapi.
    Njihova djeca bit će pohranjena u direktorije kontrolera, modela i prikaza. Datoteka index.php je ulazna točka u aplikaciju. Datoteka bootstrap.php inicira učitavanje aplikacije, povezivanje svih potrebnih modula itd.

    Ići ćemo redom; Otvorimo datoteku index.php i ispunimo je sljedećim kodom:
    ini_set("pogreške_prikaza", 1); require_once "aplikacija/bootstrap.php";
    Ovdje ne bi trebalo biti nikakvih pitanja.

    Zatim, idemo odmah na datoteku bootstrap.php:
    require_once "core/model.php"; require_once "core/view.php"; require_once "core/controller.php"; require_once "core/route.php"; Ruta::start(); //pokreni ruter
    Prva tri retka će sadržavati trenutno nepostojeće kernel datoteke. Posljednji redovi povežite datoteku s klasom usmjerivača i pokrenite je za izvođenje pozivom statička metoda početak.

    2.1. Implementacija URL usmjerivača Za sada, odstupimo od implementacije MVC uzorka i usredotočimo se na usmjeravanje. Prvi korak koji trebamo napraviti je napisati sljedeći kod u .htaccess:
    RewriteEngine On RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule .* index.php [L]
    Ovaj kod će preusmjeriti svu obradu stranice na index.php, što je ono što nam treba. Sjećate se da smo u prvom dijelu govorili o Front Controlleru?!

    Usmjeravanje ćemo smjestiti u zasebnu datoteku route.php u osnovnom direktoriju. U ovoj datoteci ćemo opisati klasu Route, koja će pokretati metode kontrolera, koje će zauzvrat generirati prikaz stranice.

    Sadržaj datoteke route.php

    klasa Ruta ( statička funkcija start() ( // kontroler i zadana akcija $controller_name = "Main"; $action_name = "index"; $routes = explode("/", $_SERVER["REQUEST_URI"]); // dobiti naziv kontrolera if (!empty($routes)) ( $controller_name = $routes; ) // dobivanje naziva akcije if (!empty($routes)) ( $action_name = $routes; ) // dodavanje prefiksa $model_name = " Model_".$controller_name; $controller_name = "Controller_".$controller_name; $action_name = "action_".$action_name; // povežite datoteku s klasom modela (možda ne postoji datoteka modela) $model_file = strtolower ($model_name). ".php"; $model_path = "application/models/".$model_file; if(file_exists($model_path)) ( uključi "application/models/".$model_file; ) // spojite datoteku s klasom kontrolera $controller_file = strtolower ($controller_name)..php"; $controller_path = "application/controllers/".$controller_file; if(file_exists($controller_path)) ( uključi "application/controllers/".$controller_file; ) else ( /* bilo bi ispravno izbaciti iznimku ovdje, ali da pojednostavimo stvari, odmah ćemo preusmjeriti na stranicu 404 */ Route::ErrorPage404(); ) // kreirati kontroler $controller = new $controller_name ; $akcija = $akcija_name; if(method_exists($controller, $action)) ( // poziva radnju kontrolera $controller->$action(); ) else ( // ovdje bi također bilo pametnije izbaciti iznimku Route::ErrorPage404(); ) ) funkcija ErrorPage404( ) ( $host = "http://".$_SERVER["HTTP_HOST"]."/"; zaglavlje("HTTP/1.1 404 nije pronađeno"); zaglavlje("Status: 404 nije pronađeno") ; zaglavlje(" Lokacija:".$host."404"); ) )


    Napominjem da klasa implementira vrlo pojednostavljenu logiku (unatoč voluminoznom kodu) i može čak imati sigurnosnih problema. Ovo je učinjeno namjerno, jer... pisanje punopravne klase usmjeravanja zaslužuje barem poseban članak. Pogledajmo glavne točke...

    Globalni element polja $_SERVER["REQUEST_URI"] sadrži puna adresa kojim je korisnik kontaktirao.
    Na primjer: example.ru/contacts/feedback

    Korištenje funkcije eksplodirati Adresa je podijeljena na komponente. Kao rezultat, dobivamo naziv kontrolera, za navedeni primjer, ovo je kontroler kontakti i naziv radnje, u našem slučaju - Povratne informacije.

    Zatim se povezuju datoteka modela (model može nedostajati) i datoteka kontrolera, ako postoji, i na kraju se kreira instanca kontrolera i ponovno se poziva akcija ako je opisana u klasi kontrolera.

    Dakle, kada idete na npr. adresu:
    primjer.com/portfolio
    ili
    primjer.com/portfolio/index
    Usmjerivač će izvršiti sljedeće radnje:

  • uključit će datoteku model_portfolio.php iz mape modela, koja sadrži klasu Model_Portfolio;
  • uključit će datoteku controller_portfolio.php iz mape controllers, koja sadrži klasu Controller_Portfolio;
  • će stvoriti instancu klase Controller_Portfolio i pozvati zadanu radnju - action_index, opisanu u njoj.
  • Ako korisnik pokuša pristupiti adresi nepostojećeg kontrolera, na primjer:
    primjer.com/ufo
    tada će biti preusmjeren na stranicu “404”:
    primjer.com/404
    Ista stvar će se dogoditi ako korisnik pristupi radnji koja nije opisana u kontroleru.2.2. Vratimo se implementaciji MVC-a. Idemo u mapu jezgre i dodamo još tri datoteke u datoteku route.php: model.php, view.php i controller.php


    Dopustite mi da vas podsjetim da će sadržavati osnovne klase, koje ćemo sada početi pisati.

    Sadržaj datoteke model.php
    model klase ( javna funkcija get_data() ( ) )
    Klasa modela sadrži jednu praznu metodu dohvaćanja podataka, koja će biti nadjačana u klasama potomcima. Kada stvorimo klase potomke sve će postati jasnije.

    Sadržaj datoteke view.php
    class View ( //javni $template_view; // ovdje možete navesti zadani opći prikaz. function generate($content_view, $template_view, $data = null) ( /* if(is_array($data)) ( // pretvori niz elemente u varijable ekstrakt($data); ) */ uključi "application/views/".$template_view; ) )
    Nije teško pogoditi da metoda generirati namijenjeno formiranju pogleda. U njega se prosljeđuju sljedeći parametri:

  • $content_file - pregledi koji prikazuju sadržaj stranice;
  • $template_file - predložak zajednički za sve stranice;
  • $data je niz koji sadrži elemente sadržaja stranice. Obično se popunjava u modelu.
  • Funkcija uključivanja dinamički povezuje opći predložak (pogled) unutar kojeg će pogled biti ugrađen
    za prikaz sadržaja određene stranice.

    U našem slučaju, opći predložak sadržavat će zaglavlje, izbornik, bočnu traku i podnožje, a sadržaj stranice bit će sadržan u zasebnom obrascu. Opet, ovo je učinjeno radi jednostavnosti.

    Sadržaj datoteke controller.php
    klasa Controller ( javni $model; javni $view; funkcija __construct() ( $this->view = new View(); ) funkcija action_index() ( ) )
    metoda indeks_radnje- ovo je radnja koja se poziva prema zadanim postavkama; nadjačat ćemo je prilikom implementacije klasa potomaka.

    2.3. Implementacija klasa potomaka Model i Controller, stvaranje View "s. Sada zabava počinje! Naša web-stranica posjetnica sastojat će se od sljedećih stranica:
  • Dom
  • Usluge
  • Portfelj
  • Kontakti
  • I također - stranica "404".
  • Svaka stranica ima vlastiti kontroler iz mape kontrolera i pogled iz mape pogleda. Neke stranice mogu koristiti model ili modele iz mape modela.


    Na prethodnoj slici, datoteka template_view.php je posebno označena - ovo je predložak koji sadrži oznake zajedničke za sve stranice. U najjednostavnijem slučaju to bi moglo izgledati ovako:
    Dom
    Kako bismo web stranici dali vidljiv izgled, stvaramo CSS predložak i integriramo ga u našu web stranicu mijenjajući strukturu HTML oznake i CSS veze i JavaScript datoteke:

    Na kraju članka, u odjeljku “Rezultat”, nalazi se poveznica na GitHub repozitorij s projektom u koji su poduzeti koraci za integraciju jednostavnog predloška.

    2.3.1. Stvaranje glavne stranice Počnimo s kontrolerom controller_main.php , ovdje je njegov kod:
    klasa Controller_Main proširuje Controller ( funkcija action_index() ( $this->view->generate("main_view.php", "template_view.php"); ) )
    U metodi generirati instanca klase View, prosljeđuju se nazivi datoteka općeg predloška i pogleda sa sadržajem stranice.
    Osim radnje indeksa, kontroler naravno može sadržavati i druge akcije.

    Datoteka sa opći pogled pogledali smo ranije. Razmotrite datoteku sadržaja main_view.php:
    Dobrodošli!

    OLOLOSHA TEAM je tim prvoklasnih stručnjaka u području razvoja web stranica s dugogodišnjim iskustvom u prikupljanju meksičkih maski, brončanih i kamenih statua iz Indije i Cejlona, ​​bareljefa i skulptura koje su stvorili majstori Ekvatorijalne Afrike pet ili šest stoljeća prije...


    Ovo sadrži jednostavno označavanje bez PHP poziva.
    Za prikaz glavne stranice možete koristiti jednu od sljedećih adresa:

    Razmotrit ćemo primjer koristeći prikaz koji prikazuje podatke dobivene iz modela u nastavku.

    2.3.2. Napravite stranicu "Portfelj" U našem slučaju, stranica "Portfelj" jedina je stranica koja koristi model.
    Model obično uključuje metode uzorkovanja podataka, na primjer:
  • metode izvornih pgsql ili mysql knjižnica;
  • metode knjižnica koje provode apstrakciju podataka. Na primjer, metode biblioteke PEAR MDB2;
  • ORM metode;
  • metode za rad s NoSQL;
  • i tako dalje.
  • Radi jednostavnosti, ovdje nećemo koristiti SQL upite ili ORM izjave. Umjesto toga, emulirati ćemo stvarne podatke i odmah vratiti niz rezultata.
    Postavite datoteku modela model_portfolio.php u mapu modela. Evo njegovog sadržaja:
    class Model_Portfolio proširuje model ( javna funkcija get_data() ( return array(array("Year" => "2012", "Site" => "http://DunkelBeer.ru", "Description" => "Promotional site of the tamno pivo Dunkel njemačkog proizvođača Löwenbraü koje u Rusiji proizvodi pivarska tvrtka "SUN InBev."), array("Godina" => "2012", "Site" => "http://ZopoMobile.ru", "Opis " => "Katalog na ruskom jeziku Kineski telefoni Tvrtka Zopo na Temeljen na Androidu OS i dodaci za njih."), // todo); ) )

    Klasa kontrolera modela nalazi se u datoteci controller_portfolio.php, ovdje je njen kod:
    klasa Controller_Portfolio proširuje Controller ( funkcija __construct() ( $this->model = new Model_Portfolio(); $this->view = new View(); ) funkcija action_index() ( $data = $this->model->get_data( ); $this->view->generate("portfolio_view.php", "template_view.php", $data); ) )
    Na varijablu podaci zapisuje se niz koji vraća metoda dobiti_podatke koje smo ranije pogledali.
    Ova se varijabla zatim prosljeđuje kao parametar metode generirati, koji također sadrži: naziv datoteke s općim predloškom i naziv datoteke koja sadrži prikaz sa sadržajem stranice.

    Prikaz koji sadrži sadržaj stranice nalazi se u datoteci portfolio_view.php.
    Portfelj

    Svi projekti u sljedećoj tablici su izmišljeni, stoga ni ne pokušavajte slijediti navedene poveznice.
    GodinaProjektOpis


    Ovdje je sve jednostavno, pogled prikazuje podatke dobivene iz modela.

    2.3.3. Izrada preostalih stranica Preostale stranice se stvaraju na isti način. Njihov kod dostupan je u repozitoriju GitHub, a poveznica na koji se nalazi na kraju članka, u odjeljku "Rezultat".3. Rezultat Evo što se na kraju dogodilo:

    Snimka zaslona rezultirajuće web stranice posjetnice



    Link na GitHub: https://github.com/vitalyswipe/tinymvc/zipball/v0.1

    Ali u ovoj verziji skicirao sam sljedeće klase (i njihove odgovarajuće tipove):

    • Controller_Login u kojem se generira pregled s formom za unos logina i lozinke, nakon čijeg popunjavanja se provodi procedura autentifikacije te se, ako je uspješna, korisnik preusmjerava na admin panel.
    • Contorller_Admin s akcijom indeksiranja koja provjerava je li korisnik prethodno bio ovlašten na web mjestu kao administrator (ako jest, prikazuje se prikaz administratorske ploče) i radnjom odjave za odjavu.
    Autentifikacija i autorizacija je druga tema, pa se o njoj ovdje ne raspravlja, već je navedena samo gore navedena poveznica kako biste imali od čega početi.4. Zaključak MVC uzorak se koristi kao arhitektonska osnova u mnogim okvirima i CMS-ovima koji su stvoreni kako bi mogli razviti višu kvalitetu kompleksna rješenja za više kratkoročno. To je omogućeno povećanjem razine apstrakcije, budući da postoji ograničenje složenosti struktura s kojima ljudski mozak može raditi.

    No, korištenje web okvira kao što su Yii ili Kohana, koji se sastoje od nekoliko stotina datoteka, pri razvoju jednostavnih web aplikacija (na primjer, stranica s posjetnicama) nije uvijek preporučljivo. Sada možemo stvoriti prekrasan MVC model kako ne bismo miješali Php, Html, CSS i JavaScript kod u jednoj datoteci.

    Ovaj je članak više polazište za učenje CMF-a nego primjer nečeg uistinu ispravnog što možete koristiti kao osnovu za svoju web aplikaciju. Možda vas je to čak i inspiriralo i već razmišljate o pisanju vlastitog microframeworka ili CMS-a temeljenog na MVC-u. No, prije nego ponovno izmislite sljedeći kotač s "mjesečinom i kurvama", razmislite još jednom: možda bi bilo razumnije usmjeriti svoje napore na razvoj i pomoć zajednici već postojećeg projekta?!

    P.S.: Članak je prerađen uzimajući u obzir neke komentare ostavljene u komentarima. Kritika se pokazala vrlo korisnom. Sudeći po odazivu: komentarima, PM-ovima i broju korisnika koji su objavu dodali u favorite, ideja o pisanju ove objave nije se pokazala tako lošom. Nažalost, zbog nedostatka vremena nije moguće uvažiti sve želje i napisati više i detaljnije... ali možda će to učiniti oni misteriozni pojedinci koji su odbacili originalnu verziju. Sretno s vašim projektima!

    5. Izbor korisnih poveznica na temu Članak se vrlo često dotiče teme web frameworka - ovo je vrlo široka tema, jer se čak i microframeworks sastoje od mnogo komponenti koje su pametno međusobno povezane i bilo bi potrebno više od jednog članka da se o njima govori komponente. Ipak, odlučio sam ovdje predstaviti mali izbor poveznica (koje sam pratio dok sam pisao ovaj članak) koji se na ovaj ili onaj način odnose na temu okvira.

    Oznake: Dodajte oznake

    Model-View-Controller (MVC) obrazac, otkriven kasnih 1970-ih, obrazac je dizajna arhitekture softver, čija je glavna zadaća odvojiti funkcije rada s podacima od njihove prezentacije. Teoretski, dobro osmišljena MVC aplikacija omogućit će front-end i back-end programerima da ne ometaju područja odgovornosti jedni drugima tijekom rada, odnosno front-end programer neće morati znati ništa o “kuhinji” svog pozadinskog kolege i obrnuto.

    Iako je MVC izvorno dizajniran za razvoj desktop aplikacija, prilagođen je za suvremeni zadaci i izuzetno je popularan među web programerima, jer je zbog podjele odgovornosti postalo moguće kreirati pregledniji, za korištenje spreman ponovno koristiti kodirati. Uzorak MVC rezultira čistim, modularnim sustavima koji programerima omogućuju vrlo brzo mijenjanje postojećeg koda.

    U ovom članku ćemo pogledati Osnovni principi MVC, počevši od definiranja uzorka i nastavljajući ga primjenjivati ​​u malom primjeru. Ovaj će članak prvenstveno biti koristan onima koji se nikada u životu nisu susreli s ovim uzorkom, a možda i onima koji žele obnoviti svoje znanje o MVC-u.

    Razumijevanje MVC-a

    Kao što je već spomenuto, naziv uzorka dolazi od kratice od tri riječi: Model (model), View (pogled) i Controller (kontrolor). Ukratko, princip rada uzorka može se ilustrirati jednim dijagramom (može se naći na Wikipediji):

    Ovaj dijagram jasno prikazuje jednosmjerni tok informacija u uzorku i također opisuje uloge svake komponente.

    Model

    Model se koristi za pristup i manipuliranje podacima. U većini slučajeva, model je ono što se koristi za pristup pohrani podataka (kao što je baza podataka). Model pruža sučelje za pretraživanje podataka, njihovo stvaranje, modificiranje i brisanje iz pohrane. U kontekstu MVC uzorka, model je posrednik između pogleda i kontrolera.

    Iznimno važna značajka modela je da tehnički nema saznanja o tome što se događa s podacima u kontroleru i prikazu. Model nikada ne bi trebao postavljati ili čekati zahtjeve prema/od drugih komponenti uzorka.

    Međutim, uvijek zapamtite da model nije samo pristupnik bazi podataka ili drugom sustavu koji ne radi ništa osim prijenosa podataka naprijed-natrag. Model je kao pristupnik podacima. Model je u većini slučajeva najsloženiji dio sustava, dijelom i zbog činjenice da je sam model poveznica za sve ostale dijelove.

    Izvođenje

    Pogled je mjesto gdje se izlaze podaci primljeni iz modela u pravom obliku. U tradicionalnim web aplikacijama razvijenim korištenjem MVC uzorka, pogled je dio sustava u kojem se generira HTML kod. Pogled je također odgovoran za primanje radnji od korisnika kako bi ih poslao kontroleru. Na primjer, pogled prikazuje gumb u korisničko sučelje, a nakon pritiska uzrokuje odgovarajuću radnju upravljača.

    Postoje neke zablude o svrsi prikaza, osobito među web programerima koji tek počinju graditi svoje aplikacije koristeći MVC. Jedno od najčešće kršenih pravila je da pogled ne smije ni na koji način komunicirati s modelom, a svi podaci koje pogled prima moraju dolaziti samo od kontrolera. U praksi programeri često ignoriraju ovaj koncept, koji je srž MVC uzorka. Članak Fabia Cevasca ilustrira ovaj zbunjujući pristup MVC-u koristeći CakePHP, jedan od mnogih nestandardnih MVC okvira:

    Izuzetno je važno razumjeti da, kako bi se dobila odgovarajuća MVC arhitektura, ne bi trebalo biti nikakvih izravnih interakcija između pogleda i modela. Sva logika za razmjenu podataka između njih mora biti implementirana u kontrolere.

    Osim toga, postoji uobičajena zabluda da je pogled samo datoteka predloška. Kao što je primijetio Tom Butler, ova zabluda je ogromna zbog činjenice da mnogi programeri krivo shvaćaju MVC strukturu od samog početka, nakon čega počinju to "znanje" dalje širiti u mase programera početnika. U stvarnosti, pogled je mnogo više od običnog predloška, ​​ali mnogi okviri izgrađeni na vrhu MVC uzorka toliko su iskrivili koncept pogleda da nikoga nije briga jesu li njihove aplikacije ispravne u smislu MVC uzorka.

    Još jedna važna točka je da pogled nikada ne radi s "čistim" podacima iz kontrolera, odnosno kontroler nikada ne radi s pogledom bez zaobilaženja modela. Tijekom interakcije između kontrolera i pogleda, model bi uvijek trebao biti između njih.

    Kontrolor

    Kontroler je posljednji dio MVC paketa. Posao kontrolera je primati podatke od korisnika i manipulirati modelom. Upravo je kontroler, i samo on, dio sustava koji komunicira s korisnikom.

    Ukratko, kontroler se može opisati kao sakupljač informacija koji ih prosljeđuje modelu za obradu i pohranu. Ne bi trebao raditi ništa s podacima, već ih samo moći primati od korisnika. Kontroler je povezan s jednim pogledom i jednim modelom, čime se organizira jednosmjerni protok podataka, kontrolirajući ih u svakoj fazi.

    Vrlo je važno zapamtiti da kontroler započinje svoj rad tek kao rezultat interakcije korisnika s pogledom, koji poziva odgovarajuću funkciju kontrolera. Najčešća pogreška među programerima je promatranje kontrolera kao jednostavnog prolaza između pogleda i modela. Kao rezultat toga, kontroler je obdaren onim funkcijama koje bi trebao obavljati pogled (usput, odatle dolazi ideja da je pogled samo datoteka predloška). Povrh toga, mnogi ljudi potpuno odbace svu logiku obrade podataka, zaboravljajući za što je model namijenjen u MVC uzorku.

    MVC u PHP-u

    Predlažem da pokušate implementirati gore navedeno u malu aplikaciju. Započnimo stvaranjem klasa modela, pogleda i kontrolera: