Opprettelse av mvc. MVC: hva er det og hva har det med brukergrensesnittet å gjøre

Mange begynner å skrive et prosjekt for å jobbe med en enkelt oppgave, uten at det betyr at det kan vokse til et flerbrukerstyringssystem, for eksempel innhold eller, gud forby, produksjon. Og alt virker flott og kult, alt fungerer, helt til du begynner å forstå at koden som er skrevet utelukkende består av krykker og hard kode. Koden er blandet med layout, spørringer og krykker, noen ganger til og med uleselig. Et presserende problem oppstår: når du legger til nye funksjoner, må du tukle med denne koden i veldig lang tid, og huske "hva ble skrevet der?" og forbanne deg selv i fortiden.

Du har kanskje til og med hørt om designmønstre og til og med bladd gjennom disse fantastiske bøkene:

  • E. Gamma, R. Helm, R. Johnson, J. Vlissides “Objektorienterte designteknikker. Designmønstre";
  • M. Fowler "Arkitektur av Enterprise Software Applications."
Og mange, uforskammet av de enorme manualene og dokumentasjonen, prøvde å studere et hvilket som helst av de moderne rammeverkene og, stilt overfor kompleksiteten i forståelsen (på grunn av tilstedeværelsen av mange arkitektoniske konsepter som er smart sammenkoblet), utsetter studiet og bruken av moderne verktøy i et "ly".

Denne artikkelen vil først og fremst være nyttig for nybegynnere. Uansett håper jeg at du i løpet av et par timer vil kunne få en ide om implementeringen av MVC-mønsteret, som ligger til grunn for alle moderne nettrammeverk, og også få "mat" for videre refleksjon om "hvordan gjør det." På slutten av artikkelen er det et utvalg nyttige lenker som også vil hjelpe deg å forstå hva nettrammeverk består av (foruten MVC) og hvordan de fungerer.

Erfarne PHP-programmerere finner neppe noe nytt for seg selv i denne artikkelen, men deres kommentarer og kommentarer til hovedteksten vil være veldig nyttige! Fordi Uten teori er praksis umulig, og uten praksis er teori ubrukelig, så først blir det litt teori, og så går vi videre til praksis. Hvis du allerede er kjent med MVC-konseptet, kan du hoppe over teoridelen og gå rett til praksisen.

1. Teori MVC-mønsteret beskriver en enkel måte å strukturere en applikasjon på, hvis formål er å skille forretningslogikk fra brukergrensesnittet. Som et resultat er applikasjonen enklere å skalere, teste, vedlikeholde og selvfølgelig implementere.

La oss se på det konseptuelle diagrammet av MVC-mønsteret (etter min mening er dette det mest vellykkede diagrammet jeg har sett):

I MVC-arkitektur gir modellen data- og forretningslogikkreglene, visningen er ansvarlig for brukergrensesnittet, og kontrolleren gir interaksjon mellom modellen og visningen.

En typisk flyt av en MVC-applikasjon kan beskrives som følger:

  • Når en bruker besøker en nettressurs, oppretter initialiseringsskriptet en forekomst av applikasjonen og starter den for kjøring.
    Dette viser en visning av for eksempel hovedsiden til nettstedet.
  • Applikasjonen mottar en forespørsel fra brukeren og bestemmer forespurt kontroller og handling. Når det gjelder hovedsiden, utføres standardhandlingen ( indeks).
  • Applikasjonen instansierer kontrolleren og kjører handlingsmetoden,
    som for eksempel inneholder modellanrop som leser informasjon fra databasen.
  • Etter dette oppretter handlingen en visning med data hentet fra modellen og viser resultatet til brukeren.
  • Modell – inneholder applikasjonens forretningslogikk og inkluderer metoder for sampling (disse kan være ORM-metoder), behandling (for eksempel valideringsregler) og å gi spesifikke data, noe som ofte gjør den veldig tykk, noe som er ganske normalt.
    Modellen skal ikke samhandle direkte med brukeren. Alle variabler knyttet til brukerforespørselen må behandles i kontrolleren.
    Modellen skal ikke generere HTML eller annen visningskode som kan endres avhengig av brukerens behov. Slik kode bør behandles i visninger.
    Den samme modellen, for eksempel: brukerautentiseringsmodellen kan brukes i både bruker- og administrative deler av applikasjonen. I dette tilfellet kan du flytte den generelle koden til en egen klasse og arve fra den, og definere underapplikasjonsspesifikke metoder i dens etterkommere.

    View - brukes til å spesifisere ekstern visning av data mottatt fra kontrolleren og modellen.
    Visninger inneholder HTML-markering og små innsettinger av PHP-kode for å krysse, formatere og vise data.
    Skal ikke ha direkte tilgang til databasen. Dette er hva modeller bør gjøre.
    Bør ikke fungere med data hentet fra en brukerforespørsel. Denne oppgaven må utføres av kontrolløren.
    Kan få direkte tilgang til egenskaper og metoder for en kontroller eller modeller for å få utdataklare data.
    Visninger er vanligvis delt inn i en felles mal, som inneholder markeringer som er felles for alle sider (for eksempel en topp- og bunntekst) og deler av malen som brukes til å vise data fra modellen eller vise dataregistreringsskjemaer.

    Kontrolleren er limet som kobler modeller, visninger og andre komponenter til en fungerende applikasjon. Behandlingsansvarlig er ansvarlig for å behandle brukerforespørsler. Kontrolleren skal ikke inneholde SQL-spørringer. Det er bedre å holde dem i modeller. Kontrolleren skal ikke inneholde HTML eller annen markering. Det er verdt å få det til syne.
    I en godt utformet MVC-applikasjon er kontroller vanligvis veldig tynne og inneholder bare noen få dusin linjer med kode. Det samme kan ikke sies om Stupid Fat Controllers (SFC) i CMS Joomla. Kontrollerlogikken er ganske typisk og det meste overføres til basisklasser.
    Modeller, tvert imot, er veldig tykke og inneholder det meste av koden knyttet til databehandling, fordi datastrukturen og forretningslogikken i den er vanligvis ganske spesifikk for en bestemt applikasjon.

    1.1. Frontkontroller og sidekontroller I de fleste tilfeller skjer brukerinteraksjon med en nettapplikasjon ved å klikke på lenker. Se nå på adressefeltet til nettleseren din - du mottok denne teksten fra denne lenken. Andre lenker, for eksempel de på høyre side av denne siden, vil gi deg annet innhold. Dermed representerer lenken en spesifikk kommando til nettapplikasjonen.

    Jeg håper du allerede har lagt merke til at forskjellige nettsteder kan ha helt forskjellige formater for å konstruere adressefeltet. Hvert format kan vise arkitekturen til en nettapplikasjon. Selv om dette ikke alltid er tilfelle, er det i de fleste tilfeller et klart faktum.

    La oss vurdere to alternativer for adressefeltet, som viser litt tekst og en brukerprofil.

    Omtrentlig behandlingskode i dette tilfellet:
    switch($_GET["handling"]) ( case "about" : require_once("about.php"); // "Om oss" sideskift; case "contacts" : require_once("contacts.php"); // "Kontakter" sideskift; case "feedback" : require_once("feedback.php"); // "Feedback" sideskift; standard: require_once("page404.php"); // side "404" break; )
    Jeg tror nesten alle har gjort dette før.

    Ved å bruke en URL-rutingsmotor kan du konfigurere applikasjonen din til å godta forespørsler som dette for å vise den samme informasjonen:
    http://www.example.com/contacts/feedback

    Her representerer kontakter kontrolleren, og tilbakemelding er kontaktkontrollermetoden som viser tilbakemeldingsskjemaet osv. Vi kommer tilbake til denne problemstillingen i den praktiske delen.

    Det er også verdt å vite at mange nettrammeverks rutere lar deg lage egendefinerte URL-ruter (spesifiser hva hver del av URL-en betyr) og regler for behandling av dem.
    Nå har vi tilstrekkelig teoretisk kunnskap til å gå videre til praksis.

    2. Øv La oss først lage følgende fil- og mappestruktur:


    Ser jeg fremover vil jeg si at kjerneklassene Model, View og Controller vil bli lagret i kjernemappen.
    Barna deres vil bli lagret i kontrollerene, modellene og visningskatalogene. index.php-filen er inngangspunktet til applikasjonen. Bootstrap.php-filen starter lasting av applikasjonen, kobler til alle nødvendige moduler osv.

    Vi vil gå sekvensielt; La oss åpne index.php-filen og fyll den med følgende kode:
    ini_set("display_errors", 1); require_once "application/bootstrap.php";
    Det burde ikke være noen spørsmål her.

    Deretter går vi umiddelbart til bootstrap.php-filen:
    require_once "core/model.php"; require_once "core/view.php"; require_once "core/controller.php"; require_once "core/route.php"; Rute::start(); //start ruteren
    De tre første linjene vil inkludere for øyeblikket ikke-eksisterende kjernefiler. De siste linjene inkluderer filen med ruterklassen og start den for kjøring ved å kalle den statiske startmetoden.

    2.1. Implementering av en URL-ruter For nå, la oss avvike fra implementeringen av MVC-mønsteret og fokusere på ruting. Det første trinnet vi må gjøre er å skrive følgende kode i .htaccess:
    RewriteEngine On RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule .* index.php [L]
    Denne koden vil omdirigere all sidebehandling til index.php, som er det vi trenger. Husker du i den første delen vi snakket om Front Controller?!

    Vi vil plassere rutingen i en egen fil route.php i kjernekatalogen. I denne filen vil vi beskrive ruteklassen, som vil kjøre kontrollermetoder, som igjen vil generere sidevisningen.

    Innholdet i route.php-filen

    klasse Rute ( statisk funksjon start() ( // kontroller og standardhandling $controller_name = "Main"; $action_name = "index"; $routes = explode("/", $_SERVER["REQUEST_URI"]); // få kontrollerenavnet if (!empty($ruter)) ( $kontrollernavn = $ruter; ) // få handlingsnavnet hvis (!empty($ruter)) ( $handlingsnavn = $ruter; ) // legg til prefikser $modellnavn = " Model_".$controller_name; $controller_name = "Controller_".$controller_name; $action_name = "action_".$action_name; // koble opp filen med modellklassen (det er kanskje ikke en modellfil) $model_file = strtolower ($model_name). ".php"; $model_path = "application/models/".$model_file; if(file_exists($model_path)) (inkluder "application/models/".$model_file;) // koble til filen med kontrollerklassen $controller_file = strtolower ($controller_name)..php"; $controller_path = "application/controllers/".$controller_file; if(file_exists($controller_path)) (inkluder "application/controllers/".$controller_file; ) else ( /* det ville være riktig å kaste et unntak her, men for å forenkle ting, vil vi umiddelbart omdirigere til 404-siden */ Route::ErrorPage404(); ) // lage en kontroller $controller = new $controller_name ; $action = $action_name; if(method_exists($controller, $action)) ( // kaller kontrollerhandlingen $controller->$action(); ) else ( // her ville det også vært klokere å kaste et unntak Route::ErrorPage404(); ) ) function ErrorPage404( ) ( $host = "http://".$_SERVER["HTTP_HOST"]."/"; header("HTTP/1.1 404 ikke funnet"); header("Status: 404 ikke funnet") ; header(" Sted:".$vert."404"); ) )


    Jeg legger merke til at klassen implementerer veldig forenklet logikk (til tross for den omfangsrike koden) og kan til og med ha sikkerhetsproblemer. Dette ble gjort med vilje, fordi... å skrive en fullverdig rutingsklasse fortjener minst en egen artikkel. La oss se på hovedpunktene...

    Det globale array-elementet $_SERVER["REQUEST_URI"] inneholder hele adressen som brukeren kontaktet.
    For eksempel: example.ru/contacts/feedback

    Bruker funksjonen eksplodere Adressen er delt inn i komponenter. Som et resultat får vi navnet på kontrolleren, for eksempelet som er gitt, er dette kontrolleren kontakter og navnet på handlingen, i vårt tilfelle - tilbakemelding.

    Deretter kobles modellfilen (modellen kan mangle) og kontrollerfilen, hvis noen, og til slutt opprettes en forekomst av kontrolleren og handlingen kalles igjen hvis den ble beskrevet i kontrollerklassen.

    Når du for eksempel går til adressen:
    example.com/portefølje
    eller
    example.com/portefølje/indeks
    Ruteren vil utføre følgende handlinger:

  • vil inkludere model_portfolio.php-filen fra models-mappen, som inneholder Model_Portfolio-klassen;
  • vil inkludere controller_portfolio.php-filen fra controllers-mappen, som inneholder Controller_Portfolio-klassen;
  • vil opprette en forekomst av Controller_Portfolio-klassen og kalle standardhandlingen - action_index, beskrevet i den.
  • Hvis brukeren prøver å få tilgang til adressen til en ikke-eksisterende kontroller, for eksempel:
    example.com/ufo
    så vil han bli omdirigert til "404"-siden:
    example.com/404
    Det samme vil skje hvis brukeren får tilgang til en handling som ikke er beskrevet i kontrolleren.2.2. La oss gå tilbake til MVC-implementeringen La oss gå til kjernemappen og legge til tre filer til i route.php-filen: model.php, view.php og controller.php


    La meg minne deg på at de vil inneholde basisklasser, som vi nå skal begynne å skrive.

    Innholdet i model.php-filen
    klasse Modell ( offentlig funksjon get_data() ( ) )
    Modellklassen inneholder en enkelt tom datahentingsmetode, som vil bli overstyrt i etterkommerklasser. Når vi oppretter etterkommerklasser vil alt bli klarere.

    Innholdet i view.php-filen
    class View ( //public $template_view; // her kan du spesifisere standard generell visning. function generate($content_view, $template_view, $data = null) ( /* if(is_array($data)) ( // convert array elementer inn i variabler extract($data); ) */ inkluderer "application/views/".$template_view; ) )
    Det er ikke vanskelig å gjette at metoden generere ment å danne et syn. Følgende parametere sendes til den:

  • $content_file - visninger som viser sideinnhold;
  • $template_file - mal felles for alle sider;
  • $data er en matrise som inneholder sideinnholdselementer. Vanligvis fylt ut i modellen.
  • Inkluder-funksjonen kobler dynamisk sammen en generell mal (visning) som visningen vil bli innebygd i
    for å vise innholdet på en bestemt side.

    I vårt tilfelle vil den generelle malen inneholde topptekst, meny, sidefelt og bunntekst, og sideinnholdet vil inneholde et eget skjema. Igjen, dette er gjort for enkelhets skyld.

    Innholdet i controller.php-filen
    klassekontroller ( offentlig $modell; offentlig $visning; funksjon __construct() ( $this->view = new View(); ) funksjon action_index() ( ) )
    Metode handlingsindeks- Dette er en handling som kalles som standard; vi vil overstyre den når vi implementerer etterkommerklasser.

    2.3. Implementering av etterkommerklassene Model og Controller, opprettelse av View "s Nå begynner moroa! Visittkortnettstedet vårt vil bestå av følgende sider:
  • hjem
  • Tjenester
  • Portefølje
  • Kontakter
  • Og også - "404"-siden
  • Hver side har sin egen kontroller fra kontroller-mappen og en visning fra visningsmappen. Noen sider kan bruke en modell eller modeller fra mappen modeller.


    I forrige figur er filen template_view.php uthevet separat - dette er en mal som inneholder markeringer som er felles for alle sider. I det enkleste tilfellet kan det se slik ut:
    hjem
    For å gi nettstedet et presentabelt utseende, lager vi en CSS-mal og integrerer den i nettstedet vårt ved å endre strukturen til HTML-markeringen og koble sammen CSS- og JavaScript-filer:

    På slutten av artikkelen, i "Resultat"-delen, er det en lenke til et GitHub-depot med et prosjekt der det er tatt skritt for å integrere en enkel mal.

    2.3.1. Opprette hovedsiden La oss starte med kontrolleren controller_main.php , her er koden:
    klasse Controller_Main utvider Controller (funksjon action_index() ( $this->view->generate("main_view.php", "template_view.php"); ) )
    I metode generere en forekomst av View-klassen, sendes navnene på filene til den generelle malen og visningen med sideinnholdet.
    I tillegg til indekshandlingen kan kontrolleren selvfølgelig inneholde andre handlinger.

    Vi gjennomgikk den generelle visningsfilen tidligere. Tenk på innholdsfilen main_view.php:
    Velkommen!

    OLOLOSHA TEAM er et team av førsteklasses spesialister innen nettstedsutvikling med mange års erfaring i å samle meksikanske masker, bronse- og steinstatuer fra India og Ceylon, basrelieffer og skulpturer laget av mestere i Ekvatorial-Afrika fem eller seks århundrer siden...


    Denne inneholder enkel markering uten PHP-kall.
    For å vise hovedsiden kan du bruke en av følgende adresser:

    Vi vil vurdere et eksempel ved å bruke en visning som viser data hentet fra modellen nedenfor.

    2.3.2. Lag en "Portefølje"-side I vårt tilfelle er "Portefølje"-siden den eneste siden som bruker modellen.
    Modellen inkluderer vanligvis datasamplingsmetoder, for eksempel:
  • metoder for native pgsql- eller mysql-biblioteker;
  • metoder for biblioteker som implementerer dataabstraksjon. For eksempel metoder for PEAR MDB2-biblioteket;
  • ORM metoder;
  • metoder for å jobbe med NoSQL;
  • og så videre.
  • For enkelhets skyld vil vi ikke bruke SQL-spørringer eller ORM-setninger her. I stedet vil vi etterligne ekte data og umiddelbart returnere en rekke resultater.
    Plasser modellfilen model_portfolio.php i modellmappen. Her er innholdet:
    klasse Model_Portfolio utvider Model ( public function get_data() ( return array(array("Year" => "2012", "Site" => "http://DunkelBeer.ru", "Description" => "Kampanjenettstedet til mørkt Dunkel-øl fra den tyske produsenten Löwenbraü produsert i Russland av bryggeriselskapet "SUN InBev."), array("Year" => "2012", "Site" => "http://ZopoMobile.ru", "Description" " => "Russiskspråklig katalog over kinesiske telefoner fra Zopo basert på Android OS og tilbehør til dem."), // todo); ) )

    Modellkontrollerklassen er inneholdt i controller_portfolio.php-filen, her er koden:
    klasse Controller_Portfolio utvider Controller ( function __construct() ( $this->model = new Model_Portfolio(); $this->view = new View(); ) function action_index() ( $data = $this->model->get_data( ); $this->view->generate("portfolio_view.php", "template_view.php", $data); ) )
    Til en variabel data matrisen som returneres av metoden skrives få_data som vi så på tidligere.
    Denne variabelen sendes deretter som en metodeparameter generere, som også inneholder: navnet på filen med den generelle malen og navnet på filen som inneholder visningen med sideinnholdet.

    Visningen som inneholder sideinnholdet er i portfolio_view.php-filen.
    Portefølje

    Alle prosjektene i tabellen nedenfor er fiktive, så ikke engang prøv å følge koblingene som er gitt.
    ÅrProsjektBeskrivelse


    Alt er enkelt her, visningen viser dataene hentet fra modellen.

    2.3.3. Opprette de resterende sidene De resterende sidene opprettes på samme måte. Koden deres er tilgjengelig i GitHub-depotet, en lenke til dette er gitt på slutten av artikkelen, i "Resultat"-delen.3. Resultat Her er hva som skjedde til slutt:

    Skjermbilde av det resulterende visittkortnettstedet



    GitHub-lenke: https://github.com/vitalyswipe/tinymvc/zipball/v0.1

    Men i denne versjonen skisserte jeg følgende klasser (og deres tilsvarende typer):

    • Controller_Login der en visning genereres med et skjema for innlogging og passord, etter utfylling utføres autentiseringsprosedyren og, hvis vellykket, blir brukeren omdirigert til adminpanelet.
    • Contorller_Admin med en indekshandling som sjekker om brukeren tidligere var autorisert på siden som administrator (i så fall vises adminpanelvisningen) og en utloggingshandling for å logge ut.
    Autentisering og autorisasjon er et annet emne, så det diskuteres ikke her, men kun lenken gitt ovenfor er gitt slik at du har noe å starte fra.4. Konklusjon MVC-mønsteret brukes som et arkitektonisk grunnlag i mange rammeverk og CMSer som ble laget for å kunne utvikle kvalitativt mer komplekse løsninger på kortere tid. Dette ble muliggjort ved å øke abstraksjonsnivået, siden det er en grense for kompleksiteten til strukturene som den menneskelige hjernen kan operere med.

    Men å bruke nettrammeverk som Yii eller Kohana, som består av flere hundre filer, når man utvikler enkle nettapplikasjoner (for eksempel visittkortsider) er ikke alltid tilrådelig. Nå kan vi lage en vakker MVC-modell for ikke å blande Php, Html, CSS og JavaScript-kode i én fil.

    Denne artikkelen er mer et utgangspunkt for å lære CMF enn et eksempel på noe virkelig riktig som du kan bruke som grunnlag for din webapplikasjon. Kanskje det til og med inspirerte deg, og du tenker allerede på å skrive ditt eget mikrorammeverk eller CMS basert på MVC. Men før du gjenoppfinner det neste hjulet med "blackjack og horer," tenk om igjen: kanskje det ville være mer fornuftig å rette innsatsen mot utviklingen og hjelpe fellesskapet til et allerede eksisterende prosjekt?!

    P.S.: Artikkelen ble skrevet om under hensyntagen til noen kommentarer i kommentarfeltet. Kritikken viste seg å være svært nyttig. Å dømme etter responsen: kommentarer, PM og antall brukere som la innlegget til favoritter, viste ideen om å skrive dette innlegget seg å ikke være så ille. Dessverre er det ikke mulig å ta hensyn til alle ønskene og skrive mer og mer detaljert på grunn av tidsmangel... men kanskje de mystiske personene som nedstemte originalversjonen vil gjøre dette. Lykke til med prosjektene dine!

    5. Et utvalg nyttige lenker om emnet Artikkelen berører veldig ofte temaet nettrammeverk - dette er et veldig bredt emne, fordi selv mikrorammeverk består av mange komponenter som er smart sammenkoblet, og det vil kreve mer enn én artikkel for å snakke om disse komponenter. Jeg bestemte meg imidlertid for å presentere her et lite utvalg lenker (som jeg fulgte mens jeg skrev denne artikkelen) som på en eller annen måte relaterer seg til temaet rammeverk.

    Tagger:

    • php
    • rammeverk
    • cmf
    • mvc
    • nettstedet
    Legg til merkelapper

    I denne artikkelen vil vi se på MVC (Model, View, Controller) arkitektoniske mønster slik det brukes på webutvikling, "i sin rene form", uten å involvere noen ekstra ikke-MVC-strukturer og -mønstre. Vi vil gå fra enkelt til komplekst, så foreløpig vil vi ikke vurdere for eksempel videreutviklingen av MVC - HMVC (Hierarchical MVC) mønsteret. Selv om HMVC utvilsomt er mye mer interessant for å utvikle webapplikasjoner, erstatter ikke bruken av behovet for å forstå "vanlig" MVC.

    Wikipedia-artikkelen (som sannsynligvis er der de som så vidt begynner å lære MVC oftest ender opp) er full av unøyaktigheter og vage formuleringer, selve definisjonen er faktisk feil, og diagrammet som er gitt samsvarer rett og slett ikke med det. brukes på nettet generelt og ved utvikling i PHP – spesielt.

    Den mest korrekte definisjonen av MVC-mønsteret jeg fant:

    MVC-designmønsteret innebærer å separere applikasjonsdata, brukergrensesnitt og kontrolllogikk i tre separate komponenter: modell, visning og kontroller – slik at modifikasjon av hver komponent kan gjøres uavhengig.
    La oss presisere at begrepet "komponent" i dette tilfellet ikke har noen sammenheng med komponentene i noen populære CMS eller rammeverk, og Bitrix-komponenter, for eksempel, er generelt bygget fra alle tre komponentene i MVC.
    I definisjonen ovenfor skal en komponent forstås som et bestemt separat stykke kode, som hver spiller en av rollene som en kontroller, modell eller visning, hvor modellen tjener til å hente og manipulere applikasjonsdata, visningen er ansvarlig for visning av disse dataene som er synlige for brukeren (det vil si som brukt på nettet, danner HTML/CSS som sendes av serveren til brukerens nettleser), og kontrolleren administrerer hele dette orkesteret.

    La oss se på en klassisk webapplikasjonsdesign:

    Bilde 1

    I denne og de følgende figurene viser de stiplede linjene kontrollinformasjon (som IDen til det forespurte blogginnlegget eller produktet i butikken), og de heltrukne linjene viser de faktiske applikasjonsdataene (som kan lagres i databasen, eller som filer på disk, eller kanskje , i RAM - dette problemet ligger utenfor omfanget av MVC-mønsteret). Når forespørselen og svaret brukes på nettet, går forespørselen og svaret over HTTP, så vi kan grovt anta at i denne figuren indikerer de stiplede linjene HTTP-forespørsels- og svarhodene, og de heltrukne linjene indikerer kroppen deres.

    Etter å ha mottatt forespørsel 1, analyserer kontrolløren den og kan, avhengig av behandlingsresultatene, gi følgende svaralternativer (hvorfor svaret er nummer 4 vil fremgå av følgende figurer):

    1. Gi umiddelbart et feilsvar (for eksempel, når du ber om en ikke-eksisterende side, oppgi bare HTTP-overskriften «404 ikke funnet»)

    2. Hvis den mottatte Forespørsel 1 gjenkjennes som korrekt, vil kontrolleren, avhengig av om det er en forespørsel om å se eller modifisere data, kalle den tilsvarende modellmetoden, slik som Lagre eller Last (Forespørsel 2 i Fig. 2).

    Figur 2

    Viktig merknad: Ikke bare er MVC-konseptet ikke knyttet til noe spesifikt programmeringsspråk, det er heller ikke knyttet til programmeringsparadigmet som brukes. Det vil si at du enkelt kan designe applikasjonen din ved hjelp av MVC, uten å bruke OOP, og designe en produktmodell for en nettbutikk på denne måten:

    Så, avhengig av svar 2 mottatt fra modell, bestemmer kontrolløren hvilken av visningene som skal ringes for å generere det endelige svaret på den første forespørselen 1:

    3.1. Ved feil – Se for feilmelding
    3.2. Hvis vellykket – Vis for å vise de forespurte dataene eller en melding om vellykket lagring (hvis Forespørsel 1 var å endre data).

    Figur 3

    Spørsmålet om hvem som skal sjekke gyldigheten og tillatelsene til inndataene (kontrollør eller modell) er gjenstand for ganske mye debatt, siden MVC-mønsteret ikke beskriver slike detaljer. Dette betyr at i denne saken er valget ditt (eller forfatterne av ditt favorittrammeverk eller CMS har laget det for deg).
    I vår praksis følger vi følgende tilnærming:
    Kontrolløren sjekker inngangsdataene for "generell" (dvs. uavhengig av en spesifikk forespørsel) korrekthet, samsvar med modellens krav til gyldigheten av de lagrede dataene kontrolleres av den tilsvarende modellmetoden, og tilgangsrettigheter kontrolleres av tilgangsmetoden av den separate brukerklassen.

    For å kalle en View i PHP, er det noen ganger designet en spesiell klasse (eller til og med flere klasser), for eksempel View (dette finnes ofte i MVC-beskrivelser i implementeringen av et bestemt rammeverk), men dette er ikke et krav for MVC.
    View-filer kalles også ofte maler, og når du bruker såkalte malmotorer, spilles rollen som View av selve malmotoren, og maler (dvs. filer som inneholder direkte HTML-markering) i noen rammeverk kalles layouter.

    Det forrige avsnittet er ikke helt klart? Glem det, for hos oss er hver View bare en separat PHP-fil, og PHP i seg selv er utformet på en slik måte at hvis vi bruker include-setningen til å utføre Request 3, Response 3 og Response 4 (husk at dette er svaret på Request 1? ) gis til nettleseren automatisk ved å bruke PHP selv.

    La oss se på et eksempel.

    Vi har to alternativer for Visninger (maler) der

    vil bety HTML-koden som går foran hovedinnholdet i det genererte nettdokumentet (dvs. inneholder doctype-taggen, hodebeholderen, sideoverskriftskoden osv.), og - omtrent det samme, bare for bunnteksten på siden.

    Oppføring 1. Product.tpl.php-malen viser data om produktet (som allerede inneholder $product-objektet når det kalles):

    Pris:

    Oppføring 2. Error.tpl.php-malen viser feilmeldingen (inneholdt i $error-variabelen):

    Feil:

    Oppføring 3. Product.php-kontrolleren som brukes til å vise produktet vil se omtrent slik ut:

    De som elsker vakker og optimalisert kode kan legge merke til at HTML.header og HTML.footer-blokkene er duplisert i begge malene (aka Views) error.tpl.php og product.tpl.php , og vil sannsynligvis ønske å flytte dem inn i produktet Kontroller. save.php:

    …. og dermed bryte den grunnleggende regelen for MVC - separat kontroller, modell og visning.

    Imidlertid er duplikatkode helt klart Evil. Hva å gjøre?
    Vi må gå fra MVC til HMVC!
    Men dette er et tema for en egen artikkel.

    Bootstrap-rammeverk: rask adaptiv layout

    Trinn-for-trinn videokurs om det grunnleggende om adaptiv layout i Bootstrap-rammeverket.

    Lær å sette enkelt, raskt og effektivt ved å bruke et kraftig og praktisk verktøy.

    Layout for å bestille og få betalt.

    Gratis kurs "Nettsted på WordPress"

    Vil du mestre WordPress CMS?

    Få leksjoner om nettsteddesign og layout på WordPress.

    Lær å jobbe med temaer og klippeoppsett.

    Gratis videokurs om å tegne et nettsted design, layout og installasjon på CMS WordPress!

    * Hold musen over for å pause rullingen.

    Tilbake fremover

    En vennlig tilnærming til webutvikling: MVC-modell

    Hva er MVC? Kort fortalt er det en tilnærming til utvikling som lar deg oppnå mer strukturert kode og applikasjonen som helhet.

    MVC står for Model-View-Controller. La oss snakke om dette mer detaljert.

    I dag er det to mest typiske måter å lage nettapplikasjoner (nettsteder).

    Den første metoden, la oss kalle den "Classical", antar at én fil kan inneholde kode fra ulike programmerings- og markup-språk.

    La oss si at i begynnelsen av filen blir det gjort en spørring til databasen for å få litt informasjon fra den. Her har vi å gjøre med SQL-språket - et spesielt spørringsspråk designet for å samhandle med en database.

    Etter dette begynner som regel html-markeringen av siden (hvor ville vi vært uten den?). Dessuten, inne i html-markeringen, er PHP-kode satt inn på de riktige stedene, som kontrollerer nettstedet og er dets logikk. Totalt har vi i én fil: SQL, (X)HTML og PHP. Dette er allerede et sammensurium. Ikke glem å legge til litt mer CSS og litt Javascript her for å fullføre bildet, og til slutt vil vi få et slikt rot at djevelen selv vil brekke beinet i denne filen.

    Selvfølgelig vil du først huske hva og hvordan som foregår i det, hvorfor du trenger det, og hvor du må gjøre endringer for å legge til/fjerne/endre visse funksjoner. Jeg garanterer deg imidlertid at du i løpet av noen måneder vil se på koden din med forvirring, prøve å huske hva som er koblet til hva, hvilke endringer som vil bli "implementert" etter at du har endret en fil, osv.

    Jeg sier ikke at denne tilnærmingen skal forlates helt, men det er klart at den må brukes klokt og svært forsiktig.

    Den andre metoden er koblet nøyaktig til bruken av "Model-View-Controller" -ordningen.

    Hva er essensen av denne tilnærmingen, og hvordan kan bruken av den hjelpe deg i arbeidet ditt?

    Hovedideen med denne tilnærmingen er behovet skille homogene elementer i forskjellige filer. For å si det veldig enkelt: én fil – ett språk. Men dette er et veldig grovt eksempel. Dette er ekstremt sjeldent.

    Foruten ideen om å holde forskjellige språk i forskjellige filer, er nøkkelbegrepet også dele filer i grupper i henhold til funksjonene de utfører i applikasjonen.

    Her begynner vi å nærme oss MVC-modellen mer detaljert.

    Denne modellen innebærer å dele alle filene som er involvert i nettstedutvikling i tre grupper:

    1. Filer av "modell"-gruppen
    2. Filer av "kontroller"-gruppen
    3. Filer fra "view"-gruppen

    Her er det viktig å umiddelbart forstå at navnet på MVC-ordningen er en konvensjon. Applikasjonen din kan selvfølgelig ha mange modeller, kontrollere og visninger (det vil si filer som faller inn i disse gruppene basert på funksjonene de utfører og deres interne struktur).

    Så, la oss se på et sammenligningsdiagram av MVC-modellen og den "klassiske" utviklingsmåten.


    På venstre side ser du nøyaktig hva vi snakket om ovenfor. Øverst på siden er SQL-spørringer til databasen. Deretter markering pluss PHP-innlegg.

    Til høyre er det enkleste diagrammet av MVC-modellen. Innenfor denne ordningen operasjoner relatert til interaksjon med databasen forekommer i modellen: hente data, endre og slette dem, telle antall poster i visse tabeller osv.

    Kontrolleren inneholder applikasjonslogikken, dvs. det som bestemmer funksjonaliteten.

    Visningen er ment å vises til sluttbrukeren.

    De tohodede pilene i diagrammet viser at det er en sammenheng i "Model - Controller" og "Controller - View"-parene. La oss vurdere dette forholdet mer detaljert ved å bruke følgende diagram som et eksempel.


    I dette diagrammet har vi lagt til to nye elementer: brukerens nettleser og databasen. La oss generelt vurdere hele syklusen: fra nettleseren får tilgang til en bestemt URL til det øyeblikket siden vises for brukeren:

    1. Brukeren skriver inn adressen og nettleseren kontakter kontrolleren.

    2. Kontrolleren får tilgang til modellen.

    3. Modellen får tilgang til databasen (for eksempel for å få informasjon som er nødvendig for utdata)

    4. Informasjon fra databasen går tilbake til modellen.

    5. Informasjon overføres fra modellen til kontrolleren.

    6. Kontrolleren sender denne informasjonen til visningen.

    7. Visningen vises i nettleseren ved hjelp av kontrolleren.

    Dette er det generelle driftsskjemaet for denne modellen. Som du kan se, skiller nettleseren og databasen seg noe ut hver for seg i dette diagrammet. Faktisk kan nettleseren bare få tilgang til kontrolleren, siden kontrolleren er en del av url-en. Den besøkende kan ikke få tilgang til noe annet enn kontrolleren. Dette er viktig å forstå. En person kan ikke få tilgang til visninger eller modeller via adressefeltet. Den samhandler kun med kontrolleren.

    I denne forbindelse kan vi snakke om kontrolleren som et slags "distribusjonssenter". Se selv: kontrolleren behandler brukerforespørsler, kontrolleren får tilgang til modellen, og kontrolleren er et mellomledd for å vise visningen i nettleseren.

    Det andre elementet som skiller seg ut er databasen. Og det er riktig. Innenfor rammen av MVC-konseptet er det akseptert at Bare modeller skal fungere med databasen Noen ganger brytes imidlertid dette prinsippet. I dette tilfellet utføres interaksjon med databasen fra en kontroller eller til og med en visning.

    Selvfølgelig bør du ikke gå for langt og bryte strukturen og prinsippene til MVC, men noen ganger kan et slikt avvik fra reglene være svært nyttig når det gjelder å forbedre kodelesbarheten og forstå applikasjonens operasjonsplan.

    Modell, forresten, er et valgfritt element i MVC-skjemaet. Det er fullt mulig å implementere alt du trenger uten å bruke modeller i det hele tatt. Naturligvis vil du i dette tilfellet samhandle med databasen fra kontrolleren og vise filer. Som du allerede forstår, er ikke dette en veldig god form. Når du bestemmer deg for å jobbe innenfor rammen av dette konseptet, anbefales det å bruke modeller og gjøre det til deres tiltenkte formål.

    Vi undersøkte "ekstremene", men vår treenighet forble i midten av diagrammet, der interaksjonene "Model - Controller" og "Controller - View" finner sted.

    Etter at vi har studert det grunnleggende i denne modellen, kan vi tenke på hva denne tilnærmingen gir oss og hvorfor den er å foretrekke fremfor den klassiske.

    Hovedfordelen med å bruke en slik ordning i arbeidet ditt er allerede nevnt - dette øke strukturen til koden og applikasjonen som helhet. Det er ingen hemmelighet at MVC-modellen har blitt tatt i bruk av mange rammeverkprodusenter, inkludert min favoritt CodeIgniter.

    Tross alt, hva er et rammeverk? Hvis vi forkaster det fremmede ordet, så er dette rett og slett et rammeverk, en bestemt struktur som du blir bedt om å utvikle en nettside etter. Denne strukturen er universell nok til å lage nesten hvilken som helst nettside med dens hjelp. Samtidig, som er veldig viktig, er rammeverket også veldig fleksibelt, slik at du kan oppnå akkurat det du trenger.

    Et rammeverk er med andre ord et fleksibelt rammeverk som begrenser deg med tanke på struktur, men ikke begrenser deg med tanke på funksjonalitet.

    For å gå tilbake til spørsmålet om MVC, kan vi se at mange rammeverk bruker akkurat denne tilnærmingen: de gir en ganske tydelig applikasjonsstruktur, som også deler filer inn i typer, modeller og kontrollere. Alt dette sammen kan spare deg for mye tid hvis du en gang bruker den på å lære hvordan du bruker MVC-rammeverket og -modellen.

    Blant andre fordeler med MVC-modellen kan vi merke inndelingen av kode i henhold til funksjonalitet. Du trenger ikke lenger å grave gjennom rotet med SQL-spørringer, markeringer og PHP-kode. Hvis du trenger å rette eller endre noe, vil du vite nøyaktig hvilken fil du må redigere.

    Nedenfor kan du se en del av filen som tilhører gruppen "visninger":


    Og her er et stykke kode fra modellen:


    Slik kan kontrolleren se ut:


    En veldig viktig fordel, som du kan se, er separasjonen av utsikten fra koden. Ofte er det nødvendig å på en eller annen måte endre designet eller til og med strukturen på nettstedet, samtidig som du opprettholder den samme informasjonen på siden som ble vist før. Og her begynner å redigere virvar av kode, som blir vanskeligere og vanskeligere over tid.

    Fordelen med MVC-modellen ligger nettopp i muligheten til å fullstendig eliminere redigering av nettstedets design når du endrer logikken til applikasjonen. Du kan endre hvilket som helst av tre elementer: Model, View, Controller. I dette tilfellet trenger du ikke å gjøre endringer i andre elementer, siden de til en viss grad er autonome.

    Spørsmålet om autonomi er spesielt relevant for modeller og arter. Når du har skrevet dem, kan du vanligvis bruke dem med hell til en rekke prosjekter med minimale eller ingen redigeringer. Dette sparer deg for mye tid ved å slippe å skrive lignende kode om og om igjen.

    Fordelene ved å bruke MVC-modellen innenfor et rammeverk, for eksempel CodeIgniter, er åpenbare.

    Det er ingen hemmelighet at hvert nettsted har et stort antall lignende, eller til og med identiske, funksjoner. Bare husk tilbakemeldingsskjemaet eller sidenavigasjonen. Dette er bare de mest slående, "eksterne" øyeblikkene. Du finner enda flere likheter i kode som ikke er synlig for den gjennomsnittlige brukeren, i kode som kjører på serveren.

    Nesten alle webutviklere står overfor behovet for å bruke lignende PHP-funksjoner, utføre lignende databasespørringer, etc. Rammeprodusenter har gjort en veldig viktig ting her - de har forsøkt å gruppere de funksjonene som brukes oftest i separate filer, noe som gir webmastere og webprogrammerere nye muligheter.

    Nå kan du gjøre ting du trenger uten å tenke for mye på hvordan de skal implementeres. Du kan skrive et par linjer med kode i stedet for et par dusin linjer, spare tid og fokusere mer på logikken til applikasjonen i stedet for hvordan du implementerer den.

    Og alt dette skjer innenfor rammen av MVC-konseptet, slik at du kan oppnå nesten alle resultater ved å bruke rammeverket. Samtidig får du en høy grad av kodelesbarhet. Hva mer trenger du for komfortabelt og produktivt arbeid?

    Etterord: Ikke glem at enhver struktur som ble opprettet for å gjøre visse oppgaver lettere å fullføre ble opprettet bare for å gjøre jobben enklere.

    Du bør ikke følge MVC-prinsippet i tilfeller hvor du er sikker på at det har en dårlig effekt på forståelsen av applikasjonsstrukturen. Det er ikke du som skal "bøye deg" under modellen, men modellen under deg.

    Dmitry Naumenko

    P.S. Tenker du på hvilket PHP-rammeverk du skal mestre? Vær oppmerksom på CakePHP - den implementerer MVC-mønsteret diskutert ovenfor, og akkurat nå kan du få et kort introduksjonsvideokurs for å få en generell ide om mulighetene til dette rammeverket:

    Likte du materialet og vil takke meg?
    Bare del med dine venner og kolleger!


    Model-View-Controller (MVC) designmønster er et programvarearkitekturmønster bygget rundt å holde representasjonen av data atskilt fra metodene som samhandler med dataene.

    Selv om MVC opprinnelig ble utviklet for personlige datamaskiner, har den blitt tilpasset og mye brukt av webutviklere på grunn av dens nøyaktige separasjon av bekymringer og muligheten til å gjenbruke kode. Ordningen oppmuntrer til utvikling av modulære systemer, som lar utviklere raskt oppdatere, legge til eller fjerne funksjonalitet.

    I denne artikkelen vil jeg beskrive de grunnleggende prinsippene, samt se på definisjonen av et byggeskjema og et enkelt MVC PHP eksempel.

    Hva er MVC

    Navnet på et designmønster bestemmes av dets tre hovedkomponenter: Model, View og Controller. Den visuelle representasjonen av MVC-mønsteret ser ut som diagrammet nedenfor:


    Figuren viser strukturen til en enveis dataflyt og dens veier mellom ulike komponenter, samt deres interaksjon. Modell

    En modell er et permanent depot av data som brukes gjennom en struktur. Den skal gi tilgang til data for visning, valg eller opptak. I den overordnede strukturen er "Modellen" broen mellom "View" og "Controller"-komponentene.

    "Modellen" har imidlertid ingen forbindelse eller informasjon om hva som skjer med dataene når de sendes til "View"- eller "Controller"-komponentene. Den eneste oppgaven til "Modellen" er å behandle data i vedvarende lagring, søke og klargjøre data overført til andre komponenter i MVC.

    "Modellen" skal fungere som en "gatekeeper", stå i nærheten av datavarehuset og ikke stille spørsmål, men akseptere alle innkommende forespørsler. Dette er ofte den mest komplekse delen av et MVC-system. "Modell" -komponenten er toppen av hele strukturen, siden uten den er forbindelsen mellom "Controller" og "View" umulig.

    Opptreden

    Visningen er den delen av systemet der dataene som forespørres fra modellen får den endelige formen for utdata. I webapplikasjoner bygget på MVC er "View" komponenten der HTML-koden genereres og vises.

    Visningen avskjærer også brukerens handling, som deretter sendes til "Kontrolleren". Et typisk eksempel på dette er knappen som genereres av "Vis". Når brukeren klikker på det, utløses en handling i "Kontrolleren".

    Det er flere vanlige misoppfatninger om View-komponenten. For eksempel tror mange feilaktig at "View" ikke har noen forbindelse med "Modellen", og alle viste data overføres fra "Controller". I virkeligheten tar ikke dette dataflytdiagrammet hensyn til teorien bak MVC-arkitektur. I sin artikkel beskriver Fabio Cevasco denne ukorrekte tilnærmingen ved å bruke eksemplet på et av de ikke-tradisjonelle MVC PHP-rammeverkene:

    "For å bruke MVC-arkitekturen riktig, bør det ikke være noen interaksjon mellom modellen og visningen: all logikk håndteres av kontrolleren."

    I tillegg er definisjonen av "View" som en malfil også unøyaktig. Men dette er ikke en persons feil, men resultatet av mange feil fra forskjellige utviklere, noe som fører til en generell misforståelse. Da forklarer de det feil for andre. Faktisk er "View" mye mer enn bare en mal. Men moderne MVC-orienterte rammeverk har absorbert denne tilnærmingen i en slik grad at ingen lenger bryr seg om den riktige MVC-strukturen støttes eller ikke.

    View-komponenten sendes aldri data direkte av kontrolløren. Det er ingen direkte forbindelse mellom "View" og "Controller" - de er koblet til ved hjelp av "Modellen".

    Kontroller

    Dens oppgave er å behandle dataene som brukeren legger inn og oppdatere "Modellen". Dette er den eneste delen av diagrammet som krever brukerinteraksjon.

    "Kontroller" kan defineres som en innsamler av informasjon, som deretter overføres til "Modellen" og deretter organiseres for lagring. Den inneholder ingen annen logikk enn behovet for å samle inn innkommende data. "Kontrolleren" kobles også til bare en "View" og en "Model". Dette skaper et enveis dataflytsystem med én inngang og én utgang ved kommunikasjonspunktene.

    Kontrolleren mottar oppgaver som skal utføres kun når brukeren samhandler med visningen, og hver funksjon avhenger av brukerens interaksjon med visningen. Den vanligste feilen utviklere gjør er at de forveksler kontrolleren med gatewayen, så de tildeler den funksjoner og oppgaver som hører til visningen.

    En annen vanlig feil er å gi "kontrolleren" funksjoner som kun er ansvarlige for å behandle og overføre data fra "modellen" til "visningen". Men i henhold til strukturen til MVC-mønsteret, bør denne interaksjonen utføres mellom "Model" og "View".

    MVC i PHP

    La oss skrive en nettapplikasjon i PHP, hvis arkitektur er basert på MVC. La oss starte med et eksempel på wireframe:


    Enkelt, ikke sant? Denne kontrolleren vil bli lagret som books_controller.php og lagt inn /app/kontrollere. Den inneholder en liste over funksjoner som utfører handlingene for vårt eksempel, samt andre funksjoner for å utføre bokrelaterte operasjoner (legge til en ny bok, slette en bok, og så videre).

    Arbeidsmiljøet gir oss mange ferdige løsninger og vi trenger bare å lage en liste med bøker. Det er en basisklasse som allerede definerer den grunnleggende funksjonaliteten til kontrolleren, så du må arve egenskapene og funksjonene til denne klassen ( AppController er arvingen Kontroller).

    Alt du trenger å gjøre i handlingslisten er å ringe modellen for å få dataene og deretter velge en visning for å presentere den for brukeren. Her er hvordan det gjøres.

    denne->bok- dette er vår modell, og en del av koden:

    $this->Book->findAllByCategory($category)

    ber modellen returnere en liste over bøker om det valgte emnet (vi skal se på modellen senere).

    Metode sett på linje:

    $this->set("bøker", $this->Book->findAllByCategory($category));

    Kontrolleren sender data til visningen. Variabel bøker godtar dataene som returneres av modellen og gjør dem tilgjengelige for visningen.

    Nå gjenstår det bare å vise visningen, men denne funksjonen gjøres automatisk i cakePHP hvis vi bruker standardvisningen. Hvis vi vil bruke en annen type, må vi eksplisitt kalle metoden gjengi.

    Modell

    Modellen er enda enklere:

    klassebok utvider AppModel (

    Hvorfor er det tomt? Fordi den arver fra en basisklasse som gir den nødvendige funksjonaliteten, og vi må bruke CakePHPs navnekonvensjon for å få kjøretiden til å håndtere alle andre oppgaver automatisk. For eksempel vet cakePHP basert på navnet at denne modellen brukes i BooksController, og at den har tilgang til en databasetabell kalt bøker.

    Med denne definisjonen vil vi ha en modell som kun kan lese, slette eller lagre data i databasen.

    Lagre koden som book.php i mappen /app/modeller.

    Utsikt

    Alt vi trenger å gjøre nå er å lage en visning (minst én) for handlingslisten. Visningen vil ha HTML-kode og noen få (så få som mulig) linjer med PHP-kode for å gå gjennom utvalget av bøker som modellen gir.



    Navn
    Forfatter
    Pris








    Som du kan se, lager visningen ikke en hel side, men bare et fragment av HTML (en tabell i dette tilfellet). Fordi CakePHP gir en annen måte å definere en sidemal på, og visningen settes inn i den malen. Arbeidsbenken gir oss også noen hjelpeobjekter for å utføre vanlige oppgaver mens du lager deler av en HTML-side (sett inn skjemaer, lenker, Ajax eller JavaScript).

    Lagre visningen som list.ctp(liste er handlingsnavnet og ctp betyr CakePHP-mal) i mappen /app/visninger/bøker(fordi det er en visning for en kontrollerhandling).

    Dette er hvordan alle tre komponentene utføres ved hjelp av CakePHP arbeidsbenken!