Home
Home Page
XML on the screen of a browser
Interaction with life cycle of page
How to overtake competitors and at once to do{make} liderskie pages
Adjustment of parameters PHP in php.ini
KHehshirovanie passwords in PHP
Total Automation of Reception of payments on a site
Object-oriented programming, classes in PHP
Abstract classes and interfaces
The module of definition of a geographical position on IP - mod_GeoIP
Conclusion of messages to the user in webs - applications.
Manipulation date on PHP
The truth about Sessions
Realization of patterns on PHP.
Protection against a spam on a site
Imitation of files and directories
Door in protection: the post web - interface
Safety of search engines in the corporate environment
CHPU and PHP (revisited)
Links
 
 

Conclusion of messages to the user in webs - applications.

Conclusion of messages to the user - enough widespread action which should carry out the web - application. It can occur at processing forms, it can be error messages, and also messages which speak that is necessary to be registered when the user tries to get access to the limited part of a site, and in many other cases.


Very much often creation and a conclusion of messages are carried on different HTTP-searches. As a rule, conveniently it happens to use a redirect after processing forms (to avoid problems with buttons Back and Refresh), but at the same time the natural moment for creation of the message is the moment of processing of forms and fulfilment of actions, to him accompanying. Why? Present, that the text of the message should look approximately so: " the Quantity{Amount} of reserved commodity units ' Kovrik for the mouse ' is successfully changed with 7 up to 12 ". After a redirect, probably, on completely another from the point of view of functionality page, it will be superfluous head - to define{determine}, that has been accomplished before.


More often messages deduce in POST-search which is engaged in processing of the form is badly, inscriptions " this page is obsolete " spoil a life (when to the user will take in head to try button Back).


Someone uses a redirect, having given up as lost friendly messages.


At the same time there is a simple and obvious way to make life is better. Despite of evidence, I for some reason had not to see, that someone used it  - at least when I looked another's source codes.


So, we have a problem - the message should "live" in different searches. The mechanism of transfer of the text of the message on page which should deduce{remove} it  is necessary for us. You already, probably, have recollected about sessions.


Yes, vobhhem you are right. Other ways, for example through a global variable, do not allow to save the data in a case when the redirect (Maxim Naumenko's remark) is used. Still I usually do{make} plus so that each screen in the application had an opportunity, alongside with the other information, to deduce{remove} messages which have been generated on the previous screens. It is convenient, because it is not required to prepare for separate screens for a conclusion of messages, and the user should not click the mouse once again. But, the truth, here it is necessary to think to the designer - to allocate area in which there would be messages.


Idea very simple, and she  can be realized with the help of pair classes.


The first, that comes to mind - to create class Message which, actually, and represented the message on our simple circuit of classes. The message should be able to save itself in session, and also to display itself.


Message.php



class Message

{


   / **

    * The maintenance{contents} of the message.

    */

   var $content;


   / **

    * The designer for initialization of the text of the message.

    *

    * @param content the maintenance{contents} of the message

    */

   function Message ($content)

   {

      $this-> content = $content;

}


   / **

    * Recording the message in session.

    */

   function send ()

   {

      $ _SESSION [' session_messages '] [] = $this-> content;

}


   / **

    * A conclusion of the message to page.

    */

   function toPage ()

   {

      echo ' - '. $this-> content. ' <br> ';

}


}


For access to session the variable $ _SESSION is used.


I shall notice, that $ _SESSION is a file, we use only one element of this file with an index ' session_message '.


In this case we deal with " a file of files " - that we store{keep} in an element ' session_message ', represents a file, it and is the list of transmitted messages (them, certainly, can be a little).


If you could not grope a string, it is high time to freshen sections of a manual devoted to sessions and files in the memories.


You can have question. And what for here classes are necessary? It would be quite possible to do without two functions. But let's have a look further. We can be necessary to create messages with various types (info, error, warning) to define{determine} addressees of messages.


Notice, that at present in session the object, but only the text of the message is put not. OOP allows us to change in further behaviour of a method send (), not changing klienskij a code which addresses to this method (for example, in the future in session it is possible to write down completely object Message if in him there will be many fields).


Let's present, that we would do{make} it with the help of functions. Probably, we would have function message_send ($txt), still there would be a function message_to_page ($txt). Now it is necessary to add an opportunity of various behaviour for various kinds of messages. Calls of functions vary: message_send ($txt, $kind), message_to_page ($txt, $kind). It is necessary to comb all code of the application in searches of such functions, doing{making} corrections.


It can be avoided, beforehand expecting a situation, having presented the message as an associative file: $msg [' txt '], $msg [' kind '] then in calls of functions there will be only one parameter. Feel, how it aspires to turn to a class?


And so, OOP enables to dare to not think over luxury all beforehand.


We go further. On each page we should deduce{remove} all acted{arrived} messages, and also to remove them from session after that. It is very similar to reading of letters from a mail box.


The following class - Inbox - just for this purpose also is intended.


Inbox.php



class Inbox

{


   / **

    * A file of the acted{arrived} messages.

    */

   var $messages = array ();


   / **

    * In the designer it is received all acted{arrived} messages

    * Also we delete them from session.

    */

   function Inbox ()

   {

      if (is_array ($ _SESSION [' session_messages ']))

      {

         $messages = $ _SESSION [' session_messages '];

         $co = sizeof ($messages);

         for ($i = 0; $i <$co; $i ++)

         {

            $this-> messages [] = new Message ($messages [$i]);

}

}


/* We clear a file of messages */

      $ _SESSION [' session_messages '] = array ();

}


   / **

    * We deduce{remove} on page contents Inbox.

    */

   function toPage ()

   {

      $co = sizeof ($this-> messages);

      if ($co> 0)

      {

         echo ' the Message from system: <br> ';

}

      for ($i = 0; $i <$co; $i ++)

      {

         $this-> messages [$i]-> ToPage ();

}

}


}


Let's test our system of messages.


Let's create very simple example which in reply to sending of the form will inform quantity{amount} of seconds in the current minute.


index.php



<? php


include (' Inbox.php ');

include (' Message.php ');


session_start ();


if (' POST ' == $ _SERVER [' REQUEST_METHOD '])

{

   $msg = new Message (' msg: '. date (' s '));

   $msg-> send ();


/* perenapravlenie on itself */

   header (' location: ');

}

else

{

   $inbox = new Inbox ();

   $inbox-> toPage ();

}


?>

<form method=post action=index.php> <input type=submit> </form>


With files and sessions we have hidden all job inside classes, and the final code looks simply and beautifully.


Create the catalogue on the web - server, then create in him these three files and try a script in job. Notice, problems with buttons Back and Refresh do not arise.


And now present, that you create a complex  portal where, as a rule, on pages there are some blocks, and everyone can contain inside itself(himself) the separate application.


Here we meet two difficulties:


* It would be desirable, that the list of messages appeared in the certain part of page, and you have already picked up a good place for this purpose.

Problem in that it is necessary to start $inbox-command> toPage () during that moment which would correspond{meet} to position of the list of messages on page. If we shall want to change position of this list, it is necessary to climb in a code, but badly constantly for this purpose to change a skeleton of a portal. The best decision would be to draw a conclusion of messages as the separate module about which it is known only, that it{he} should be connected to a skeleton.

That is to be released{exempted} from strict sequence of start of modules. Really, time result of job of conclusion Inbox does not depend on job of system (on the given step - all data at us already are in session), what for superfluous complexities?

* To support appearance (design) of the list of messages it is necessary to care of a HTML-code, which at us zashit in methods toPage () classes Message and Inbox. As a rule, it is necessary to change a PHP-code to change design.


To try to solve the first problem, it is possible to create the buffer in which the result of job of conclusion Inbox would be stored{kept}.


Probably, at us still will be a little similar (on Inbox) things, and it is necessary to create system of buffers. To not mix where whose conclusion, we, probably shall come to imenovaniju buffers. At us the sequence according to which there should be a conclusion of buffers will be stored{kept} somewhere - it is desirable in an external file that it was easier to make changes.


Already this attempt of the decision gives us idea to use XML as means of storage of the intermediate data. And use of styles XSLT will help to consult and with the second problem.


I shall not stop that such XML, and that such XSLT. If you are not familiar with these things, zvon.org becomes a good starting point for studying.


Idea in, that in methods toPage () to form not a HTML-code, and XML structure. The document of page will be created as stringa with a XML-code (he will serve as "buffer"), and at last stage of job of a script we shall use XSL-transformation.


For the beginning we shall imagine, that should grow out jobs of the basic part of a code.



<messages>

<message> minute 57 </message>

<message> second: 45 </message>

</messages>


<refresh_form/>


What is it such - to guess rather simply - two messages and the form. Notice, the PHP-script should prepare only such string - he very simple. And the order of following of the basic tegov is unimportant - <refresh_form/> it is possible to put in the beginning, for example, as it will be convenient for the programmer. As it to realize. It is possible, almost nothing changing, to use output buffering, instead of a HTML-code to deduce{remove} XML, and in the end simply to grasp a conclusion in string. But then we shall lose in flexibility - for example, it would be desirable to deduce{remove} sometimes the debugging information directly on page (with the help echo). At the same time, developers PHP work above the DOM-module which offers more advanced way of creation and transfer of treelike documents. If we shall want to introduce DOM it is necessary to alter the application, changing a conclusion stringov on creation of DOM-elements. Therefore I prefer to store{keep} XML-performance of objects inside objects, consistently collecting the general{common} XML-document. It not so is difficult, small updating is necessary only. You will see, that such reception is not adhered rigidly to a concrete way of storage of the XML-given, and it will allow to make transition to use DOM " small blood ". First of all we shall notice, that each our object has method toPage (). This similarity should force to reflect us on entering a new general{common} parental class. Let each class which is capable to create slices of the XML-document for page, will be inherited from a class which will care of XML-performance of object. We shall name it  Outputable.


Outputable.php



class Outputable

{

    / **

     * XML the container (string).

     */

    var $output = ";


    / **

     * To give contents of the container and to clear the container.

     *

     * @return string with the XML-given

     */

    function getOutput ()

    {

        $out = $this-> output;

        $this-> output = ";

        return $out;

}


    / **

     * To add a portion to contents of the container.

     *

     * @param string added string

     */

    function appendOutput ($string)

    {

        $this-> output. = $string. "n";

}


    / **

     * The "Abstract" method.

     */

    function toPage ()

    {

}

}


The method toPage () is made empty - in this case he is necessary as the indicator of how classes external "nested dolls" should communicate with an internal class. However, here it would be possible to offer realization by default if we have noticed, that there are many objects which equally deduce myself on page.


Classes Message and Inbox will change a little - now both they should be inherited from Outputable, and also methods toPage () will change also

Message.php



class Message extends Outputable

{


   / **

    * The maintenance{contents} of the message.

    */

   var $content;


   / **

    * The designer for initialization of the text of the message.

    *

    * @param content the maintenance{contents} of the message

    */

   function Message ($content)

   {

      $this-> content = $content;

}


   / **

    * Recording the message in session.

    */

   function send ()

   {

      $ _SESSION [' session_messages '] [] = $this-> content;

}


   / **

    * A conclusion of the message to page.

    */

   function toPage ()

   {

      $this-> appendOutput (' <message> '. $ this-> content. ' </message> ');

}


}


Inbox.php



class Inbox extends Outputable

{


   / **

    * A file of the acted{arrived} messages.

    */

   var $messages = array ();


   / **

    * In the designer it is received all acted{arrived} messages

    * Also we delete them from session.

    */

   function Inbox ()

   {

      if (is_array ($ _SESSION [' session_messages ']))

      {

         $messages = $ _SESSION [' session_messages '];

         $co = sizeof ($messages);

         for ($i = 0; $i <$co; $i ++)

         {

            $this-> messages [] = new Message ($messages [$i]);

}

}


/* We clear a file of messages */

      $ _SESSION [' session_messages '] = array ();

}


   / **

    * We deduce{remove} on page contents Inbox.

    */

   function toPage ()

   {

      $co = sizeof ($this-> messages);

      $this-> appendOutput (' <messages> ');

      for ($i = 0; $i <$co; $i ++)

      {

         $this-> messages [$i]-> toPage ();

         $this-> appendOutput ($this-> messages [$i]-> getOutput ());

}

      $this-> appendOutput (' </messages> ');

}


}


The way of a conclusion has changed - now instead of a direct conclusion to page external performance for the time being is stored{kept} in Outputable which "sits" in each of objects. The method appendOutput () serves as some replacement of a design echo (). To take away a conclusion of object, the method getOutput () is used.


Now we shall see, that itself the client part of a code which will solve the same problem , as represents earlier.

index.php



<? php


include (' Outputable.php ');

include (' Inbox.php ');

include (' Message.php ');


session_start ();


/* The XML-code */will accumulate here

$global_content = new Outputable;


if (' POST ' == $ _SERVER [' REQUEST_METHOD '])

{

/* The current minute */

   $msg_min = new Message (' minute '. date (' i '));

   $msg_min-> send ();


/* The current second */

   $msg_sec = new Message (' second: '. date (' s '));

   $msg_sec-> send ();


/* perenapravlenie on itself */

   header (' location: ');

   exit;

}

else

{


/* We prepare the list of messages as XML */

   $inbox = new Inbox ();

   $inbox-> toPage ();

   $global_content-> appendOutput ($inbox-> getOutput ());

}


$global_content-> appendOutput (' <refresh_form/> ');


$xml_string = $global_content-> getOutput ();


$xh = xslt_create ();

$xarg = array ();


/* Heading of the XML-document */

$xarg [' xml '] = ' <? xml version = " 1.0" encoding = "KOI8-R"?> '. "n";


/* A body of the XML-document */

$xarg [' xml ']. = ' <page> '. $xml_string. ' </page> ';


/* A XSL-pattern */

$xarg [' xsl '] = implode (", file (' style.xsl '));


/* We deduce{remove} a HTML-code - result of XSL-transformation */

echo xslt_process ($xh, ' arg:xml ',' arg:xsl ', NULL, $xarg);


/* We deduce{remove} a XML-source code (debug) */

echo ' <hr> <pre> '. htmlspecialchars ($xml_string.) ' </pre> ';

?>


The main innovation - in object $global_content which name speaks for itself. In this case he belongs to class Outputable, in real problems{tasks} you, probably, will create a separate class for a content of page.


If closely{attentively} to look narrowly, the substantial part of a script practically has not changed - the same inbox, the same toPage (). The instruction which contents of the list of messages deduce in a content of page is added. For a change now it is generated two messages.


To see at result, it are necessary to prepare a XSL-pattern only.

style.xsl



<? xml version = " 1.0" encoding = "KOI8-R"?>

<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = " 1.0">


<! - the main pattern which corresponds{meets} to a root element->

<xsl:template match = "/page">

<html>

<head>

<title> XSLT Example </title>

</head>

<body bgcolor = " * eeeeee ">


<! - we deduce{remove} the list of messages->

<xsl:apply-templates select = "/page/messages "/>


<! - we deduce{remove} the form->

<xsl:apply-templates select = "/page/refresh_form "/>


</body>

</html>

</xsl:template>


<! - a pattern for scenery of messages->

<xsl:template match = "/page/messages/message ">

<table border = "1" cellspacing = "0" cellpadding = "0">

<tr> <th> message </th> </tr>

<tr> <td class = "message"> <xsl:value-of select = "."/> </td> </tr>

</table>

</xsl:template>


<! - the pattern deduces the form with the button->

<xsl:template match = "/page/refresh_form ">

<form method = "POST" action = "index.php">

<input type = "submit"/>

</form>

</xsl:template>


</xsl:stylesheet>


That have we achieved?


First of all, it is possible to undertake more safely complex  projects - real independence of modules is provided. The order of stacking of results on page now is supervised with the help of an external XSL-pattern and does not depend on the order of start of modules.


Any module which generates the XML-given as result of the job, can be used in the project. By the way, this one of advantages before template-cursors, in which creation of the data consists in sequence of a call of methods (assign, etc.) a concrete cursor on which there is no general{common} standard.


One more advantage - ease of debugging. If you start a script will notice, that on each page there is a debug-conclusion - the XML-prototype which it is healthy simplifies debugging applications.


Of what it is necessary to think still - how to create the object - message. It is not always convenient to use new directly in a client code. But, perhaps, it is a subject for separate clause{article}.


At last, gallop about prospects:


* Pop-up windows for the list of the important messages

* "Pages - senders" and "pages - addressees" in messages

* Conducting a broad gully of messages in a database

* The button " to show a history of my actions "

* The statistical analysis of actions of users within the limits of sessions

* " Intellectual assistants " in webs - applications