The task on the server side is usually to perform logical operations according to the client's request and return the result response. This response is usually in XML format (so the server side needs to use PHP's DOM to create an XML response)
1. PHP uses DOM to create an XML response, which is parsed by the client's JS and then displayed on the page; (so you need to be proficient in PHP's DOM API)
In fact, there are two ways to generate XML in PHP:
Use DOM API; (Method 1)
The other is to directly echo the XML content; (Method 2)
See example:
HTML page (contains three JS trigger functions: onmouseover, onmouseout, onclick; trigger their own functions respectively)
<!doctype html public "-//w3c//dtd html 4.0 tRANSITIONAL//en">
<html>
<head>
<title> Server PHP Ajax </title>
<script type="text/javascript" src="js.js"></script>
</head>
<body>
<span onmouseover="PHPechoXML()" onmouseout="PHPDOMXML()">Default Words</span>
<div id="show"></div>
divide<input type="text" id="firstNumber"/>by
<input type="text" id="secondNumber"/>
<input type="button" value="Send" onclick="CSparameter()"/>
<div id="result"></div>
</body>
</html>
JS page (define three JS trigger functions respectively: PHPechoXML, PHPDOMXML, and CSparameter)
There are XMLHttpRequest object creation functions and respective Server response processing functions.
///////1. Create XMLHttpRequest object
var xmlHttp = createXmlHttpRequestObject();
function createXmlHttpRequestObject()
...{
var xmlHttp;
try
...{
// try to create XMLHttpRequest object
xmlHttp = new XMLHttpRequest();
}
catch(e)
...{
// assume IE6 or older
var XmlHttpVersions = new Array('MSXML2.XMLHTTP.6.0',
'MSXML2.XMLHTTP.5.0',
'MSXML2.XMLHTTP.4.0',
'MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP',
'Microsoft.XMLHTTP');
for (var i=0; i<XmlHttpVersions.length && !xmlHttp; i++)
...{
try
...{
// try to create XMLHttpRequest object
xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
}
catch (e) ...{}
}
}
if (!xmlHttp)
alert("Error creating the XMLHttpRequest object.");
else
return xmlHttp;
}
///////2. JavaScript event response function (onmouseover trigger)
// read a file from the server
function PHPichoXML()
...{
// only continue if xmlHttp isn't void
if(xmlHttp)
...{
// try to connect to the server
try
...{
//initiate reading a file from the server
//Send an asynchronous request to the PHPechoXML.php file on the server side
xmlHttp.open("GET", "PHPechoXML.php", true);
xmlHttp.onreadystatechange = handleRequestStateChange;
xmlHttp.send(null);
}
// display the error in case of failure
catch (e)
...{
alert("Can't connect to server: " + e.toString());
}
}
}
///////3. JavaScript event response function (onmouseout trigger)
functionPHPDOMXML()
...{
// only continue if xmlHttp isn't void
if(xmlHttp)
...{
// try to connect to the server
try
...{
//initiate reading a file from the server
//Send an asynchronous request to the PHPDOMXML.php file on the server side
xmlHttp.open("GET", "PHPDOMXML.php", true);
xmlHttp.onreadystatechange = handleRequestStateChange;
xmlHttp.send(null);
}
// display the error in case of failure
catch (e)
...{
alert("Can't connect to server: " + e.toString());
}
}
}
// handles the response received from the server, server-side status callback function
function handleRequestStateChange()
...{
if (xmlHttp.readyState == 4)
...{
// continue only if HTTP status is "OK"
if (xmlHttp.status == 200)
...{
try
...{
// read the message from the server
var xmlResponse = xmlHttp.responseXML;
//Capture potential errors in IE and Opera
if(!xmlResponse||!xmlResponse.documentElement)
...{
throw("Invalid XML structure: "+xmlHttp.responseText);
}
//Capture potential errors in FireFox
var rootNodeName=xmlResponse.documentElement.nodeName;
if(rootNodeName=="parsererror")
...{
throw("Invalid XML structure: "+xmlHttp.responseText);
}
//Get the XML response from the server, parse it, and display it on the web page
//obtain the XML's document element
xmlRoot = xmlResponse.documentElement;
// obtain arrays with book titles and ISBNs
cityArray=xmlRoot.getElementsByTagName("city");
//generate HTML output
var html = "";
// iterate through the arrays and create an HTML structure
for (var i=0; i<cityArray.length; i++)
html += cityArray.item(i).firstChild.data + "<br/>";
// obtain a reference to the <div> element on the page
myDiv = document.getElementById("show");
// display the HTML output
myDiv.innerHTML = "Server says: <br />" + html;
}
catch(e)
...{
//display error message
alert("Error reading the response: " + e.toString());
}
}
else
...{
//display status message
alert("There was a problem retrieving the data: " +
xmlHttp.statusText);
}
}
}
///////4. JavaScript event response function (onclick trigger)
function CSparameter()
...{
// only continue if xmlHttp isn't void
if(xmlHttp)
...{
// try to connect to the server
try
...{
//Get the value in the form
var firstNumber=document.getElementById("firstNumber").value;
var secondNumber=document.getElementById("secondNumber").value;
//Set as a parameter to make an asynchronous request to CSparameter.php on the server side
var param="firstNumber="+firstNumber+"&secondNumber="+secondNumber;
// initiate reading a file from the server
xmlHttp.open("GET", "CSparameter.php?"+param, true);
xmlHttp.onreadystatechange = handleRequestStateChangePara;
xmlHttp.send(null);
}
// display the error in case of failure
catch (e)
...{
alert("Can't connect to server: " + e.toString());
}
}
}
//Server status change callback function (the server accepts the parameters from the client and returns an XML response after logical calculation. The client parses the XML and returns the updates to the page)
// handles the response received from the server
function handleRequestStateChangePara()
...{
if (xmlHttp.readyState == 4)
...{
// continue only if HTTP status is "OK"
if (xmlHttp.status == 200)
...{
try
...{
// read the message from the server
var xmlResponse = xmlHttp.responseXML;
//Capture potential errors in IE and Opera
if(!xmlResponse||!xmlResponse.documentElement)
...{
throw("Invalid XML structure: "+xmlHttp.responseText);
}
//Capture potential errors in FireFox
var rootNodeName=xmlResponse.documentElement.nodeName;
if(rootNodeName=="parsererror")
...{
throw("Invalid XML structure: "+xmlHttp.responseText);
}
//obtain the XML's document element
xmlRoot = xmlResponse.documentElement;
cityArray=xmlRoot.getElementsByTagName("result");
//generate HTML output
var html = "";
// iterate through the arrays and create an HTML structure
for (var i=0; i<cityArray.length; i++)
html += cityArray.item(i).firstChild.data + "<br/>";
// obtain a reference to the <div> element on the page
myDiv = document.getElementById("result");
// display the HTML output
myDiv.innerHTML = "Server says: <br />" + html;
}
catch(e)
...{
//display error message
alert("Error reading the response: " + e.toString());
}
}
else
...{
//display status message
alert("There was a problem retrieving the data: " +
xmlHttp.statusText);
}
}
}
Server-side PHP script (responsible for accepting asynchronous requests from the Client, responding to them, and returning them to the Client in XML format)
PHEchoXML.php (the first method for PHP to generate XML response, echo outputs XML content)
<?php
//The first method for server-side PHP to generate XML files is to echo the XML directly.
header('Content-Type: text/xml');
//generate XML header
echo '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
echo '<cities>';
$cityArray=array('Paris','London','NewYork','Beijing','Tokoy');
foreach ($cityArray as $city)
{
echo '<city>'.$city.'</city>';
}
echo '</cities>';
?>
PHPDOMXML.php (The second method for PHP to generate an XML response, using PHP's DOM API to output a response in XML format)
<?php
header('Content-Type: text/xml');
$cityArray=array('Shanghai','Beijing','Shanxi','Shandong');
//Create an XML document
$dom=new DOMDocument();
//Outermost Tag
$citiesTag=$dom->createElement('cities');
$dom->appendChild($citiesTag);
//The Tag inside can be generated through looping
foreach ($cityArray as $city)
{
$cityTag=$dom->createElement('city');
$cityName=$dom->createTextNode($city);
$cityTag->appendChild($cityName);
$citiesTag->appendChild($cityTag);
}
//Save the XML structure as a string and output it
$xmlString=$dom->saveXML();
echo $xmlString;
?>
2. Parameter transfer between client side and server side:
There can be a form in the client-side web page, so that parameters can be passed to the server-side <GET or POST method, variable or XML>, and the server-side generates an XML response that meets the requirements based on the passed parameters; (implemented client-side and server-side parameters interaction)
See example:
As in 1, the script on the PHP side for parameter passing is as follows CSparameter.php (accepts the parameters of the client form asynchronous request, performs logical processing, and generates an XML response to send back to the client) <?php
//Customize the error handling function on the server side
require_once('error_handler.php');
header('Content-Type: text/xml');
//Accept parameters of client asynchronous request
$firstNumber=$_GET['firstNumber'];
$secondNumber=$_GET['secondNumber'];
//Perform logical calculations
$result=$firstNumber/$secondNumber;
//Generate a response in XML format and return it to the Client
$dom=new DOMDocument();
$resultsTag=$dom->createElement('results');
$dom->appendChild($resultsTag);
$resultTag=$dom->createElement('result');
$resultText=$dom->createTextNode($result);
$resultTag->appendChild($resultText);
$resultsTag->appendChild($resultTag);
$xmlString=$dom->saveXML();
echo $xmlString;
?>
3. Handling of error exceptions on the PHP side (the errors or exceptions mentioned here refer to logical errors):
a) By default, PHP will not throw an exception when an error or exception occurs (this is because the default display_errors in php.ini is set to off, and the error will be saved in the Apache error log record), so it is written Hard to debug. <It is often difficult to locate errors displayed by the browser>
b) But if display_errors is set to on, the error will be displayed, but the error message will be unfriendly.
http://www.downcodes.com/
c) You can write your own PHP error exception handling function (display_errors is not necessarily required to be set to on) to display errors in an obvious way for easy debugging;
Usually you write your own exception handling function as follows:
Display the defined server-side error exception throwing function error_handler.php (can be easily reused in PHP programs)
<?php
//set a user-defined error handler function user-defined error exception handling method
set_error_handler('error_handler', E_ALL);
function error_handler($errNo,$errStr,$errFile,$errLine)
{
//If the output buffer is not empty, empty it
if(ob_get_length()) ob_clean();
//Define custom output
$error_message='ERRNO: '.$errNo.chr(10).'TEXT: '.$errStr.chr(10).'LOCATION: '.$errFile.', Line'.$errLine;
echo $error_message;
exit;
}
?>
4. Server-side access to database <Use MySQL to access data to achieve true dynamics>
This is already very classic, you can use MySQL, MSSQL, Oracle, etc.
a) Open the database; b) SQL statement Query c) Close the database
5. Server-side PHP program encapsulation and architecture (server-side PHP program introduces design mode)
a) appname.php <Accept client request>
b) appname.class.php <Encapsulate server-side logic, database operations, error handling, etc. into classes, including attributes, methods, constructors, and destructors>
c) config.php
d) error_handler.php
is an example of introducing design patterns on the server side: (Design the program architecture of server-side PHP scripts to enhance scalability and reusability)
A very simple Keywords Suggest program: (including index.html, css/style.css, js.js and PHP code php/suggest.php, suggest.class.php, error_handler.php, config.php supports database)
index.html(css/style.css, js.js; note that two JS client events trigger onkeyup, onclick)
onkeyup sends a request to the server asynchronously in real time when the user inputs, and the server responds; onclick sends a request to the server when the user clicks search.
<!doctype html public "-//w3c//dtd html 4.0 tRANSITIONAL//en">
<html>
<head>
<title> Design Pattern PHP AJAX (keywords suggest DEMO) </title>
<link type="text/css" rel="stylesheet" href="css/style.css"/>
<script type="text/javascript" src="js.js"></script>
</head>
<body>
<noscript>
<strong>This example requires a JavaScript-enabled browser!</strong>
</noscript>
<div class="project">
<span class="title">Welcome to Design Pattern PHP AJAX (keywords suggest DEMO) </span>
<br />
<br />
<div class="news">
<br /><input type="text" id="keyword" onkeyup="keyup()" /><input type="button" id="search" onclick="search()" value="search"> <br /><br />
suggest keywords:
<div id="show"></div>
</div>
</div>
</body>
</html>
css/style.css
body
{...}{
font-family: Arial;
font-size: small;
background-color: #fff;
}
.title
{...}{
font-size:x-large;
}
div.project
{...}{
background-color: #99ccff;
padding:5px;
border:#000099 1px solid;
}
div.news
{...}{
background-color:#fffbb8;
padding:2px;
border: 1px dashed;
}
#show
{...}{
color: #008000;
font-style: italic;
}js.js (define response function in JS and callback function for Client to process Server response)
///////////////////////////////////////////////////// /////////
//1. Create XMLHttpRequest object
///////////////////////////////////////////////////// /////////
var xmlHttp = createXmlHttpRequestObject();
function createXmlHttpRequestObject()
...{
var xmlHttp;
try
...{
// try to create XMLHttpRequest object
xmlHttp = new XMLHttpRequest();
}
catch(e)
...{
// assume IE6 or older
var XmlHttpVersions = new Array('MSXML2.XMLHTTP.6.0',
'MSXML2.XMLHTTP.5.0',
'MSXML2.XMLHTTP.4.0',
'MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP',
'Microsoft.XMLHTTP');
for (var i=0; i<XmlHttpVersions.length && !xmlHttp; i++)
...{
try
...{
// try to create XMLHttpRequest object
xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
}
catch (e) ...{}
}
}
if (!xmlHttp)
alert("Error creating the XMLHttpRequest object.");
else
return xmlHttp;
}
//Display the correct response from the server to the div with the id of show
function display(message)
...{
showDIV=document.getElementById("show");
showDIV.innerHTML=message;
}
//Display the error message of the server-side response to the div with the id of show
function displayError(errormessage)
...{
//Display error message
display("Error retrieving the new message!<br/>"+errormessage);
}
//////////////////////////////////////////////////// //////////
//2. event-driven function (keyup function)
///////////////////////////////////////////////////// /////////
var keyupAddress="php/suggest.php?action=keyup&keyword=";
function keyup()
...{
if(xmlHttp)
...{
//Send an asynchronous request when the server is not busy
if(xmlHttp.readyState==0||xmlHttp.readyState==4)
...{
try
...{
var keyword=document.getElementById("keyword").value;
//Make an asynchronous request
xmlHttp.open("GET",keyupAddress+keyword,true);
xmlHttp.onreadystatechange=handlereadystatechange;
xmlHttp.send(null);
}
catch(e)
...{
displayError(e.toString);
}
}
}
}
///////////////////////////////////////////////////// /////////
//3. Callback function, this function is triggered when the server response status changes.
///////////////////////////////////////////////////// /////////
function handlereadystatechange()
...{
if(xmlHttp.readyState==4)
...{
if(xmlHttp.status==200)
...{
try
...{
//Get server response
var xmlResponse = xmlHttp.responseXML;
suggestArray=xmlResponse.getElementsByTagName("suggest");
var showText="";
for(var i=0;i<suggestArray.length;i++)
...{
var textNodes=suggestArray[i].getElementsByTagName("text");
var timesNodes=suggestArray[i].getElementsByTagName("times");
for(var j=0;j<textNodes.length;j++)
...{
showText+=textNodes[j].childNodes[0].nodeValue+" ("+timesNodes[j].childNodes[0].nodeValue+") <br />";
}
}
//Display the response to the page
display(showText);
}
catch(e)
...{
displayError(e.toString());
}
}
}
}
///////////////////////////////////////////////////// /////////
//2. event-driven function (search function)
///////////////////////////////////////////////////// /////////
var searchAddress="php/suggest.php?action=search&keyword=";
function search()
...{
if(xmlHttp)
...{
//Send an asynchronous request when the server is not busy
if(xmlHttp.readyState==0||xmlHttp.readyState==4)
...{
try
...{
var keyword=document.getElementById("keyword").value;
//Make an asynchronous request
xmlHttp.open("GET",searchAddress+keyword,true);
xmlHttp.onreadystatechange=handlereadystatechange;
xmlHttp.send(null);
}
catch(e)
...{
displayError(e.toString);
}
}
}
}
Final note: The program structure of the server-side PHP script (suggest.php is the main processing function on the server side, and there are also suggest.class.php, error_handler.php, config.php, etc.)
suggest.php (get the parameters of the client, and call the two methods of the suggest class to generate a response in XML format and send it back to the client)
<?php
require_once('suggest.class.php');
header('Content-Type: text/xml');
//Make sure the user's browser will not cache the results
header('Expires: Wed, 23 Dec 1980 00:30:00 GMT');
header('Last-Modified: '.gmdate('D, d MYH:i:s').' GMT' );
header('Cache-Control: no-cache, must-revalidate');
header('Pragma: no-cache');
$action=$_GET['action'];
$keyword=$_GET['keyword'];
$oSuggest=new suggest();
if($action=='keyup'&&$keyword!='')
{
$suggestXML=$oSuggest->getSuggests($keyword);
}
if($action=='search'&&$keyword!='')
{
$suggestXML=$oSuggest->submitKeyword($keyword);
}
echo $suggestXML;
?>suggest.class.php class
<?php
require_once('error_handler.php');
require_once('config.php');
class suggest
{
//Member variables
private $conn;
//Constructor, database link
function__construct()
{
$this->conn=new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE);
if (mysqli_connect_errno()) {
printf("Connect failed: %s ", mysqli_connect_error());
exit();
}
}
//Destructor, disconnect the database link
function __destruct()
{
$this->conn->close();
}
//getSuggests member function (this function mainly responds to Client-side action=keyup, that is, an asynchronous request when the user is typing)
public function getSuggests($keyword)
{
//Generate suggestion (generate keywords in the database that are the same as the first half of the entered keyword)
$suggest_query='select * from keywords where keyword like ''.$keyword.'%' order by times desc limit 5';
$suggest_result=$this->conn->query($suggest_query);
$suggest_num=$suggest_result->num_rows;
$strOUT='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
if($suggest_num==0)
{
//$strOUT=$strOUT.'<suggests><suggest><text>'.$keyword.'</text><times>0</times></suggest></suggests>';
}
else
{
$strOUT=$strOUT."<suggests>";
for($i=0;$i<$suggest_num;$i++)
{
$suggest_row = $suggest_result->fetch_row();
$strOUT=$strOUT.'<suggest><text>'.$suggest_row[1].'</text><times>'.$suggest_row[2].'</times></suggest>';
}
$strOUT=$strOUT.'</suggests>';
}
return $strOUT;
}
//submitKeyword member function (this function mainly responds to Client-side action=search, that is, the asynchronous request when the user clicks search)
public function submitKeyword($keyword)
{
$select_query='select * from keywords where keyword=''.$keyword.''';
$select_result=$this->conn->query($select_query);
$select_num=$select_result->num_rows;
//Add new keywords to the database when encountering them, and increase the number of existing keywords when encountering them.
$strOUT='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
//Already exists, increase the number of times
if($select_num!=0)
{
$select_row = $select_result->fetch_row();
$times_now=$select_row[2];
$times_now=$times_now+1;
$update_query='update keywords set times ='.$times_now.' where keyword=''.$keyword.''';
$update_result=$this->conn->query($update_query);
$strOUT=$strOUT.'<suggests><suggest><text>'.$keyword.'</text><times>'.$times_now.'</times></suggest></suggests>';
}
else
{
//No save insertion
$insert_query='insert into keywords(keyword, times) values (''.$keyword.'',1)';
$insert_result=$this->conn->query($insert_query);
$strOUT=$strOUT.'<suggests><suggest><text>'.$keyword.'</text><times>1</times></suggest></suggests>';
}
return $strOUT;
}
}
?>
The last two functions, config.php save application configuration information (such as database configuration information)
<?php
define('DB_HOST', 'localhost');
define('DB_USER','phpajaxuser');
define('DB_PASSWORD','phpajaxuser');
define('DB_DATABASE','phpajax');
?>
error_handler.php saves custom exception handling
<?php
//Set user-defined error handling function
set_error_handler('error_handler', E_ALL);
function error_handler($errNo,$errStr,$errFile,$errLine)
{
if(ob_get_length()) ob_clean();
$error_message='ERRNO: '.$errNo.chr(10).'TEXT: '.$errStr.chr(10).'LOCATION: '.$errFile.' Line: '.$errLine;
echo $error_message;
exit;
}
?>Finally, sql statements are needed to add the database for saving keywords to the database.
CREATE TABLE `keywords` (
`id` int(10) unsigned NOT NULL auto_increment,
`keyword` varchar(32) NOT NULL default '',
`times` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`id`)
) TYPE=MyISAM AUTO_INCREMENT=1;
6. Little knowledge about PHP for future research:
How PHP reads data from a remote server (somewhat similar to Web Crawl):
file_get_contents;
Or CURL<Client URL Library>www.php.net/curl