Corak untuk pemula: MVC lwn MVP lwn MVVM. Peraturan am untuk memilih corak. Pilihan pautan berguna mengenai subjek

Pengawal

Setiap permintaan yang masuk ke dalam aplikasi diproses oleh pengawal. Pengawal boleh mengendalikan permintaan sewenang-wenangnya selagi ia tidak melepasi sempadan tanggungjawab pandangan model. Ini bermakna pengawal tidak seharusnya mengandungi atau menyimpan data, dan juga tidak boleh menjana antara muka pengguna.

Dalam Rangka Kerja ASP.NET MVC, pengawal ialah kelas .NET yang mengandungi logik yang diperlukan untuk memproses permintaan. Peranan pengawal adalah untuk merangkum logik aplikasi. Dalam erti kata lain, pengawal bertanggungjawab untuk memproses permintaan masuk dan melaksanakan operasi pada model bidang subjek dan memilih paparan untuk divisualisasikan kepada pengguna.

Contoh permohonan

Untuk tujuan ini dan artikel seterusnya kami akan buat projek baru MVC menamakan ControllersAndActions menggunakan templat Kosong, menyemak kotak pilihan MVC di bawah Tambah folder dan rujukan teras untuk, dan projek ujian unit yang dipanggil ControllersAndActions.Tests. Ujian unit yang anda akan buat tidak memerlukan pelaksanaan olok-olok, jadi anda tidak perlu memasang pakej Moq, tetapi anda perlu memasang pakej MVC supaya ujian boleh mengakses kelas pengawal asas.

Dalam tetingkap konsol Pengurus Pakej Visual Studio NuGet, masukkan arahan berikut:

Pakej Pasang Microsoft.Aspnet.Mvc -versi 5.0.0 -nama projek ControllersAndActions.Tests

Selepas mencipta projek, pilih Properties ControllersAndActions daripada menu Projek dalam Visual Studio, dalam kotak dialog yang terbuka, pergi ke tab Web dan semak butang radio Halaman Tertentu ( Halaman tertentu) dalam kategori Tindakan Mula. Tidak perlu memasukkan sebarang nilai - hanya pilih butang radio.

Konsep pengawal

Anda telah melihat kes penggunaan untuk pengawal dalam hampir semua artikel ASP.NET MVC sebelumnya. Sudah tiba masanya untuk melihat di sebalik tabir.

Mencipta pengawal menggunakan antara muka IController

Dalam Rangka Kerja MVC, kelas pengawal mesti melaksanakan antara muka IController daripada ruang nama System.Web.Mvc ditunjukkan dalam contoh di bawah:

Menggunakan System.Web.Routing; ruang nama System.Web.Mvc ( antara muka awam IController ( void Execute(RequestContext requestContext); ) )

Untuk mendapatkan definisi antara muka ini, anda perlu memuat turun kod sumber Rangka Kerja MVC, yang sangat berguna untuk mengetahui cara kerja dalaman alat rangka kerja.

Seperti yang anda lihat, antara muka IController adalah sangat mudah. hanya miliknya Jalankan () kaedah Dipanggil apabila permintaan dihantar ke kelas pengawal ini. Rangka Kerja MVC menentukan kelas mana yang disasarkan oleh permintaan dengan membaca nilai sifat pengawal yang dijana oleh data penghalaan atau melalui kelas penghalaan khas.

Anda boleh mencipta kelas pengawal dengan melaksanakan antara muka IController, tetapi memandangkan antara muka ini adalah tahap rendah, anda perlu melakukan banyak kerja untuk mendapatkan sesuatu yang berguna. Walau bagaimanapun, antara muka IController berguna untuk menunjukkan pengendalian pengawal dan untuk tujuan ini fail kelas baharu yang dipanggil BasicController.cs dicipta dalam folder Pengawal, yang kandungannya ditunjukkan dalam contoh di bawah:

Menggunakan System.Web.Mvc; menggunakan 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("Pengawal: (0), Kaedah Tindakan: (1)", pengawal, tindakan)); ) ) )

Kaedah Execute() antara muka IController diluluskan objek RequestContext, yang memberikan maklumat tentang permintaan semasa dan laluan yang sepadan dengannya (dan menyebabkan pengawal yang diberikan dipanggil untuk memproses permintaan itu). Kelas RequestContext mentakrifkan dua sifat, diterangkan dalam jadual di bawah:

Objek HttpContextBase menyediakan akses kepada satu set objek yang menerangkan permintaan semasa, dipanggil objek konteks; kami akan kembali kepada mereka nanti. Objek RouteData menerangkan laluan. Sifat penting kelas RouteData disenaraikan dalam jadual di bawah:

Artikel Mengkonfigurasi Sistem Penghalaan menunjukkan cara menggunakan jenis RouteBase dan IRouteHandler untuk mengkonfigurasi sistem penghalaan. Dalam contoh yang sedang dipertimbangkan, menggunakan sifat Nilai, nilai pengawal dan pembolehubah segmen tindakan diperoleh, yang kemudiannya ditulis pada tindak balas.

Sebahagian daripada masalah dengan mencipta pengawal tersuai ialah kekurangan akses kepada ciri seperti paparan. Ini bermakna anda perlu bekerja pada tahap yang lebih rendah, yang menerangkan penulisan kandungan secara langsung sebagai tindak balas kepada pelanggan. Harta benda HttpContextBase.Response mengembalikan objek HttpResponseBase yang membolehkan anda mengkonfigurasi dan menambah kandungan pada respons untuk dihantar kepada klien. Ini adalah satu lagi titik hubungan antara platform ASP.NET dan Rangka Kerja MVC.

Jika anda menjalankan aplikasi dan pergi ke URL seperti /Basic/Index, pengawal khas akan menjana output yang ditunjukkan dalam rajah di bawah:

Melaksanakan antara muka IController membolehkan anda mencipta kelas yang Rangka Kerja MVC mengiktiraf sebagai pengawal dan menghantar permintaan kepadanya, tanpa sebarang sekatan tentang cara permintaan diproses atau tindak balas yang dihasilkan untuknya. ini contoh yang baik kerana ia menunjukkan betapa meluasnya Rangka Kerja MVC walaupun untuk blok binaan utama seperti pengawal, tetapi menulis aplikasi yang kompleks dengan cara ini boleh penuh dengan kesukaran yang besar.

Kelas dengan nama yang berakhir dengan Base

Rangka Kerja MVC bergantung pada rangka kerja ASP.NET untuk memproses permintaan, yang sangat masuk akal kerana... platform ini adalah pelaksanaan yang terbukti dan kaya dengan ciri yang berintegrasi rapat dengan pelayan aplikasi IIS. Masalahnya ialah kelas yang ASP.NET gunakan untuk menyediakan maklumat permintaan tidak sesuai untuk ujian unit, faedah utama menggunakan Rangka Kerja MVC.

Microsoft memutuskan untuk memperkenalkan keupayaan ujian sambil mengekalkan keserasian dengan aplikasi sedia ada Borang Web ASP.NET, jadi hasilnya adalah Kelas asas. Kelas ini dipanggil sedemikian kerana mereka mempunyai nama yang sama dengan kelas teras rangka kerja ASP.NET, diikuti dengan perkataan Base.

Sebagai contoh, rangka kerja ASP.NET menyediakan maklumat kontekstual tentang permintaan semasa dan beberapa perkhidmatan aplikasi utama melalui objek HttpContext. Kelas Asasnya yang sepadan ialah HttpContextBase, contoh yang dihantar kepada kaedah Execute() yang ditakrifkan dalam antara muka IController (kelas Base lain akan ditunjukkan dalam contoh seterusnya). Kelas asal dan Asas mentakrifkan sifat dan kaedah yang sama, tetapi kelas Asas sentiasa abstrak, yang bermaksud ia mudah digunakan untuk ujian unit.

Kadangkala anda akan mendapat contoh salah satu kelas ASP.NET asal, seperti HttpContext. Dalam kes ini, anda perlu mencipta kelas Pangkalan mesra MVC yang serupa dengan HttpContextBase. Ini dilakukan menggunakan salah satu daripada Kelas pembalut, yang mempunyai nama yang sama seperti kelas asal, ditambah dengan perkataan Wrapper, contohnya HttpContextWrapper. Kelas pembungkus berasal daripada kelas Asas dan mempunyai pembina yang menerima contoh kelas asal:

Kelas asal, kelas asas dan kelas Wrapper ditakrifkan dalam ruang nama System.Web, jadi rangka kerja ASP.NET boleh menyokong Rangka Kerja MVC dan aplikasi lama dengan lancar aplikasi web Borang.

Mencipta pengawal dengan mewarisi daripada kelas Pengawal

Seperti yang ditunjukkan dalam contoh sebelumnya, Rangka Kerja MVC membenarkan penyesuaian dan sambungan yang hampir tidak terhad. Untuk menyediakan sebarang jenis pemprosesan pertanyaan dan penjanaan hasil yang dikehendaki, anda boleh melaksanakan antara muka IController. Tidak suka kaedah tindakan? Tidak mahu risau tentang paparan yang diberikan? Dalam kes ini, anda boleh mengambil perkara sendiri dan melaksanakan cara yang lebih baik, lebih pantas dan lebih elegan untuk mengendalikan permintaan. Sebagai alternatif, anda boleh memanfaatkan alatan yang ditawarkan oleh pasukan MVC Framework di Microsoft dan mewarisi pengawal anda daripada kelas System.Web.Mvc.Controller.

Kelas Pengawal menyediakan sokongan pemprosesan permintaan yang biasa kepada kebanyakan pembangun aplikasi MVC. Ia digunakan dalam semua contoh yang dibincangkan dalam artikel sebelumnya. Kelas Pengawal menyediakan tiga kunci bermakna yang diterangkan di bawah:

Kaedah tindakan

Tingkah laku pengawal tersebar merentasi pelbagai kaedah (bukannya dilaksanakan dalam borang satu-satunya kaedah Laksanakan()). Setiap kaedah tindakan dipetakan ke URL yang sepadan dan dipanggil dengan parameter yang diambil daripada permintaan masuk.

Hasil tindakan

Anda boleh mengembalikan objek yang menerangkan hasil tindakan (seperti memaparkan paparan atau mengubah hala ke URL atau kaedah tindakan lain) dan kemudian memprosesnya dalam apa jua cara yang anda suka. Pemisahan antara menentukan keputusan dan melaksanakannya menjadikan ujian unit lebih mudah.

Penapis

Tingkah laku boleh guna semula (seperti pengesahan) boleh dirangkumkan sebagai penapis dan kemudian setiap aspek tingkah laku pengawal dan kaedah tindakan boleh ditandakan dengan atribut dalam kod sumber.

Melainkan anda berurusan dengan keperluan khusus, pendekatan terbaik untuk mencipta pengawal adalah untuk mendapatkannya daripada kelas Pengawal, iaitu apa yang Visual Studio lakukan, seperti yang anda jangkakan, apabila ia mencipta kelas baru sebagai tindak balas kepada item menu Tambah --> Scaffold (Tambah --> Templat).

Contoh di bawah menunjukkan kod pengawal mudah dipanggil DerivedController, dicipta dengan cara yang sama. Ia dijana menggunakan pilihan Pengawal MVC 5 - Kosong dengan beberapa perubahan mudah, bertujuan untuk menetapkan sifat ViewBag dan memilih paparan:

Menggunakan Sistem; menggunakan System.Web; menggunakan System.Web.Mvc; namespace ControllersAndActions.Controllers ( public class DerivedController: Controller ( public ActionResult Index() ( ViewBag.Message = "Hello dari pengawal DerivedController action method Index"; return View("MyView"); ) ) )

Kelas Pengawal juga menyediakan komunikasi dengan sistem pandangan Razor. Dalam contoh ini, kami mengembalikan hasil panggilan kepada kaedah View(), yang diluluskan sebagai parameter nama paparan untuk diberikan kepada klien. Untuk mencipta paparan ini, buat folder Views/Derived, klik padanya Klik kanan tetikus dan pilih masuk menu konteks item Tambah --> MVC 5 Lihat Halaman (Cukur) (Tambah --> MVC 5 Lihat Halaman (Cukur)). Tentukan nama MyView.cshtml dan klik OK untuk mencipta fail paparan.

Bawa kandungan fail mengikut contoh:

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

Selepas menjalankan aplikasi dan menavigasi ke URL paparan /Derived/Index, kaedah tindakan ini dipanggil dan MyView diberikan:

Warisan daripada kelas Pengawal menyebabkan keperluan untuk melaksanakan kaedah tindakan, menerima sebarang input yang diperlukan untuk memproses permintaan dan menjana respons yang sesuai. Artikel berikut menerangkan banyak pendekatan untuk melakukan ini.

Ramai orang mula menulis projek untuk bekerja dengan satu tugas, tidak membayangkan bahawa ia boleh berkembang menjadi sistem pengurusan berbilang pengguna, contohnya, kandungan atau, Allah melarang, pengeluaran. Dan semuanya kelihatan hebat dan hebat, semuanya berfungsi, sehingga anda mula memahami bahawa kod yang ditulis terdiri sepenuhnya daripada tongkat dan kod keras. Kod bercampur dengan susun atur, pertanyaan dan tongkat, kadangkala tidak boleh dibaca. Masalah mendesak timbul: apabila menambah ciri baharu, anda perlu bermain-main dengan kod ini untuk masa yang sangat lama, mengingati "apa yang ditulis di sana?" dan mengutuk diri sendiri pada masa lalu.

Anda mungkin pernah mendengar tentang corak reka bentuk dan juga membaca buku-buku indah ini:

  • E. Gamma, R. Helm, R. Johnson, J. Vlissides “Teknik objektif reka bentuk berorientasikan. Corak Reka Bentuk";
  • M. Fowler "Seni Bina Aplikasi Perisian Perusahaan."
Dan ramai, tidak gentar dengan manual dan dokumentasi yang besar, cuba mengkaji mana-mana rangka kerja moden dan, berhadapan dengan kerumitan pemahaman (disebabkan kehadiran banyak konsep seni bina yang saling berkaitan), menangguhkan kajian dan penggunaan alat moden dalam perlindungan."

Artikel ini akan berguna terutamanya untuk pemula. Bagaimanapun, saya harap dalam beberapa jam anda boleh mendapat idea pelaksanaan MVC corak yang mendasari semua rangka kerja web moden, dan juga mendapatkan "makanan" untuk refleksi lanjut tentang "cara melakukannya." Di akhir artikel terdapat pilihan pautan yang berguna, yang juga akan membantu anda memahami rangka kerja web yang terdiri daripada (selain MVC) dan cara ia berfungsi.

Pengaturcara PHP yang berpengalaman tidak mungkin menemui sesuatu yang baru untuk diri mereka sendiri dalam artikel ini, tetapi ulasan dan ulasan mereka pada teks utama akan sangat membantu! Kerana Tanpa teori, amalan adalah mustahil, dan tanpa amalan, teori adalah sia-sia, kemudian mula-mula akan ada sedikit teori, dan kemudian kita akan beralih kepada amalan. Jika anda sudah biasa dengan konsep MVC, anda boleh melangkau bahagian teori dan terus ke latihan.

1. Teori Corak MVC menerangkan cara mudah untuk menstruktur aplikasi, yang tujuannya adalah untuk memisahkan logik perniagaan daripada antara muka pengguna. Akibatnya, aplikasi lebih mudah untuk skala, ujian, penyelenggaraan dan, sudah tentu, dilaksanakan.

Mari lihat gambarajah konsep corak MVC (pada pendapat saya, ini adalah gambar rajah paling berjaya yang saya lihat):

Dalam seni bina model MVC menyediakan data dan peraturan logik perniagaan, pandangan bertanggungjawab untuk antara muka pengguna, dan pengawal menyediakan interaksi antara model dan pandangan.

Aliran biasa aplikasi MVC boleh diterangkan seperti berikut:

  • Apabila pengguna melawat sumber web, skrip permulaan mencipta contoh aplikasi dan melancarkannya untuk pelaksanaan.
    Ini memaparkan pandangan, katakan halaman rumah tapak.
  • Aplikasi menerima permintaan daripada pengguna dan menentukan pengawal dan tindakan yang diminta. Dalam kes halaman utama, tindakan lalai dilakukan ( indeks).
  • Aplikasi membuat instantiate pengawal dan menjalankan kaedah tindakan,
    yang, sebagai contoh, mengandungi panggilan model yang membaca maklumat daripada pangkalan data.
  • Selepas ini, tindakan mencipta paparan dengan data yang diperoleh daripada model dan memaparkan hasilnya kepada pengguna.
  • Model - mengandungi logik perniagaan aplikasi dan termasuk kaedah untuk pensampelan (ini boleh menjadi kaedah ORM), pemprosesan (contohnya, peraturan pengesahan) dan menyediakan data khusus, yang sering menjadikannya sangat tebal, yang agak biasa.
    Model tidak boleh berinteraksi secara langsung dengan pengguna. Semua pembolehubah yang berkaitan dengan permintaan pengguna mesti diproses dalam pengawal.
    Model tidak boleh menjana HTML atau kod paparan lain yang boleh berubah bergantung pada keperluan pengguna. Kod sedemikian harus diproses dalam paparan.
    Model yang sama, sebagai contoh: model pengesahan pengguna boleh digunakan dalam kedua-dua bahagian pengguna dan pentadbiran aplikasi. Dalam kes ini, ia boleh diambil kod am ke dalam kelas yang berasingan dan mewarisi daripadanya, mentakrifkan kaedah khusus untuk subaplikasi dalam keturunannya.

    View - digunakan untuk menentukan paparan luaran data yang diterima daripada pengawal dan model.
    Paparan mengandungi penanda HTML dan sisipan kecil kod PHP untuk melintasi, memformat dan memaparkan data.
    Tidak boleh mengakses pangkalan data secara langsung. Inilah yang harus dilakukan oleh model.
    Tidak boleh berfungsi dengan data yang diperoleh daripada permintaan pengguna. Tugas ini mesti dilakukan oleh pengawal.
    Boleh mengakses secara langsung sifat dan kaedah pengawal atau model untuk mendapatkan data sedia keluaran.
    Paparan biasanya dibahagikan kepada templat biasa, mengandungi penanda biasa kepada semua halaman (contohnya, pengepala dan pengaki) dan bahagian templat yang digunakan untuk memaparkan output data daripada model atau memaparkan borang kemasukan data.

    Pengawal ialah gam yang menghubungkan model, pandangan dan komponen lain ke dalam aplikasi kerja. Pengawal bertanggungjawab untuk memproses permintaan pengguna. Pengawal seharusnya tidak mengandungi pertanyaan SQL. Adalah lebih baik untuk menyimpannya dalam model. Pengawal tidak boleh mengandungi HTML atau penanda lain. Ia berbaloi untuk memaparkannya.
    Dalam aplikasi MVC yang direka dengan baik, pengawal biasanya sangat nipis dan mengandungi hanya beberapa dozen baris kod. Perkara yang sama tidak boleh dikatakan tentang Stupid Fat Controllers (SFC) dalam CMS Joomla. Logik pengawal agak tipikal dan kebanyakannya dijalankan dalam kelas asas.
    Model, sebaliknya, sangat tebal dan mengandungi kebanyakan kod yang berkaitan dengan pemprosesan data, kerana struktur data dan logik perniagaan yang terkandung di dalamnya biasanya agak khusus untuk aplikasi tertentu.

    1.1. Pengawal Hadapan dan Pengawal Halaman Dalam kebanyakan kes, interaksi pengguna dengan aplikasi web berlaku melalui klik pada pautan. Lihat sekarang pada bar alamat penyemak imbas anda - anda menerima teks ini daripada pautan ini. Pautan lain, seperti yang berada di sebelah kanan halaman ini, akan memberikan anda kandungan yang berbeza. Oleh itu, pautan mewakili arahan khusus kepada aplikasi web.

    Saya harap anda telah menyedari bahawa tapak yang berbeza boleh mempunyai sempurna format yang berbeza pembinaan bar alamat. Setiap format boleh memaparkan seni bina aplikasi web. Walaupun ini tidak selalu berlaku, dalam kebanyakan kes ia adalah fakta yang jelas.

    Mari kita pertimbangkan dua pilihan untuk bar alamat, yang memaparkan beberapa teks dan profil pengguna.

    Anggaran kod pemprosesan dalam kes ini:
    suis($_GET["action"]) ( case "about" : require_once("about.php"); // "Mengenai Kami" pemecahan halaman; case "contacts" : require_once("contacts.php"); // Pemisah halaman "Kenalan"; kes "maklum balas" : require_once("maklum balas.php"); // Pemisah halaman "Maklum Balas"; lalai: require_once("page404.php"); // pemecahan halaman "404"; )
    Saya rasa hampir semua orang pernah melakukan ini sebelum ini.

    Menggunakan enjin penghalaan URL, anda boleh mengkonfigurasi aplikasi anda untuk menerima permintaan seperti ini untuk memaparkan maklumat yang sama:
    http://www.example.com/contacts/feedback

    Di sini kenalan mewakili pengawal dan maklum balas ialah kaedah pengawal kenalan yang memaparkan borang maklum balas dan lain-lain. Kami akan kembali kepada isu ini dalam bahagian praktikal.

    Perlu juga diketahui bahawa banyak penghala rangka kerja web membenarkan anda membuat sewenang-wenangnya Laluan URL(nyatakan maksud setiap bahagian URL) dan peraturan untuk memprosesnya.
    Kini kami mempunyai pengetahuan teori yang mencukupi untuk meneruskan amalan.

    2. Berlatih Mula-mula, mari buat struktur berikut fail dan folder:


    Melihat ke hadapan, saya akan mengatakan bahawa kelas teras Model, View dan Controller akan disimpan dalam folder teras.
    Anak-anak mereka akan disimpan dalam direktori pengawal, model dan pandangan. Fail index.php ialah titik masuk ke dalam aplikasi. Fail bootstrap.php memulakan pemuatan aplikasi, menyambungkan semua modul yang diperlukan, dsb.

    Kami akan pergi secara berurutan; Mari buka fail index.php dan isi dengan kod berikut:
    ini_set("display_errors", 1); memerlukan_sekali "application/bootstrap.php";
    Tidak sepatutnya ada sebarang soalan di sini.

    Seterusnya, mari segera pergi ke fail bootstrap.php:
    memerlukan_sekali "teras/model.php"; memerlukan_sekali "teras/view.php"; memerlukan_sekali "teras/pengawal.php"; memerlukan_sekali "teras/laluan.php"; Route::start(); //mulakan penghala
    Tiga baris pertama akan termasuk fail kernel yang tidak wujud pada masa ini. Baris terakhir sambungkan fail dengan kelas penghala dan lancarkannya untuk pelaksanaan dengan memanggil kaedah statik mulakan.

    2.1. Melaksanakan Penghala URL Buat masa ini, mari kita menyimpang daripada pelaksanaan corak MVC dan fokus pada penghalaan. Langkah pertama yang perlu kita lakukan ialah menulis kod berikut dalam .htaccess:
    RewriteEngine On RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule .* index.php [L]
    Kod ini akan mengubah hala semua pemprosesan halaman ke index.php, yang kami perlukan. Ingat di bahagian pertama kita bercakap tentang Pengawal Depan?!

    Kami akan meletakkan penghalaan dalam fail route.php yang berasingan dalam direktori teras. Dalam fail ini kami akan menerangkan kelas Route, yang akan menjalankan kaedah pengawal, yang seterusnya akan menjana paparan halaman.

    Kandungan fail route.php

    Laluan kelas ( fungsi statik mula () ( // pengawal dan tindakan lalai $controller_name = "Utama"; $action_name = "index"; $routes = meletup("/", $_SERVER["REQUEST_URI"]); // dapatkan nama pengawal jika (!empty($routes)) ( $controller_name = $routes; ) // dapatkan nama tindakan jika (!empty($routes)) ( $action_name = $routes; ) // tambah awalan $model_name = " Model_".$controller_name; $controller_name = "Controller_".$controller_name; $action_name = "action_".$action_name; // sambungkan fail dengan kelas model (mungkin tiada fail model) $model_file = strtolower ($model_name). ".php"; $model_path = "application/models/".$model_file; if(file_exists($model_path)) ( masukkan "application/models/".$model_file; ) // sambungkan fail dengan kelas pengawal $controller_file = strtolower ($controller_name)..php"; $controller_path = "application/controllers/".$controller_file; if(file_exists($controller_path)) ( masukkan "application/controllers/".$controller_file; ) else ( /* adalah betul untuk membuang pengecualian di sini, tetapi untuk memudahkan perkara, kami akan segera mengubah hala ke halaman 404 */ Route::ErrorPage404(); ) // buat pengawal $controller = new $controller_name ; $action = $action_name; if(method_exists($controller, $action)) ( // panggil tindakan pengawal $controller->$action(); ) else ( // di sini juga lebih bijak untuk membuang pengecualian Route::ErrorPage404(); ) ) fungsi ErrorPage404( ) ($host = "http://".$_SERVER["HTTP_HOST"]."/"; header("HTTP/1.1 404 Not Found"); header("Status: 404 Not Found") ; header("Lokasi:".$host."404"); ) )


    Saya perhatikan bahawa kelas melaksanakan logik yang sangat mudah (walaupun kod besar) dan mungkin mempunyai masalah keselamatan. Ini dilakukan dengan sengaja, kerana... menulis kelas penghalaan penuh patut mendapat sekurang-kurangnya artikel berasingan. Mari kita lihat perkara utama...

    Elemen tatasusunan global $_SERVER["REQUEST_URI"] mengandungi alamat penuh yang mana pengguna menghubungi.
    Contohnya: example.ru/contacts/feedback

    Menggunakan fungsi meletup Alamat dibahagikan kepada komponen. Akibatnya, kami mendapat nama pengawal, untuk contoh yang diberikan, ini adalah pengawal kenalan dan nama tindakan, dalam kes kami - maklum balas.

    Seterusnya, fail model (model mungkin tiada) dan fail pengawal, jika ada, disambungkan dan akhirnya, contoh pengawal dibuat dan tindakan dipanggil, sekali lagi, jika ia diterangkan dalam kelas pengawal.

    Oleh itu, apabila pergi ke, sebagai contoh, alamat:
    example.com/portfolio
    atau
    example.com/portfolio/index
    Penghala akan melakukan tindakan berikut:

  • akan memasukkan fail model_portfolio.php daripada folder model, yang mengandungi kelas Model_Portfolio;
  • akan memasukkan fail controller_portfolio.php daripada folder pengawal, yang mengandungi kelas Controller_Portfolio;
  • akan membuat contoh kelas Controller_Portfolio dan memanggil tindakan lalai - action_index, yang diterangkan di dalamnya.
  • Jika pengguna cuba mengakses alamat pengawal yang tidak wujud, contohnya:
    example.com/ufo
    maka dia akan dialihkan ke halaman "404":
    example.com/404
    Perkara yang sama akan berlaku jika pengguna mengakses tindakan yang tidak diterangkan dalam pengawal.2.2. Mari kembali ke pelaksanaan MVC Mari pergi ke folder teras dan tambah tiga lagi fail pada fail route.php: model.php, view.php dan controller.php


    Biar saya ingatkan anda bahawa ia akan mengandungi kelas asas, yang kini kita akan mula menulis.

    Kandungan fail model.php
    Model kelas ( fungsi awam get_data() ( ) )
    Kelas model mengandungi satu kaedah pengambilan data kosong, yang akan ditindih dalam kelas turunan. Apabila kita mencipta kelas keturunan semuanya akan menjadi lebih jelas.

    Kandungan fail view.php
    class View ( //public $template_view; // di sini anda boleh menentukan paparan umum lalai. function generate($content_view, $template_view, $data = null) ( /* if(is_array($data)) ( // convert array elemen ke dalam ekstrak pembolehubah($data); ) */ sertakan "application/views/".$template_view; ) )
    Ia tidak sukar untuk meneka bahawa kaedah menjana bertujuan untuk membentuk pandangan. Parameter berikut dihantar kepadanya:

  • $content_file - paparan memaparkan kandungan halaman;
  • $template_file - templat biasa kepada semua halaman;
  • $data ialah tatasusunan yang mengandungi elemen kandungan halaman. Biasanya diisi dalam model.
  • Fungsi sertakan secara dinamik menghubungkan templat umum (pandangan) di mana paparan akan dibenamkan
    untuk memaparkan kandungan halaman tertentu.

    Dalam kes kami, templat umum akan mengandungi pengepala, menu, bar sisi dan pengaki, dan kandungan halaman akan terkandung dalam bentuk yang berasingan. Sekali lagi, ini dilakukan untuk kesederhanaan.

    Kandungan fail controller.php
    Pengawal kelas ( public $model; public $view; function __construct() ( $this->view = new View(); ) function action_index() ( ) )
    Kaedah indeks_tindakan- ini ialah tindakan yang dipanggil secara lalai; kami akan mengatasinya apabila melaksanakan kelas keturunan.

    2.3. Pelaksanaan kelas turunan Model dan Pengawal, penciptaan View "s Sekarang keseronokan bermula! Laman web kad perniagaan kami akan terdiri daripada halaman berikut:
  • rumah
  • Perkhidmatan
  • Portfolio
  • Kenalan
  • Dan juga - halaman "404".
  • Setiap halaman mempunyai pengawal sendiri dari folder pengawal dan paparan dari folder pandangan. Sesetengah halaman mungkin menggunakan model atau model daripada folder model.


    Dalam rajah sebelumnya, fail template_view.php diserlahkan secara berasingan - ini adalah templat yang mengandungi markup biasa untuk semua halaman. Dalam kes paling mudah ia boleh kelihatan seperti ini:
    rumah
    Untuk memberikan tapak rupa yang rapi, kami mencipta templat CSS dan menyepadukannya ke dalam tapak kami dengan mengubah struktur penanda HTML dan Sambungan CSS dan fail JavaScript:

    Pada penghujung artikel, dalam bahagian "Hasil", terdapat pautan ke repositori GitHub dengan projek yang mana langkah telah diambil untuk menyepadukan templat mudah.

    2.3.1. Mencipta halaman utama Mari kita mulakan dengan controller controller_main.php , berikut ialah kodnya:
    kelas Controller_Main memanjangkan Pengawal ( function action_index() ( $this->view->generate("main_view.php", "template_view.php"); ) )
    Dalam kaedah menjana contoh kelas Lihat, nama fail templat umum dan paparan dengan kandungan halaman diluluskan.
    Sebagai tambahan kepada tindakan indeks, pengawal sudah tentu boleh mengandungi tindakan lain.

    Failkan dengan Pandangan umum kita tengok tadi. Pertimbangkan fail kandungan main_view.php:
    Selamat datang!

    OLOLOSHA TEAM ialah pasukan pakar kelas pertama dalam bidang pembangunan laman web dengan pengalaman bertahun-tahun dalam mengumpul topeng Mexico, patung gangsa dan batu dari India dan Ceylon, relief dan arca yang dicipta oleh pakar Afrika Khatulistiwa lima atau enam abad lalu...


    Ini mengandungi markup mudah tanpa sebarang panggilan PHP.
    Untuk memaparkan halaman utama, anda boleh menggunakan salah satu daripada alamat berikut:

    Kami akan mempertimbangkan contoh menggunakan paparan yang memaparkan data yang diperoleh daripada model di bawah.

    2.3.2. Buat halaman "Portfolio" Dalam kes kami, halaman "Portfolio" ialah satu-satunya halaman yang menggunakan model.
    Model biasanya termasuk kaedah pensampelan data, contohnya:
  • kaedah perpustakaan pgsql atau mysql asli;
  • kaedah perpustakaan yang melaksanakan abstraksi data. Sebagai contoh, kaedah perpustakaan PEAR MDB2;
  • kaedah ORM;
  • kaedah untuk bekerja dengan NoSQL;
  • dan sebagainya.
  • Untuk memudahkan, kami tidak akan menggunakan pertanyaan SQL atau pernyataan ORM di sini. Sebaliknya, kami akan mencontohi data sebenar dan segera mengembalikan pelbagai hasil.
    Letakkan fail model model_portfolio.php dalam folder model. Berikut adalah kandungannya:
    class Model_Portfolio memanjangkan Model ( public function get_data() ( return array(array("Year" => "2012", "Site" => "http://DunkelBeer.ru", "Description" => "Tapak promosi bagi bir Dunkel gelap dari pengeluar Jerman Löwenbraü yang dihasilkan di Rusia oleh syarikat pembuatan bir "SUN InBev."), array("Year" => "2012", "Site" => "http://ZopoMobile.ru", "Description " => "Katalog bahasa Rusia telefon Cina Syarikat Zopo dihidupkan berasaskan Android OS dan aksesori untuk mereka."), // todo); ) )

    Kelas pengawal model terkandung dalam fail controller_portfolio.php, berikut ialah kodnya:
    kelas Controller_Portfolio memanjangkan Pengawal ( 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); ) )
    Kepada pembolehubah data tatasusunan yang dikembalikan oleh kaedah ditulis dapatkan_data yang kita tengok tadi.
    Pembolehubah ini kemudiannya diluluskan sebagai parameter kaedah menjana, yang juga mengandungi: nama fail dengan templat umum dan nama fail yang mengandungi paparan dengan kandungan halaman.

    Paparan yang mengandungi kandungan halaman adalah dalam fail portfolio_view.php.
    Portfolio

    Semua projek dalam jadual berikut adalah rekaan, jadi jangan cuba mengikuti pautan yang disediakan.
    tahunProjekPenerangan


    Segala-galanya mudah di sini, paparan memaparkan data yang diperoleh daripada model.

    2.3.3. Mencipta halaman selebihnya Halaman selebihnya dibuat dengan cara yang sama. Kod mereka tersedia dalam repositori GitHub, pautan yang disediakan pada penghujung artikel, dalam bahagian "Hasil".3. Keputusan Inilah yang berlaku pada akhirnya:

    Tangkapan skrin tapak web kad perniagaan yang terhasil



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

    Tetapi dalam versi ini saya melakarkan kelas berikut (dan jenis yang sepadan):

    • Controller_Login di mana paparan dijana dengan borang untuk memasukkan log masuk dan kata laluan, selepas mengisi prosedur pengesahan dijalankan dan, jika berjaya, pengguna dialihkan ke panel pentadbir.
    • Contorller_Admin dengan tindakan indeks yang menyemak sama ada pengguna telah diberi kuasa sebelum ini di tapak sebagai pentadbir (jika ya, paparan panel pentadbir dipaparkan) dan tindakan log keluar untuk log keluar.
    Pengesahan dan kebenaran adalah topik yang berbeza, jadi ia tidak dibincangkan di sini, tetapi hanya pautan yang diberikan di atas disediakan supaya anda mempunyai sesuatu untuk bermula.4. Kesimpulan Corak MVC digunakan sebagai asas seni bina dalam banyak rangka kerja dan CMS yang dicipta untuk dapat membangunkan kualiti yang lebih tinggi penyelesaian yang kompleks untuk lebih jangka pendek. Ini dimungkinkan dengan meningkatkan tahap abstraksi, kerana terdapat had kepada kerumitan struktur yang boleh dikendalikan oleh otak manusia.

    Tetapi, menggunakan rangka kerja web seperti Yii atau Kohana, yang terdiri daripada beberapa ratus fail, apabila membangunkan aplikasi web mudah (contohnya, tapak kad perniagaan) tidak selalu digalakkan. Kini kita boleh mencipta model MVC yang cantik supaya tidak mencampurkan kod Php, Html, CSS dan JavaScript dalam satu fail.

    Artikel ini lebih merupakan titik permulaan untuk mempelajari CMF daripada contoh sesuatu yang benar-benar betul yang boleh anda gunakan sebagai asas untuk aplikasi web anda. Mungkin ia juga memberi inspirasi kepada anda dan anda sudah berfikir tentang menulis rangka kerja mikro atau CMS anda sendiri berdasarkan MVC. Tetapi, sebelum mencipta semula roda seterusnya dengan "blackjack dan pelacur," fikirkan sekali lagi: mungkin lebih munasabah untuk mengarahkan usaha anda kepada pembangunan dan membantu komuniti projek yang sedia ada?!

    P.S.: Artikel itu telah ditulis semula dengan mengambil kira beberapa komen yang ditinggalkan dalam komen. Kritikan itu ternyata sangat berguna. Berdasarkan maklum balas: komen, PM dan bilangan pengguna yang menambah siaran ke kegemaran, idea untuk menulis siaran ini ternyata tidak begitu buruk. Malangnya, tidak mungkin untuk mengambil kira semua hasrat dan menulis lebih banyak dan lebih terperinci kerana kesuntukan masa... tetapi mungkin individu-individu misteri yang menolak versi asal akan melakukan ini. Semoga berjaya dengan projek anda!

    5. Pilihan pautan yang berguna mengenai subjek Artikel ini sering menyentuh topik rangka kerja web - ini adalah topik yang sangat luas, kerana kerangka kerja mikro pun terdiri daripada banyak komponen yang saling berkaitan dengan bijak dan memerlukan lebih daripada satu artikel untuk membincangkan perkara ini. komponen. Walau bagaimanapun, saya memutuskan untuk membentangkan di sini pilihan kecil pautan (yang saya ikuti semasa menulis artikel ini) yang dalam satu cara atau yang lain berkaitan dengan topik rangka kerja.

    Tag: Tambah tag

    Corak Model-View-Controller (MVC), ditemui pada akhir 1970-an, ialah corak reka bentuk seni bina perisian, tugas utamanya adalah untuk memisahkan fungsi bekerja dengan data daripada pembentangan mereka. Secara teorinya, aplikasi MVC yang direka dengan baik akan membolehkan pembangun bahagian hadapan dan belakang tidak mengganggu bidang tanggungjawab masing-masing semasa kerja mereka, iaitu, pembangun bahagian hadapan tidak perlu mengetahui apa-apa tentang "dapur" rakan sekerja belakangnya dan sebaliknya.

    Walaupun MVC pada asalnya direka untuk pembangunan aplikasi desktop, ia telah disesuaikan untuk tugas moden dan sangat popular di kalangan pembangun web, kerana disebabkan pembahagian tanggungjawab, ia telah menjadi mungkin untuk mencipta yang lebih jelas, sedia untuk digunakan guna semula kod. Corak MVC menghasilkan sistem modular yang bersih yang membolehkan pembangun membuat perubahan pada kod sedia ada dengan cepat.

    Dalam artikel ini kita akan melihat prinsip asas MVC, bermula dengan menentukan corak dan terus menerapkannya dalam contoh kecil. Artikel ini akan berguna terutamanya kepada mereka yang tidak pernah menemui corak ini dalam hidup, dan juga, mungkin, kepada mereka yang ingin meningkatkan pengetahuan mereka tentang MVC.

    Memahami MVC

    Seperti yang telah disebutkan, nama corak berasal dari singkatan tiga perkataan: Model (model), View (pandangan) dan Pengawal (pengawal). Secara ringkas, prinsip operasi corak boleh digambarkan dengan satu rajah (boleh didapati di Wikipedia):

    Gambar rajah ini jelas menunjukkan aliran maklumat satu arah dalam corak dan juga menerangkan peranan setiap komponen.

    Model

    Model ini digunakan untuk mengakses dan memanipulasi data. Dalam kebanyakan kes, model ialah apa yang digunakan untuk mengakses stor data (seperti pangkalan data). Model ini menyediakan antara muka untuk mencari data, menciptanya, mengubah suainya dan memadamkannya daripada storan. Dalam konteks corak MVC, model adalah pengantara antara pandangan dan pengawal.

    Ciri yang sangat penting bagi model ialah ia secara teknikal tidak mempunyai pengetahuan tentang perkara yang berlaku dengan data dalam pengawal dan paparan. Model tidak boleh membuat atau menunggu sebarang permintaan kepada/daripada komponen corak lain.

    Walau bagaimanapun, sentiasa ingat bahawa model itu bukan hanya pintu masuk ke pangkalan data atau sistem lain yang tidak melakukan apa-apa selain memindahkan data ke sana ke mari. Model adalah seperti pintu masuk kepada data. Model dalam kebanyakan kes adalah bahagian sistem yang paling kompleks, sebahagiannya disebabkan oleh fakta bahawa model itu sendiri adalah pautan penghubung untuk semua bahagian lain.

    Prestasi

    Pandangan adalah di mana data yang diterima daripada model dikeluarkan dalam bentuk yang betul. Dalam aplikasi web tradisional yang dibangunkan menggunakan corak MVC, paparan adalah sebahagian daripada sistem di mana kod HTML dijana. Pandangan juga bertanggungjawab untuk menerima tindakan daripada pengguna untuk menghantarnya kepada pengawal. Sebagai contoh, paparan memaparkan butang masuk antaramuka pengguna, dan selepas menekannya menyebabkan tindakan pengawal yang sepadan.

    Terdapat beberapa salah tanggapan tentang tujuan paparan, terutamanya dalam kalangan pembangun web yang baru mula membina aplikasi mereka menggunakan MVC. Salah satu peraturan yang paling kerap dilanggar ialah pandangan tidak boleh berkomunikasi dengan model dalam apa jua cara, dan semua data yang diterima oleh paparan mesti datang hanya daripada pengawal. Dalam amalan, pembangun sering mengabaikan konsep ini, yang merupakan teras kepada corak MVC. Artikel Fabio Cevasco menggambarkan pendekatan MVC yang mengelirukan ini menggunakan CakePHP, salah satu daripada banyak rangka kerja MVC bukan standard:

    Adalah amat penting untuk memahami bahawa untuk mendapatkan seni bina MVC yang betul, tidak seharusnya ada sebarang interaksi langsung antara pandangan dan model. Semua logik untuk bertukar-tukar data antara mereka mesti dilaksanakan dalam pengawal.

    Selain itu, terdapat salah tanggapan umum bahawa pandangan hanyalah fail templat. Seperti yang dinyatakan oleh Tom Butler, salah tanggapan ini sangat besar disebabkan oleh fakta bahawa ramai pembangun salah faham struktur MVC sejak awal lagi, selepas itu mereka mula mencurahkan "pengetahuan" ini lebih jauh ke dalam ramai pemaju pemula. Pada hakikatnya, pandangan adalah lebih daripada sekadar templat, tetapi banyak rangka kerja yang dibina di atas corak MVC telah memutarbelitkan konsep pandangan sehingga tiada siapa yang mengambil berat sama ada aplikasi mereka adalah betul dari segi corak MVC.

    Satu lagi perkara penting ialah pandangan tidak pernah berfungsi dengan data "tulen" daripada pengawal, iaitu, pengawal tidak pernah berfungsi dengan pandangan tanpa memintas model. Semasa interaksi antara pengawal dan pandangan, model harus sentiasa berada di antara mereka.

    Pengawal

    Pengawal ialah bahagian terakhir dalam himpunan MVC. Tugas pengawal adalah untuk menerima data daripada pengguna dan memanipulasi model. Ia adalah pengawal, dan hanya itu, bahagian sistem yang berinteraksi dengan pengguna.

    Secara ringkasnya, pengawal boleh digambarkan sebagai pengumpul maklumat yang menghantarnya kepada model untuk pemprosesan dan penyimpanan. Ia tidak sepatutnya melakukan apa-apa dengan data, tetapi hanya boleh menerimanya daripada pengguna. Pengawal dikaitkan dengan satu pandangan dan satu model, dengan itu mengatur aliran data satu arah, mengawalnya pada setiap peringkat.

    Adalah sangat penting untuk diingat bahawa pengawal hanya memulakan kerjanya hasil interaksi pengguna dengan paparan, yang memanggil fungsi pengawal yang sepadan. Kesilapan yang paling biasa di kalangan pembangun ialah melihat pengawal sebagai pintu masuk antara paparan dan model. Akibatnya, pengawal dikurniakan fungsi-fungsi yang sepatutnya dilakukan oleh pandangan (omong-omong, di sinilah idea bahawa pandangan hanyalah fail templat berasal). Selain itu, ramai orang membuang sepenuhnya semua logik pemprosesan data, melupakan tujuan model itu dalam corak MVC.

    MVC dalam PHP

    Saya cadangkan cuba melaksanakan perkara di atas dalam aplikasi kecil. Mari mulakan dengan mencipta kelas model, paparan dan pengawal: