Voici l'approche que je prends lors de la création de sites web en PHP à l'aide d'un MVC/séparation des préoccupations modèle:
Le cadre-je utiliser a trois parties principales:
- Modèles - les Classes PHP. J'ai ajouter des méthodes à eux de récupérer et de sauvegarder les données. Chaque
modèle représente un type distinct de l'entité dans le système: les utilisateurs, les pages,
billets de blog
- Vues - Smarty templates. C'est là que le code html de vie.
- Contrôleurs - classes PHP. Ce sont les cerveaux de l'application. Généralement
url du site d'appeler des méthodes de la classe. example.com/user/show/1 serait
invoquer l' $user_controller->show(1) de la méthode. Le contrôleur récupère des données
le modèle et la donne à la vue.
Chacune de ces pièces a un travail spécifique ou d'une "situation préoccupante". Le modèle dela tâche est de fournir une interface propre pour les données. Généralement, les données du site est stocké dans une base de données SQL. J'ai ajouter des méthodes pour le modèle pour l'extraction de données et la sauvegarde des données dans.
La vue's de l'emploi est pour l'affichage des données. Toutes les balises HTML va dans la vue. Une logique de gestion des zèbres de segmentation pour une table de données dans la vue. Code pour gérer le format d'une date doit être affichée en va dans la vue. J'ai comme l'utilisation de Smarty templates pour les vues, car il offre quelques fonctionnalités intéressantes pour gérer des choses comme ça.
Le contrôleur dela tâche est d'agir comme un intermédiaire entre l'utilisateur, le modèle et la vue.
Regardons un exemple de la façon dont ceux-ci viennent ensemble, et où les avantages de mensonge:
Imaginez un simple site de blog. La pièce principale de données est un post. Aussi, imaginez que le site garde une trace du nombre de fois qu'un poste est affiché. Nous allons créer une table SQL pour que:
posts
id date_created title body hits
Maintenant, supposons que vous souhaitez afficher 5 messages les plus populaires. Voici ce que vous pourriez voir dans un non application MVC:
$sql = "SELECT * FROM posts ORDER BY hits DESC LIMIT 5";
$result = mysql_query($sql);
while ($row = mysql_fetch_assoc($result)) {
echo "<a href="post.php?id=$row['id']">$row['title']</a><br />";
}
Cet extrait est assez simple et fonctionne bien si:
- C'est le seul endroit où vous souhaitez afficher les messages les plus populaires
- Vous ne voulez jamais à changer la façon dont il semble
- Ne jamais vous décidez de changer de ce qu'est un "populaire post" est
Imaginez que vous souhaitez afficher les 10 messages les plus populaires sur la page d'accueil et les 5 les plus populaires dans un encadré sur les sous-pages. Maintenant, vous avez besoin soit de dupliquer le code ci-dessus, ou le mettre dans un fichier inclus avec la logique pour vérifier où il est affiché.
Que faire si vous voulez mettre à jour le balisage de la page d'accueil pour ajouter un "nouveau post" classe à des postes qui ont été créés aujourd'hui?
Supposons que vous décidez qu'un post est populaire parce qu'il a beaucoup de commentaires, pas de hits. La base de données va changer pour refléter cela. Maintenant, chaque endroit dans votre application qui montre populaire postes doivent être mis à jour pour refléter la nouvelle logique.
Vous commencez à voir une boule de neige de la complexité de la forme. Il est facile de voir comment les choses peuvent devenir de plus en plus difficile à maintenir sur la durée d'un projet. Aussi, tenir compte de la complexité lorsque plusieurs développeurs travaillent sur un projet. Le designer doit-il se concerter avec le développeur de base de données lors de l'ajout d'une classe à la sortie?
En prenant une approche MVC et l'application d'une séparation des préoccupations au sein de votre application peut atténuer ces problèmes. Idéalement, nous voulons nous séparer en trois zones:
- les données de la logique
- la logique de l'application
- et la logique d'affichage
Nous allons voir comment faire cela:
Nous allons commencer avec le modèle. Nous allons avoir un $post_model
de la classe et de lui donner une méthode appelée get_popular()
. Cette méthode retourne un tableau de postes. En outre, nous allons lui donner un paramètre pour spécifier le nombre de postes à retourner:
post_model.php
class post_model {
public function get_popular($number) {
$sql = "SELECT * FROM posts ORDER BY hits DESC LIMIT $number";
$result = mysql_query($sql);
while($row = mysql_fetch_assoc($result)) {
$array[] = $row;
}
return $array;
}
}
Maintenant pour la page d'accueil, nous avons un contrôleur, nous allons l'appeler "maison". Imaginons que nous avons une url schéma de routage qui appelle de notre contrôleur de la page d'accueil est demandée. C'est le travail est d'obtenir le populaire postes et de les offrir à la vue correcte:
home_controller.php
class home_controller {
$post_model = new post_model();
$popular_posts = $post_model->get_popular(10);
// This is the smarty syntax for assigning data and displaying
// a template. The important concept is that we are handing over the
// array of popular posts to a template file which will use them
// to generate an html page
$smarty->assign('posts', $popular_posts);
$smarty->view('homepage.tpl');
}
Maintenant, nous allons voir ce que la vue ressemblerait à:
homepage.tpl
{include file="header.tpl"}
// This loops through the posts we assigned in the controller
{foreach from='posts' item='post'}
<a href="post.php?id={$post.id}">{$post.title}</a>
{/foreach}
{include file="footer.tpl"}
Maintenant, nous avons les morceaux de base de notre application et vous pouvez voir la séparation des préoccupations.
Le modèle est concerné par l'obtention des données. Il sait à propos de la base de données, il sait à propos de requêtes SQL et de LIMITER les déclarations. Il sait qu'il doit remettre un joli tableau.
Le contrôleur sait au sujet de la demande de l'utilisateur, qu'ils sont à la recherche à la page d'accueil. Il sait que la page d'accueil doit présenter 10 populaire postes. Il récupère les données à partir du modèle et donne à la vue.
La vue sait qu'un tableau de postes devrait être affiché comme une série d'acor balises avec les balises de saut après eux. Il sait qu'un post a un titre et un numéro d'identification. Elle sait que c'est un post du titre devrait être utilisée pour le texte d'ancre et que les postes id doit être utilisé dans le href. Il sait qu'il devrait y avoir un en-tête et pied de page indiqué sur la page.
Il est également important de mentionner que chaque morceau ne pas savoir.
Le modèle ne sait pas que les populaires les messages sont affichés sur la page d'accueil.
Le contrôleur et la vue ne sais pas que les messages sont stockés dans une base de données SQL.
Le contrôleur et le modèle ne savent pas que chaque lien vers un post sur la page d'accueil doit avoir une étiquette de rupture après.
Donc, dans cet état, nous avons établi une claire séparation des préoccupations entre les données de la logique (le modèle), la logique de l'application (le contrôleur), et une logique d'affichage (la vue). Alors maintenant, quoi? Nous avons pris un court, simple bout de code PHP et il s'est brisé en trois confusion des fichiers. Qu'est-ce à nous donner?
Regardons comment le fait d'avoir une séparation des préoccupations qui peuvent nous aider avec les questions mentionnées ci-dessus. Pour rappel, nous voulons:
- Spectacle populaire postes dans un encadré sur les sous-pages
- Mettre en évidence de nouveaux postes avec un supplément de classe css
- Modifier la définition de "populaire post"
Pour afficher le populaire postes dans une barre latérale, nous allons ajouter deux fichiers de notre page:
Une sous-page de contrôleur...
subpage_controller.php
class subpage_controller {
$post_model = new post_model();
$popular_posts = $post_model->get_popular(5);
$smarty->assign('posts', $popular_posts);
$smarty->view('subpage.tpl');
}
...et une sous-page modèle:
subpage.tpl
{include file="header.tpl"}
<div id="sidebar">
{foreach from='posts' item='post'}
<a href="post.php?id={$post.id}">{$post.title}</a>
{/foreach}
</div>
{include file="footer.tpl"}
Le nouveau volet de contrôleur sait que la page doit afficher uniquement les 5 populaire postes. La sous-page afficher sait que les sous-pages, devrait mettre la liste des postes à l'intérieur d'un div sidebar.
Maintenant, sur la page d'accueil, nous voulons mettre en évidence de nouveaux postes. Nous pouvons y arriver en modifiant la page d'accueil.tpl.
{include file="header.tpl"}
{foreach from='posts' item='post'}
{if $post.date_created == $smarty.now}
<a class="new-post" href="post.php?id={$post.id}">{$post.title}</a>
{else}
<a href="post.php?id={$post.id}">{$post.title}</a>
{/if}
{/foreach}
{include file="footer.tpl"}
Ici, la vue s'occupe de toutes les nouvelle logique pour l'affichage populaires postes. Le contrôleur et le modèle n'a pas besoin de savoir quelque chose au sujet de ce changement. C'est purement logique d'affichage. La sous-page de la liste continue de se manifester comme il le faisait avant.
Enfin, nous aimerions changer ce populaire post est. Au lieu d'être basée sur le nombre de visites à une page arrivés, nous aimerions qu'il soit basé sur le nombre de commentaires d'un post a obtenu. Nous pouvons appliquer cette modification sur le modèle:
post_model.php
class post_model {
public function get_popular($number) {
$sql = "SELECT * , COUNT(comments.id) as comment_count
FROM posts
INNER JOIN comments ON comments.post_id = posts.id
ORDER BY comment_count DESC
LIMIT $number";
$result = mysql_query($sql);
while($row = mysql_fetch_assoc($result)) {
$array[] = $row;
}
return $array;
}
}
Nous avons augmenté la complexité de la "populaire post" de la logique. Cependant, une fois que nous avons fait ce changement dans le modèle, à un endroit, la nouvelle logique est appliquée partout. La page d'accueil et la page, n'ayant pas d'autres modifications, affiche désormais populaire postes sur la base des commentaires. Notre concepteur n'a pas besoin d'être impliqué dans ce domaine. Le balisage n'est pas affectée.
Nous espérons que cela vous fournit un exemple éloquent de la façon de séparer les préoccupations des données de la logique, de la logique de l'application, et la logique d'affichage, peuvent rendre le développement de votre application plus facile. Les changements dans un domaine ont tendance à avoir moins d'impact sur les autres zones.
Suite à cette convention n'est pas une solution magique qui va automatiquement votre code parfait. Et vous allez sans doute trouver des problèmes là où il est beaucoup moins claire dans la mesure où la séparation devrait être. En fin de compte, il est tout au sujet de la gestion de la complexité au sein de l'application.
Vous devez donner beaucoup de pensée à la façon dont vous construire vos modèles. Quel genre d'interfaces qu'ils fournissent (voir Grégoire de répondre, en ce qui concerne les contrats)? Ce format de données le contrôleur et la vue s'attendre à travailler avec? En pensant à ces choses à l'avance rendra les choses plus faciles en bas de la route.
Aussi, il peut y avoir une surcharge lors du démarrage d'un projet pour obtenir l'ensemble de ces éléments travaillent ensemble à merveille. Il y a beaucoup de cadres qui fournissent les blocs de construction pour les modèles, les contrôleurs, la création de modèles de moteurs, le routage d'url, et plus encore. Voir de nombreux autres postes sur DONC pour des suggestions sur les frameworks PHP MVC. Ces cadres de vous lever et courir, mais vous en tant que le développeur en charge de la gestion de la complexité et de l'application d'une séparation des préoccupations.
Je vais aussi noter que les extraits de code ci-dessus sont quelques exemples très simplifiés. Ils peuvent (plus probable) ont des bugs. Cependant, ils sont très similaires dans leur structure pour le code que j'utilise dans mes propres projets.