Simple restful service on native PHP. SuperGlobal Array $ _Server Ruthless User Info PHP

To begin with, we will improve the registration page by adding the ability to download avatar. The original image should be a JPG, GIF or PNG format. It should also be no more than 2 MB. Do not worry, after compressing the script, the size of the avatar will be about 3 KB and the JPG format. Open page rEG.php.and add in tag < form> line enctype \u003d "MultiPart / Form-Data"As in the example:


check in










Now save reg.php.

2. Categories you need to create another field in the table users.. Go to B. phpmyAdmin., Choose the desired database and table.


Expose all values \u200b\u200bas in the picture:

In this field, the path will be recorded before Avatar, and it is saved in a separate folder itself, call it "avatars". The folder will be located in the same directory as the other script files.

3. Purchase to the file save._ user.. php. and add the following code after removing spaces from login and password:

// Remove extra gaps
$ login \u003d trim ($ login);

// add a new ********************************************

// Add a check on the length of the login and password
If (Strlen ($ Login)< 3 or strlen($login) > 15) {
Exit ("Login should consist of at least 3 characters and no more than 15.");
}
If (Strlen ($ Password)< 3 or strlen($password) > 15) {
EXIT ("Password should consist of at least 3 characters and no more than 15.");
}

if (! empty ($ _ post ["fupload"])) // Check if the user sent an image
{
$ Fupload \u003d $ _ post ["fupload"]; $ FupLoad \u003d Trim ($ Fupload);
if ($ Fupload \u003d\u003d "" OR EMPTY ($ Fupload)) (
Unset ($ Fupload); // If the $ Fupload variable is empty, then delete it
}
}
if (! Isset ($ Fupload) or Empty ($ Fupload) or $ Fupload \u003d\u003d "")
{
// If the variable does not exist (the user has not sent the image), then we assign it a pre-prepared picture with the inscription "No avatar"
$ avatar \u003d "avatars / net-avatara.jpg"; // You can draw Net-Avatara.jpg or take in source
}
eLSE.
{
// Otherwise - download the user image
$ path_to_90_directory \u003d "avatars /"; // Folder, where the initial picture and its compressed copy will be loaded

If (preg_match ("/ [.] (JPG) | (JPG) | (GIF) | (GIF) | (PNG) | (PNG) $ /", $ _ files ["fupload"] ["Name"])) // Checking the format of the original image
{
$ filename \u003d $ _files ["FUPLOAD"] ["NAME"];
$ source \u003d $ _files ["fupload"] ["TMP_NAME"];
$ target \u003d $ path_to_90_directory. $ FileName;
Move_uploaded_File ($ Source, $ target); // Download the original in the folder $ Path_TO_90_Directory
if (preg_match ("/ [.] (GIF) | (GIF) $ /", $ FileName)) (
$ im \u003d imagecreatefromgif ($ Path_TO_90_Directory. $ FileName); // If the original was in GIF format, then create an image in the same format. Need for subsequent compression
}
if (preg_match ("/ [.] (PNG) | (PNG) $ /", $ FileName)) (
$ im \u003d imageCreateFromPNG ($ path_to_90_directory. $ FileName); // If the original was in PNG format, then create an image in the same format. Need for subsequent compression
}

If (preg_match ("/ [.] (JPG) | (JPG) | (JPEG) | (JPEG) $ /", $ FileName)) (
$ im \u003d imagecreatefromjpeg ($ path_to_90_directory. $ FileName); // If the original was in JPG format, then create an image in the same format. Need for subsequent compression
}
// Creating a Square Image and its subsequent compression taken from the site www.codenet.ru
// Creating a Square 90x90
// Dest - result image
// W - image width
// Ratio - proportionality coefficient
$ w \u003d 90; // Square 90x90. You can put another size.
// Create a source image based on
// source file and determine its dimensions
$ w_src \u003d imagesx ($ im); // Calculate the width
$ h_src \u003d imagesy ($ im); // Calculate the height of the image
// Create an empty square picture
// It is true that TrueColor!, otherwise we will have an 8-bit result
$ Dest \u003d ImageCreateTusolor ($ W, $ W);
// cut the square middle of X, if the photo is horizontal
if ($ w_src\u003e $ H_SRC)
imagecopyresampled ($ Dest, $ im, 0, 0,
Round ((MAX ($ W_SRC, $ H_SRC) -min ($ W_SRC, $ H_SRC)) / 2),
0, $ w, $ w, min ($ w_src, $ h_src), min ($ w_src, $ h_src));
// Cut the square top of Y,
// If the photo is vertical (although you can also a middle)
if ($ w_src<$h_src)
imagecopyresampled ($ Dest, $ im, 0, 0, 0, 0, $ w, $ w,
min ($ w_src, $ h_src), min ($ w_src, $ h_src));
// Square picture scaled without cut
if ($ w_src \u003d\u003d $ h_src)
imagecopyresampled ($ Dest, $ im, 0, 0, 0, 0, $ w, $ w, $ w_src, $ w_src);
$ DATE \u003d TIME (); // Calculate the time at the moment.
imagejpeg ($ Dest, $ path_to_90_directory. $ date. ". jpg"); // Save the image of the JPG format to the desired folder, the name will be the current time. Made so that avatars have no identical names.
// Why exactly JPG? It takes very little space + destroy the Animation of the GIF image that distracts the user. It is not very pleasant to read his comment when the edge of the eyes notice some movement.
$ avatar \u003d $ path_to_90_directory. $ date. ". jpg"; // We enter the path variable to avatar.
$ DELFULL \u003d $ path_to_90_directory. $ FileName;
Unlink ($ Delfull); // Delete the original of the downloaded image, it is no longer needed. The task was to get a miniature.
}
ELSE.
{
// In case of inconsistency of the format, we issue the appropriate message
exit ("avatar should be in format JPG, GIF or PNG");
}
// End of the download process and assignment $ avatar variable address downloaded ava
}



// Finished a new ********************************************
// Next comes from the first part of the article, but it is necessary to add a change to the request to the database.
// Connect to the database
// Check on the existence of a user with the same login
$ result \u003d mysql_query ("Select ID from Users WHERE LOGIN \u003d" $ LOGIN "", $ db);
If (! Empty ($ myrow ["id"])) (
Exit ("Sorry, the login entered already registered. Enter another login.");
}
// If not, we save the data
$ result2 \u003d mysql_query ("Insert Into Users (Login, Password, Avatar) Values \u200b\u200b(" $ Login "," $ password "," $ avatar ")");
// Check if there are errors
if ($ result2 \u003d\u003d "TRUE")
{
Echo "You are successfully registered! Now you can go to the site. Home page";
}
eLSE (
Echo "Error! You are not registered.";
}
?>

4. You must add one table to the same database. It will store IP addresses that allowed errors at the entrance. Thus, we can limit access to those who mistaken more than three times in a row for about 15 minutes. I think the password programs will have to mess around for a long time.
Let's go to PHPMYAdmin and create a new table with 3-fields:


IP - IP address.
date - the date of an unsuccessful entrance for the last 15 minutes by the user with IP data. COL - the number of errors over the past 15 minutes by the user with IP data.
Excellent! Ready, now change the login and password check file, because now we have a password encrypted. Open TestReg.php and delete everything that further removes spaces from the login and password. Next, add the following code:

// Remove extra gaps
$ login \u003d trim ($ login);
$ password \u003d trim ($ password);

// Replace the new ********************************************
// Connect to the database
include ("bd.php"); // BD.PHP file must be in the same folder as everyone else, if not, then simply change the way
// Minipvertect for password selection
$ ip \u003d getenv ("http_x_forwarded_for");
if (Empty ($ ip) || $ ip \u003d\u003d "unknown") ($ ip \u003d getenv ("remote_addr");) // Remove IP
mySQL_Query ("Delete from Oshibka WHERE UNIX_TIMESTAMP () - UNIX_TIMESTAMP (DATE)\u003e 900"); // Delete the IP addresses of the umbered at the input of users after 15 minutes.
$ Result \u003d MySQL_Query ("Select col from oshibka where ip \u003d" $ ip "", $ db); // Remove the number of unsuccessful input attempts for the last 15 from the user with IP data from the database
$ myrow \u003d mysql_fetch_array ($ result);
if ($ MyRow ["COL"]\u003e 2) (
// If the errors are more than two, that is, three, then issue a message.
Exit ("You scored a login or password incorrectly 3 times. Wait 15 minutes until the next attempt.");
}
$ password \u003d MD5 ($ password); // Encrypt password
$ password \u003d strrev ($ password); // for reliability add a reverse
$ password \u003d $ password. "B3P6F";
// You can add a few of your characters to taste, for example, I entered "B3P6F". If this password will be selected by the selection by the server on the server of the same MD5, then clearly nothing good will come out. But I advise you to put other characters, you can at the beginning of the line or in the middle.
// In this case, it is necessary to increase the length of the Password field in the database. The encrypted password may be much larger.

$ result \u003d mysql_query ("Select * from Users Where login \u003d" $ login "and password \u003d" $ password "", $ db); // Remove from the database all the user data with the entered login and password
$ myrow \u003d mysql_fetch_array ($ result);
if (empty ($ myrow [id "]))
{
// if the user with the login and password does not exist
// Make an entry that this IP could not enter.
$ select \u003d MySQL_Query ("Select ip from oshibka where ip \u003d" $ ip "");
$ TMP \u003d MySQL_FETCH_ROW ($ SELECT);
If ($ ip \u003d\u003d $ TMP) (// Check, is there a user in the "Oshibka" table
$ result52 \u003d mysql_query ("Select col from oshibka where ip \u003d" $ ip "", $ db);
$ MyRow52 \u003d mysql_fetch_array ($ result52);
$ col \u003d $ MyRow52 + 1; // add another attempt to unsuccessful entrance
MySQL_Query ("Update Oshibka set col \u003d $ col, date \u003d now () where ip \u003d" $ ip ");
}
eLSE (
MySQL_Query ("INSERT INTO OSHIBKA (IP, DATE, COL) VALUES (" $ ip ", now ()," 1 ")");
// If there were no errors in the last 15 minutes, then insert a new entry to the "Oshibka" table
}

eXIT ("Sorry, the login or password entered by you.");
}
ELSE (
nBSP; // If passwords match, we start the user's session! You can congratulate it, he entered!
$ _Session ["Password"] \u003d $ MyRow ["Password"];
$ _Session ["Login"] \u003d $ myrow ["login"];
$ _Session ["ID"] \u003d $ MyRow ["ID"]; // This data is very often used, here they will "wear with you" included user

// Next, we remember the data in cookies, for the subsequent entrance.
//ATTENTION!!! Do this at your discretion, as the data is stored in cookies without encryption.
if ($ _POST ["Save"] \u003d\u003d 1) (
// If the user wants its data to be preserved for a subsequent entrance, we keep in the cookies of his browser
Setcookie ("Login", $ _post ["login"], time () + 9999999);
setcookie ("Password", $ _post ["password"], time () + 9999999);
}}
Echo " "; // Redirect the user to the main page, there he will not inform about the successful entrance
?>

5. Fully change the main page. It is necessary to display the user's avatar on it, to display a link to output from the account and add a checkbox to memorize the password at the entrance.
Index.php.

// The whole procedure works at sessions. It is in it that the user data is stored while it is on the site. It is very important to launch them at the very beginning of the page !!!
session_start ();
include ("bd.php"); // BD.PHP file must be in the same folder as everyone else, if not, then simply change the way
if (! Empty ($ _ session ["login"]) and! empty ($ _ session ["password]))
{
// If there is a login and password in sessions, then check them and remove the avatar
$ login \u003d $ _session ["Login"];
$ password \u003d $ _session ["Password"];
$ result \u003d mysql_query ("SELECT ID, avatar from users where login \u003d" $ login "and password \u003d" $ password "", $ db);
$ myrow \u003d mysql_fetch_array ($ result);
// Remove the necessary user data
}
?>


Main page.


Main page.

If (! Isset ($ myrow ["avatar"]) OR $ MyRow ["avatar"] \u003d\u003d "") (
// Check if the user data from the database is not retrieved. If not, he has not entered, or the password in the session is incorrect. We display the login window. But we will not withdraw it for those who have entered, it is no longer necessary for them.
Print.<<


Here;

If (ISset ($ _ cookie ["login"])) // Is there a variable with a login in the cookie. It should be if the user at the previous entrance clicked on Chekbox "Remember Me"
{
// If yes, then insert its value into the form. At the same time, the user is displayed that its login is already inscribed in the desired graph
Echo "Value \u003d". $ _ cookie ["Login"]. ""\u003e ";
}

print.<<




Here;

If (ISset ($ _ cookie ["Password"])) // Is there a variable with a password in the cookie. It should be if the user at the previous entrance clicked on Chekbox "Remember Me"
{
// If yes, then insert its value into the form. At the same time, the user is displayed that its password is already inscribed in the desired graph.
Echo "Value \u003d". "$ _ Cookie [" Password "]." "\u003e";
}

Print.<<



Remember me.






Register



You entered the site as guest

Here;
}
eLSE.
{
// With a good input, the user is issued all that is located below as stars.

print.<<
You entered the site as $ _Session (output)


This link is available only to registered users.

Your avatar:




Here;

//************************************************************************************
// With a good input, the user is issued all that is located above between asterisks.
}
?>



6. It is necessary to make the opportunity to exit the accounts to users who entered. On the main page already there was a reference to the exit. But this file does not exist yet. So create a new file exit.php. With code:

session_start ();
if (Empty ($ _ session ["login"]) or empty ($ _ session ["password"]))
{
// If there is no session with a login and password, it means that the unpellent user came to this file. It's not a place here. We give an error message, stop the script
Exit ("Access to this page is allowed only to registered users. If you are registered, then log in to the site under your login and password
Main page ");
}

unset ($ _ session ["password"]);
Unset ($ _ session ["Login"]);
Unset ($ _ session ["id"]); // Destroy variables in sessions
Exit (" ");
// Send a user to the main page.
?>

That's it! Use on health! Good luck!

Sometimes I want to distract from the current routine of coding and from small problems that the place is destined in the articles on the "details". Looking around what you do for a long time. So, my vision of approaches to the main PHP programming task is to generate web pages. Partly the topic I was already affected by parts - articles about the class of templates and about XML you can find in the archive. Now I would like to reduce all this together and do something monumental. First part.

1. The origins of PHP.

Why, actually began PHP for most of us? From the script inserts in the HTML pages. For example, own reference catalog. Page with reference from a specific category:

". mysql_result ($ result, 0).""; mysql_free_result ($ result); $ result \u003d mysql_query (" Select ID, Title, Ratio, Description, Site_Date From Site WHERE RUBRIKA \u003d ". INTVAL ($ ID)." Order by Ratio Desc, Site_Date DESC, TITLE "); if (mysql_error ()) echo mysql_error (); Else While ($ row \u003d mysql_fetch_assoc ($ result)) ECHO " ($ row)
($ row)
Recorded: ($ Row), Rating: ($ ROW)

Just and simple, but the main thing is that this code works. Difficulties begin if you try to write the name of the heading in the title page. To do this, you have to create a PHP insert inside the tag , transfer the code that performs the first request (sampling of the heading name), save the result of the request to the variable, which is then displayed in the body of the page.</p> <p>The following complication is an attempt to work with cookies and issue them depending on which the user is visiting. To better imagine this: let we decide that crowds of visitors will go to our homepeage, and for potential advertisers, we make a banner engine with targeting. For example, the user who visited the headings of rock music and musical instruments, on the next page there will be a banner with an advertisement of an electric train store.</p> <p>In this case, we will have to make the PHP code insert at the very beginning of the file and move there to check the presence of the heading, because cookies can be issued only before issuing the first byte of the document.</p> <p><i>Of course, you will say that it can be easily done using the user session mechanism, which is easier from the point of view of the content of the content and safer, because the user can manually change the contents of the Cook. Yes, it is so, but firstly, a vision of the programming programming that makes their homepage is presented here, and secondly we are talking about a distant past - we are virtually we are in 1998.</i></p> <p>It does not greatly facilitate life and output of the same HTML and PHP code blocks into plug-in files. The task described above is to build a simple reference catalog with headings - perhaps the upper limit of the capabilities of this approach. When performing more complex tasks, the risk of colling with great labor costs.</p> <p>2. Complication of code</p> <p>The logical development of the previous approach is a complete transition to PHP in the sense that all pages are PHP code - at the beginning of the file it is the opening tag "<?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> class \u003d "club_article_small_caption"\u003e news for customers</h2> <table cellpadding=\"4\" cellspacing=\"0\" border=\"0\">"); $ result \u003d 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 \u003d Mysql_Fetch_assoc ($ Result)) Print (" <tr><td>($ row) "); if ($ row [" news_date "]\u003e date (" Y-M-D ", Time () - 3600 * 24 * 14)) Print (" <font color=\"#cc0000\">nEW!</font>"); Print ("</td><td> <a href=\"read.php?id={$row}\"><b>($ row)</b></a> <br>($ row)</td></tr>"); Print ("</table>"); include" Page-FOOTER.INC ";?\u003e</p><p> <?php ... else while ($row = mysql_fetch_assoc($result)) print_announce($row); ... ?> </p><p>But this does not easily simplify work, and the hour of payback will necessarily come: there will be a need to remake the design of the site. The designer edit it will simply refuse. Only the one who wrote such a code will be able to figure it out and replace the old HTML to a new one. If this person is no longer working on the project, the project will have to rewrite almost from scratch or he will die, turning into a monument to human short-sightedness.</p> <p>Another option to develop a mixed HTML and PHP approach. PHP has such a property as Advanced-escaping. It allows inside language structures to output the usual HTML code:</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">News for customers</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", Time () - 3600 * 24 * 14)) (?\u003e <font color="#cc0000">nEW!</font><?php } ?></td><td> "> <b><?=$row["title"]?></b> <br><?=$row["announce"]?></td></tr><?php } ?></table><p>The gauge or designer, opening this file in the Homesite, will see the HTML markup with a backlight and can be edited to edit pages. In simple sites, this method is quite suitable. In difficult - not to hell is not suitable.</p> <p>3. Reversal</p> <p>With the release of PHP 3.0 ... By the way, it would not hurt to restore chronology, since we are talking about a comprehensive story. So, the chronology managed to restore using the PHP Announce newsletter archive and the page from the web archive:</p><p>08.1997 PHP 3.0 Beta1 06.06.1998 PHP 3.0 Release 19.07.1999 PHP 4.0 Beta1 22.05.2000 PHP 4.0 Release 10.12.2001 PHP 4.1 Release 04/20/2002 PHP 4.2 Release 10.10.2002 PHP 4.3.0PRE1 (Pre1 is not beta, but still Not Release Candidate)</p><p>So, with the output of PHP 3.0, a toolkit appeared to apply a new approach in PHP programming - buffering pages in scripts. (It is important to note that this is not the wrong buffering that is now.)</p> <p>Over time, the tasks of building sites became more complicated, PHP was used wider, sites became all "dynamic". The more the site, the problematic to do everything on the plug-in files in the mixed PHP and HTML. It is quite logical by the next step of the PHP extension step in the processing of an HTML page in the script memory and issuing it to the user entirely or in parts.</p> <p>Implement data The approach helped the help-poor support (well, ok, emulation) object-oriented programming. Were created <i>classes templates</i>which allowed to easily operate the page and data template that should be made to it.</p> <p>It expanded the capabilities of programs, but at the same time required more system resources. Today we can say that the benefits of the use of such an approach have blocked the costs of system resources, but another two or three years ago many people believed that keeping the entire document in memory - a non-disabilities for web programming.</p> <p>So, figuratively speaking, there was a coup in technology: if before PHP was hiding in HTML code and timidly added its information, now it came out in the first place and keeps all HTML in his paws.</p> <p>4. What are bad patterns of templates</p> <p>Six months later, I decided to change something in the plans. Moralizing on the topic of badness of self-defense classes will not be. They are good. Use them, and will come with you what you need! Just consider that you will interfere with some circumstances.</p> <p>First. If the class was written specifically, it means that he is somewhat torn off from life. Let the class cost a lot of developing experience, it still was done in greenhouse conditions. The resulting technology will have its own specific conditions for use, which will have to customize future development, or redo the class.</p> <p>Second. The class, which is synthesized from the developments in different projects, also requires changes - the glifter than it, the more.</p> <p>So, you can do your own classes (classes of templates, as far as I know, very many use their own). If you go a deductive method, building a class from the assessment of what will be needed is a small chance that something is ingenious will be possible. And the high probability that it turns out not exactly what is needed. You can apply induction - then after a big and long work you are guaranteed to get what works, but not necessarily ingenious.</p> <p>The badness of the homemade, which I mentioned in the previous parts lies in the first case in a very high probability to get that it fell, working not as you dreamed, requiring a special approach and a lot of coding. In the second case, you can work hard for a long time and get what has already been done and published before you.</p> <p>As for the comparison of technologies, the main question is - relevance. Very simple site can be done on plug-in files and do not think about classes and engines. The site is more comfortable to do in templates. If the complexity increases and does a lot of different conditions on the same page - the navigation menu depending on the status, etc. - It is better to think about the XML & XSLT bundle.</p> <p>Example: PhpBB forum. In it, it is impossible to change the design completely, as you want, because a lot of design elements are not in templates, but in the PHP code. All sorts of input forms, management menu for the user's included user, etc. - Insert into the page via PHP code, and not as an attached pattern. The popular solution is not always the best.</p> <p>Dmitry Koters comments on the experience of studying phpbb: I wrote a template class, many, being full of enthusiasm, start to shove everything for this class. The idea of \u200b\u200bthis class is to divide the code and design, but the authors of phpbb on the contrary mixed them as much as possible.</p> <p>But in my opinion, even with the normal implementation of this approach (template class), the code would turn out bulky, files with templates would be a lot. Recently, I come to the conclusion that in the class classes, in principle, it is not possible to separate the PHP code from data and design. With the change of the design of the site on this engine, it will be necessary to dig in PHP scripts, and it will not be a designer, but you.</p><p> <table border> <tr> <td colspan=2> <b>__Global__</b> <p> (Hidden and automatically added)</td> </tr> <tr> <td><b>block1</b></td> <td> <table border> <tr> <td colspan=2><b>block2.</b></td> </tr> <tr> <td><b>inner1.</b></td> <td><b>inner2.</b></td> </tr> </table> </td> </tr> </table> </p><p>The documentation says that there is no need to specify in the template, which block is a subsidiary from which. Class it will understand.</p> <p>In the documentation for this class it is written that he knows that inner1 is a subsidiary for block2 block, and there is no need to inform him about it. To insert data into the block, it is enough to execute such a code as many times as rows need:</p><p> <?php $tpl->setVariable (...); $ TPL-\u003e PARSECURRENTBLOCK (); ? \u003e.</p><p>To make content in Block1, you need to perform this:</p><p> <?php $tpl->setcurrentblock ("inner1"); $ TPL-\u003e SETVARIABLE (...); $ TPL-\u003e PARSECURRENTBLOCK (); $ TPL-\u003e SETVARIABLE (...); $ TPL-\u003e PARSECURRENTBLOCK (); $ TPL-\u003e PARSE ("Block1"); ? \u003e.</p><p>As a result, the script code looks like this:</p><p> <?php $tpl = new HTML_Template_IT(); // загрузка шаблона или указание его через класс $tpl->loadtemplatefile (String Filename [, Boolean RemoveunknownVariables, Boolean RemoveEmptyBlocks]) // Set the "Global" variables, i.e. variables that are not included in the block (child unit) $ TPL-\u003e SETVARIABLE (String Variablename, Mixed Value); // Another way to specify variables - through an array of $ TPL-\u003e SETVARIABLE (ARRAY (STRING VARNAME \u003d\u003e MIXED VALUE)); // We will use some block, even even deeply invested in another $ TPL-\u003e SetCurrentBlock (String BlockName); // We repeat as much as $ TPL-\u003e SETVARIABLE (Array (String Varname \u003d\u003e Mixed Value))); $ TPL-\u003e PARSECURRENTBLOCK (); // Get the result or printing it causing $ TPL-\u003e SHOW () $ TPL-\u003e Get (); ? \u003e.</p><p>The code is more convenient and clearer than with FastTemplate.</p> <p>But many programmers still write their own template classes. More simple, but having some functions that are not available in publicly available classes. I wrote my own class in which I made blocks in which the results of SQL queries were automatically inserted, the cap and the tail of the block were included in the additives (for example, tags <table> and</table>), which appeared as a result only if there were lines in the SQL request.</p> <p>The XML processing functions module appeared in PHP3. Using the functions of this module, you can create your own XML code handlers, but, however, it is impossible to check the correctness of the XML document.</p> <p><i>A small excursion to the theory about what XML is and why it is needed.</i></p> <p><i>XML is a way to write structured data. Under the "structured data" usually imply things such as spreadsheets, address books, configuration parameters, financial transactions, technical drawings, and so on. XML is a set of rules (you can also consider them instructions or agreements) to develop text formats that will allow you to structure your data.</i></p> <p>Explanation of what structure is.</p><p> <eshop> <!-- категории товаров --> <category id="3"> <title>Meat products A fish kilogram 100 Meat kilogram 200 Waste production Icra fish kilogram 10 Vegetable products Sunflower thing 50

So in XML you can write down the structured data on the food store, in which the goods are divided into categories, and the categories may be subordinate to each other. Of course, this data can be recorded differently, say, text with tabs as separators and indicating the ID of the parent category (by the way, when writing data in XML format, it is not necessary to specify it). XML is a ready-made format for writing such a structure, in which you only remain inventing the names of the nodes (tags) and the rules in which the structure should be laid (for example, that the goods cannot be located out of category or that category levels may not be more Three). Further:

XML is not a programming language, and you do not need to be a programmer to use or explore it. XML facilitates the computer to the task of creating and reading data, while ensuring the uniqueness of their structure. XML avoids common languages \u200b\u200bdesign errors: it is expanding, independent of the platform, includes support for internationalization and localization. XML is fully compatible with Unicode.

PHP developers offer handling individual XML document elements with PHP functions. Example from PHP Guide:

"B", "Emphasis" \u003d\u003e "I", "Literal" \u003d\u003e "TT"); // Function for the start of the tag (it can output complex text, but in this example it issues // just the corresponding tag). Function Startelement ($ Parser, $ Name, $ ATTRS) (Global $ Map_Array; if ($ HTMLTAG \u003d $ MAP_ARRAY [$ Name]) (Print<$htmltag>";)) // Function for the end of the Tag Function Endelement ($ Parser, $ Name) (Global $ Map_Array; if ($ HTMLTAG \u003d $ Map_Array [$ Name]) (Print"";)) // Function for text (text node) FUNCTION CHARACTERDATA ($ PARSER, $ DATA) (Print $ Data;) $ XML_PARSER \u003d XML_PARSER_CREATE (); // Use Case-Folding SO WE ARE SURE TO FIND THE TAG IN $ map_array xml_parser_set_option ($ xml_parser, XML_OPTION_CASE_FOLDING, true); xml_set_element_handler ($ xml_parser, "startElement", "endElement"); xml_set_character_data_handler ($ xml_parser, "characterData"); // Reading XML-file if (($ fp \u003d fopen! ($ File, "R"))) (DIE ("COULD NOT OPEN XML INPUT");) While ($ Data \u003d Fread ($ FP, 4096)) (if (! XML_PARSE ($ XML_PARSER, $ DATA, FeOF ( $ FP))) (DIE (Sprintf ("XML Error:% s at Line% D", XML_ERROR_STRING (XML_GET_ROR_Code ($ XML_PARSER)), XML_GET_CURRENT_LINE_NUMBER ($ XML_PARSER)));)) XML_PARSER_FREE ($ XML_PARSER);?\u003e

This example can be expanded by adding an array of tag names that will be processed in a different way, and the corresponding conditions in the Startelement and Endelement function.

The code looks just awful. For use in the XML conversion in the HTML pages, it is almost unsuitable, although in some places used, for example, on how it works. Of course, you can write your own automatizers that would read configuration files and created arrays, but in total work costs it is more profitable to use powerful patterns of templates such as Smarty.

Work on this project began in 1999, when the team of developers began writing the specification of the pattern of templates. Having defined what he should do, the developers tried to write a module on C, but in the end they decided that it was better to make a class on PHP, affordable and understandable to all site developers.

Now Smarty is one of PHP projects, its website is located on the PHP server at smarty.php.net.

Formally Smarty - Template Class. In fact, its functionality is an order of magnitude higher than that of the set * template.

First, Smarty produces not only the insertion of variables into the template, but also performs the PHP code in the template itself. Secondly, templates in Smarty are converted into PHP scripts, and all dirty work on the insertion of variables into text and the execution of logical structures gives the part of PHP in PHP. These PHP scripts when the caching is enabled are stored in files that are called at the following appeals to templates. When patterns change, scripts are generated again. Such caching significantly accelerates the work of the scripts.

Also, Smarty can process the IF-ELSE logical designs built into the templates, converting them to PHP code. Similarly, structures called Variable Modifiers are processed. They allow you to remove some functions from the main script, transferred to them into the template and their cached php scripts.

(* Write the title with capital letters *)

($ Title | Upper),

(* Reduce top to 40 characters, putting ... at the end *) Topic: ($ Topic | Truncate: 40: "...")

This text is converted to such a code:

_Run_Mod_Handler ("Upper", True, $ this -\u003e _ TPL_VARS ["NAME"]); ?\u003e Topic:_Run_Mod_Handler ("Truncate", True, $ this -\u003e _ tpl_vars ["Name"], 40, "..."); ? \u003e.

A set of built-in variables such as $ smarty.Now (current time) is available. The ideilic picture complements the output of the debug window containing the values \u200b\u200bof the variables, call the nested templates, support the custom I / O filters and plug-ins.

Everything would be fine, be smarty less in size. Now (version 2.3.1) "weighs" 144 kilobytes and on AMD K6 266 MHz works significantly slowly. Smarty developers recommend using Zend Accelerator or PHP Accelerator.

DOM - at the moment the last word in the documents templates in PHP. I described the module in the article "XML: Specification and DOM functions in PHP".

Despite the verification and large amount of code that performs enough simple operations, DOM XML has great perspectives.

The main disadvantage of the text approach in editing the XML document (editing in the script, naturally) - what you need or carefully read into the specificization of XML, or not to be fully confident in what happened in the end.

For example, insert text into the node is a simple task. However, in the XML document, service characters and symbols that are not included in the ISO table must be converted to XML entities (<) или в номера символов UTF-8 (&x0442;). В модуле DOM XML достаточно сконвертировать текст в UTF-8 и вызвать метод create_text_node.

On my site, it is still working for an old engine that generates a text string, and sometimes he throws interesting tricks with non-well-form documents. In addition, objects can be transmitted as a function parameter, and the name of the called method is variable.

Finally, the main advantage of DOM XML is that the binary module for text processing in PHP is missing. This means that you yourself will have to write a parser.

As for the large amount of code, it is quite natural. After all, if you want to edit a document via text, you write regular expressions, use a set of string functions. This code also needs a lot, if you follow XML conventions.

Operations with a document via DOM need to be grouped into their own functions, that is, to build a DOM class of the template.

In a separate template, you can endure the data common to the site or its partitions. The rest is to insert the reception that I described:

document_element (); $ Child \u003d $ root1-\u003e child_nodes (); $ root2 \u003d $ DOM2-\u003e Document_element (); for ($ i \u003d 0; $ i< sizeof($child); $i++) $root2->append_Child ($ Child [$ i] -\u003e Clone_Node ()); ? \u003e.

For the site you can make a simple script in which requests for documents will be redirected. V.HTaccess writes the following:

Options FollowSymLinks RewriteEngine ON # Checking a file with the same name # and PHPXML extension for the root section of the RewriteCond% (Document_root) / $ 1 / index.phpxml -f # If such a file is there, the rule is triggered by Rewriterule ^ (+) /? $ / $ 1 /INDEX.php # This rule will work for the address rewritten to the previous rule, and for all other # files, sending a request to the composer.php script. RewriteCond% (Document_Root) / $ 1.phpxml -f Rewriterule ^ (+) \\. PHP $ /composer.php [L]

The Composer.PHP script will open the file with the same name as requested, but with the PHPXML extension. APACHE server when processing rules has already checked the existence of this file.

6.1 Validation of documents

This is a tool that should replace or significantly dial homemade data verification tools. Now it has become fashionable to refuse the database and store data in files.

The base was simple: you get an array and make a text string (cycle or template class like PHP-templates), or get a string using SQL2XML objects of objects (or again a string). It is more difficult to work with the file, because just in case it is desirable to check the integrity of the data.

There are two approaches in creating markup. The first - data-oriented markup (Data-Centric Markup), the second - document-oriented markup (Document-Centric Markup).

An example of data-oriented markup:

Etcc. Fia-Organized Racing Series. Use Racing Cars. Btcc. British Touring Car Championship Analogue to Etcc, Except That Races Take. http://btcc.co.uk DTM. Deuche Tourenwagen Masters.

Two levels of hierarchy - string + field (naturally, if they are 3 or 4, nothing will change with a qualitatively), in general, the same as the query from the database, formatted using SQL2xml. An example of document-oriented markup:

Fia Organized About 20 Racing Servies, Including 2 Touring Cars Championships. EUROPEAN TURING CAR CHAMPIONSHIP (Etcc.) Uses Significantly Tuned Road Cars, Mostly BMW. ANOTHER FIA SERIES IS British Touring Car (Btcc.) is Analogue to Etcc, Except That Races Take. AllThough, These Are Not The World "S Most Famous Championships. DTM. (Deuche Tourenwagen Masters.), The Most Famous Touring Racing Series Not Only in Germany.

This option is written by a free human language, but the data in the elements of ACRO and TITLE remains the same, they can be obtained from the document the same XPath or XQuery requests: CHAMPIONSHIPS / CHAMPIONSHIP / TITLE The first markup option can be represented as a database table. It is possible to complicate it, for example - a fragment of the document:

DTM. Deuche Tourenwagen Masters. Most Famous German Touring Racing Series. Laurent Aiello. Bernd Schneider. MARCEL FASSLER. Jean Alesi. Cristian Albers.

From this document will not cease to be Data-CENTRIC. The new document can be represented as 2 tables connected when requesting the Left Join operator.

The second document has a more complex structure, and in general it will not be able to flush into the table.

By the way, this is the main difference of XML databases from non-XML. XML-Database works with a document-oriented markup (and not only that the results are issued in XML). The markup of the type of Data-CENTRIC can well be stored in the relational database, and at the output format the utility like SQL2XML.

So, returning to the validation of documents, it should be noted that document-oriented markup is very difficult to check for a DTD conformance or an XML schema by a simple string parser.

Another example is a form markup in my TXF class:

0"/>

I check it through the DTD scheme. Check Compliance Document Scheme - Standard DOM XML Library Function.

For general user data exchange formats, for example, RSS, there are specifications and DTD schemas (XML schemas). In order not to bother with writing your own RSS parser, you can simply add a scheme to the document and check for admissibility. Then get the necessary nodes from the document via GET_CONTENT or XPath expressions.

6.2 Lyrical retreat

Urgently completed the writing of this part of the series forced me the last note Spectator-A called "PHP templates for teapots".

Calls on to forget the words like XML, XHTML "and other X ...", accordingway, gives a deserved Smarty kick, and, completing its impromptu, calls for the clever shaver of the Okka's razor.

Poor razor! Raised it on the banner, they make it everywhere where you can, poke and try to impose an injury to opponents.

To hell with a razor! To hell it is a stupid rule "not to produce essences in excess of the necessary." This is too betful truth to remind it to people, and in order to evaluate others, it is not suitable at all. The number of "over the necessary" for each person is different. The customer of the site can say: "Why do I need your scripts, make it in simple HTML so that we are later FrontPage to edit! Read about the razor of Okkam?"

I have long considered that the main reason why it is worth using new technologies in programming - this is the effect of scale. As I wrote in the comments to the old article, "with the growth of the volume of the site you will drown in your templates." And in my articles, I desoped exactly on it - they say, please break with your cunning include and a code mixed with HTML, it will turn the throat when you need to do a lot of program code.

In fact, there is another reason. This is the skills of each particular person. Who knows the XML, XSLT and XPath well, or knows how to quickly find solutions to tasks in this environment, that in more cases will execute the project on XML-technologies. He will be simple and easy for him, because he knows how well. Who does not know or know badly - will do "common" ways.

There is only a question, will its decisions on XML technologies more efficiently than if he did on the template classes or mixed PHP & HTML? Yes, there will be. I will give an allegorical comparison.

Have you seen how experienced players and "Lamers" play volleyball? The teams of "Klokov" are truth and untrue throwing the ball on the other side, so that the opponent drops the ball. The striker does not know how to do the strike, and, guided by the notorious razor, they play simply. An experienced player is much better than Kulka can cross the ball. However, he will achieve greater results if he fulfilling a good striker.




There are still questions or something incomprehensible - welcome to our
Did you like the article? To share with friends: