PHPで名刺サイトを作成する例でのMVCパターンの実装

mvc

記事のタイトルから推測したかもしれませんが、本日は最も人気のあるものについて説明しますが、 SingletonMVCデザインパターンを除き、そのような比較は完全に適切ではありません。 MVCの概念を理解することは、プロジェクトが陥りそうな不快な状況をリファクタリングして解決するのに役立ちます。 ギャップを埋めるために、単純な名刺サイトの例を使用してMVCテンプレートを実装します。





目次



はじめに

1. 理論

1.1。 フロントコントローラーとページコントローラー

1.2。 URLルーティング

2. 練習

2.1。 URLルーターの実装

2.2。 MVC実装に戻る

2.3。 モデルとコントローラーの子クラスの実装、ビューの作成

2.3.1。 ホームページを作成する

2.3.2。 ポートフォリオページを作成する

2.3.3。 残りのページを作成します

3. 結果

4. 結論

5. 件名に役立つリンク集





はじめに



多くの人は、プロジェクトがマルチユーザー管理システムに成長できることを意味するのではなく、単一のタスクで動作するプロジェクトを書き始めます。 そして、すべてがクールでクールなように見えます。書かれているコードが完全に松葉杖とハードコードで構成されていることを理解し始めるまで、すべてが機能します。 コードにはレイアウト、クエリ、松葉杖が混在しており、読み取り不可能な場合もあります。 緊急の問題があります。新しい機能を追加するときは、「そこに何が書かれていて、何だったのか」を覚えて、このコードを非常に長い間混乱させなければなりません。



デザインパターンについて聞いたことがあり、これらの美しい本に目を通すことさえありました。



そして、巨大なマニュアルとドキュメンテーションを恐れない多くの人が、現代のフレームワークのいずれかを研究しようとし、理解の困難に直面しました(多くの建築概念が巧妙に結び付けられているため)。



この記事は主に初心者に役立ちます。 いずれにせよ、数時間以内に、現代のすべてのWebフレームワークの基礎となるMVCパターンの実装についてのアイデアを得て、さらにそれを行う方法をさらに検討するための「食べ物」を手に入れてほしい。 記事の最後には、Webフレームワーク(MVC以外)がどのようなもので構成され、どのように機能するかを理解するのに役立つ便利なリンクがあります。



燃えるPHPプログラマーは、この記事で自分自身にとって新しいものを見つけることはほとんどありませんが、彼らのコメントやメインテキストに対するコメントは非常に役立ちます。 なぜなら 理論がなければ、実践は不可能であり、実践がなければ、理論は役に立たず、最初に少し理論があり、それから実践に移ります。 MVCの概念に既に精通している場合は、理論のセクションをスキップして、すぐに実践に進むことができます。





1.理論



MVCパターンは、ビジネスロジックをユーザーインターフェイスから分離することを目的とする、アプリケーション構造を構築する簡単な方法を説明しています。 その結果、アプリケーションのスケーリング、テスト、保守が容易になり、もちろん実装されます。



MVCパターンの概念設計を検討してください(私の意見では、これは私が見た中で最も成功した設計です)。



mvc-schema



MVCアーキテクチャでは、モデルがデータとビジネスロジックのルールを提供し、ビューがユーザーインターフェイスを担当し、コントローラーがモデルとビュー間の相互作用を提供します。



MVCアプリケーションの典型的な一連の操作は、次のように説明できます。

  1. ユーザーがWebリソースを入力すると、初期化スクリプトがアプリケーションのインスタンスを作成し、実行のために起動します。

    これにより、サイトのメインページなどのビューが表示されます。

  2. アプリケーションはユーザーからリクエストを受け取り、リクエストされたコントローラーとアクションを決定します。 メインページの場合、デフォルトのアクション( index )が実行されます。

  3. アプリケーションはコントローラーのインスタンスを作成し、アクションメソッドを起動します。

    たとえば、データベースから情報を読み取るモデル呼び出しが含まれます。

  4. その後、アクションはモデルから取得したデータを使用してビューを形成し、結果をユーザーに表示します。



モデル -アプリケーションのビジネスロジックが含まれており、サンプリングメソッド(これらはORMメソッドの場合もあります)、処理(検証ルールなど)、および特定のデータの提供を含みます。

モデルはユーザーと直接対話しないでください。 ユーザー要求に関連するすべての変数は、コントローラーで処理する必要があります。

このモデルでは、ユーザーのニーズに応じて異なる可能性のあるHTMLまたはその他の表示コードを生成しないでください。 このようなコードはビューで処理する必要があります。

同一のモデル。たとえば、ユーザー認証モデルは、ユーザーとアプリケーションの管理部分の両方で使用できます。 この場合、継承者でアプリケーション固有のメソッドを定義することにより、一般的なコードを別のクラスに取り込み、そこから継承できます。



ビュー -コントローラーとモデルから受信したデータの外部表示を指定するために使用されます。

ビューには、データをクロール、フォーマット、および表示するためのHTMLマークアップと小さなPHPコードの挿入が含まれます。

データベースに直接アクセスしないでください。 これはモデルによって行われるべきです。

ユーザーのリクエストから取得したデータを処理しないでください。 このタスクはコントローラーが実行する必要があります。

コントローラまたはモデルのプロパティとメソッドに直接アクセスして、出力可能なデータを取得できます。

ビューは通常、すべてのページ(ヘッダーやフッターなど)に共通のマークアップを含む共通テンプレートと、モデルからのデータ出力の表示またはデータ入力フォームの表示に使用されるテンプレートの部分に分割されます。



コントローラーは、モデル、ビュー、その他のコンポーネントを動作中のアプリケーションに接続する接続リンクです。 コントローラーは、ユーザーのリクエストを処理します。 コントローラにSQLクエリを含めることはできません。 それらはモデルに保存するのが最適です。 コントローラーにHTMLまたはその他のマークアップを含めることはできません。 それは種に入れられるべきです。

適切に設計されたMVCアプリケーションでは、コントローラーは通常非常に薄く、数十行のコードしか含まれていません。 Joomla CMSのStupid Fat Controller(SFC)についても同じことは言えません。 コントローラーのロジックは非常に典型的であり、そのほとんどは基本クラスで実行されます。

それどころか、モデルは非常に厚く、データ処理に関連するほとんどのコードが含まれています。 それらに含まれるデータ構造とビジネスロジックは、通常、特定のアプリケーションに非常に固有のものです。





1.1。 フロントコントローラーとページコントローラー



ほとんどの場合、Webアプリケーションとのユーザーインタラクションは、リンクをクリックして実行されます。 ブラウザのアドレスバーを見てください。このリンクからこのテキストを取得しました。 たとえば、このページの右側にある他のリンクは、異なるコンテンツを提供します。 したがって、リンクはWebアプリケーションへの特定のコマンドを表します。



アドレスバーを作成するために、サイトごとに形式が完全に異なる可能性があることにすでに気付いていることを願っています。 各形式は、Webアプリケーションのアーキテクチャを表示できます。 これは常にそうではありませんが、ほとんどの場合、これは明らかな事実です。



一部のテキストとユーザープロファイルを表示するアドレスバーの2つのオプションを検討します。



最初のオプション:

  1. www.example.com/article.php?id=3
  2. www.example.com/user.php?id=4


ここで、各スクリプトは特定のコマンドを実行します。



2番目のオプション:

  1. www.example.com/index.php?article=3
  2. www.example.com/index.php?user=4


そして、ここでは、すべての呼び出しが1つのindex.phpスクリプトで発生します。



phpBBエンジンを使用したフォーラムで、多くのインタラクションポイントを使用したアプローチを観察できます。 フォーラムの表示は、スクリプトviewforum.phpを介して行われ、トピックはviewtopic.phpを介して表示されます。 1つの物理スクリプトファイルを介してアクセスする2番目のアプローチは、すべての呼び出しがindex.phpを経由するお気に入りのCMS MODXで確認できます。



これら2つのアプローチは完全に異なります。 最初の方法はページコントローラー(Page Controller)の典型的な方法で、2番目の方法はクエリコントローラー(Front Controller)パターンによって実装されます。 ページコントローラーは、かなり単純なロジックを持つサイトに適しています。 リクエストコントローラーは、リクエストを処理するためのすべてのアクションを1か所にまとめ、追加機能を提供します。これにより、ページコントローラーで通常解決されるよりも難しいタスクを実装することができます。 ページコントローラーの実装の詳細については説明しませんが、実際の部分では正確にリクエストコントローラー(ある程度の類似性)を開発するというだけです。





1.2。 URLルーティング



URLルーティングを使用すると、アプリケーションの実際のファイルと一致しないURLからの要求を受け入れるようにアプリケーションを構成できます。また、ユーザーにとって意味的に意味があり、検索エンジン最適化に適したCNCを使用できます。



たとえば、フィードバックフォームを表示する通常のページの場合、URLは次のようになります。

http://www.example.com/contacts.php?action=feedback



この場合のおおよその処理コード:

switch($_GET['action'])
{ 
	case "about" :
		require_once("about.php"); //  " "
		break;
	case "contacts" :
		require_once("contacts.php"); //  ""
		break;
	case "feedback" :
		require_once("feedback.php"); //  " "
		break;
	default : 
		require_once("page404.php"); //  "404"
	break;
}

      
      





, .



URL :

http://www.example.com/contacts/feedback



contacts , feedback — contacts, .. .



, - URL (, URL) .

, .





2.



:



project-folders

, , core Model, View Controller.

controllers, models views. index.php . bootstrap.php , .



; index.php :

ini_set('display_errors', 1);
require_once 'application/bootstrap.php';

      
      





.



, bootstrap.php:

require_once 'core/model.php';
require_once 'core/view.php';
require_once 'core/controller.php';
require_once 'core/route.php';
Route::start(); //  

      
      





. start.





2.1. URL



MVC . , , .htaccess:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]

      
      





index.php, . Front Controller?!



route.php core. Route, , .



route.php
class Route
{
	static function start()
	{
		//     
		$controller_name = 'Main';
		$action_name = 'index';
		
		$routes = explode('/', $_SERVER['REQUEST_URI']);

		//   
		if ( !empty($routes[1]) )
		{	
			$controller_name = $routes[1];
		}
		
		//   
		if ( !empty($routes[2]) )
		{
			$action_name = $routes[2];
		}

		//  
		$model_name = 'Model_'.$controller_name;
		$controller_name = 'Controller_'.$controller_name;
		$action_name = 'action_'.$action_name;

		//      (     )

		$model_file = strtolower($model_name).'.php';
		$model_path = "application/models/".$model_file;
		if(file_exists($model_path))
		{
			include "application/models/".$model_file;
		}

		//     
		$controller_file = strtolower($controller_name).'.php';
		$controller_path = "application/controllers/".$controller_file;
		if(file_exists($controller_path))
		{
			include "application/controllers/".$controller_file;
		}
		else
		{
			/*
			     ,
			        404
			*/
			Route::ErrorPage404();
		}
		
		//  
		$controller = new $controller_name;
		$action = $action_name;
		
		if(method_exists($controller, $action))
		{
			//   
			$controller->$action();
		}
		else
		{
			//       
			Route::ErrorPage404();
		}
	
	}
	
	function ErrorPage404()
	{
        $host = 'http://'.$_SERVER['HTTP_HOST'].'/';
        header('HTTP/1.1 404 Not Found');
		header("Status: 404 Not Found");
		header('Location:'.$host.'404');
    }
}

      
      







, ( ) . , .. . …



$_SERVER['REQUEST_URI'] .

: example.ru/contacts/feedback



explode . , , contacts , — feedback.



( ) , , , , .



, , , :

example.com/portfolio



example.com/portfolio/index

:

  1. model_portfolio.php models, Model_Portfolio;
  2. controller_portfolio.php controllers, Controller_Portfolio;
  3. Controller_Portfolio — action_index, .


, :

example.com/ufo

«404»:

example.com/404

, .





2.2. MVC



core route.php : model.php, view.php controller.php



core-folder

, , .



model.php

class Model
{
	public function get_data()
	{
	}
}

      
      





, . .



view.php

class View
{
	//public $template_view; //       .
	
	function generate($content_view, $template_view, $data = null)
	{
		/*
		if(is_array($data)) {
			//     
			extract($data);
		}
		*/
		
		include 'application/views/'.$template_view;
	}
}

      
      





, generate . :

  1. $content_file — ;
  2. $template_file — ;
  3. $data — , . .


include (),

.



header, menu, sidebar footer, . .





controller.php

class Controller {
	
	public $model;
	public $view;
	
	function __construct()
	{
		$this->view = new View();
	}
	
	function action_index()
	{
	}
}

      
      





action_index — , , .





2.3. Model Controller, View's



! - :

  1. — «404»


controllers views. models.



mvc-folders

template_view.php — , . :

<!DOCTYPE html>
<html lang="ru">
<head>
	<meta charset="utf-8">
	<title></title>
</head>
<body>
	<?php include 'application/views/'.$content_view; ?>
</body>
</html>

      
      





CSS HTML- CSS JavaScript :

<link rel="stylesheet" type="text/css" href="/css/style.css" />
<script src="/js/jquery-1.6.2.js" type="text/javascript"></script>

      
      





, «», GitHub- , .





2.3.1.



controller_main.php, :

class Controller_Main extends Controller
{
	function action_index()
	{	
		$this->view->generate('main_view.php', 'template_view.php');
	}
}

      
      





generate View c .

.



. main_view.php:

<h1> !</h1>
<p>
<img src="/images/office-small.jpg" align="left" >
<a href="/"> TEAM</a> -       -      ,        ,   ,     -  ...
</p>

      
      





PHP-.

:



, .





2.3.2. «»



, «» — .

, :

  1. pgsql mysql;
  2. , . , PEAR MDB2;
  3. ORM;
  4. NoSQL;
  5. .


, SQL- ORM-. .

model_portfolio.php models. :

class Model_Portfolio extends Model
{
	public function get_data()
	{	
		return array(
			
			array(
				'Year' => '2012',
				'Site' => 'http://DunkelBeer.ru',
				'Description' => '-   Dunkel    Löwenbraü      "C ".'
			),
			array(
				'Year' => '2012',
				'Site' => 'http://ZopoMobile.ru',
				'Description' => '     Zopo   Android OS    .'
			),
			// todo
		);
	}
}

      
      







controller_portfolio.php, :

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);
	}
}

      
      





data , get_data, .

generate, : , c .



portfolio_view.php.

<h1></h1>
<p>
<table>
      ,        .
<tr><td></td><td></td><td></td></tr>
<?php

	foreach($data as $row)
	{
		echo '<tr><td>'.$row['Year'].'</td><td>'.$row['Site'].'</td><td>'.$row['Description'].'</td></tr>';
	}
	
?>
</table>
</p>

      
      





, .





2.3.3.



. GitHub, , «».





3.



:



-
site



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



( ):



— , , , .





4.



MVC CMS, , . , , .



, -, Yii Kohana, , - (, -) . MVC , Php, Html, CSS JavaScript .



CMF, - , -. CMS, MVC. , « », , ?!



P.S.: , . . : , . , … , . !





5.



- — , , . , ( ), .



5.1. MVC







5.2.



PHP , …





5.3. URL







5.4.







5.5.








All Articles