Mga pattern para sa mga nagsisimula: MVC vs MVP vs MVVM. Pangkalahatang mga patakaran para sa pagpili ng isang pattern. Isang seleksyon ng mga kapaki-pakinabang na link sa paksa

Mga Controller

Ang bawat kahilingan na dumarating sa application ay pinoproseso ng controller. Maaaring pangasiwaan ng controller ang kahilingan nang basta-basta hangga't hindi ito lalampas sa hangganan ng responsibilidad ng model-view. Nangangahulugan ito na ang mga controller ay hindi dapat maglaman o mag-imbak ng data, at hindi rin sila dapat bumuo ng mga user interface.

Sa ASP.NET MVC Framework, ang mga controller ay .NET na mga klase na naglalaman ng lohika na kinakailangan upang maproseso ang isang kahilingan. Ang papel ng controller ay upang i-encapsulate ang application logic. Sa madaling salita, responsable ang mga controller para sa pagproseso ng mga papasok na kahilingan at pagsasagawa ng mga operasyon sa modelo lugar ng paksa at pagpili ng mga view na ipapakita sa user.

Halimbawang Aplikasyon

Para sa mga layunin nito at susunod na mga artikulo gagawa tayo bagong proyekto Pinangalanan ng MVC ang ControllersAndActions gamit ang Empty template, tinitingnan ang checkbox ng MVC sa ilalim ng Magdagdag ng mga folder at pangunahing reference para sa, at isang proyekto sa pagsubok ng unit na tinatawag na ControllersAndActions.Tests. Ang mga unit test na gagawin mo ay hindi nangangailangan ng mga kunwaring pagpapatupad, kaya hindi mo na kailangang i-install ang Moq package, ngunit kakailanganin mong i-install ang MVC package para ma-access ng mga pagsubok ang mga base controller classes.

Sa window ng console ng Visual Studio NuGet Package Manager, ipasok ang sumusunod na command:

Install-Package Microsoft.Aspnet.Mvc -bersyon 5.0.0 -projectname ControllersAndActions.Tests

Pagkatapos gawin ang proyekto, piliin ang ControllersAndActions Properties mula sa Project menu sa Visual Studio, sa dialog box na bubukas, pumunta sa tab na Web at lagyan ng tsek ang radio button na Specific Page ( Partikular na Pahina) sa kategoryang Start Action. Hindi na kailangang magpasok ng anumang halaga - piliin lamang ang radio button.

Konsepto ng controller

Nakita mo na ang mga kaso ng paggamit para sa mga controller sa halos lahat ng nakaraang artikulo ng ASP.NET MVC. Oras na para tingnan ang behind the scenes.

Paglikha ng controller gamit ang interface ng IController

Sa MVC Framework, dapat ipatupad ng mga klase ng controller ang interface ng IController mula sa namespace System.Web.Mvc ipinapakita sa halimbawa sa ibaba:

Gamit ang System.Web.Routing; namespace System.Web.Mvc ( public interface IController ( void Execute(RequestContext requestContext); )

Upang makuha ang kahulugan ng interface na ito, kailangan mong i-download ang source code ng MVC Framework, na lubhang kapaki-pakinabang para sa pag-alam sa mga panloob na gawain ng mga tool sa framework.

Tulad ng nakikita mo, ang interface ng IController ay napaka-simple. Ang kanyang lamang Ipatupad ang() na pamamaraan Tinatawag kapag ipinadala ang isang kahilingan sa klase ng controller na ito. Tinutukoy ng MVC Framework kung aling klase ang tina-target ng kahilingan sa pamamagitan ng pagbabasa ng halaga ng property ng controller na nabuo ng data ng pagruruta, o sa pamamagitan ng mga espesyal na klase sa pagruruta.

Maaari kang lumikha ng mga klase ng controller sa pamamagitan ng pagpapatupad ng interface ng IController, ngunit dahil mababa ang antas ng interface na ito, kakailanganin mong gumawa ng maraming trabaho upang magkaroon ng anumang kapaki-pakinabang. Gayunpaman, ang interface ng IController ay kapaki-pakinabang para sa pagpapakita ng pagpapatakbo ng mga controllers at para sa layuning ito isang bagong class file na tinatawag na BasicController.cs ay nilikha sa Controllers folder, ang mga nilalaman nito ay ipinapakita sa halimbawa sa ibaba:

Gamit ang System.Web.Mvc; gamit ang System.Web.Routing; namespace ControllersAndActions.Controllers ( public class BasicController: IController ( public void Execute(RequestContext requestContext) ( string controller = (string)requestContext.RouteData.Values["controller"]; string action = (string)requestContext.RouteData.Values["action "]; requestContext.HttpContext.Response.Write(string.Format("Controller: (0), Action Method: (1)", controller, action)); ) ) )

Ang paraan ng Execute() ng interface ng IController ay ipinasa sa isang object ng RequestContext, na nagbibigay ng impormasyon tungkol sa kasalukuyang kahilingan at ang ruta na tumutugma dito (at nagiging sanhi ng pagtawag sa ibinigay na controller upang iproseso ang kahilingang iyon). Tinutukoy ng klase ng RequestContext ang dalawang katangian, na inilarawan sa talahanayan sa ibaba:

Ang HttpContextBase object ay nagbibigay ng access sa isang set ng mga object na naglalarawan sa kasalukuyang kahilingan, na tinatawag na context object; babalik tayo sa kanila mamaya. Ang RouteData object ay naglalarawan sa ruta. Ang mahahalagang katangian ng klase ng RouteData ay nakalista sa talahanayan sa ibaba:

Ipinakita ng artikulong Configuring a Routing System kung paano gamitin ang mga uri ng RouteBase at IRouteHandler para mag-configure ng routing system. Sa halimbawang isinasaalang-alang, gamit ang Values ​​property, ang mga halaga ng controller at mga variable ng segment ng aksyon ay nakuha, na pagkatapos ay isusulat sa tugon.

Bahagi ng problema sa paggawa ng mga custom na controller ay ang kawalan ng access sa mga feature gaya ng mga view. Nangangahulugan ito na kailangan mong magtrabaho sa isang mas mababang antas, na nagpapaliwanag sa pagsulat ng nilalaman nang direkta bilang tugon sa kliyente. Ari-arian HttpContextBase.Response nagbabalik ng HttpResponseBase object na nagpapahintulot sa iyo na i-configure at magdagdag ng nilalaman sa tugon na ipapadala sa kliyente. Ito ay isa pang punto ng pakikipag-ugnayan sa pagitan ng ASP.NET platform at ng MVC Framework.

Kung patakbuhin mo ang application at pumunta sa isang URL tulad ng /Basic/Index, bubuo ng espesyal na controller ang output na ipinapakita sa figure sa ibaba:

Ang pagpapatupad ng interface ng IController ay nagpapahintulot sa iyo na lumikha ng isang klase na kinikilala ng MVC Framework bilang isang controller at nagpapadala ng mga kahilingan dito, nang walang anumang mga paghihigpit sa kung paano pinoproseso ang kahilingan o kung anong tugon ang nabuo para dito. Ito magandang halimbawa dahil ipinapakita nito kung gaano kalawak ang MVC Framework kahit para sa mga pangunahing bloke ng gusali tulad ng mga controller, ngunit sa pagsusulat kumplikadong aplikasyon sa paraang ito ay maaaring puno ng malaking paghihirap.

Mga klase na may mga pangalan na nagtatapos sa Base

Ang MVC Framework ay umaasa sa ASP.NET framework upang iproseso ang mga kahilingan, na may malaking kahulugan dahil... ang platform na ito ay isang napatunayan at mayaman sa tampok na pagpapatupad na mahigpit na pinagsama sa server ng application ng IIS. Ang problema ay ang mga klase na ginagamit ng ASP.NET upang magbigay ng impormasyon ng kahilingan ay hindi angkop para sa pagsubok ng yunit, ang pangunahing benepisyo ng paggamit ng MVC Framework.

Nagpasya ang Microsoft na ipakilala ang mga kakayahan sa pagsubok habang pinapanatili ang pagiging tugma sa umiiral na mga aplikasyon ASP.NET Web Forms, kaya ang resulta ay Mga batayang klase. Tinatawag ang mga klaseng ito dahil pareho ang mga pangalan nila sa mga pangunahing klase ng ASP.NET framework, na sinusundan ng salitang Base.

Halimbawa, ang ASP.NET framework ay nagbibigay ng kontekstwal na impormasyon tungkol sa kasalukuyang kahilingan at isang bilang ng mga pangunahing serbisyo ng application sa pamamagitan ng HttpContext object. Ang katumbas na Base class nito ay HttpContextBase, isang instance kung saan ipinapasa sa Execute() method na tinukoy sa interface ng IController (ipapakita ang iba pang Base class sa mga kasunod na halimbawa). Ang orihinal at Base na mga klase ay tumutukoy sa parehong mga katangian at pamamaraan, ngunit ang mga Base na klase laging abstract, na ang ibig sabihin ay madaling gamitin ang mga ito para sa unit testing.

Minsan magkakaroon ka ng isang halimbawa ng isa sa mga orihinal na klase ng ASP.NET, gaya ng HttpContext. Sa kasong ito, kailangan mong lumikha ng MVC-friendly na Base class na katulad ng HttpContextBase. Ginagawa ito gamit ang isa sa Mga klase ng wrapper, na may parehong mga pangalan tulad ng mga orihinal na klase, na idinagdag sa salitang Wrapper, halimbawa HttpContextWrapper. Ang mga klase ng wrapper ay nagmula sa mga Base class at may mga constructor na tumatanggap ng mga instance ng mga orihinal na klase:

Ang mga orihinal na klase, Base class, at Wrapper na klase ay tinukoy sa System.Web namespace, kaya maayos na masusuportahan ng ASP.NET framework ang MVC Framework at mas lumang mga application Mga aplikasyon sa web Mga porma.

Paglikha ng controller sa pamamagitan ng pagmamana mula sa klase ng Controller

Tulad ng ipinakita sa nakaraang halimbawa, ang MVC Framework ay nagbibigay-daan para sa halos walang limitasyong pag-customize at extension. Upang magbigay ng anumang nais na uri ng pagproseso ng query at pagbuo ng resulta, maaari mong ipatupad ang interface ng IController. Hindi gusto ang mga paraan ng pagkilos? Ayaw mong mag-alala tungkol sa mga na-render na view? Sa kasong ito, maaari mong gawin ang mga bagay sa iyong sariling mga kamay at magpatupad ng mas mahusay, mas mabilis, at mas eleganteng paraan upang mahawakan ang mga kahilingan. Bilang kahalili, maaari mong samantalahin ang mga tool na inaalok ng MVC Framework team sa Microsoft at mamanahin ang iyong mga controllers mula sa System.Web.Mvc.Controller class.

Ang klase ng Controller ay nagbibigay ng suporta sa pagpoproseso ng kahilingan na pamilyar sa karamihan ng mga developer ng MVC application. Ginamit ito sa lahat ng mga halimbawang tinalakay sa mga nakaraang artikulo. Ang klase ng Controller ay nagbibigay ng tatlo ibig sabihin ng susi na inilarawan sa ibaba:

Mga paraan ng pagkilos

Ang pag-uugali ng controller ay kumakalat sa maraming pamamaraan (sa halip na ipatupad sa form ang tanging paraan Ipatupad()). Ang bawat paraan ng pagkilos ay nakamapa sa isang katumbas na URL at tinatawag na may mga parameter na nakuha mula sa papasok na kahilingan.

Mga resulta ng mga aksyon

Maaari kang magbalik ng isang bagay na naglalarawan sa resulta ng isang aksyon (tulad ng pag-render ng view o pag-redirect sa ibang URL o paraan ng pagkilos) at pagkatapos ay iproseso ito sa anumang paraan na gusto mo. Ang paghihiwalay sa pagitan ng pagtukoy ng mga resulta at pagpapatupad ng mga ito ay nagpapadali sa pagsubok ng unit.

Mga filter

Maaaring i-encapsulate bilang mga filter ang magagamit muli na gawi (gaya ng pagpapatotoo) at pagkatapos ay mamarkahan ng attribute sa source code ang bawat aspeto ng pag-uugali ng controller at mga pamamaraan ng pagkilos.

Maliban kung nakikitungo ka sa isang partikular na kinakailangan, ang pinakamahusay na diskarte sa paglikha ng mga controller ay upang makuha ang mga ito mula sa klase ng Controller, na kung ano ang ginagawa ng Visual Studio, tulad ng iyong inaasahan, kapag lumikha ito. bagong klase bilang tugon sa menu item Add --> Scaffold (Add --> Template).

Ang halimbawa sa ibaba ay nagpapakita ng code simpleng controller tinatawag na DerivedController, nilikha sa katulad na paraan. Ito ay nabuo gamit ang MVC 5 Controller - Empty na opsyon na may ilan simpleng pagbabago, na nilayon para sa pagtatakda ng ViewBag property at pagpili ng view:

Paggamit ng System; gamit ang System.Web; gamit ang System.Web.Mvc; namespace ControllersAndActions.Controllers ( public class DerivedController: Controller ( public ActionResult Index() ( ViewBag.Message = "Hello from the controller DerivedController action method Index"; return View("MyView"); ) ) ) )

Nagbibigay din ang klase ng Controller ng komunikasyon sa Razor view system. Sa halimbawang ito, ibinabalik namin ang resulta ng isang tawag sa View() na paraan, na ipinasa bilang parameter ang pangalan ng view na ire-render sa client. Upang lumikha ng view na ito, lumikha ng isang folder na Views/Derived, i-click ito i-right click mouse at piliin sa menu ng konteksto aytem Magdagdag --> MVC 5 View Page (Razor) (Add --> MVC 5 View Page (Razor)). Tukuyin ang pangalan MyView.cshtml at i-click ang OK upang gawin ang view na file.

Dalhin ang mga nilalaman ng file alinsunod sa halimbawa:

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

Pagkatapos patakbuhin ang application at mag-navigate sa view URL /Derived/Index, ang paraan ng pagkilos na ito ay tinatawag at ang MyView ay nai-render:

Ang pagmamana mula sa klase ng Controller ay nagreresulta sa pangangailangang magpatupad ng mga pamamaraan ng pagkilos, tumanggap ng anumang input na kailangan upang maproseso ang kahilingan, at makabuo ng naaangkop na tugon. Ang mga sumusunod na artikulo ay naglalarawan ng maraming paraan upang gawin ito.

Maraming mga tao ang nagsimulang magsulat ng isang proyekto upang gumana sa isang solong gawain, hindi nagpapahiwatig na maaari itong lumago sa isang multi-user na sistema ng pamamahala, halimbawa, nilalaman o, ipinagbabawal ng Diyos, ang produksyon. At ang lahat ay tila mahusay at cool, lahat ay gumagana, hanggang sa simulan mong maunawaan na ang code na nakasulat ay ganap na binubuo ng mga saklay at hardcode. Ang code ay halo-halong may layout, mga query at saklay, kung minsan kahit na hindi nababasa. Ang isang pagpindot na problema ay lumitaw: kapag nagdaragdag ng mga bagong tampok, kailangan mong mag-tinker sa code na ito nang napakatagal, naaalala ang "ano ang nakasulat doon?" at isumpa ang iyong sarili sa nakaraan.

Maaaring narinig mo na rin ang tungkol sa mga pattern ng disenyo at nabasa mo pa ang mga magagandang aklat na ito:

  • E. Gamma, R. Helm, R. Johnson, J. Vlissides "Mga diskarte sa layunin oriented na disenyo. Mga Pattern ng Disenyo";
  • M. Fowler "Arkitektura ng Enterprise Software Applications."
At marami, hindi natakot sa malalaking manwal at dokumentasyon, ay sinubukang pag-aralan ang alinman sa mga modernong balangkas at, nahaharap sa pagiging kumplikado ng pag-unawa (dahil sa pagkakaroon ng maraming mga konsepto ng arkitektura na matalinong magkakaugnay), ipagpaliban ang pag-aaral at paggamit ng mga modernong kasangkapan sa isang "silungan."

Ang artikulong ito ay magiging kapaki-pakinabang lalo na para sa mga nagsisimula. Anyway, umaasa ako na sa loob ng ilang oras ay makakakuha ka ng ideya Mga pagpapatupad ng MVC pattern na sumasailalim sa lahat ng modernong web frameworks, at nakakakuha din ng "pagkain" para sa karagdagang pagmuni-muni sa "kung paano ito gagawin." Sa dulo ng artikulo ay may isang seleksyon kapaki-pakinabang na mga link, na tutulong din sa iyo na maunawaan kung ano ang binubuo ng mga web frameworks (bukod sa MVC) at kung paano gumagana ang mga ito.

Ang mga batikang programmer ng PHP ay malamang na hindi makahanap ng bago para sa kanilang sarili sa artikulong ito, ngunit ang kanilang mga komento at komento sa pangunahing teksto ay magiging lubhang kapaki-pakinabang! kasi Kung walang teorya, imposible ang pagsasanay, at kung walang pagsasanay, ang teorya ay walang silbi, pagkatapos ay magkakaroon muna ng kaunting teorya, at pagkatapos ay magpatuloy tayo sa pagsasanay. Kung pamilyar ka na sa konsepto ng MVC, maaari mong laktawan ang seksyon ng teorya at dumiretso sa pagsasanay.

1. Teorya Ang pattern ng MVC ay naglalarawan ng isang simpleng paraan upang buuin ang isang application, ang layunin nito ay paghiwalayin ang logic ng negosyo mula sa user interface. Bilang resulta, ang application ay mas madaling sukatin, subukan, panatilihin at, siyempre, ipatupad.

Tingnan natin ang conceptual diagram ng MVC pattern (sa palagay ko, ito ang pinakamatagumpay na diagram na nakita ko):

Sa arkitektura MVC model nagbibigay ng data at mga panuntunan sa lohika ng negosyo, ang view ay responsable para sa user interface, at ang controller ay nagbibigay ng pakikipag-ugnayan sa pagitan ng modelo at ng view.

Ang isang karaniwang daloy ng isang MVC application ay maaaring ilarawan bilang mga sumusunod:

  • Kapag bumisita ang isang user sa isang web resource, ang script ng initialization ay gagawa ng isang instance ng application at ilulunsad ito para sa execution.
    Ito ay nagpapakita ng view, sabihin home page site.
  • Ang application ay tumatanggap ng kahilingan mula sa user at tinutukoy ang hiniling na controller at aksyon. Sa kaso ng pangunahing pahina, ang default na pagkilos ay isinasagawa ( index).
  • Ginagawa ng application ang controller at pinapatakbo ang paraan ng pagkilos,
    na, halimbawa, ay naglalaman ng mga modelong tawag na nagbabasa ng impormasyon mula sa database.
  • Pagkatapos nito, ang aksyon ay lumilikha ng view gamit ang data na nakuha mula sa modelo at ipinapakita ang resulta sa user.
  • Modelo - naglalaman ng lohika ng negosyo ng application at may kasamang mga pamamaraan para sa pag-sample (maaaring mga pamamaraan ng ORM ito), pagproseso (halimbawa, mga panuntunan sa pagpapatunay) at pagbibigay ng partikular na data, na kadalasang ginagawa itong napakakapal, na medyo normal.
    Hindi dapat direktang makipag-ugnayan ang modelo sa user. Ang lahat ng mga variable na nauugnay sa kahilingan ng gumagamit ay dapat iproseso sa controller.
    Ang modelo ay hindi dapat bumuo ng HTML o iba pang display code na maaaring magbago depende sa mga pangangailangan ng user. Ang nasabing code ay dapat iproseso sa mga view.
    Ang parehong modelo, halimbawa: ang modelo ng pagpapatunay ng user ay maaaring gamitin sa parehong user at administratibong bahagi ng application. Sa kasong ito, maaari itong kunin pangkalahatang code sa isang hiwalay na klase at magmana mula dito, na tumutukoy sa mga pamamaraang partikular sa mga subapplication sa mga inapo nito.

    View - ginagamit upang tukuyin ang panlabas na pagpapakita ng data na natanggap mula sa controller at modelo.
    Ang mga view ay naglalaman ng HTML markup at maliliit na pagsingit ng PHP code upang i-traverse, i-format, at ipakita ang data.
    Hindi dapat direktang ma-access ang database. Ito ang dapat gawin ng mga modelo.
    Hindi dapat gumana sa data na nakuha mula sa isang kahilingan ng user. Ang gawaing ito ay dapat gawin ng controller.
    Maaaring direktang ma-access ang mga katangian at pamamaraan ng isang controller o mga modelo upang makakuha ng data na handa sa output.
    Ang mga view ay karaniwang nahahati sa isang pangkalahatang template, na naglalaman ng markup na karaniwan sa lahat ng mga pahina (halimbawa, isang header at footer) at mga bahagi ng template na ginagamit upang ipakita ang output ng data mula sa modelo o ipakita ang mga form ng pagpasok ng data.

    Ang controller ay ang pandikit na nag-uugnay sa mga modelo, view at iba pang bahagi gumaganang aplikasyon. Ang controller ay responsable para sa pagproseso ng mga kahilingan ng user. Ang controller ay hindi dapat maglaman ng mga query sa SQL. Mas mainam na panatilihin ang mga ito sa mga modelo. Ang controller ay hindi dapat maglaman ng HTML o iba pang markup. Ito ay nagkakahalaga na dalhin ito sa view.
    Sa isang mahusay na idinisenyong MVC application, ang mga controller ay kadalasang napakanipis at naglalaman lamang ng ilang dosenang linya ng code. Ang parehong ay hindi masasabi tungkol sa Stupid Fat Controllers (SFC) sa CMS Joomla. Ang lohika ng controller ay medyo tipikal at karamihan sa mga ito ay isinasagawa sa mga batayang klase.
    Ang mga modelo, sa kabaligtaran, ay napakakapal at naglalaman ng karamihan sa mga code na nauugnay sa pagproseso ng data, dahil ang istraktura ng data at lohika ng negosyo na nakapaloob dito ay karaniwang medyo tiyak sa isang partikular na aplikasyon.

    1.1. Front Controller at Page Controller Sa karamihan ng mga kaso, ang pakikipag-ugnayan ng user sa isang web application ay nangyayari sa pamamagitan ng pag-click sa mga link. Tingnan ngayon ang address bar ng iyong browser - natanggap mo ang tekstong ito mula sa link na ito. Ang iba pang mga link, tulad ng mga nasa kanang bahagi ng pahinang ito, ay magbibigay sa iyo ng ibang nilalaman. Kaya, ang link ay kumakatawan sa isang partikular na command sa web application.

    Sana ay napansin mo na ang iba't ibang mga site ay maaaring magkaroon ng perpekto iba't ibang mga format pagtatayo address bar. Maaaring ipakita ng bawat format ang arkitektura ng isang web application. Kahit na ito ay hindi palaging ang kaso, sa karamihan ng mga kaso ito ay isang malinaw na katotohanan.

    Isaalang-alang natin ang dalawang opsyon para sa address bar, na nagpapakita ng ilang text at profile ng user.

    Tinatayang processing code sa kasong ito:
    switch($_GET["action"]) ( case "about" : require_once("about.php"); // "Tungkol sa Amin" page break; case "contacts" : require_once("contacts.php"); // "Contacts" page break;
    Sa tingin ko halos lahat ay nagawa na ito dati.

    Gamit ang isang URL routing engine, maaari mong i-configure ang iyong application upang tanggapin ang mga kahilingang tulad nito upang ipakita ang parehong impormasyon:
    http://www.example.com/contacts/feedback

    Dito kinakatawan ng mga contact ang controller at ang feedback ay ang paraan ng controller ng mga contact na nagpapakita ng form puna atbp. Babalik tayo sa isyung ito sa praktikal na bahagi.

    Ito rin ay nagkakahalaga ng pag-alam na maraming mga web frameworks 'router ay nagbibigay-daan sa iyo upang lumikha ng arbitrary Mga ruta ng URL(ipahiwatig kung ano ang ibig sabihin ng bawat bahagi ng URL) at ang mga panuntunan para sa pagproseso ng mga ito.
    Ngayon ay mayroon na tayong sapat na teoretikal na kaalaman upang magpatuloy sa pagsasanay.

    2. Magsanay Una, gumawa tayo sumusunod na istraktura mga file at folder:


    Sa hinaharap, sasabihin ko na ang mga pangunahing klase ng Model, View at Controller ay maiimbak sa pangunahing folder.
    Ang kanilang mga anak ay maiimbak sa mga direktoryo ng controller, modelo at view. Ang index.php file ay ang entry point sa application. Sinisimulan ng bootstrap.php file ang paglo-load ng application, pagkonekta sa lahat ng kinakailangang module, atbp.

    Kami ay pupunta nang sunud-sunod; Buksan natin ang index.php file at punan ito ng sumusunod na code:
    ini_set("display_errors", 1); require_once "application/bootstrap.php";
    Hindi dapat magkaroon ng anumang mga katanungan dito.

    Susunod, pumunta agad tayo sa bootstrap.php file:
    require_once "core/model.php"; require_once "core/view.php"; require_once "core/controller.php"; require_once "core/route.php"; Ruta::start(); //simulan ang router
    Ang unang tatlong linya ay magsasama ng kasalukuyang hindi umiiral na mga file ng kernel. Mga huling linya ikonekta ang file sa klase ng router at ilunsad ito para sa pagpapatupad sa pamamagitan ng pagtawag static na pamamaraan simulan.

    2.1. Pagpapatupad ng URL Router Sa ngayon, lumihis tayo sa pagpapatupad ng pattern ng MVC at tumuon sa pagruruta. Ang unang hakbang na kailangan nating gawin ay isulat ang sumusunod na code sa .htaccess:
    RewriteEngine Sa RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule .* index.php [L]
    Ire-redirect ng code na ito ang lahat ng pagpoproseso ng pahina sa index.php, na siyang kailangan namin. Tandaan sa unang bahagi na pinag-usapan natin ang Front Controller?!

    Ilalagay namin ang pagruruta sa isang hiwalay na file route.php sa pangunahing direktoryo. Sa file na ito, ilalarawan namin ang klase ng Ruta, na magpapatakbo ng mga pamamaraan ng controller, na bubuo naman ng page view.

    Mga nilalaman ng route.php file

    Ruta ng klase ( static function start() ( // controller at default na aksyon $controller_name = "Main"; $action_name = "index"; $routes = explode("/", $_SERVER["REQUEST_URI"]); // get ang pangalan ng controller kung (!empty($routes)) ( $controller_name = $routes; ) // makuha ang action name kung (!empty($routes)) ( $action_name = $routes; ) // magdagdag ng mga prefix $model_name = " Model_".$controller_name; $controller_name = "Controller_".$controller_name; $action_name = "action_".$action_name; ($model_name). ".php"; $model_path = "application/models/".$model_file; if(file_exists($model_path)) ( isama ang "application/models/".$model_file; ) // i-hook up ang file kasama ang controller class na $controller_file = strtolower ($controller_name).php"; $controller_path = "application/controllers/".$controller_file; if(file_exists($controller_path)) ( isama ang "application/controllers/".$controller_file;


    ) else ( /* tama na maglagay ng exception dito, ngunit para gawing simple ang mga bagay, magre-redirect kami kaagad sa 404 page */ Route::ErrorPage404(); ) // lumikha ng controller $controller = new $controller_name ;

    $action = $action_name; if(method_exists($controller, $action)) ( // tawagan ang controller action $controller->$action(); ) else ( // dito rin ay mas matalinong magtapon ng exception Route::ErrorPage404(); ) ) function na ErrorPage404( ) ($host = "http://".$_SERVER["HTTP_HOST"]."/"; header("HTTP/1.1 404 Not Found"); header("Status: 404 Not Found") ; header(" Lokasyon:".$host."404" ) ) Pansinin ko na ang klase ay nagpapatupad ng napakasimpleng lohika (sa kabila ng napakalaking code) at maaaring magkaroon ng mga problema sa seguridad. Sinadya ito, dahil... Ang pagsulat ng isang ganap na klase sa pagruruta ay nararapat kahit isang hiwalay na artikulo. Tingnan natin ang mga pangunahing punto...
    Naglalaman ang global array element na $_SERVER["REQUEST_URI"].

    buong address kung saan nakipag-ugnayan ang user. Halimbawa: example.ru/contacts/feedback Gamit ang function sumabog Ang address ay nahahati sa mga bahagi. Bilang isang resulta, nakuha namin ang pangalan ng controller, para sa halimbawang ibinigay, ito ay controller.

    mga contact

    Kaya, kapag pupunta sa, halimbawa, ang address:
    example.com/portfolio
    o
    example.com/portfolio/index
    Gagawin ng router ang mga sumusunod na aksyon:

  • isasama ang model_portfolio.php file mula sa folder ng mga modelo, na naglalaman ng klase ng Model_Portfolio;
  • isasama ang controller_portfolio.php file mula sa folder ng controllers, na naglalaman ng klase ng Controller_Portfolio;
  • ay lilikha ng isang halimbawa ng klase ng Controller_Portfolio at tatawagin ang default na aksyon - action_index, na inilarawan dito.
  • Kung sinubukan ng user na i-access ang address ng isang hindi umiiral na controller, halimbawa:
    example.com/ufo
    pagkatapos ay ire-redirect siya sa pahinang "404":
    example.com/404
    Ang parehong bagay ay mangyayari kung ang gumagamit ay nag-access ng isang aksyon na hindi inilarawan sa controller.2.2. Bumalik tayo sa pagpapatupad ng MVC Pumunta tayo sa core folder at magdagdag ng tatlo pang file sa route.php file: model.php, view.php at controller.php


    Hayaan mong ipaalala ko sa iyo na maglalaman sila ng mga batayang klase, na sisimulan na nating isulat.

    Mga nilalaman ng model.php file
    Modelo ng klase ( public function get_data() ( ) )
    Ang klase ng modelo ay naglalaman ng isang walang laman na paraan ng pagkuha ng data, na ma-o-override sa mga descendant na klase. Kapag gumawa tayo ng mga descendant class ay magiging mas malinaw ang lahat.

    Mga nilalaman ng view.php file
    class View ( //public $template_view; // dito maaari mong tukuyin ang default na pangkalahatang view. function generate($content_view, $template_view, $data = null) ( /* if(is_array($data)) ( // convert array elemento sa mga variable extract($data); ) */ isama ang "application/views/".$template_view;
    Ito ay hindi mahirap hulaan na ang paraan bumuo nilayon upang bumuo ng isang view. Ang mga sumusunod na parameter ay ipinapasa dito:

  • $content_file - mga view na nagpapakita ng nilalaman ng pahina;
  • $template_file - template na karaniwan sa lahat ng pahina;
  • Ang $data ay isang array na naglalaman ng mga elemento ng nilalaman ng pahina. Karaniwang pinupunan sa modelo.
  • Ang include function ay dynamic na nag-uugnay sa isang pangkalahatang template (view) kung saan ang view ay i-embed
    upang ipakita ang nilalaman ng isang partikular na pahina.

    Sa aming kaso, ang pangkalahatang template ay maglalaman ng header, menu, sidebar at footer, at ang nilalaman ng pahina ay lalagyan sa isang hiwalay na form. Muli, ito ay ginagawa para sa pagiging simple.

    Mga nilalaman ng controller.php file
    Class Controller ( public $model; public $view; function __construct() ($this->view = new View(); ) function action_index() ( ) )
    Pamamaraan action_index- ito ay isang aksyon na tinatawag bilang default;

    2.3. Pagpapatupad ng mga descendant classes na Model at Controller, paglikha ng View "s Ngayon ay magsisimula na ang saya! Ang aming website ng business card ay binubuo ng mga sumusunod na pahina:
  • Bahay
  • Mga serbisyo
  • Portfolio
  • Mga contact
  • At gayundin - ang pahina ng "404".
  • Ang bawat pahina ay may sariling controller mula sa controllers folder at isang view mula sa view folder. Ang ilang mga pahina ay maaaring gumamit ng isang modelo o mga modelo mula sa folder ng mga modelo.


    Sa nakaraang figure, ang file na template_view.php ay naka-highlight nang hiwalay - ito ay isang template na naglalaman ng markup na karaniwan sa lahat ng mga pahina. Sa pinakasimpleng kaso, maaaring ganito ang hitsura:
    Bahay
    Upang bigyan ang site ng isang presentable na hitsura, gumawa kami ng CSS template at isinasama ito sa aming site sa pamamagitan ng pagbabago sa istruktura ng HTML markup at Mga koneksyon sa CSS at mga JavaScript file:

    Sa dulo ng artikulo, sa seksyong "Resulta", mayroong isang link sa isang GitHub repository na may isang proyekto kung saan ang mga hakbang ay ginawa upang maisama ang isang simpleng template.

    2.3.1. Paglikha ng pangunahing pahina Magsimula tayo sa controller controller_main.php , narito ang code nito:
    class Controller_Main extends Controller ( function action_index() ($this->view->generate("main_view.php", "template_view.php"); ) )
    Sa pamamaraan bumuo halimbawa ng klase ng View, ang mga pangalan ng mga file ng pangkalahatang template at ang view na may nilalaman ng pahina ay ipinasa.
    Bilang karagdagan sa index action, ang controller ay maaaring maglaman ng iba pang mga aksyon.

    Mag-file gamit ang pangkalahatang pananaw napatingin kami kanina. Isaalang-alang ang file ng nilalaman main_view.php:
    Maligayang pagdating!

    Ang OLOLOSHA TEAM ay isang pangkat ng mga first-class na espesyalista sa larangan ng pag-develop ng website na may maraming taon ng karanasan sa pagkolekta ng mga Mexican mask, bronze at stone statues mula sa India at Ceylon, bas-relief at sculpture na nilikha ng mga masters ng Equatorial Africa lima o anim na siglo. kanina...


    Naglalaman ito ng simpleng markup nang walang anumang mga tawag sa PHP.
    Upang ipakita ang pangunahing pahina, maaari mong gamitin ang isa sa mga sumusunod na address:

    Isasaalang-alang namin ang isang halimbawa gamit ang isang view na nagpapakita ng data na nakuha mula sa modelo sa ibaba.

    2.3.2. Gumawa ng page na “Portfolio” Sa aming kaso, ang page na “Portfolio” ay ang tanging page na gumagamit ng modelo.
    Karaniwang kasama sa modelo ang mga pamamaraan ng sampling ng data, halimbawa:
  • mga pamamaraan ng katutubong pgsql o mysql na mga aklatan;
  • mga paraan ng mga aklatan na nagpapatupad ng data abstraction. Halimbawa, ang mga pamamaraan ng PEAR MDB2 library;
  • Mga pamamaraan ng ORM;
  • mga pamamaraan para sa pagtatrabaho sa NoSQL;
  • atbp.
  • Para sa pagiging simple, hindi kami gagamit ng mga SQL query o ORM statement dito. Sa halip, tutularan namin ang totoong data at agad na magbabalik ng hanay ng mga resulta.
    Ilagay ang model file model_portfolio.php sa folder ng mga modelo. Narito ang mga nilalaman nito:
    class Model_Portfolio extends Model ( public function get_data() ( return array(array("Year" => "2012", "Site" => "http://DunkelBeer.ru", "Description" => "Promosyonal na site ng dark Dunkel beer mula sa German manufacturer na Löwenbraü na ginawa sa Russia ng brewing company na "SUN InBev."), array("Year" => "2012", "Site" => "http://ZopoMobile.ru", "Description " => "Katalog ng wikang Ruso Mga teleponong Intsik Naka-on ang kumpanya ng Zopo Batay sa Android OS at accessories para sa kanila."), // todo); ) )

    Ang klase ng controller ng modelo ay nakapaloob sa controller_portfolio.php file, narito ang code nito:
    class Controller_Portfolio extends 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 ) )
    Sa isang variable datos ang array na ibinalik ng pamamaraan ay nakasulat get_data na tiningnan namin kanina.
    Ang variable na ito ay ipinapasa bilang isang parameter ng pamamaraan bumuo, na naglalaman din ng: ang pangalan ng file na may pangkalahatang template at ang pangalan ng file na naglalaman ng view na may nilalaman ng pahina.

    Ang view na naglalaman ng nilalaman ng pahina ay nasa portfolio_view.php file.
    Portfolio

    Ang lahat ng mga proyekto sa sumusunod na talahanayan ay kathang-isip, kaya't huwag subukang sundin ang mga link na ibinigay.
    taonProyektoPaglalarawan


    Ang lahat ay simple dito, ipinapakita ng view ang data na nakuha mula sa modelo.

    2.3.3. Paglikha ng natitirang mga pahina Ang natitirang mga pahina ay nilikha sa parehong paraan. Available ang kanilang code sa repositoryo ng GitHub, isang link kung saan ibinibigay sa dulo ng artikulo, sa seksyong "Resulta".3. Resulta Narito ang nangyari sa huli:

    Screenshot ng nagresultang website ng business card



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

    Ngunit sa bersyong ito ay inilarawan ko ang mga sumusunod na klase (at ang kanilang mga kaukulang uri):

    • Controller_Login kung saan ang isang view ay nabuo gamit ang isang form para sa pagpasok ng login at password, pagkatapos punan kung saan ang pamamaraan ng pagpapatunay ay ginanap at, kung matagumpay, ang user ay na-redirect sa admin panel.
    • Contorller_Admin na may index action na nagsusuri kung ang user ay dating pinahintulutan sa site bilang isang administrator (kung gayon, ang view ng admin panel ay ipinapakita) at isang logout action para sa pag-log out.
    Ang pagpapatunay at awtorisasyon ay ibang paksa, kaya hindi ito tinalakay dito, ngunit ang link na ibinigay sa itaas lamang ang ibinigay upang mayroon kang simulan.4. Konklusyon Ang pattern ng MVC ay ginagamit bilang batayan ng arkitektura sa maraming mga balangkas at mga CMS na nilikha upang makagawa ng mas mataas na kalidad kumplikadong solusyon para sa higit pa panandalian. Ito ay naging posible sa pamamagitan ng pagtaas ng antas ng abstraction, dahil may limitasyon ang pagiging kumplikado ng mga istruktura na maaaring gamitin ng utak ng tao.

    Ngunit, ang paggamit ng mga web framework gaya ng Yii o Kohana, na binubuo ng ilang daang mga file, kapag ang pagbuo ng mga simpleng web application (halimbawa, mga business card site) ay hindi palaging ipinapayong. Ngayon ay maaari na tayong lumikha ng isang magandang modelo ng MVC upang hindi paghaluin ang Php, Html, CSS at JavaScript code sa isang file.

    Ang artikulong ito ay higit na panimulang punto para sa pag-aaral ng CMF kaysa sa isang halimbawa ng isang bagay na tunay na tama na magagamit mo bilang batayan para sa iyong web application. Marahil ay naging inspirasyon ka pa nito at iniisip mo na ang pagsulat ng iyong sariling microframework o CMS batay sa MVC. Ngunit, bago muling likhain ang susunod na gulong na may "blackjack at whores," isipin muli: marahil ito ay magiging mas makatwirang idirekta ang iyong mga pagsisikap sa pag-unlad at pagtulong sa komunidad ng isang umiiral nang proyekto?!

    P.S.: Ang artikulo ay muling isinulat na isinasaalang-alang ang ilang mga komento na naiwan sa mga komento. Ang pagpuna ay naging lubhang kapaki-pakinabang. Sa paghusga sa tugon: mga komento, PM at ang bilang ng mga gumagamit na nagdagdag ng post sa mga paborito, ang ideya ng pagsulat ng post na ito ay naging hindi masama. Sa kasamaang palad, hindi posible na isaalang-alang ang lahat ng mga kagustuhan at magsulat nang higit pa at nang mas detalyado dahil sa kakulangan ng oras ... ngunit marahil ang mga mahiwagang indibidwal na nag-downvote sa orihinal na bersyon ay gagawa nito. Good luck sa iyong mga proyekto!

    5. Isang seleksyon ng mga kapaki-pakinabang na link sa paksa Ang artikulo ay madalas na tumatalakay sa paksa ng web frameworks - ito ay isang napakalawak na paksa, dahil kahit ang microframeworks ay binubuo ng maraming mga bahagi na matalinong magkakaugnay at nangangailangan ng higit sa isang artikulo upang pag-usapan ang mga ito mga bahagi. Gayunpaman, nagpasya akong ipakita dito ang isang maliit na seleksyon ng mga link (na sinundan ko habang isinusulat ang artikulong ito) na sa isang paraan o iba ay nauugnay sa paksa ng mga balangkas.

    Mga Tag: Magdagdag ng mga tag

    Ang pattern ng Model-View-Controller (MVC), na natuklasan noong huling bahagi ng 1970s, ay isang pattern ng disenyo ng arkitektura software, ang pangunahing gawain kung saan ay upang paghiwalayin ang mga function ng pagtatrabaho sa data mula sa kanilang presentasyon. Sa teoryang, ang isang mahusay na idinisenyong MVC na application ay magbibigay-daan sa mga front-end at back-end na mga developer na hindi makagambala sa mga lugar ng responsibilidad ng isa't isa sa panahon ng kanilang trabaho, iyon ay, ang front-end na developer ay hindi kailangang malaman ang anumang bagay tungkol sa "kusina" ng kanyang back-end na kasamahan at vice versa.

    Bagama't orihinal na idinisenyo ang MVC para sa pagbuo ng desktop application, inangkop ito para sa modernong mga gawain at napakapopular sa mga web developer, dahil dahil sa paghahati ng mga responsibilidad naging posible na lumikha ng isang mas malinaw, handa nang gamitin muling gamitin code. Ang pattern ng MVC ay nagreresulta sa malinis, modular na mga system na nagbibigay-daan sa mga developer na gumawa ng mga pagbabago sa umiiral nang code nang napakabilis.

    Sa artikulong ito ay titingnan natin pangunahing mga prinsipyo MVC, simula sa pagtukoy ng isang pattern at patuloy na ilapat ito sa isang maliit na halimbawa. Ang artikulong ito ay pangunahing magiging kapaki-pakinabang sa mga hindi pa nakatagpo ng pattern na ito sa buhay, at gayundin, marahil, sa mga nais magsipilyo sa kanilang kaalaman sa MVC.

    Pag-unawa sa MVC

    Tulad ng nabanggit na, ang pangalan ng pattern ay nagmula sa pagdadaglat ng tatlong salita: Modelo (modelo), View (view) at Controller (controller). Sa madaling sabi, ang prinsipyo ng pagpapatakbo ng pattern ay maaaring ilarawan sa isang diagram (matatagpuan sa Wikipedia):

    Malinaw na ipinapakita ng diagram na ito ang unidirectional na daloy ng impormasyon sa pattern at inilalarawan din ang mga tungkulin ng bawat bahagi.

    Modelo

    Ang modelo ay ginagamit upang i-access at manipulahin ang data. Sa karamihan ng mga kaso, ang modelo ay kung ano ang ginagamit upang ma-access ang data store (tulad ng isang database). Ang modelo ay nagbibigay ng isang interface para sa paghahanap ng data, paglikha nito, pagbabago nito, at pagtanggal nito mula sa imbakan. Sa konteksto ng pattern ng MVC, ang modelo ay ang tagapamagitan sa pagitan ng view at ng controller.

    Ang isang napakahalagang tampok ng isang modelo ay ang teknikal na walang kaalaman sa kung ano ang nangyayari sa data sa controller at view. Ang modelo ay hindi dapat gumawa o maghintay para sa anumang mga kahilingan sa/mula sa iba pang mga bahagi ng pattern.

    Gayunpaman, laging tandaan na ang modelo ay hindi lamang isang gateway sa isang database o iba pang sistema na walang ginagawa kundi maglipat ng data pabalik-balik. Ang isang modelo ay parang gateway sa data. Ang modelo ay sa karamihan ng mga kaso ang pinaka-kumplikadong bahagi ng system, bahagyang dahil sa ang katunayan na ang modelo mismo ay ang link sa pagkonekta para sa lahat ng iba pang mga bahagi.

    Pagganap

    Ang view ay kung saan ang data na natanggap mula sa modelo ay output sa sa tamang anyo. Sa tradisyonal na mga web application na binuo gamit ang MVC pattern, ang view ay bahagi ng system kung saan nabuo ang HTML code. Responsable din ang view para sa pagtanggap ng mga aksyon mula sa user upang maipadala ang mga ito sa controller. Halimbawa, ang isang view ay nagpapakita ng isang pindutan sa user interface, at pagkatapos ng pagpindot dito ay nagiging sanhi ng kaukulang aksyon ng controller.

    Mayroong ilang mga maling kuru-kuro tungkol sa layunin ng isang view, lalo na sa mga web developer na nagsisimula pa lang bumuo ng kanilang mga application gamit ang MVC. Ang isa sa mga pinakakaraniwang sirang panuntunan ay ang view ay hindi dapat makipag-ugnayan sa modelo sa anumang paraan, at ang lahat ng data na natanggap ng view ay dapat manggaling lamang sa controller. Sa pagsasagawa, madalas na binabalewala ng mga developer ang konseptong ito, na nasa core ng pattern ng MVC. Ang artikulo ni Fabio Cevasco ay naglalarawan ng nakakalito na diskarte na ito sa MVC gamit ang CakePHP, isa sa maraming hindi karaniwang mga framework ng MVC:

    Napakahalagang maunawaan na upang makakuha ng wastong arkitektura ng MVC, hindi dapat magkaroon ng anumang direktang pakikipag-ugnayan sa pagitan ng mga view at modelo. Ang lahat ng lohika para sa pagpapalitan ng data sa pagitan ng mga ito ay dapat na ipatupad sa mga controllers.

    Bilang karagdagan, mayroong isang karaniwang maling kuru-kuro na ang isang view ay isang template file lamang. Tulad ng nabanggit ni Tom Butler, ang maling kuru-kuro na ito ay napakalaki dahil sa katotohanan na maraming mga developer ang hindi nauunawaan ang istraktura ng MVC mula pa sa simula, pagkatapos nito ay sinimulan nilang ibuhos ang "kaalaman" na ito nang higit pa sa masa ng mga baguhan na developer. Sa totoo lang, ang isang view ay higit pa sa isang template, ngunit maraming mga framework na binuo sa ibabaw ng MVC pattern ang nagdistort sa konsepto ng isang view kaya walang nagmamalasakit kung ang kanilang mga application ay tama sa mga tuntunin ng MVC pattern.

    Ang isa pang mahalagang punto ay ang view ay hindi kailanman gumagana sa "dalisay" na data mula sa controller, iyon ay, ang controller ay hindi kailanman gumagana sa view nang hindi nilalampasan ang modelo. Sa panahon ng pakikipag-ugnayan sa pagitan ng controller at ng view, ang modelo ay dapat palaging nasa pagitan nila.

    Controller

    Ang controller ay ang huling bahagi ng MVC bundle. Ang trabaho ng controller ay tumanggap ng data mula sa user at manipulahin ang modelo. Ito ang controller, at ito lamang, ang bahagi ng system na nakikipag-ugnayan sa user.

    Sa madaling sabi, ang isang controller ay maaaring ilarawan bilang isang kolektor ng impormasyon na ipinapasa ito sa modelo para sa pagproseso at pag-iimbak. Hindi ito dapat gumawa ng anuman sa data, ngunit matanggap lamang ito mula sa gumagamit. Ang controller ay nauugnay sa isang view at isang modelo, kaya nag-aayos ng isang unidirectional na daloy ng data, na kinokontrol ito sa bawat yugto.

    Napakahalagang tandaan na ang controller ay nagsisimula lamang sa trabaho nito bilang resulta ng pakikipag-ugnayan ng user sa view, na tumatawag sa kaukulang function ng controller. Ang pinakakaraniwang pagkakamali sa mga developer ay ang tingnan ang controller bilang simpleng gateway sa pagitan ng view at ng modelo. Bilang isang resulta, ang controller ay pinagkalooban ng mga function na dapat gawin ng view (nga pala, dito nagmula ang ideya na ang isang view ay isang template file lamang). Higit pa rito, maraming tao ang ganap na nagtatapon ng lahat ng lohika sa pagproseso ng data, na nalilimutan ang tungkol sa kung ano ang inilaan ng modelo sa pattern ng MVC.

    MVC sa PHP

    Iminumungkahi kong subukang ipatupad ang nasa itaas sa isang maliit na aplikasyon. Magsimula tayo sa paglikha ng mga klase ng modelo, view at controller: