Simple service reposant sur PHP natif. Array superglobal $ _Server info info impitoyable php

Pour commencer, nous améliorerons la page d'enregistrement en ajoutant la possibilité de télécharger Avatar. L'image d'origine doit être un format JPG, GIF ou PNG. Il ne devrait pas aussi être plus de 2 Mo. Ne vous inquiétez pas, après avoir comprimé le script, la taille de l'avatar sera d'environ 3 Ko et le format JPG. Page ouverte reg.php.et ajouter une balise < forme> ligne eNCTYPE \u003d "Multipart / Form-Data"Comme dans l'exemple:


enregistrement










Maintenant sauvegarder reg.php.

2. Catégories Vous devez créer un autre champ dans la table utilisateurs.. Aller à B. phpmyadmin., Choisissez la base de données et la table souhaitées.


Exposez toutes les valeurs comme dans l'image:

Dans ce champ, le chemin sera enregistré avant Avatar et il est enregistré dans un dossier séparé lui-même, appelez-le "Avatars". Le dossier sera situé dans le même répertoire que les autres fichiers de script.

3. Achat au fichier sauvegarder._ utilisateur.. php. et ajoutez le code suivant après avoir supprimé les espaces de la connexion et du mot de passe:

// enlever des lacunes supplémentaires
$ Connexion \u003d garniture ($ login);

// Ajouter un nouveau ******************************************************

// Ajoutez un chèque sur la longueur du login et du mot de passe
Si (SHLEN ($ Connexion)< 3 or strlen($login) > 15) {
La sortie ("Connexion doit être composée d'au moins 3 caractères et pas plus de 15.");
}
Si (SHLEN ($ mot de passe)< 3 or strlen($password) > 15) {
La sortie («Le mot de passe doit être composé d'au moins 3 caractères et pas plus de 15.»);
}

si (! vide ($ _ POST ["FUPLOAD"])) // Vérifiez si l'utilisateur a envoyé une image
{
$ Fupload \u003d $ _ post ["fupload"]; $ Fupload \u003d bordure ($ fupload);
Si ($ fupload \u003d\u003d "" ou vide ($ fupload)) (
Non défini ($ fupload); // si la variable $ fupload est vide, puis supprimez-la
}
}
si (! Isset ($ fupload) ou vide ($ fupload) ou $ fupload \u003d\u003d "")
{
// Si la variable n'existe pas (l'utilisateur n'a pas envoyé l'image), nous l'affectons une image pré-préparée avec l'inscription "Aucun avatar"
$ avatar \u003d "avatars / net-avatara.jpg"; // Vous pouvez dessiner net-avatara.jpg ou prendre la source
}
aUTRE.
{
// sinon - Téléchargez l'image utilisateur
$ path_to_90_directory \u003d "avatars /"; // dossier, où la photo initiale et sa copie compressée seront chargées

Si (Preg_Match ("/ [.] (JPG) | (JPG) | (GIF) | (GIF) | (PNG) | (PNG) $ /", $ _ Fichiers ["Fupload"] ["Nom"] ) // Vérification du format de l'image d'origine
{
$ nom de fichier \u003d $ _files ["fupload"] ["nom"];
$ source \u003d $ _files ["Fupload"] ["Noms TMP_NAME"];
$ cible \u003d $ path_to_90_directory. $ Nom de fichier;
Move_Uploaded_file ($ source, $ cible); // Téléchargez l'original dans le dossier $ PATH_TO_90_DIRECTORY
Si (Preg_Match ("/ [.] (GIF) | (GIF) $ /", nom de fichier $)) (
$ im \u003d imagecreatefromgif ($ path_to_90_directory. $ nom de fichier); // Si l'original était au format GIF, créez une image dans le même format. Besoin de compression ultérieure
}
Si (Preg_Match ("/ [.] (PNG) | (PNG) $ /", Nom de fichier $)) (
$ im \u003d imagecreatefrompng ($ path_to_90_directory. $ nom de fichier); // si l'original était au format PNG, créez une image dans le même format. Besoin de compression ultérieure
}

Si (Preg_Match ("/ [.] (JPG) | (JPG) | (JPEG) | (JPEG) $ /", Nom de fichier $)) (
$ im \u003d imagecreatefromjpeg ($ path_to_90_directory. $ nom de fichier); // Si l'original était au format JPG, créez une image dans le même format. Besoin de compression ultérieure
}
// Création d'une image carrée et de sa compression ultérieure prise du site www.codenet.ru
// Création d'un carré 90x90
// Dest - Résultat image
// w - largeur de l'image
// ratio - coefficient de proportionnalité
$ w \u003d 90; // carré 90x90. Vous pouvez mettre une autre taille.
// Créer une image source basée sur
// fichier source et déterminer ses dimensions
$ w_src \u003d imagesx ($ im); // calculer la largeur
$ h_src \u003d impacty ($ im); // calculer la hauteur de l'image
// Créer une image carrée vide
// c'est vrai que Truecolor! Sinon, nous aurons un résultat 8 bits
$ Devt \u003d imagecreateusolor ($ w, $ w);
// couper le milieu carré de x, si la photo est horizontale
Si ($ w_src\u003e $ h_src)
Imagecopyresamplé ($ devt, $ im, 0, 0,
Rond (maximum ($ w_src, $ h_src) -min ($ w_src, $ h_src)) / 2),
0, $ w, $ w, min ($ w_src, $ h_src), min ($ w_src, $ h_src));
// couper le dessus carré de y,
// Si la photo est verticale (bien que vous puissiez aussi un milieu)
Si ($ w_src<$h_src)
imagecyresamplé ($ devt, $ im, 0, 0, 0, 0, $ w, $ w,
min ($ w_src, $ h_src), min ($ w_src, $ h_src));
// image carrée à l'échelle sans coupure
Si ($ w_src \u003d\u003d $ h_src)
Imagecopyresamplé ($ devt, $ im, 0, 0, 0, 0, $ w, $ w, $ w_src, $ w_src);
Date de $ \u003d heure (); // Calculez le temps pour le moment.
imagejpeg ($ devt, $ path_to_90_directory. $ DATE. ". JPG"); // Enregistrez l'image du format JPG dans le dossier souhaité, le nom sera l'heure actuelle. Fait pour que les avatars n'ont pas de noms identiques.
// Pourquoi exactement jpg? Il faut très peu d'espace + détruire l'animation de l'image GIF qui distraite l'utilisateur. Il n'est pas très agréable de lire son commentaire lorsque le bord des yeux remarque un mouvement.
$ avatar \u003d $ path_to_90_directory. $ DATE. ". JPG"; // Nous entrons dans la variable du chemin d'avatar.
$ Delfulll \u003d $ path_to_90_directory. $ Nom de fichier;
Dislink ($ Delfull); // Supprimez l'original de l'image téléchargée, il n'est plus nécessaire. La tâche consistait à obtenir une miniature.
}
AUTRE.
{
// en cas d'incohérence du format, nous émettons le message approprié
Quitter («Avatar doit être au format Jpg, gif ou png");
}
// fin du processus de téléchargement et mission $ AVATAR Variable Adresse téléchargée Ava
}



// a terminé un nouveau ******************************************************
// Suivant vient de la première partie de l'article, mais il est nécessaire d'ajouter une modification à la demande à la base de données.
// Connexion à la base de données
// Vérifiez l'existence d'un utilisateur avec le même identifiant
$ résultat \u003d mysql_query ("Sélectionnez l'identifiant des utilisateurs où login \u003d" $ Connexion "", $ dB);
Si (! Vide ($ myrow ["id"])) (
Quitter ("Désolé, le login entré déjà enregistré. Entrez un autre identifiant.");
}
// sinon, nous enregistrons les données
$ résultat2 \u003d mysql_query ("insérer dans les utilisateurs (connexion, mot de passe, mot de passe, avatar) (" $ login "," $ mot de passe "," $ avatar ")");
// Vérifiez s'il y a des erreurs
Si ($ résultat2 \u003d\u003d "vrai")
{
Echo "Vous êtes inscrit avec succès! Vous pouvez maintenant aller sur le site. Page d'accueil";
}
aUTRE (
Echo "erreur! Vous n'êtes pas enregistré.";
}
?>

4. Vous devez ajouter une table à la même base de données. Il stockera les adresses IP qui permettront des erreurs à l'entrée. Ainsi, nous pouvons limiter l'accès à ceux qui se trompent plus de trois fois de suite pendant environ 15 minutes. Je pense que les programmes de mot de passe devront gêner longtemps pendant une longue période.
Allons à PhpMyAdmin et créons une nouvelle table avec 3 champs:


IP - Adresse IP.
date - Date d'une entrée infructueuse pour les 15 dernières minutes par l'utilisateur avec des données IP. Col - Le nombre d'erreurs au cours des 15 dernières minutes par l'utilisateur avec des données IP.
Excellent! Prêt, maintenant Modifiez le fichier de vérification de la connexion et du mot de passe, car nous avons maintenant un mot de passe crypté. Ouvrez testreg.php et supprimez tout ce qui supprime d'autres espaces de la connexion et du mot de passe. Ensuite, ajoutez le code suivant:

// enlever des lacunes supplémentaires
$ Connexion \u003d garniture ($ login);
$ mot de passe \u003d garniture ($ mot de passe);

// Remplacez le nouveau ******************************************************
// Connexion à la base de données
inclure ("bd.php"); // fichier bd.php doit être dans le même dossier que tout le monde, sinon, change simplement la voie
// minippvertet pour la sélection de mot de passe
$ IP \u003d getenv ("http_x_forwarded_for");
si (vide ($ ip) || $ ip \u003d\u003d "inconnu") ($ IP \u003d getenv ("Remote_addr");) // Supprimer IP
mysql_query ("Supprimer de oshibka où UNIX_TIMESTAMP () - UNIX_TIMESTAMP (DATE)\u003e 900"); // Supprimez les adresses IP du ombre à l'entrée des utilisateurs après 15 minutes.
$ Résultat \u003d mysql_query ("Sélectionnez Col à partir d'Oshibka où IP \u003d" $ IP "", $ dB); // Supprimez le nombre de tentatives d'entrée infructueuses pour les 15 derniers de l'utilisateur avec les données IP de la base de données
$ myrow \u003d mysql_fetch_array ($ Résultat);
si ($ myrow ["col"]\u003e 2) (
// Si les erreurs sont plus de deux, c'est-à-dire trois, puis émettent un message.
Quitter («Vous avez marqué un identifiant ou un mot de passe incorrectement 3 fois. Attendez 15 minutes jusqu'à la prochaine tentative.");
}
$ mot de passe \u003d md5 ($ mot de passe); // chiffrer le mot de passe
$ mot de passe \u003d strIV ($ mot de passe); // pour la fiabilité Ajouter un inverse
$ mot de passe \u003d $ mot de passe. "B3P6F";
// Vous pouvez ajouter quelques-uns de vos personnages au goût, par exemple, je suis entré "B3P6F". Si ce mot de passe sera sélectionné par la sélection par le serveur sur le serveur du même MD5, alors clairement rien de bon résultera. Mais je vous conseille de mettre d'autres personnages, vous pouvez au début de la ligne ou au milieu.
// Dans ce cas, il est nécessaire d'augmenter la longueur du champ de mot de passe de la base de données. Le mot de passe crypté peut être beaucoup plus grand.

$ résultat \u003d mysql_query ("Select * à partir des utilisateurs où login \u003d" $ Connexion "et mot de passe \u003d" $ mot de passe "", $ dB); // Supprimer de la base de données Toutes les données utilisateur avec le login saisi et le mot de passe
$ myrow \u003d mysql_fetch_array ($ Résultat);
Si (vide ($ myrow [id "])))
{
// Si l'utilisateur avec le login et le mot de passe n'existent pas
// Faire une entrée selon laquelle cette adresse IP n'a pas pu entrer.
$ SELECT \u003d MYSQL_QUERY ("Sélectionnez IP d'Oshibka où IP \u003d" $ IP "");
$ TMP \u003d mysql_fetch_row ($ Select);
Si ($ IP \u003d\u003d $ TMP) (// chèque, existe-t-il un utilisateur dans la table "Oshibka"
$ résultat52 \u003d mysql_query ("Sélectionnez Col d'Oshibka où IP \u003d" $ IP "", $ dB);
$ Myrow52 \u003d mysql_fetch_array ($ résultat52);
$ col \u003d $ myrow52 + 1; // Ajouter une autre tentative d'entrée infructueuse
Mysql_query ("mise à jour oshibka set col \u003d $ col, date \u003d () où ip \u003d" $ ip ");
}
aUTRE (
Mysql_query ("insérer dans les valeurs d'Oshibka (IP, Date, Col) (" $ IP ", maintenant ()," 1 ")");
// s'il n'y avait pas d'erreur au cours des 15 dernières minutes, insérez une nouvelle entrée à la table "Oshibka"
}

quitter ("Désolé, le login ou le mot de passe saisi par vous.");
}
AUTRE (
nbsp; // Si les mots de passe correspondent, nous commençons la session de l'utilisateur! Vous pouvez le féliciter, il est entré!
$ _Session ["mot de passe"] \u003d $ myrow ["mot de passe"];
$ _Session ["login"] \u003d $ myrow ["login"];
$ _Session ["id"] \u003d $ myrow ["id"]; // Ces données sont très souvent utilisées, elles "porteront avec vous" incluse

// Ensuite, nous nous souvenons des données des cookies, pour l'entrée ultérieure.
//ATTENTION!!! Faites ceci à votre discrétion, car les données sont stockées dans des cookies sans cryptage.
Si ($ _Post ["Enregistrer"] \u003d\u003d 1) (
// Si l'utilisateur souhaite que ses données soient conservées pour une entrée ultérieure, nous gardons dans les cookies de son navigateur
Setcookie ("Connexion", $ _Post ["Login"], Time () + 9999999);
setcookie ("mot de passe", $ _post ["mot de passe"], heure () + 9999999);
}}
Écho " "; // redirige l'utilisateur à la page principale, il n'informera pas l'entrée réussie
?>

5. Changez complètement la page principale. Il est nécessaire d'afficher l'avatar de l'utilisateur dessus, d'afficher un lien pour sortir à partir du compte et d'ajouter une case à cocher pour mémoriser le mot de passe à l'entrée.
Index.php.

// La procédure entière fonctionne aux sessions. Il en est que les données utilisateur sont stockées lorsqu'elles sont sur le site. Il est très important de les lancer au tout début de la page !!!
session_start ();
inclure ("bd.php"); // fichier bd.php doit être dans le même dossier que tout le monde, sinon, change simplement la voie
si (! vide ($ _ session ["login]]) et! vide ($ _ session [" mot de passe]))
{
// S'il existe un identifiant et un mot de passe dans des sessions, vérifiez-les et supprimez l'avatar.
$ Connexion \u003d $ _Session ["Login"];
$ mot de passe \u003d $ _session ["mot de passe"];
$ résultat \u003d mysql_query ("Sélectionnez ID, Avatar à partir d'utilisateurs où login \u003d" $ Connexion "et mot de passe \u003d" $ mot de passe "", $ dB);
$ myrow \u003d mysql_fetch_array ($ Résultat);
// retirez les données utilisateur nécessaires
}
?>


Page d'accueil


Page d'accueil

Si (! Isset ($ myrow ["avatar"]) ou $ myRow ["Avatar"] \u003d\u003d "") (
// Vérifiez si les données utilisateur de la base de données ne sont pas récupérées. Sinon, il n'est pas entré, ni le mot de passe de la session est incorrect. Nous affichons la fenêtre de connexion. Mais nous ne la retirerons pas pour ceux qui sont entrés, ce n'est plus nécessaire pour eux.
Imprimer<<


Ici;

Si (Isset ($ _ cookie ["Connexion"])) // existe une variable avec une connexion dans le cookie. Il devrait être si l'utilisateur à l'entrée précédente a cliqué sur Chekbox "Souviens-toi de moi"
{
// Si oui, insérez la valeur dans le formulaire. Dans le même temps, l'utilisateur est affiché que son identifiant est déjà inscrit dans le graphique souhaité.
Echo "valeur \u003d". $ _ Cookie ["login"]. ""\u003e ";
}

imprimer<<




Ici;

Si (Isset ($ _ cookie ["mot de passe"])) // existe une variable avec un mot de passe dans le cookie. Il devrait être si l'utilisateur à l'entrée précédente a cliqué sur Chekbox "Souviens-toi de moi"
{
// Si oui, insérez la valeur dans le formulaire. Dans le même temps, l'utilisateur est affiché que son mot de passe est déjà inscrit dans le graphique souhaité.
Echo "valeur \u003d". "$ _ Cookie [" mot de passe "]." "\u003e";
}

Imprimer<<



Souviens-toi de moi.






S'inscrire



Vous êtes entré dans le site comme invité

Ici;
}
aUTRE.
{
// Avec une bonne entrée, l'utilisateur est émis tout ce qui est situé ci-dessous comme des étoiles.

imprimer<<
Vous avez entré le site sous forme de $ _session (sortie)


Ce lien n'est disponible qu'aux utilisateurs enregistrés.

Votre avatar:




Ici;

//************************************************************************************
// Avec une bonne entrée, l'utilisateur est émis tout ce qui est situé au-dessus d'un astérisque.
}
?>



6. Il est nécessaire d'avoir la possibilité de quitter les comptes aux utilisateurs qui sont entrés. Sur la page principale déjà, il y avait une référence à la sortie. Mais ce fichier n'existe pas encore. Donc créer un nouveau fichier sortie.php. Avec code:

session_start ();
Si (vide ($ _ session ["login]]) ou vide ($ _ session [" mot de passe "]))
{
// S'il n'y a pas de session avec un identifiant et un mot de passe, cela signifie que l'utilisateur impellent est venu dans ce fichier. Ce n'est pas un endroit ici. Nous donnons un message d'erreur, arrêtons le script
Quitter («L'accès à cette page est autorisé uniquement aux utilisateurs enregistrés. Si vous êtes inscrit, puis connectez-vous sur le site sous votre identifiant et votre mot de passe
Page d'accueil ");
}

nonset ($ _ session ["mot de passe"]);
Nonset ($ _ session ["login"]);
Non défini ($ _ session ["ID"]); // Détruisez les variables en sessions
Sortir (" ");
// Envoie un utilisateur à la page principale.
?>

C'est ça! Utiliser sur la santé! Bonne chance!

Parfois, je veux distraire de la routine actuelle de codage et de petits problèmes que l'endroit est destiné aux articles sur les "détails". Regarder autour de ce que vous faites pendant longtemps. Donc, ma vision des approches de la tâche principale de programmation PHP est de générer des pages Web. Partiellement, le sujet que j'ai déjà été affecté par des pièces - des articles sur la classe de modèles et sur XML que vous pouvez trouver dans les archives. Maintenant, je voudrais réduire tout cela ensemble et faire quelque chose de monumental. Première partie.

1. Les origines de PHP.

Pourquoi, effectivement commencé PHP pour la plupart d'entre nous? À partir des insertions de script dans les pages HTML. Par exemple, propre catalogue de référence. Page avec référence à partir d'une catégorie spécifique:

". mysql_result ($ résultat, 0)"."; mysql_free_result ($ résultat); $ résultat \u003d mysql_query (" Sélectionnez l'ID, le titre, le ratio, la description, Site_Date de site où Rubrika \u003d ". Intval ($ ID)." Commande par ratio desc, site_date Desc, titres "); Si (mysql_error ()) echo mysql_error (); sinon alors que ($ rang \u003d mysql_fetch_assoc ($ résultat)) echo " ($ ligne)
($ ligne)
Enregistré: ($ ligne), note: ($ rangée)

Juste et simple, mais la principale chose est que ce code fonctionne. Les difficultés commencent si vous essayez d'écrire le nom de l'en-tête de la page de titre. Pour ce faire, vous devez créer une insertion PHP à l'intérieur de la balise. , Transférez le code qui effectue la première demande (échantillonnage du nom de la position), enregistrez le résultat de la demande à la variable, qui est ensuite affichée dans le corps de la page.</p> <p>La complication suivante est une tentative de travailler avec des cookies et de les émettre en fonction de laquelle l'utilisateur est visité. Pour mieux imaginer ceci: laissez-nous décider que les foules de visiteurs iront à notre homologue et pour les annonceurs potentiels, nous faisons un moteur de bannière avec ciblage. Par exemple, l'utilisateur qui a visité les rubriques de Rock Music and Musical Instruments, à la page suivante Il y aura une bannière avec une publicité d'un magasin d'entraînement électrique.</p> <p>Dans ce cas, nous devrons effectuer l'insertion du code PHP au tout début du fichier et passer là pour vérifier la présence de la position, car les cookies ne peuvent être émis que avant de délivrer le premier octet du document.</p> <p><i>Bien sûr, vous direz que cela peut être facilement effectué à l'aide du mécanisme de session utilisateur, ce qui est plus facile du point de vue du contenu du contenu et plus sûr, car l'utilisateur peut modifier manuellement le contenu de la cuisinière. Oui, c'est vrai, mais d'abord, une vision de la programmation de programmation qui rend leur page d'accueil est présentée ici et, d'autre part, nous parlons d'un passé lointain - nous sommes pratiquement nous sommes en 1998.</i></p> <p>Il ne facilite pas grandement la vie et la sortie des mêmes blocs de code HTML et PHP dans des fichiers plug-in. La tâche décrite ci-dessus consiste à créer un catalogue de référence simple avec des en-têtes - peut-être la limite supérieure des capacités de cette approche. Lorsque vous effectuez des tâches plus complexes, le risque de collision avec de grandes coûts de main-d'œuvre.</p> <p>2. Complication du code</p> <p>Le développement logique de l'approche précédente est une transition complète vers PHP dans le sens où toutes les pages sont du code PHP - au début du fichier, c'est l'étiquette d'ouverture "<?php", и дальше php-код не прерывается. Весь вывод делается через echo (print). Такой код, вроде бы, выглядит логичнее. Пример: страница подписки на новые ссылки в каталоге. В форме предлагается выбрать, на какие рубрики подписывается пользователь.</p><p> <?php include "db-connect.inc"; include "login-check.inc"; if (!$logged_in) { header ("Location: /register.php"); exit(); } include "page-header.inc"; print("<h2> Classe \u003d "club_article_small_caption"\u003e Actualités pour les clients</h2> <table cellpadding=\"4\" cellspacing=\"0\" border=\"0\">"); $ résultat \u003d mysql_query (" Sélectionnez ID, Titre, Annoncer, News_Date à partir de la commande de nouvelles par News_Date Desc Limite 10 "); Si (mysql_error ()) Imprimer (mySQL_Error ()); Sinon tandis que ($ rang \u003d mysql_fetch_assoc ($ Résultat)) Imprimer (" <tr><td>($ rangée) "); si ($ ligne [" News_Date "]\u003e Date (" Y-M-D ", Time () - 3600 * 24 * 14)) Imprimer (" <font color=\"#cc0000\">nOUVEAU!</font>"); Imprimer ("</td><td> <a href=\"read.php?id={$row}\"><b>($ ligne)</b></a> <br>($ ligne)</td></tr>"); Imprimer ("</table>"); inclure" page-footer.inc ";?\u003e</p><p> <?php ... else while ($row = mysql_fetch_assoc($result)) print_announce($row); ... ?> </p><p>Mais cela ne simplifie pas facilement le travail et l'heure de récupération sera nécessairement: il sera nécessaire de refaire la conception du site. Le designer Modifier cela va simplement refuser. Seuls celui qui a écrit un tel code sera capable de le comprendre et de remplacer l'ancien HTML à un nouveau. Si cette personne ne travaille plus sur le projet, le projet devra réécrire presque à partir de zéro ou qu'il mourra, se transformant en monument à la manifestation humaine.</p> <p>Une autre option pour développer une approche mixte HTML et PHP. PHP a une telle propriété comme évasion avancée. Il permet aux structures linguistiques intérieures de produire le code HTML habituel:</p><p> <?php include "db-connect.inc"; include "login-check.inc"; if (!$logged_in) { header ("Location: /register.php"); exit(); } include "page-header.inc"; ?><h2 class="club_article_small_caption">Nouvelles pour les clients</h2> <table cellpadding="4" cellspacing="0" border="0"><?php $result = mysql_query("SELECT id, title, announce, news_date FROM news ORDER BY news_date DESC LIMIT 10"); if (mysql_error()) print(mysql_error()); else while ($row = mysql_fetch_assoc($result)) { ?><tr><td><?=$row["news_date"]?><?php if ($row["news_date"] > Date ("y-m-d", heure () - 3600 * 24 * 14)) (?\u003e <font color="#cc0000">nOUVEAU!</font><?php } ?></td><td> "> <b><?=$row["title"]?></b> <br><?=$row["announce"]?></td></tr><?php } ?></table><p>La jauge ou le concepteur, ouvrant ce fichier dans le foyer, verra le balisage HTML avec un rétroéclairage et peut être modifié pour éditer des pages. Dans des sites simples, cette méthode convient parfaitement. Dans difficile - pas pour l'enfer ne convient pas.</p> <p>3. inversion</p> <p>Avec la sortie de PHP 3.0 ... Au fait, cela ne ferait pas mal de restaurer la chronologie, car nous parlons d'une histoire complète. Donc, la chronologie a réussi à restaurer à l'aide de l'archive PHP Annoncez-vous et la page de l'archive Web:</p><p>08.1997 PHP 3.0 BETA1 06.06.1998 PHP 3.0 Version 19.07.1999 PHP 4.0 BETA1 22.05.2000 PHP 4.0 version 10.12.2001 PHP 4.1 Release 04/20/2002 PHP 4.2 Release 10.10.2002 PHP 4.3.0PRE1 (Pre1 n'est pas bêta, mais toujours pas libérer le candidat)</p><p>Ainsi, avec la sortie de PHP 3.0, une boîte à outils semblait appliquer une nouvelle approche dans la programmation PHP - Pages tamponneuses de scripts dans les scripts. (Il est important de noter que ce n'est pas le mauvais tampon qui est maintenant.)</p> <p>Au fil du temps, les tâches des chantiers de construction sont devenues plus compliquées, PHP a été utilisé plus large, les sites sont devenus toutes "dynamiques". Plus le site, la problématique de tout faire sur les fichiers plug-in dans la php mixte et HTML. Il est assez logique à la prochaine étape de l'étape d'extension PHP dans le traitement d'une page HTML dans la mémoire du script et en l'émettant à l'utilisateur entièrement ou en pièces.</p> <p>Mettre en œuvre des données L'approche a aidé le soutien à l'aide (bien, ok, émulation) programmation orientée objet. Ont été créés <i>modèles de classes</i>qui permettait d'utiliser facilement la page et le modèle de données qui doivent être apportés.</p> <p>Il a élargi les capacités des programmes, mais nécessite en même temps plus de ressources système. Aujourd'hui, nous pouvons dire que les avantages de l'utilisation d'une telle approche ont bloqué les coûts des ressources système, mais il y a deux ou trois ans, de nombreuses personnes ont estimé que la conservation de l'ensemble du document en mémoire - une non-handicap pour la programmation Web.</p> <p>Ainsi, à la figurité, il y avait un coup d'État dans la technologie: si vous avez déjà caché PHP dans le code HTML et ajouté timidement ses informations, il est désormais sorti en premier lieu et conserve tout HTML dans ses pattes.</p> <p>4. Quels sont les mauvais modèles de modèles</p> <p>Six mois plus tard, j'ai décidé de changer quelque chose dans les plans. La moralisation sur le sujet de la méchanceté des classes de légitime défense ne sera pas. Ils sont bons. Utilisez-les et viendra avec vous ce dont vous avez besoin! Considérez simplement que vous interférerez avec certaines circonstances.</p> <p>D'abord. Si la classe a été écrite spécifiquement, cela signifie qu'il est quelque peu déchiré de la vie. Laissez la classe coûter beaucoup d'expérience en développement, il a toujours été fait dans des conditions de serre. La technologie résultante aura ses propres conditions d'utilisation, qui devront personnaliser le développement futur, ou refaire la classe.</p> <p>Deuxième. La classe, qui est synthétisée à partir des développements de différents projets, nécessite également des changements - le goupille que celui qu'il en soit.</p> <p>Ainsi, vous pouvez faire vos propres cours (classes de modèles, autant que je sache, beaucoup utilisent leur propre). Si vous allez une méthode déductive, la construction d'une classe de l'évaluation de ce qui sera nécessaire est une petite chance que quelque chose soit ingénieux soit possible. Et la probabilité élevée qu'il s'avère pas exactement ce qui est nécessaire. Vous pouvez appliquer une induction - puis après un grand et long travail que vous êtes garanti pour obtenir ce qui fonctionne, mais pas nécessairement ingénieux.</p> <p>La méchanceté de la maison, que j'ai mentionnée dans les parties précédentes réside dans le premier cas de très forte probabilité de l'avoir chuté, ne travaillant pas comme vous avez rêvé, nécessitant une approche spéciale et beaucoup de codage. Dans le second cas, vous pouvez travailler dur pendant longtemps et obtenir ce qui a déjà été fait et publié devant vous.</p> <p>Quant à la comparaison des technologies, la principale question concerne la pertinence. Le site très simple peut être effectué sur des fichiers plug-in et ne pense pas aux classes et aux moteurs. Le site est plus confortable à faire dans les modèles. Si la complexité augmente et que beaucoup de conditions différentes sur la même page - le menu de navigation en fonction du statut, etc. - Il vaut mieux penser au paquet XML & XSLT.</p> <p>Exemple: forum phpBB. En cela, il est impossible de changer complètement la conception, comme vous le souhaitez, car de nombreux éléments de conception ne sont pas dans des modèles, mais dans le code PHP. Toutes sortes de formulaires d'entrée, menu de gestion de l'utilisateur inclus de l'utilisateur, etc. - Insérez dans la page via le code PHP et non comme un motif joint. La solution populaire n'est pas toujours la meilleure.</p> <p>Dmitry Koters commente l'expérience d'étudier phpBB: j'ai écrit une classe de modèle, beaucoup, étant pleine d'enthousiasme, commencez à tout pousser pour cette classe. L'idée de cette classe est de diviser le code et la conception, mais les auteurs de phpBB au contraire les mélangèrent autant que possible.</p> <p>Mais à mon avis, même avec la mise en œuvre normale de cette approche (classe de modèles), le code s'avérerait volumineux, les fichiers avec des modèles seraient beaucoup. Récemment, je suis à la conclusion que dans les classes de classe, en principe, il n'est pas possible de séparer le code PHP des données et des conceptions. Avec le changement de conception du site sur ce moteur, il sera nécessaire de creuser dans des scripts PHP, et ce ne sera pas de concepteur, mais vous.</p><p> <table border> <tr> <td colspan=2> <b>__Global__</b> <p> (Caché et ajouté automatiquement)</td> </tr> <tr> <td><b>bloc1</b></td> <td> <table border> <tr> <td colspan=2><b>bloc2.</b></td> </tr> <tr> <td><b>inner1.</b></td> <td><b>inner2.</b></td> </tr> </table> </td> </tr> </table> </p><p>La documentation indique qu'il n'est pas nécessaire de spécifier dans le modèle, quel bloc est une filiale à partir de laquelle. Classe il comprendra.</p> <p>Dans la documentation de cette classe, il est écrit qu'il sait que INTER1 est une filiale pour le bloc de bloc2, et il n'est pas nécessaire de l'informer de cela. Pour insérer des données dans le bloc, il suffit d'exécuter un tel code autant de fois que les lignes ont besoin:</p><p> <?php $tpl->setVariable (...); $ TPL-\u003e parsecurrentBlock (); ?\u003e</p><p>Pour faire du contenu en bloc1, vous devez effectuer ceci:</p><p> <?php $tpl->sETCURRENTBLOCK ("INTERN1"); $ TPL-\u003e SetVariable (...); $ TPL-\u003e parsecurrentBlock (); $ TPL-\u003e SetVariable (...); $ TPL-\u003e parsecurrentBlock (); $ Tpl-\u003e parse ("block1"); ?\u003e</p><p>En conséquence, le code de script ressemble à ceci:</p><p> <?php $tpl = new HTML_Template_IT(); // загрузка шаблона или указание его через класс $tpl->lOADTEMPLATEFILE (Nom de fichier String [, Boolean ReleduitsunknownVariables, Boolean Reimentsblocks]) // Définissez les variables «globales», c'est-à-dire variables qui ne sont pas incluses dans le bloc (unité enfant) $ TPL-\u003e SETVARIABLE (chaîne variable, valeur mixte); // Une autre façon de spécifier des variables - via un tableau de $ TPL-\u003e SetVariable (tableau (chaîne varname \u003d\u003e valeur mixte)); // nous utiliserons un peu de bloc, même profondément investi dans un autre $ TPL-\u003e SetCurrentRentBlockBlock (String BlockName); // on répète autant que $ TPL-\u003e SetVariable (tableau (chaîne varname \u003d\u003e valeur mixte)); $ TPL-\u003e parsecurrentBlock (); // obtenir le résultat ou l'imprimer causant $ TPL-\u003e spectacle () $ TPL-\u003e get (); ?\u003e</p><p>Le code est plus pratique et plus clair qu'avec FastTemplate.</p> <p>Mais de nombreux programmeurs écrivent toujours leurs propres classes de modèles. Plus simple, mais avoir des fonctions qui ne sont pas disponibles dans les classes disponibles publiquement. J'ai écrit ma propre classe dans laquelle j'ai fabriqué des blocs dans lesquels les résultats des requêtes SQL ont été automatiquement insérés, le capuchon et la queue du bloc ont été inclus dans les additifs (par exemple, des balises <table> et</table>), qui est apparu comme un résultat que s'il y avait des lignes dans la demande SQL.</p> <p>Le module de fonctions de traitement XML est apparu dans PHP3. En utilisant les fonctions de ce module, vous pouvez créer vos propres gestionnaires de code XML, mais il est toutefois impossible de vérifier l'exactitude du document XML.</p> <p><i>Une petite excursion à la théorie sur ce que XML est et pourquoi il est nécessaire.</i></p> <p><i>XML est un moyen d'écrire des données structurées. Sous les "données structurées" impliquent généralement des éléments tels que des feuilles de calcul, des livres d'adresses, des paramètres de configuration, des transactions financières, des dessins techniques, etc. XML est un ensemble de règles (vous pouvez également les considérer comme des instructions ou des accords) pour développer des formats de texte qui vous permettront de structurer vos données.</i></p> <p>Explication de quelle structure est.</p><p> <eshop> <!-- категории товаров --> <category id="3"> <title>Produits carnés Un poisson kilogramme 100 Viande kilogramme 200 Production de déchets Poisson icra kilogramme 10 Produits végétaux Tournesol chose 50

Donc, en XML, vous pouvez écrire les données structurées sur le magasin d'aliments, dans laquelle les marchandises sont divisées en catégories et que les catégories peuvent être subordonnées les unes aux autres. Bien entendu, ces données peuvent être enregistrées différemment, par exemple, texte avec des onglets comme séparateurs et indiquant l'ID de la catégorie mère (à la manière, lors de la rédaction de données au format XML, il n'est pas nécessaire de la spécifier). XML est un format prêt à écrire pour écrire une telle structure, dans laquelle vous ne restez que d'inventer les noms des nœuds (balises) et les règles dans lesquelles la structure doit être déposée (par exemple, que les marchandises ne peuvent pas être situées hors de la catégorie ou que les niveaux de catégorie peuvent ne pas être plus trois). Plus loin:

XML n'est pas un langage de programmation et vous n'avez pas besoin d'être programmeur pour l'utiliser ou l'explorer. XML facilite l'ordinateur à la tâche de créer et de lire des données, tout en garantissant le caractère unique de leur structure. XML évite les erreurs de conception des langues ordinaires: elle est en expansion, indépendante de la plate-forme, comprend le soutien à l'internationalisation et à la localisation. XML est entièrement compatible avec Unicode.

Les développeurs PHP offrent des éléments de document XML individuels avec des fonctions PHP. Exemple de PHP Guide:

"B", "emphasre" \u003d\u003e "I", "littéral" \u003d\u003e "TT"); // Fonction pour le début de la balise (il peut émettre du texte complexe, mais dans cet exemple, il utilise // juste la balise correspondante). Fonction StartElement ($ analyseur, Nom $, $ attrsses) (GLOBAL $ MAP_ARRAY; IF ($ HTMLTAG \u003d $ map_array [$ nom]) (Imprimer<$htmltag>";)) // fonction pour la fin de la fonction de balise endelement ($ analyseur, nom $) (GLOBAL $ MAP_ARRAY; si ($ htmltag \u003d $ map_array [$ nom]) (Imprimer")";)) // Fonction pour le texte (noeud de texte) CaractérislocéryData ($ Parser, $ données) (Imprimer $ données;) $ xml_parser \u003d xml_parser \u003d xml_parser_create (); // Utiliser le pliage de cas afin de trouver la balise dans $ map_array xml_parser_set_option ($ xml_parser, xml_option_case_folding, true); xml_set_element_handler ($ xml_parser, "startelement", "endélément"); xml_set_character_data_handler ($ xml_parser, "lisant x ($ Dossier, "r"))) (Die ("Impossible d'ouvrir une entrée XML");) tandis que ($ Data \u003d Fread ($ FP, 4096)) (si (! Xml_parser ($ xml_parser, $ données, Feof ( $ PF)))) (DIE (Sprintf (Sprintf ("Erreur XML:% s à la ligne% D", xml_error_string (xml_get_ror_code ($ xml_parser)), xml_get_current_line_number ($ xml_parser)));));));));));));)

Cet exemple peut être élargi en ajoutant un tableau de noms de balises qui seront traités d'une manière différente et les conditions correspondantes dans la fonction de démarrage et d'endélation.

Le code est juste affreux. Pour une utilisation dans la conversion XML dans les pages HTML, il est presque inapproprié, bien que, dans certains endroits utilisés, par exemple, sur la façon dont cela fonctionne. Bien sûr, vous pouvez écrire vos propres automatistionneurs qui liraient des fichiers de configuration et des tableaux créés, mais dans des coûts de travail totaux, il est plus rentable d'utiliser de puissants modèles de modèles tels que Smarty.

Les travaux sur ce projet ont commencé en 1999, lorsque l'équipe de développeurs a commencé à écrire la spécification du modèle de modèles. Après avoir défini ce qu'il devrait faire, les développeurs ont essayé d'écrire un module sur C, mais à la fin, ils décidaient qu'il était préférable de faire une classe sur PHP, abordable et compréhensible pour tous les développeurs de sites.

Maintenant Smarty est l'un des projets PHP, son site Web est situé sur le serveur PHP de Smarty.PL.NET.

Classe de modèle officiellement Smarty - En fait, sa fonctionnalité est une commande de grandeur supérieure à celle du modèle SET *.

Premièrement, Smarty produit non seulement l'insertion de variables dans le gabarit, mais effectue également le code PHP dans le modèle lui-même. Deuxièmement, les modèles de Smarty sont convertis en scripts PHP et tous les travaux sales sur l'insertion de variables en texte et l'exécution de structures logiques donne la part de PHP en PHP. Ces scripts PHP lorsque la mise en cache est activée sont stockées dans des fichiers appelés lors des appels suivants aux modèles. Lorsque les motifs changent, les scripts sont générés à nouveau. Une telle mise en cache accélère considérablement le travail des scripts.

De plus, Smarty peut traiter les conceptions logiques IF-sinon intégrées aux modèles, la convertissant en code PHP. De même, les structures appelées modificateurs variables sont traitées. Ils vous permettent de supprimer certaines fonctions du script principal, transférées dans le modèle et de leurs scripts PHP en cache.

(* Écrivez le titre avec des lettres majuscules *)

($ Titre | Tige),

(* Réduisez le sommet à 40 caractères, mettre ... au bout *) Sujet: (Topic $ | Trondate: 40: "...")

Ce texte est converti en un tel code:

_Run_mod_handler ("supérieure", vrai, $ ceci -\u003e _ tpl_vars ["nom"]); ?\u003e Sujet:_Run_mod_handler ("tronquer", vrai, $ ceci -\u003e _ tpl_vars ["nom"], 40, "..."); ?\u003e.

Un ensemble de variables intégrées telles que $ Smarty.now (heure actuelle) est disponible. L'image idéilique complète la sortie de la fenêtre de débogage contenant les valeurs des variables, appelez les modèles imbriqués, prennent en charge les filtres d'E / S personnalisés et les plug-ins.

Tout irait bien, soyez plus intelligent de taille. Maintenant (version 2.3.1) "Pese" 144 kilo-octets et sur AMD K6 266 MHz fonctionne de manière significative lentement. Les développeurs Smarty recommandent d'utiliser Zend Accelerator ou PHP Accelerator.

DOM - Pour le moment, le dernier mot des modèles de documents en PHP. J'ai décrit le module dans l'article "XML: Spécifications et DOM Fonctions en PHP".

Malgré la vérification et la grande quantité de code qui effectue suffisamment d'opérations simples, DOM XML a de grandes perspectives.

Le principal inconvénient de l'approche de texte dans la modification du document XML (édition dans le script, naturellement) - ce dont vous avez besoin ou lisez avec précaution dans la spécificité de XML, ou de ne pas être pleinement confiant dans ce qui s'est passé à la fin.

Par exemple, insérer du texte dans le nœud est une tâche simple. Cependant, dans le document XML, les caractères de service et les symboles non inclus dans la table ISO doivent être convertis en entités XML (<) или в номера символов UTF-8 (&x0442;). В модуле DOM XML достаточно сконвертировать текст в UTF-8 и вызвать метод create_text_node.

Sur mon site, il travaille toujours pour un vieux moteur qui génère une chaîne de texte, et il jette parfois des astuces intéressantes avec des documents non-formes. De plus, les objets peuvent être transmis en tant que paramètre de fonction et le nom de la méthode appelée est variable.

Enfin, le principal avantage de DOM XML est que le module binaire du traitement de texte en PHP est manquant. Cela signifie que vous devrez vous-même écrire un analyseur.

Quant à la grande quantité de code, il est assez naturel. Après tout, si vous souhaitez modifier un document via un texte, vous écrivez des expressions régulières, utilisez un ensemble de fonctions de chaîne. Ce code a également besoin de beaucoup, si vous suivez des conventions XML.

Les opérations avec un document via DOM doivent être regroupées dans leurs propres fonctions, c'est-à-dire pour construire une classe DOM du modèle.

Dans un modèle séparé, vous pouvez supporter les données communes sur le site ou ses partitions. Le reste est d'insérer la réception que j'ai décrite:

document_élément (); $ Enfant \u003d $ root1-\u003e enfant_nodes (); $ root2 \u003d $ DOM2-\u003e document_élément (); pour ($ i \u003d 0; $ i< sizeof($child); $i++) $root2->append_child ($ enfant [$ I] -\u003e clona_node ()); ?\u003e.

Pour le site, vous pouvez créer un script simple dans lequel les demandes de documents seront redirigées. V.htaccess écrit ce qui suit:

Options suivantes rewriteEngine sur # Vérification d'un fichier avec le même nom # et extension PHPXML pour la section racine du% REWRITECOND% (document_root) / $ 1 / index.phpxml -f # Si un tel fichier est là, la règle est déclenchée par RewriteRule ^ (+) /? $ / 1 $ /Dindex.php # Cette règle fonctionnera pour l'adresse réécrit à la règle précédente et pour tous les autres fichiers #, envoyant une demande au script Compositeur.php. Réécritecond% (document_root) / $ 1.PLOPXML -F Rewriterule ^ (+) \\. PHP $ /Composer.php [l]

Le script Compositeur.php ouvrira le fichier avec le même nom que demandé, mais avec l'extension PHPXML. Server Apache Lorsque les règles de traitement ont déjà vérifié l'existence de ce fichier.

6.1 Validation des documents

Ceci est un outil qui devrait remplacer ou composer de manière significative des outils de vérification des données maison. Maintenant, il est devenu à la mode de refuser la base de données et de stocker des données dans des fichiers.

La base était simple: vous obtenez un tableau et crée une chaîne de texte (classement de cycle ou de modèle comme des modèles PHP) ou obtenez une chaîne à l'aide d'objets SQL2XML d'objets (ou à nouveau une chaîne). Il est plus difficile de travailler avec le fichier, car au cas où il est souhaitable de vérifier l'intégrité des données.

Il existe deux approches dans la création de balise. Le premier marquillage orienté vers les données (marquage centré sur les données), le deuxième - Marquillage orienté sur les documents (marquage centré sur le document).

Un exemple de balisage axé sur les données:

Etcc. Série de courses organisées par la FIA. Utilisez des voitures de course. BTCC. Championnat de voiture de tourisme britannique Analogique à ETCC, sauf que les courses prennent. http://btcc.co.uk. Dtm. Deuche Tourenwagen Masters.

Deux niveaux de hiérarchie - String + champ (naturellement, s'ils sont 3 ou 4, rien ne changera avec un système qualitativement), en général, identique à la requête de la base de données, formaté à l'aide de SQL2XML. Un exemple de balisage orienté sur les documents:

FIA a organisé environ 20 serveurs de course, dont 2 championnats de tourisme de voitures. Championnat de la voiture européenne de Turing (Etcc.) Utilise des voitures de route de manière significative, principalement BMW. Une autre série FIA \u200b\u200best Voiture de tournée britannique (BTCC.) est analogique à l'ETCC, sauf que les courses prennent. Bien que ce ne sont pas les championnats les plus célèbres du monde. Dtm. (Deuche Tourenwagen Masters.), La plus célèbre série de courses de tourisme non seulement en Allemagne.

Cette option est écrite par un langage humain libre, mais les données des éléments d'ACRO et de titre restent les mêmes, elles peuvent être obtenues à partir du document les mêmes demandes XPath ou XQuery: Championnats / Championnat / Titre La première option de balisage peut être représentée sous forme de table de base de données. Il est possible de compliquer, par exemple - un fragment du document:

Dtm. Deuche Tourenwagen Masters. La plus célèbre série de courses de tourisme allemande. Laurent Aiello. Bernd Schneider. Marcel Fassler. Jean Alesi. Cristian Albers.

De ce document ne cessera pas d'être centré sur les données. Le nouveau document peut être représenté sous forme de 2 tableaux connectés lors de la demande de l'opérateur de jointure gauche.

Le deuxième document a une structure plus complexe et, en général, il ne sera pas en mesure de rincer la table.

À propos, il s'agit de la principale différence de bases de données XML à partir de non-XML. XML-Base de données fonctionne avec un marquillage orienté sur le document (et non seulement les résultats sont émis dans XML). La balise du type de données-centré peut être stockée dans la base de données relationnelle et au format de sortie de l'utilitaire comme SQL2XML.

Donc, retour à la validation des documents, il convient de noter que le marquillage orienté sur les documents est très difficile à vérifier pour une conformité DTD ou un schéma XML par un simple analyseur à cordes.

Un autre exemple est un balisage de formulaire dans ma classe TXF:

0"/>

Je vérifie le schéma DTD. Vérifier la conformité Document Scheme - Fonction de la bibliothèque Standard DOM XML.

Pour les formats d'échange de données d'utilisateur généraux, par exemple, RSS, il existe des spécifications et des schémas DTD (schémas XML). Afin de ne pas vous soucier d'écrire votre propre analyseur RSS, vous pouvez simplement ajouter un schéma au document et vérifier la recevabilité. Obtenez ensuite les nœuds nécessaires du document via Get_Content ou XPath Expressions.

6.2 Retraite lyrique

En toute urgence, la rédaction de cette partie de la série m'a forgé le dernier spectateur Note-Spectron-A appelé "Modèles de PHP pour TheePots".

Appelle à oublier les mots tels que XML, XHTML "et d'autres x ...", confère à un coup de pied intelligent mérité, et, complétant son impromptu, appelle au rasoir intelligent du rasoir de l'Okka.

Rasoir pauvre! Élevé sur la bannière, ils le rendent partout où vous pouvez, poquer et essayer d'imposer une blessure aux adversaires.

En enfer avec un rasoir! En enfer, il s'agit d'une règle stupide "de ne pas produire d'essais excédant le nécessaire." C'est une vérité trope de la vérité pour la rappeler aux gens et pour évaluer les autres, il ne convient pas du tout. Le nombre de "sur le nécessaire" pour chaque personne est différent. Le client du site peut dire: "Pourquoi ai-je besoin de tes scripts, de le faire dans un simple HTML afin que nous soyons la dernière frontpage pour éditer! Lisez sur le rasoir d'Okkam?"

J'ai longtemps considéré que la principale raison pour laquelle il vaut la peine d'utiliser de nouvelles technologies dans la programmation - c'est l'effet de l'échelle. Comme j'ai écrit dans les commentaires à l'ancien article ", avec la croissance du volume du site, vous vous noyer dans vos modèles." Et dans mes articles, je me suis désopié exactement - ils disent, veuillez vous casser avec votre ruse et un code mélangé avec HTML, il allumera la gorge lorsque vous devez faire beaucoup de code de programme.

En fait, il y a une autre raison. C'est les compétences de chaque personne. Qui connaît bien le XML, XSLT et XPath, ou sait comment trouver rapidement des solutions aux tâches dans cet environnement, que dans plusieurs cas, exécuteront le projet sur XML-Technologies. Il sera simple et facile pour lui, car il sait comment bien. Qui ne sait pas ou ne savait pas mal - fera des façons "communes".

Il n'y a qu'une question que ses décisions sur les technologies XML seront-elles plus efficaces que s'il l'a fait sur les classes de modèle ou sur PHP & HTML mixte? Oui, il y aura. Je vais donner une comparaison allégorique.

Avez-vous vu à quel point des joueurs et des "lamers" ont-ils joué au volleyball? Les équipes de "Klokov" sont la vérité et la fausse lancer la balle de l'autre côté, de sorte que l'adversaire goutte la balle. L'attaquant ne sait pas comment faire la grève et, guidé par le rasoir notoire, ils jouent simplement. Un joueur expérimenté est beaucoup mieux que Kulka peut traverser la balle. Cependant, il obtiendra des résultats plus importants s'il remplit un bon attaquant.




Il y a encore des questions ou quelque chose d'incompréhensible - Bienvenue à notre
Avez-vous aimé l'article? Partager avec des amis: