Oprettelse af mvc. MVC: hvad er det, og hvad har det med brugergrænsefladen at gøre

Mange mennesker begynder at skrive et projekt for at arbejde med en enkelt opgave, uden at det er ensbetydende med, at det kan vokse til et multi-user management system, for eksempel indhold eller, gud forbyde, produktion. Og alt virker fantastisk og fedt, alt fungerer, indtil du begynder at forstå, at den kode, der er skrevet, udelukkende består af krykker og hård kode. Koden er blandet med layout, forespørgsler og krykker, nogle gange endda ulæselig. Et presserende problem opstår: Når du tilføjer nye funktioner, skal du pille ved denne kode i meget lang tid og huske "hvad blev skrevet der?" og forbande dig selv i fortiden.

Du har måske endda hørt om designmønstre og endda bladret i disse vidunderlige bøger:

  • E. Gamma, R. Helm, R. Johnson, J. Vlissides “Objektorienterede designteknikker. Designmønstre";
  • M. Fowler "Arkitektur af Enterprise Software Applications."
Og mange, uforskrækkede over de enorme manualer og dokumentation, forsøgte at studere enhver af de moderne rammer, og stillet over for kompleksiteten af ​​forståelse (på grund af tilstedeværelsen af ​​mange arkitektoniske koncepter, der er smart forbundet med hinanden), udskyde undersøgelsen og brugen af moderne værktøj "på bagsiden".

Denne artikel vil primært være nyttig for begyndere. Jeg håber i hvert fald, at du i løbet af et par timer vil være i stand til at få en idé om implementeringen af ​​MVC-mønsteret, som ligger til grund for alle moderne web-frameworks, og også få "mad" til yderligere refleksion over "hvordan man gør det." I slutningen af ​​artiklen er der et udvalg af nyttige links, som også vil hjælpe dig med at forstå, hvad web frameworks består af (udover MVC), og hvordan de fungerer.

Erfarne PHP-programmører finder næppe noget nyt for sig selv i denne artikel, men deres kommentarer og kommentarer til hovedteksten ville være meget nyttige! Fordi Uden teori er praksis umulig, og uden praksis er teori ubrugelig, så først kommer der lidt teori, og så går vi videre til praksis. Hvis du allerede er bekendt med MVC-konceptet, kan du springe teoriafsnittet over og gå direkte til praksis.

1. Teori MVC-mønsteret beskriver en enkel måde at strukturere en applikation på, hvis formål er at adskille forretningslogik fra brugergrænsefladen. Som et resultat er applikationen nemmere at skalere, teste, vedligeholde og selvfølgelig implementere.

Lad os se på det konceptuelle diagram af MVC-mønsteret (efter min mening er dette det mest succesrige diagram, jeg har set):

I MVC-arkitektur giver modellen data- og forretningslogikreglerne, visningen er ansvarlig for brugergrænsefladen, og controlleren sørger for interaktion mellem modellen og visningen.

Et typisk flow af en MVC-applikation kan beskrives som følger:

  • Når en bruger besøger en webressource, opretter initialiseringsscriptet en forekomst af applikationen og starter den til udførelse.
    Dette viser en visning af f.eks. webstedets hovedside.
  • Applikationen modtager en anmodning fra brugeren og bestemmer den anmodede controller og handling. I tilfælde af hovedsiden udføres standardhandlingen ( indeks).
  • Applikationen instansierer controlleren og kører handlingsmetoden,
    som fx indeholder modelkald, der læser information fra databasen.
  • Herefter opretter handlingen en visning med data hentet fra modellen og viser resultatet for brugeren.
  • Model - indeholder applikationens forretningslogik og inkluderer metoder til sampling (disse kan være ORM-metoder), behandling (for eksempel valideringsregler) og tilvejebringelse af specifikke data, hvilket ofte gør det meget tykt, hvilket er ganske normalt.
    Modellen bør ikke interagere direkte med brugeren. Alle variabler relateret til brugeranmodningen skal behandles i controlleren.
    Modellen bør ikke generere HTML eller anden visningskode, der kan ændre sig afhængigt af brugerens behov. En sådan kode bør behandles i visninger.
    Den samme model, for eksempel: brugergodkendelsesmodellen kan bruges i både bruger- og administrative dele af applikationen. I dette tilfælde kan du flytte den generelle kode til en separat klasse og arve fra den, ved at definere underapplikationsspecifikke metoder i dens efterkommere.

    View - bruges til at angive den eksterne visning af data modtaget fra controlleren og modellen.
    Visninger indeholder HTML-markering og små indsættelser af PHP-kode til at krydse, formatere og vise data.
    Bør ikke få direkte adgang til databasen. Dette er hvad modeller skal gøre.
    Bør ikke fungere med data hentet fra en brugeranmodning. Denne opgave skal udføres af controlleren.
    Kan direkte få adgang til egenskaber og metoder for en controller eller modeller for at opnå output-klare data.
    Visninger er normalt opdelt i en fælles skabelon, der indeholder markeringer, der er fælles for alle sider (f.eks. et sidehoved og en sidefod) og dele af skabelonen, der bruges til at vise dataoutput fra modellen eller vise dataindtastningsformularer.

    Controlleren er limen, der forbinder modeller, visninger og andre komponenter til en fungerende applikation. Den dataansvarlige er ansvarlig for at behandle brugeranmodninger. Controlleren bør ikke indeholde SQL-forespørgsler. Det er bedre at holde dem i modeller. Controlleren bør ikke indeholde HTML eller anden opmærkning. Det er værd at bringe det til syne.
    I en veldesignet MVC-applikation er controllere normalt meget tynde og indeholder kun et par dusin linjer kode. Det samme kan ikke siges om Stupid Fat Controllers (SFC) i CMS Joomla. Controllerlogikken er ret typisk, og det meste af den overføres til basisklasser.
    Modeller er tværtimod meget tykke og indeholder det meste af koden relateret til databehandling, pga datastrukturen og forretningslogikken indeholdt i den er normalt ret specifikke for en bestemt applikation.

    1.1. Front Controller og Page Controller I de fleste tilfælde sker brugerinteraktion med en webapplikation ved at klikke på links. Se nu på adresselinjen i din browser - du har modtaget denne tekst fra dette link. Andre links, såsom dem på højre side af denne side, vil give dig andet indhold. Linket repræsenterer således en specifik kommando til webapplikationen.

    Jeg håber, du allerede har bemærket, at forskellige websteder kan have helt forskellige formater til at konstruere adresselinjen. Hvert format kan vise arkitekturen af ​​en webapplikation. Selvom dette ikke altid er tilfældet, er det i de fleste tilfælde et klart faktum.

    Lad os overveje to muligheder for adresselinjen, som viser noget tekst og en brugerprofil.

    Omtrentlig behandlingskode i dette tilfælde:
    switch($_GET["handling"]) (case "about" : require_once("about.php"); // "Om os" sideskift; case "contacts" : require_once("contacts.php"); // "Kontakter" sideskift; case "feedback" : require_once("feedback.php"); // "Feedback" sideskift; standard: require_once("page404.php"); // side "404" pause; )
    Jeg tror næsten alle har gjort dette før.

    Ved at bruge en URL-routingmotor kan du konfigurere din applikation til at acceptere anmodninger som denne for at vise de samme oplysninger:
    http://www.example.com/kontakter/feedback

    Her repræsenterer kontakter controlleren, og feedback er kontaktcontrollermetoden, der viser feedbackformularen osv. Vi vender tilbage til dette problem i den praktiske del.

    Det er også værd at vide, at mange web-frameworks routere giver dig mulighed for at oprette brugerdefinerede URL-ruter (angiv, hvad hver del af URL'en betyder) og regler for behandling af dem.
    Nu har vi tilstrækkelig teoretisk viden til at komme videre til praksis.

    2. Øv Lad os først oprette følgende fil- og mappestruktur:


    Fremadrettet vil jeg sige, at kerneklasserne Model, View og Controller vil blive gemt i kernemappen.
    Deres børn vil blive gemt i controllere, modeller og visningsmapper. index.php-filen er indgangspunktet til applikationen. Bootstrap.php-filen starter indlæsningen af ​​applikationen, forbinder alle de nødvendige moduler osv.

    Vi vil gå sekventielt; Lad os åbne filen index.php og udfylde den med følgende kode:
    ini_set("display_errors", 1); require_once "application/bootstrap.php";
    Der burde ikke være nogen spørgsmål her.

    Lad os derefter straks gå 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 routeren
    De første tre linjer vil inkludere i øjeblikket ikke-eksisterende kernefiler. De sidste linjer inkluderer filen med routerklassen og start den til udførelse ved at kalde den statiske startmetode.

    2.1. Implementering af en URL-router Lad os nu afvige fra implementeringen af ​​MVC-mønsteret og fokusere på routing. Det første trin, vi skal gøre, er at skrive følgende kode i .htaccess:
    RewriteEngine On RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule .* index.php [L]
    Denne kode vil omdirigere al sidebehandling til index.php, hvilket er hvad vi har brug for. Kan du huske, at vi i første del talte om Front Controller?!

    Vi vil placere routing i en separat fil route.php i kernebiblioteket. I denne fil vil vi beskrive ruteklassen, som vil køre controller-metoder, som igen vil generere sidevisningen.

    Indholdet af filen route.php

    klasse Rute ( statisk funktion start() ( // controller og standardhandling $controller_name = "Main"; $action_name = "index"; $routes = explode("/", $_SERVER["REQUEST_URI"]); // get controllerens navn if (!empty($routes)) ( $controller_name = $routes; ) // få handlingsnavnet if (!empty($routes)) ( $action_name = $routes; ) // tilføj præfikser $model_navn = " Model_".$controller_name; $controller_name = "Controller_".$controller_name; $action_name = "action_".$action_name; // tilslut filen med modelklassen (der er muligvis ikke en modelfil) $model_file = strtolower ($model_name). ".php"; $model_path = "application/models/".$model_file; if(file_exists($model_path)) (inkluder "application/models/".$model_file;) // tilslut filen med controller-klassen $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 korrekt at smide en undtagelse her, men for at forenkle tingene, omdirigerer vi straks til 404-siden */ Route::ErrorPage404(); ) // create a controller $controller = new $controller_name ; $action = $action_name; if(method_exists($controller, $action)) ( // kalder controllerhandlingen $controller->$action(); ) else ( // her ville det også være klogere at smide en undtagelse Route::ErrorPage404(); ) ) funktion ErrorPage404( ) ( $host = "http://".$_SERVER["HTTP_HOST"]."/"; header("HTTP/1.1 404 ikke fundet"); header("Status: 404 ikke fundet") ; header(" Placering:".$host."404"); ) )


    Jeg bemærker, at klassen implementerer meget forenklet logik (på trods af den omfangsrige kode) og kan endda have sikkerhedsproblemer. Dette blev gjort med vilje, fordi... at skrive en fuldgyldig routing-klasse fortjener mindst en separat artikel. Lad os se på hovedpunkterne...

    Det globale array-element $_SERVER["REQUEST_URI"] indeholder den fulde adresse, som brugeren kontaktede.
    For eksempel: example.ru/contacts/feedback

    Brug af funktionen eksplodere Adressen er opdelt i komponenter. Som et resultat får vi navnet på controlleren, for det givne eksempel er dette controller kontakter og navnet på handlingen, i vores tilfælde - feedback.

    Dernæst forbindes modelfilen (modellen mangler muligvis) og controllerfilen, hvis der er nogen, og til sidst oprettes en instans af controlleren, og handlingen kaldes igen, hvis den blev beskrevet i controllerklassen.

    Således, når man går til for eksempel adressen:
    example.com/portefølje
    eller
    example.com/portefølje/indeks
    Routeren udfører følgende handlinger:

  • vil inkludere filen model_portfolio.php fra mappen models, der indeholder klassen Model_Portfolio;
  • vil inkludere filen controller_portfolio.php fra mappen controllere, der indeholder klassen Controller_Portfolio;
  • vil oprette en instans af klassen Controller_Portfolio og kalde standardhandlingen - action_index, beskrevet i den.
  • Hvis brugeren forsøger at få adgang til adressen på en ikke-eksisterende controller, for eksempel:
    example.com/ufo
    så vil han blive omdirigeret til "404"-siden:
    example.com/404
    Det samme vil ske, hvis brugeren tilgår en handling, der ikke er beskrevet i controlleren.2.2. Lad os vende tilbage til MVC-implementeringen Lad os gå til kernemappen og tilføje yderligere tre filer til route.php-filen: model.php, view.php og controller.php


    Lad mig minde dig om, at de vil indeholde basisklasser, som vi nu vil begynde at skrive.

    Indholdet af model.php-filen
    klasse Model ( offentlig funktion get_data() ( ) )
    Modelklassen indeholder en enkelt tom datahentningsmetode, som vil blive tilsidesat i efterkommerklasser. Når vi opretter efterkommerklasser, bliver alt tydeligere.

    Indholdet af view.php-filen
    class View ( //public $template_view; // her kan du angive standardoversigten. funktion generere($content_view, $template_view, $data = null) ( /* if(is_array($data)) ( // convert array elementer i variabler ekstraherer($data); ) */ inkluderer "application/views/".$template_view; ) )
    Det er ikke svært at gætte, at metoden frembringe beregnet til at danne sig en opfattelse. Følgende parametre overføres til den:

  • $content_file - visninger, der viser sideindhold;
  • $template_file - skabelon fælles for alle sider;
  • $data er et array, der indeholder sideindholdselementer. Normalt udfyldt i modellen.
  • Inkluderingsfunktionen forbinder dynamisk en generel skabelon (visning), hvori visningen vil blive indlejret
    for at vise indholdet af en bestemt side.

    I vores tilfælde vil den generelle skabelon indeholde sidehoved, menu, sidebjælke og sidefod, og sideindholdet vil være indeholdt i en separat form. Igen er dette gjort for nemheds skyld.

    Indholdet af controller.php-filen
    klasse Controller ( offentlig $model; offentlig $view; funktion __construct() ( $this->view = new View(); ) funktion action_index() ( ) )
    Metode handlingsindeks- dette er en handling kaldet som standard; vi vil tilsidesætte den, når vi implementerer efterkommerklasser.

    2.3. Implementering af efterkommerklasserne Model og Controller, oprettelse af View "s Nu begynder det sjove! Vores visitkort hjemmeside vil bestå af følgende sider:
  • hjem
  • Tjenester
  • Portefølje
  • Kontaktpersoner
  • Og også - siden "404".
  • Hver side har sin egen controller fra mappen controllere og en visning fra mappen views. Nogle sider kan bruge en model eller modeller fra mappen models.


    I den foregående figur er filen template_view.php fremhævet separat - dette er en skabelon, der indeholder markeringer, der er fælles for alle sider. I det simpleste tilfælde kunne det se sådan ud:
    hjem
    For at give siden et præsentabelt udseende opretter vi en CSS-skabelon og integrerer den i vores side ved at ændre strukturen af ​​HTML-markeringen og forbinde CSS- og JavaScript-filer:

    I slutningen af ​​artiklen, i afsnittet "Resultat", er der et link til et GitHub-lager med et projekt, hvor der er taget skridt til at integrere en simpel skabelon.

    2.3.1. Oprettelse af hovedsiden Lad os starte med controlleren controller_main.php , her er dens kode:
    klasse Controller_Main udvider Controller (funktion action_index() ( $this->view->generate("main_view.php", "template_view.php"); ) )
    I metode frembringe en forekomst af klassen View, navnene på filerne i den generelle skabelon og visningen med sideindholdet videregives.
    Ud over indekshandlingen kan controlleren naturligvis indeholde andre handlinger.

    Vi gennemgik den generelle visningsfil tidligere. Overvej indholdsfilen main_view.php:
    Velkommen!

    OLOLOSHA TEAM er et team af førsteklasses specialister inden for webstedsudvikling med mange års erfaring i at indsamle mexicanske masker, bronze- og stenstatuer fra Indien og Ceylon, basrelieffer og skulpturer skabt af mestre i Ækvatorialafrika fem eller seks århundreder siden...


    Dette indeholder simpel markup uden nogen PHP-kald.
    For at få vist hovedsiden kan du bruge en af ​​følgende adresser:

    Vi vil overveje et eksempel med en visning, der viser data opnået fra modellen nedenfor.

    2.3.2. Opret en "Portfolio"-side I vores tilfælde er "Portfolio"-siden den eneste side, der bruger modellen.
    Modellen inkluderer normalt datasamplingsmetoder, for eksempel:
  • metoder til native pgsql- eller mysql-biblioteker;
  • metoder til biblioteker, der implementerer dataabstraktion. For eksempel metoder i PEAR MDB2-biblioteket;
  • ORM metoder;
  • metoder til at arbejde med NoSQL;
  • og osv.
  • For nemheds skyld vil vi ikke bruge SQL-forespørgsler eller ORM-sætninger her. I stedet vil vi efterligne rigtige data og straks returnere en række resultater.
    Placer modelfilen model_portfolio.php i mappen models. Her er dens indhold:
    klasse Model_Portfolio udvider Model ( public function get_data() ( return array(array("Year" => "2012", "Site" => "http://DunkelBeer.ru", "Description" => "Kampagnewebsted for mørk Dunkel-øl fra den tyske producent Löwenbraü produceret i Rusland af bryggerivirksomheden "SUN InBev."), array("Year" => "2012", "Site" => "http://ZopoMobile.ru", "Description" " => "Russisksproget katalog over kinesiske telefoner fra Zopo baseret på Android OS og tilbehør til dem."), // todo); ) )

    Modelcontrollerklassen er indeholdt i controller_portfolio.php-filen, her er dens kode:
    klasse Controller_Portfolio udvider Controller (funktion __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 det array, der returneres af metoden, skrives få_data som vi så på tidligere.
    Denne variabel sendes derefter som en metodeparameter frembringe, som også indeholder: navnet på filen med den generelle skabelon og navnet på filen, der indeholder visningen med sidens indhold.

    Visningen, der indeholder sideindholdet, er i portfolio_view.php-filen.
    Portefølje

    Alle projekter i følgende tabel er fiktive, så prøv ikke engang at følge de angivne links.
    ÅrProjektBeskrivelse


    Alt er simpelt her, visningen viser data opnået fra modellen.

    2.3.3. Oprettelse af de resterende sider De resterende sider oprettes på samme måde. Deres kode er tilgængelig i GitHub-lageret, hvortil et link findes i slutningen af ​​artiklen, i afsnittet "Resultat".3. Resultat Her er hvad der skete til sidst:

    Skærmbillede af det resulterende visitkortwebsted



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

    Men i denne version skitserede jeg følgende klasser (og deres tilsvarende typer):

    • Controller_Login, hvor en visning genereres med en formular til indtastning af login og adgangskode, hvorefter autentificeringsproceduren udføres, og hvis det lykkes, omdirigeres brugeren til adminpanelet.
    • Contorller_Admin med en indekshandling, der kontrollerer, om brugeren tidligere var autoriseret på webstedet som administrator (hvis det er tilfældet, vises visningen af ​​adminpanelet) og en logout-handling for at logge ud.
    Autentificering og autorisation er et andet emne, så det diskuteres ikke her, men kun linket ovenfor er givet, så du har noget at starte fra.4. Konklusion MVC-mønsteret bruges som et arkitektonisk grundlag i mange frameworks og CMS'er, der er skabt for at kunne udvikle kvalitativt mere komplekse løsninger på kortere tid. Dette blev muliggjort ved at øge abstraktionsniveauet, da der er en grænse for kompleksiteten af ​​de strukturer, som den menneskelige hjerne kan operere med.

    Men det er ikke altid tilrådeligt at bruge web-frameworks som Yii eller Kohana, der består af flere hundrede filer, når man udvikler simple webapplikationer (for eksempel visitkortsider). Nu kan vi skabe en smuk MVC-model for ikke at blande Php, Html, CSS og JavaScript-kode i én fil.

    Denne artikel er mere et udgangspunkt for at lære CMF end et eksempel på noget virkelig korrekt, som du kan bruge som grundlag for din webapplikation. Måske har det endda inspireret dig, og du overvejer allerede at skrive dit eget microframework eller CMS baseret på MVC. Men før du genopfinder det næste hjul med "blackjack og horer", så tænk igen: måske ville det være mere rimeligt at rette din indsats mod udviklingen og hjælpe fællesskabet af et allerede eksisterende projekt?!

    P.S.: Artiklen blev omskrevet under hensyntagen til nogle kommentarer tilbage i kommentarerne. Kritikken viste sig at være meget nyttig. At dømme efter svaret: kommentarer, PM'er og antallet af brugere, der føjede indlægget til favoritter, viste ideen om at skrive dette indlæg sig ikke at være så dårlig. Desværre er det ikke muligt at tage hensyn til alle ønskerne og skrive mere og mere detaljeret på grund af tidsmangel... men måske vil de mystiske personer, der nedstemte den originale version, gøre dette. Held og lykke med dine projekter!

    5. Et udvalg af nyttige links om emnet Artiklen berører meget ofte emnet web-frameworks - dette er et meget bredt emne, fordi selv mikrorammeværker består af mange komponenter, der er smart forbundet, og det ville tage mere end én artikel at tale om disse komponenter. Jeg besluttede mig dog for her at præsentere et lille udvalg af links (som jeg fulgte, mens jeg skrev denne artikel), som på den ene eller anden måde relaterer sig til emnet rammer.

    Tags:

    • php
    • rammer
    • cmf
    • mvc
    • websted
    Tilføj tags

    I denne artikel vil vi se på MVC (Model, View, Controller) arkitektoniske mønster som anvendt til webudvikling, "i sin rene form", uden at involvere yderligere ikke-MVC strukturer og mønstre. Vi vil gå fra simpelt til komplekst, så indtil videre vil vi ikke overveje for eksempel den videre udvikling af MVC - HMVC (Hierarchical MVC) mønsteret. Selvom HMVC utvivlsomt er meget mere interessant til at udvikle webapplikationer, erstatter brugen ikke behovet for at forstå "almindelig" MVC.

    Wikipedia-artiklen (som formentlig er der, de som lige er begyndt at lære MVC oftest ender) er fyldt med unøjagtigheder og vage formuleringer, selve definitionen er faktisk forkert, og det angivne diagram svarer ganske enkelt ikke til det. bruges på nettet generelt og ved udvikling i PHP – i særdeleshed.

    Den mest korrekte definition af MVC-mønsteret, jeg fandt:

    MVC-designmønsteret involverer adskillelse af applikationsdata, brugergrænseflade og kontrollogik i tre separate komponenter: Model, View og Controller - så modifikation af hver komponent kan udføres uafhængigt.
    Lad os præcisere, at udtrykket "komponent" i dette tilfælde ikke har nogen forbindelse med komponenterne i nogle populære CMS eller rammer, og Bitrix-komponenter er for eksempel generelt bygget af alle tre komponenter i MVC.
    I ovenstående definition skal en komponent forstås som et bestemt separat stykke kode, som hver spiller en af ​​rollerne som en controller, model eller visning, hvor modellen tjener til at hente og manipulere applikationsdata, visningen er ansvarlig for visning af disse data, der er synlige for brugeren (dvs. som anvendt på web, danner HTML/CSS, der sendes af serveren til brugerens browser), og controlleren administrerer hele dette orkester.

    Lad os se på et klassisk webapplikationsdesign:

    Billede 1

    I denne og de følgende figurer viser de stiplede linjer kontrolinformation (såsom ID'et for det ønskede blogindlæg eller produkt i butikken), og de optrukne linjer viser de faktiske applikationsdata (som kan gemmes i databasen eller som filer på disk, eller endda måske , i RAM - dette problem ligger uden for omfanget af MVC-mønsteret). Når det anvendes på nettet, går anmodningen og svaret over HTTP, så vi kan groft antage, at i denne figur angiver de stiplede linjer HTTP-anmodnings- og svaroverskrifterne, og de ubrudte linjer angiver deres krop.

    Efter at have modtaget anmodning 1, analyserer controlleren den og kan, afhængigt af behandlingsresultaterne, udstede følgende svarmuligheder (hvorfor svaret er nummer 4, vil fremgå af følgende figurer):

    1. Angiv øjeblikkeligt et fejlsvar (angiv f.eks. kun HTTP-headeren "404 ikke fundet", når du anmoder om en ikke-eksisterende side)

    2. Hvis den modtagne anmodning 1 genkendes som korrekt, så kalder controlleren, afhængigt af om det er en anmodning om at se eller modificere data, den tilsvarende modelmetode, såsom Gem eller Indlæs (anmodning 2 i fig. 2).

    Figur 2

    Vigtig bemærkning: Ikke alene er MVC-konceptet ikke bundet til noget specifikt programmeringssprog, det er heller ikke bundet til det programmeringsparadigme, der bruges. Det vil sige, at du nemt kan designe din applikation ved hjælp af MVC, uden at bruge OOP, og designe en produktmodel til en online butik på denne måde:

    Så afhængigt af svar 2 modtaget fra model, beslutter controlleren, hvilken af ​​visningerne der skal ringes til for at generere det endelige svar på den oprindelige anmodning 1:

    3.1. I tilfælde af fejl – Se for fejlmeddelelse
    3.2. Hvis det lykkedes – Vis for at vise de anmodede data eller en meddelelse om dens succesfulde lagring (hvis anmodning 1 skulle ændre data).

    Figur 3

    Spørgsmålet om, hvem der skal kontrollere gyldigheden og tilladelserne af inputdataene (Controller eller Model) er genstand for en del debat, da MVC-mønsteret ikke beskriver sådanne detaljer. Det betyder, at valget i denne sag er dit (eller forfatterne af dit yndlingsramme eller CMS har lavet det til dig).
    I vores praksis følger vi følgende tilgang:
    Den registeransvarlige kontrollerer inputdataene for "generel" (dvs. uafhængig af en specifik anmodning) korrekthed, overholdelse af modellens krav til gyldigheden af ​​de lagrede data kontrolleres af den tilsvarende modelmetode, og adgangsrettigheder kontrolleres ved adgangsmetoden af den separate brugerklasse.

    For at kalde en View i PHP er der nogle gange designet en speciel klasse (eller endda flere klasser), for eksempel View (dette findes ofte i MVC-beskrivelser i implementeringen af ​​et bestemt framework), men dette er ikke et krav fra MVC.
    Desuden kaldes View-filer ofte for skabeloner, og når man bruger såkaldte skabelonmotorer, spilles rollen som View af selve skabelonmotoren, og skabeloner (dvs. filer, der indeholder direkte HTML-markering) i nogle rammer kaldes layouts.

    Det foregående afsnit er ikke helt klart? Glem det, for hos os er hver View blot en separat PHP-fil, og PHP i sig selv er designet på en sådan måde, at hvis vi bruger include-sætningen til at udføre Request 3, Response 3 og Response 4 (husk at dette er svaret på Request 1? ) gives til browseren automatisk ved hjælp af PHP selv.

    Lad os se på et eksempel.

    Vi har to muligheder for Visninger (skabeloner), hvori

    vil betyde HTML-koden, der går forud for hovedindholdet i det genererede webdokument (dvs. indeholder doctype-tag, hovedbeholder, sidehovedkode osv.), og - omtrent det samme, kun for sidefoden på siden.

    Liste 1. Skabelonen product.tpl.php viser data om produktet (som på det tidspunkt, det kaldes, allerede indeholder $product-objektet):

    Pris:

    Liste 2. Skabelonen error.tpl.php viser fejlmeddelelsen (indeholdt i $error-variablen):

    Fejl:

    Liste 3. Den product.php-controller, der bruges til at vise produktet, vil se nogenlunde sådan ud:

    De, der elsker smuk og optimeret kode, bemærker måske, at HTML.header- og HTML.footer-blokkene er duplikeret i begge skabeloner (aka Views) error.tpl.php og product.tpl.php , og vil sandsynligvis gerne flytte dem ind i produktet Controller. save.php:

    …. og dermed bryde grundreglen for MVC - adskil Controller, Model og View.

    Duplikatkode er dog klart Evil. Hvad skal man gøre?
    Vi skal flytte fra MVC til HMVC!
    Men dette er et emne for en separat artikel.

    Bootstrap-ramme: hurtigt adaptivt layout

    Trin-for-trin videokursus om det grundlæggende i adaptivt layout i Bootstrap-rammen.

    Lær at sætte enkelt, hurtigt og effektivt ved hjælp af et kraftfuldt og praktisk værktøj.

    Layout for at bestille og få betalt.

    Gratis kursus "Site på WordPress"

    Vil du mestre WordPress CMS?

    Få undervisning i hjemmesidedesign og layout på WordPress.

    Lær at arbejde med temaer og klippelayouts.

    Gratis videokursus om tegning af hjemmeside design, layout og installation på CMS WordPress!

    * Hold musen over for at pause rulning.

    Tilbage frem

    En venlig tilgang til webudvikling: MVC-model

    Hvad er MVC? Kort sagt er det en tilgang til udvikling, der giver dig mulighed for at opnå mere struktureret kode og applikationen som helhed.

    MVC står for Model-View-Controller. Lad os tale om dette mere detaljeret.

    I dag er der to mest typiske måder at oprette webapplikationer (sites).

    Den første metode, lad os kalde det "Klassisk", antager, at en fil kan indeholde kode fra forskellige programmerings- og opmærkningssprog.

    Lad os sige, at der i begyndelsen af ​​filen laves en forespørgsel til databasen for at få noget information fra den. Her har vi at gøre med SQL-sproget - et specielt forespørgselssprog designet til at interagere med en database.

    Herefter begynder html-markeringen af ​​siden som regel (hvor ville vi være uden den?). Desuden er PHP-kode indsat i html-markeringen de rigtige steder, som styrer webstedet og er dets logik. I alt har vi i én fil: SQL, (X)HTML og PHP. Det her er allerede et sammensurium. Glem ikke at tilføje noget mere CSS og lidt Javascript her for at fuldende billedet, og i sidste ende får vi sådan et rod, at djævelen selv vil brække benet i denne fil.

    Selvfølgelig vil du først huske, hvad og hvordan der foregår i det, hvorfor du har brug for det, og hvor du skal foretage ændringer for at tilføje/fjerne/ændre visse funktioner. Jeg garanterer dig dog, at du inden for et par måneder vil se på din kode med forvirring, forsøge at huske, hvad der er forbundet med hvad, hvilke ændringer der vil blive "implementeret" efter at have ændret en fil osv.

    Jeg siger ikke, at denne tilgang helt skal opgives, men det er klart, at den skal bruges klogt og meget omhyggeligt.

    Den anden metode er forbundet præcist med brugen af ​​"Model-View-Controller"-skemaet.

    Hvad er essensen af ​​denne tilgang, og hvordan kan brugen af ​​den hjælpe dig i dit arbejde?

    Hovedideen med denne tilgang er behovet adskille homogene elementer i forskellige filer. For at sige det meget enkelt: én fil - ét sprog. Men dette er et meget groft eksempel. Dette er yderst sjældent.

    Udover ideen om at opbevare forskellige sprog i forskellige filer, er nøglekonceptet også opdeling af filer i grupper i henhold til de funktioner, de udfører i applikationen.

    Her begynder vi at nærme os MVC-modellen mere detaljeret.

    Denne model involverer opdeling af alle filer involveret i webstedsudvikling i tre grupper:

    1. Filer af "model"-gruppen
    2. Filer fra "controller"-gruppen
    3. Filer fra "view"-gruppen

    Her er det vigtigt straks at forstå, at navnet på MVC-ordningen er en konvention. Din applikation kan selvfølgelig have mange modeller, controllere og visninger (det vil sige filer, der falder ind under disse grupper baseret på de funktioner, de udfører og deres interne struktur).

    Så lad os se på et sammenligningsdiagram af MVC-modellen og den "klassiske" måde at udvikle på.


    I venstre side ser du præcis, hvad vi talte om ovenfor. Øverst på siden er SQL-forespørgsler til databasen. Derefter markup plus PHP indsættelser.

    Til højre er det enkleste diagram af MVC-modellen. Inden for denne ordning operationer relateret til interaktion med databasen forekommer i modellen: hente data, ændre og slette dem, tælle antallet af poster i visse tabeller osv.

    Controlleren indeholder applikationslogikken, dvs. det, der bestemmer dens funktionalitet.

    Visningen er beregnet til at blive vist til slutbrugeren.

    De dobbelthovedede pile i diagrammet viser, at der er en sammenhæng i "Model - Controller" og "Controller - View" parrene. Lad os overveje dette forhold mere detaljeret ved at bruge følgende diagram som et eksempel.


    I dette diagram har vi tilføjet to nye elementer: brugerens browser og databasen. Lad os generelt betragte hele cyklussen: fra browseren får adgang til en bestemt URL til det øjeblik siden vises for brugeren:

    1. Brugeren indtaster adressen, og browseren kontakter controlleren.

    2. Controlleren tilgår modellen.

    3. Modellen får adgang til databasen (for eksempel for at indhente oplysninger, der er nødvendige for output)

    4. Information fra databasen går tilbage til modellen.

    5. Information overføres fra modellen til controlleren.

    6. Controlleren videregiver denne information til visningen.

    7. Visningen vises i browseren ved hjælp af controlleren.

    Dette er det generelle driftsskema for denne model. Som du kan se, skiller browseren og databasen sig noget adskilt ud i dette diagram. Faktisk kan browseren kun få adgang til controlleren, da controlleren er en del af url'en. Den besøgende kan ikke få adgang til andet end controlleren. Dette er vigtigt at forstå. En person kan ikke få adgang til visninger eller modeller via adresselinjen. Den interagerer kun med controlleren.

    I denne forbindelse kan vi tale om controlleren som en slags "distributionscenter". Se selv: controlleren behandler brugeranmodninger, controlleren får adgang til modellen, og controlleren er et mellemled til at vise visningen i browseren.

    Det andet element, der skiller sig ud, er databasen. Og det er rigtigt. Inden for rammerne af MVC-konceptet er det accepteret, at Kun modeller bør arbejde med databasen Men nogle gange overtrædes dette princip. I dette tilfælde udføres interaktion med databasen fra en controller eller endda en visning.

    Selvfølgelig skal du ikke gå for langt og overtræde strukturen og principperne for MVC, men nogle gange kan en sådan afvigelse fra reglerne være meget nyttig med hensyn til at forbedre kodelæsbarheden og forstå applikationens driftsskema.

    Model, i øvrigt, er et valgfrit element i MVC-skema. Det er ganske muligt at implementere alt, hvad du har brug for, uden overhovedet at bruge modeller. Naturligvis vil du i dette tilfælde interagere med databasen fra controlleren og se filer. Som du allerede forstår, er dette ikke en særlig god form. Når du beslutter dig for at arbejde inden for rammerne af dette koncept, anbefales det at bruge modeller og gøre det til deres tilsigtede formål.

    Vi undersøgte "ekstremerne", men vores treenighed forblev i midten af ​​diagrammet, hvor interaktionerne "Model - Controller" og "Controller - View" finder sted.

    Efter at vi har studeret det grundlæggende i denne model, kan vi tænke over, hvad denne tilgang giver os, og hvorfor den er at foretrække frem for den klassiske.

    Den største fordel ved at bruge en sådan ordning i dit arbejde er allerede blevet nævnt - dette at øge strukturen af ​​koden og applikationen som helhed. Det er ingen hemmelighed, at MVC-modellen er blevet adopteret af mange rammeproducenter, inklusive min favorit CodeIgniter.

    Når alt kommer til alt, hvad er en ramme? Hvis vi kasserer det fremmede ord, så er dette blot en ramme, en bestemt struktur, som du bliver bedt om at udvikle en hjemmeside efter. Denne struktur er universel nok til at skabe næsten enhver hjemmeside med dens hjælp. Samtidig, hvilket er meget vigtigt, er rammerne også meget fleksible, så du kan opnå præcis det, du har brug for.

    Et framework er med andre ord et fleksibelt framework, der begrænser dig i forhold til struktur, men ikke begrænser dig i forhold til funktionalitet.

    Vender vi tilbage til spørgsmålet om MVC, kan vi se, at mange frameworks bruger netop denne tilgang: De giver en ret klar applikationsstruktur, som også opdeler filer i typer, modeller og controllere. Alt dette tilsammen kan spare dig for en masse tid, hvis du en gang bruger den på at lære at bruge MVC-rammen og modellen.

    Blandt andre fordele ved MVC-modellen kan vi bemærke opdelingen af ​​kode efter funktionalitet. Du behøver ikke længere at grave gennem rodet af SQL-forespørgsler, markup og PHP-kode. Hvis du skal rette eller ændre noget, ved du præcis, hvilken fil du skal redigere.

    Nedenfor kan du se en del af filen, der tilhører gruppen "visninger":


    Og her er et stykke kode fra modellen:


    Sådan kan controlleren se ud:


    En meget vigtig fordel, som du kan se, er adskillelsen af ​​udsigten fra koden. Ofte er det nødvendigt på en eller anden måde at ændre webstedets design eller endda strukturen, samtidig med at de samme oplysninger på siden, der blev vist før, bevares. Og her begynder at redigere virvar af kode, som bliver sværere og sværere med tiden.

    Fordelen ved MVC-modellen ligger netop i evnen til helt at eliminere redigering af webstedets design, når man ændrer applikationens logik. Du kan ændre et hvilket som helst af tre elementer: Model, View, Controller. I dette tilfælde behøver du ikke at foretage ændringer i andre elementer, da de til en vis grad er autonome.

    Spørgsmålet om autonomi er især relevant for modeller og arter. Når du har skrevet dem, kan du normalt bruge dem med succes til en række projekter med minimale eller ingen redigeringer. Dette sparer dig for en masse tid ved ikke at skulle skrive lignende kode igen og igen.

    Fordelene ved at bruge MVC-modellen inden for rammer, for eksempel CodeIgniter, er indlysende.

    Det er ingen hemmelighed, at hver hjemmeside har et stort antal lignende eller endda identiske funktioner. Bare husk feedbackformularen eller sidenavigationen. Dette er kun de mest slående, "ydre" øjeblikke. Du vil finde endnu flere ligheder i kode, der ikke er synlig for den gennemsnitlige bruger, i kode, der kører på serveren.

    Næsten alle webudviklere står over for behovet for at bruge lignende PHP-funktioner, udføre lignende databaseforespørgsler osv. Framework-producenter har gjort en meget vigtig ting her - de har forsøgt at gruppere de funktioner, der oftest bruges, i separate filer, hvilket giver webmastere og webprogrammører nye muligheder.

    Nu kan du gøre ofte nødvendige ting uden at tænke for meget over, hvordan de vil blive implementeret. Du kan skrive et par linjer kode i stedet for et par dusin linjer, hvilket sparer din tid og fokuserer mere på applikationens logik snarere end på, hvordan den implementeres.

    Og alt dette sker inden for rammerne af MVC-konceptet, så du kan opnå næsten alle resultater ved at bruge rammen. Samtidig får du en høj grad af kodelæsbarhed. Hvad har du ellers brug for til behageligt og produktivt arbejde?

    Efterord: Glem ikke, at enhver struktur, der blev oprettet for at gøre visse opgaver nemmere at udføre, blev oprettet bare for at gøre arbejdet lettere.

    Du bør ikke overholde MVC-princippet i de tilfælde, hvor du er sikker på, at det har en dårlig effekt på din forståelse af ansøgningsstrukturen. Det er ikke dig, der skal “bøje” under modellen, men modellen under dig.

    Dmitry Naumenko

    P.S. Tænker du på, hvilken PHP-ramme du skal mestre? Vær opmærksom på CakePHP - det implementerer MVC-mønsteret diskuteret ovenfor, og lige nu kan du få et kort introduktionsvideokursus for at få en generel idé om mulighederne i denne ramme:

    Kunne du lide materialet og vil du gerne takke mig?
    Bare del med dine venner og kolleger!


    Model-View-Controller (MVC) designmønsteret er et softwarearkitekturmønster bygget op omkring at holde repræsentationen af ​​data adskilt fra de metoder, der interagerer med dataene.

    Selvom MVC oprindeligt blev udviklet til personlige computere, er det blevet tilpasset og brugt i vid udstrækning af webudviklere på grund af dets præcise adskillelse af bekymringer og evnen til at genbruge kode. Ordningen tilskynder til udvikling af modulære systemer, som giver udviklere mulighed for hurtigt at opdatere, tilføje eller fjerne funktionalitet.

    I denne artikel vil jeg beskrive de grundlæggende principper, samt se på definitionen af ​​en byggeordning og et simpelt MVC PHP eksempel.

    Hvad er MVC

    Navnet på et designmønster bestemmes af dets tre hovedkomponenter: Model, View og Controller. Den visuelle repræsentation af MVC-mønsteret ser ud som nedenstående diagram:


    Figuren viser strukturen af ​​et envejsdataflow og dets veje mellem forskellige komponenter, samt deres interaktion. Model

    En model er et permanent lager af data, der bruges gennem en struktur. Den skal give adgang til data til visning, valg eller optagelse. I den overordnede struktur er "Modellen" broen mellem "View" og "Controller" komponenterne.

    "Modellen" har dog ingen forbindelse eller information om, hvad der sker med dataene, når de overføres til "View"- eller "Controller"-komponenterne. Den eneste opgave for "Modellen" er at behandle data i vedvarende lagring, søge og forberede data overført til andre komponenter i MVC.

    "Modellen" skal fungere som en "gatekeeper", der står i nærheden af ​​datavarehuset og ikke stiller spørgsmål, men accepterer alle indkommende anmodninger. Dette er ofte den mest komplekse del af et MVC-system. "Model" -komponenten er toppen af ​​hele strukturen, da uden den er forbindelsen mellem "Controller" og "View" umulig.

    Ydeevne

    Visningen er den del af systemet, hvori de data, der anmodes om fra modellen, får den endelige form af dets output. I webapplikationer bygget på MVC er "View" den komponent, hvori HTML-koden genereres og vises.

    Visningen opsnapper også brugerens handling, som derefter sendes til "Controlleren". Et typisk eksempel på dette er knappen genereret af "Vis". Når brugeren klikker på det, udløses en handling i "Controlleren".

    Der er flere almindelige misforståelser om View-komponenten. For eksempel tror mange mennesker fejlagtigt, at "View" ikke har nogen forbindelse med "Modellen", og alle viste data overføres fra "Controller". I virkeligheden tager dette dataflowdiagram ikke højde for teorien bag MVC-arkitektur. I sin artikel beskriver Fabio Cevasco denne forkerte tilgang ved at bruge eksemplet med en af ​​de ikke-traditionelle MVC PHP-frameworks:

    "For korrekt at anvende MVC-arkitekturen bør der ikke være nogen interaktion mellem modellen og visningen: al logik håndteres af controlleren."

    Derudover er definitionen af ​​"View" som en skabelonfil også unøjagtig. Men dette er ikke én persons skyld, men resultatet af mange fejl fra forskellige udviklere, hvilket fører til en generel misforståelse. Så forklarer de det forkert til andre. Faktisk er "View" meget mere end blot en skabelon. Men moderne MVC-orienterede rammer har absorberet denne tilgang i en sådan grad, at ingen længere bekymrer sig om, hvorvidt den korrekte MVC-struktur understøttes eller ej.

    View-komponenten videregives aldrig data direkte af controlleren. Der er ingen direkte forbindelse mellem "View" og "Controller" - de er forbundet ved hjælp af "Model".

    Controller

    Dens opgave er at behandle de data, som brugeren indtaster, og opdatere "Modellen". Dette er den eneste del af diagrammet, der kræver brugerinteraktion.

    "Controller" kan defineres som en indsamler af information, som derefter overføres til "Modellen" og derefter organiseres til opbevaring. Den indeholder ingen anden logik end behovet for at indsamle indgående data. "Controlleren" forbinder også kun én "View" og en "Model". Dette skaber et envejs dataflowsystem med én indgang og én udgang ved kommunikationspunkterne.

    Controlleren modtager kun opgaver, der skal udføres, når brugeren interagerer med visningen, og hver funktion afhænger af brugerens interaktion med visningen. Den mest almindelige fejl, udviklere laver, er, at de forveksler controlleren med gatewayen, så de tildeler den funktioner og opgaver, der hører til visningen.

    En anden almindelig fejl er at forsyne "Controlleren" med funktioner, der kun er ansvarlige for at behandle og overføre data fra "Modellen" til "Visningen". Men i henhold til strukturen af ​​MVC-mønsteret bør denne interaktion udføres mellem "Modellen" og "Visningen".

    MVC i PHP

    Lad os skrive en webapplikation i PHP, hvis arkitektur er baseret på MVC. Lad os starte med et eksempel på wireframe:


    Simpelt, er det ikke? Denne controller vil blive gemt som books_controller.php og lagt ind /app/controllere. Den indeholder en liste over funktioner, der udfører handlingerne for vores eksempel, såvel som andre funktioner til at udføre bogrelaterede handlinger (tilføj en ny bog, slet en bog, og så videre).

    Arbejdsmiljøet giver os mange færdige løsninger, og vi mangler kun at lave en liste med bøger. Der er en basisklasse, der allerede definerer controllerens grundlæggende funktionalitet, så du skal arve egenskaberne og funktionerne for denne klasse ( AppController er arving Controller).

    Alt du skal gøre i handlingslisten er at ringe til modellen for at få dataene og derefter vælge en visning for at præsentere dem for brugeren. Her er hvordan det gøres.

    denne->bog- dette er vores model, og en del af koden:

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

    beder modellen om at returnere en liste over bøger om det valgte emne (vi ser på modellen senere).

    Metode sæt i kø:

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

    Controlleren videregiver data til visningen. Variabel bøger accepterer de data, som modellen returnerer, og gør dem tilgængelige for visningen.

    Nu er der kun tilbage at vise visningen, men denne funktion udføres automatisk i cakePHP, hvis vi bruger standardvisningen. Hvis vi vil bruge en anden type, skal vi udtrykkeligt kalde metoden gengive.

    Model

    Modellen er endnu enklere:

    klassebog udvider AppModel (

    Hvorfor er den tom? Fordi det arver fra en basisklasse, der giver den nødvendige funktionalitet, og vi er nødt til at bruge CakePHPs navnekonvention for at få runtime til at håndtere alle andre opgaver automatisk. For eksempel ved cakePHP ud fra sit navn, at denne model bruges i BooksController, og at den har adgang til en databasetabel med navnet bøger.

    Med denne definition vil vi have en model, der kun kan læse, slette eller gemme data i databasen.

    Gem koden som book.php i mappe /app/modeller.

    Udsigt

    Alt, hvad vi skal gøre nu, er at oprette en visning (mindst én) til handlingslisten. Visningen vil have HTML-kode og et par (så få som muligt) linjer PHP-kode til at sløjfe gennem den række af bøger, som modellen giver.



    Navn
    Forfatter
    Pris








    Som du kan se, opretter visningen ikke en hel side, men kun et fragment af HTML (en tabel i dette tilfælde). Fordi CakePHP giver en anden måde at definere en sideskabelon på, og visningen indsættes i den skabelon. Arbejdsbordet giver os også nogle hjælpeobjekter til at udføre almindelige opgaver, mens du laver dele af en HTML-side (indsættelse af formularer, links, Ajax eller JavaScript).

    Gem visningen som list.ctp(listen er handlingens navn og ctp betyder CakePHP skabelon) i mappen /app/visninger/bøger(fordi det er en visning for en controllerhandling).

    Sådan udføres alle tre komponenter ved hjælp af CakePHP-arbejdsbordet!