RSS

Closures to Extend Variable Scope

Closures in JavaScript are a fairly straightforward concept, and have been discussed online in a number of in-depth articles. The fact that they are straightforward doesn’t necessarily mean they’re simple however, as seen by the extensive articles that cover the subject. To create a closure, you nest a function inside of a function. That inner function has access to all variables in its parent function’s scope. This comes in handy when creating methods and properties in object oriented scripts. Here is a simple example that demonstrates the use of a closure:

function myObject() {
  this.property1 = "value1";
  this.property2 = "value2";
  var newValue = this.property1;
 this.performMethod = function() { myMethodValue = newValue; return myMethodValue; };
  }
  var myObjectInstance = new myObject();
  alert(myObjectInstance.performMethod());

The key portions of the script are the nested anonymous function are highlighted in bold and the method call in the alert function (last line). Because the method in the alert is actually calling a nested function, that method is able to read the value of the variable called newValue, even thought that variable is not within the scope of the anonymous function, or method.

Developers use closures all the time, probably unknowingly, since a closure is created any time an anonymous function is nested inside another function and utilizes variables from the parent function’s scope. The power of the closure is revealed when that method (the inner function) is called, and values that normally wouldn’t be accessible are within “regional” scope and are thus able to be used as any other value.

 
Leave a comment

Posted by on June 13, 2011 in JavaScript, Scopes and Closures

 

JavaScript XMLHttpRequest readyState values

In JavaScript, possible readyState values after sending an XMLHttpRequest are:

0 = open has not yet been called
1 = send has not yet been called but open has been called
2 = send has been called but no response from server
3 = data is in the process of being received from the server
4 = response from server has arrived

 
Leave a comment

Posted by on June 10, 2011 in JavaScript, Mixed

 

JavaScript XMLHttpRequest responseText Property

Once an XMLHttpRequest has been initiated, sent and a response received, the XMLHttpRequest will have a responseText property. This property contains the server response, excluding headers.

Note that responseText is not fully loaded until the XMLHttpRequest readyState is 4. The responseText property can also contain a partial portion of the final result text if readyState is 3, which means that data is in the process of being received from the server.

To access this property: If an XMLHttpRequest call is saved in a variable named objXHR, the responseText can be accessed as objXHR.responseText.

 
Leave a comment

Posted by on June 10, 2011 in JavaScript, Mixed

 

The Hitchhikers Guide to PHP Load Balancing

There was once a time when running a big (or popular) web application meant running a big web server. As your application attracted more users you would add more memory and processors to your server.

Today, the ‘one huge server’ paradigm has been replaced with the idea of having a large number of smaller servers which employ one or more methods of balancing the load (known as ‘load balancing’) across the entire group (known as a ‘farm’ or ‘cluster’). This is partly down to the fall in hardware prices which made this approach more viable.

The advantages of ‘many small servers’ approach over the old ‘big server’ method are twofold:

If a server falls over then the load balancing system is normally clever enough to stop sending requests to the crashed machine and distribute the load across the remaining healthy servers.
It now becomes much easier to scale your infrastructure. All you need to do is plug a few new servers into the load balancer and away you go. No downtime necessary.
So there must be a catch… right? Well yes, it can make developing your applications a little more complex and this is what the remainder of the blog post will be covering.

At this point you may be saying to yourself, ‘ok, but how do I know if I am using this load balancing thingy’. The honest answer is that if you are asking this question then the answer is probably going to be that you are not using a load balanced system and you don’t need to worry too much. Most people explicitly setup load balancing when their applications grow to a size that demands it. However, I have occasionally seen web hosting companies that load balance their shared hosting accounts. These companies may tell you that they do this load balancing, or you may have to work it out for yourself based on the remainder of the blog post.

Before we continue I would like to point out that this post focuses on load balancing from the perspective of PHP (or your chosen server side language). I may write an additional blog post on database load balancing in the future, but for now that will have to wait.

A note on ‘web applications’: You may notice that I keep referring to ‘web applications’ rather than websites. I do this to distinguish between sites which simply display static content, and more advanced sites which are typically powered by databases and server-side programming.

Your PHP Files

The first question you may have is, ‘if there are lots of servers, how do I get my files onto all of them?’
There are a few of ways we can distribute our files to all of our servers:

  1. Upload all of our files to each server separately, just as we used to do with one server. This way clearly sucks because a) imagine doing this for 20 servers and b) it is far too easy to get something wrong and have different versions of your files on different servers.
  2. Use ‘rsync‘ (or similar). Such tools can sync local directories to multiple remote locations. An example of this would be syncing your single staging server with your multiple live servers.
  3. Use a version control system (such as subversion). This is my preferred method as I can maintain my code in subversion and then run an ‘svn update’ command on each live server when I am ready to make my changes live. This also makes rolling back changes particularly easy.
  4. Use a file server (you may find NFS useful). In this case you use a file server to store your web root directory/directories and then mount the share onto each of your web server. Of course, if your file server crashes then all your sites go down, and there can be a lot of overhead in pulling files from remote machines, especially if each request involves a large number of files.

The option you choose will depend on your requirements and the skills at your disposal. If you use a version control system then you may want to devise a way of running the update command on all servers simultaneously, whereas if you use a file server you may want to implement some form of failover system in case the file server crashes or becomes unreachable.

Uploads

A file upload is still a simple request, so the file will only be sent to one server. This is, of course, not a problem when you only have one server, but what do we do when there are several machines that the file needs to be placed on?

The problem of handling file uploads is very similar that of distributing your files across the server farm, and has the following potential solutions:

  1. Store your uploaded files in a database. Most databases allow you to store files in the form of binary data, so you can use a database to store you file uploads rather than storing them as files on disk. When you come to send the file to a user you can pull the file data from the database along with some extra data such as the file name and mime type. Before continuing down this route you should consider how much database storage you have at your disposal. This method also has quite a high overhead as the request needs to be passed though PHP, which then has to pull the data from the database.
  2. Store your uploaded files on a file server. Here, as with the previous section, you mount a fileserver share on each of your web servers and place your uploads there. This way the upload is available on all your web servers instantly. However, if the file server is unavailable then you may end up with broken images or downloads. Also, there is still an overhead in pulling files off a file server.
  3. Design your upload handling code to transfer the file to each server. This option does not have the disadvantages of using a file server or database but will probably complexity to your code. For example, what happens if one server is down at the time of the upload?

It is possible to reduce the overhead with the database storage option by keeping a local file cache. When a server receives a request for an uploaded file it first checks its local cache of uploaded files. If the file is found then it can be sent from the cache, otherwise it can be pulled from the database and the cache updated with the file.

Sessions

If you are familiar with PHP’s built in session handling you will probably know that by default it stores session data in temporary session files on the server. Again, this file is only present on the server which handled the request, but subsequent requests which use the session could be passed to any server in your farm. The result is that sessions are frequently not recognised, and the user is (for example) continually logged out.

The solution I recommend here is to either override PHP’s built in session handling and store the session data in your database, or implement some guaranteed way of always sending users to the same server. It may be easier to use the former given that larger applications will probably implement their own session handling anyway.

Configuration

I feel that configuration is worth covering here even though the topic is not just isolated to PHP. When running a server farm it is an excellent idea to have some way of keeping your configuration files in sync between servers, whether they are related to PHP or not. If your configuration files become out of sync it can lead to some very strange and intermittent behaviour that can be difficult to track down.

I recommend keeping most, if not all, of your configuration files in a separate area of your version control system. This way you can store different PHP configuration files for different installations of your projects, as well as keep all your server configuration files in sync.

Logging

Like configuration, logging is not solely related to PHP but it is still very important for keeping an eye on your servers’ health. Without a proper logging system how will you know if your PHP code starts producing errors (you do have display_errors set to ‘off’, right?)

There are a few ways you can implement logging:

  1. Log on each server – This is the simplest method available to you (aside from not logging at all!). Each machine simply logs to a file as it would do if it were not part of a larger farm. This has the benefit of being simple and requiring very little (if any) work to setup. However, as the number of servers you have begins to grow you may find that monitoring these individual log files become untenable.
  2. Log to a share – In this method each machine still has its own log files, but they are stored on a central file server and are written to via a share. This can make log monitoring simpler as all the logs are stored centrally, but there is an overhead in writing to log files on a share. Also, if the file server becomes unreachable your servers or applications may do anything from simply not logging messages to completely crashing.
  3. Log to logging server – You can use a logging application such as syslog to perform all your logging on a central server. Although this method requires the most configuration it also provides the most robust solution.

I have only covered a small area of logging here, the (very exciting! Ahem) topic of logging best practices could justify an entire blog post to itself. As always, I recommend choosing the technique best suited to your situation.

Conclusion

This blog post has given you an introduction to running your PHP applications on a larger scale. Most of the problems listed here stem from working with files, and the fact that these files often need to be shared between all the servers in your farm. It is therefore a good idea to think about the implications of load balancing when working with local files.

You can apply the techniques here if you are developing a large scale web application or if you work on projects which are distributed to a number of users or clients. For example, if you contribute to an open source project it is likely that some installations of your application will be run across several servers. It is therefore important to be aware of this when designing and creating your application.

 
Leave a comment

Posted by on June 9, 2011 in Mixed, PHP

 

Some techniques to optimize the mysql query

I would like to introduce you to some very simple techniques that can speed up your queries.

1) LIMIT:


Using the limit statement is the first and most critical query statement, because the dbms ( database management system ) will stop searching when it will found the necessery records. It reduces query time specially in tables with lots of records.

examples :

SELECT * FROM table WHERE field = 'value' LIMIT 10
                    UPDATE LOW_PRIORITY table SET field = 'value' WHERE field = 'value' LIMIT 1

 

2) UPDATE LOW_PRIORITY


When you are making an update in tables that their data are not about to be used immediately, you can use update statements with LOW_PRIORITY. This way the query will be stored in a buffer, and it will be executed when the server is not busy. This type of query is perfect for statistics, session control and rate it types of tables.

example :

UPDATE LOW_PRIORITY table SET field = 'value' WHERE field = 'value' LIMIT 1

 

3) Allways search indexed fields


When you are making SELECT statements try to insert indexed fields in the WHERE clause. To create an indexed field use this command:

ALTER TABLE `table` ADD INDEX ( `field` )

 

4) INSERT DELAYED statement


When you insert a record into a table, but you do not actually want it to be available in the exact moment, and you are not about to use the insert id of the record, you can use this statement. This way, the query will be puted to a buffer, and when the database is not busy, it will execute it. This way the server is not producing overhead, and the client get the requests faster.

example :

INSERT DELAYED INTO log_table VALUES ('1', '2', '3' )
 
Leave a comment

Posted by on June 8, 2011 in Mixed, PHP

 

Some caching techniques with PHP

In this article I will try to give a view of what is the custom caching with php, why and how we can use it.

In the modern days, most of the sites are database driven. That means that your site is actually an application which retrieves data from a DBMS ( database managment system, eg MySQL) , parses the data and shows the result to the user. Most of these data are usually don’t change frequently or don’t change at all, and the reason that we use the database is that we can easilly update the site and the content.

A problem that this process creates is the server overhead. Every time we execute a query in the database, the instance of our script will call the DBMS, and then the DBMS will send the results of the query. This is time consuming, and especcially for sites with heavy traffic is a real big problem.

How we can solve this problem?

There are two ways to solve this if you want to make your site faster. First is optimizing the queries, but we will not talk about this at the present article. The second and most valuable is using some kind of custom caching technique.

Custom caching with php

First let me explain the idea behind custom caching. When we have dynamic pages that their data is not updated frequently, we can use a ‘system’ that will be able to create the page, and then store it for later use. That means that after the page’s creation, our application will not run the queries again in order to display the page, but it will show the cached one. Of course this system must be able to keep the cached pages for a time period that we will set.

Let’s code it

Here is a simple class that will do the job. Let’s see the code first :

<?php
class cache
{
    var $cache_dir = './tmp/cache/';//This is the directory where the cache files will be stored;
    var $cache_time = 1000;//How much time will keep the cache files in seconds.

    var $caching = false;
    var $file = '';

    function cache()
    {
        //Constructor of the class
        $this->file = $this->cache_dir . urlencode( $_SERVER['REQUEST_URI'] );
        if ( file_exists ( $this->file ) && ( fileatime ( $this->file ) + $this->cache_time ) > time() )
        {
            //Grab the cache:
            $handle = fopen( $this->file , "r");
            do {
                $data = fread($handle, 8192);
                if (strlen($data) == 0) {
                    break;
                }
                echo $data;
            } while (true);
            fclose($handle);
            exit();
        }
        else
        {
            //create cache :
            $this->caching = true;
            ob_start();
        }
    }

    function close()
    {
        //You should have this at the end of each page
        if ( $this->caching )
        {
            //You were caching the contents so display them, and write the cache file
            $data = ob_get_clean();
            echo $data;
            $fp = fopen( $this->file , 'w' );
            fwrite ( $fp , $data );
            fclose ( $fp );
        }
    }
}

//Example :
$ch = new cache();
echo date("D M j G:i:s T Y");
$ch->close();
?>

Now let me explain:

function cache()

This is the constructor function of the class. The job of this function is to check if there is a cached file for the page that we want, or it should create it. Here is how this is done :
$this->file = $this->cache_dir . urlencode( $_SERVER[‘REQUEST_URI’] );

This line creates the file name of our cached page. So the cached file will be something like /path/to/cache/dir/request_uri

if ( file_exists ( $this->file ) && ( fileatime ( $this->file ) + $this->cache_time ) > time() )

Here we check if there is a cached version of this page, and if the file must be recreated because it has expired. If the file is cached, it will show the cached page and the exit. I will explain later why exit. If the cached file must be created this code will be executed :

$this->caching = true;
ob_start();

The first statement indicates to the close() function that it is creating the cache file, and the ob_start() will start buffering the output. The buffer’s data will be used later by the close() function to save the cache file.

function close()

This function must be called from the end of your script, and it will do the rest of the job. Actually it is needed only when we are in the process of caching that’s why it starts with the statement if ( $this->caching )

Let me explain what is happening here :

$data = ob_get_clean();

Here we get all the data from the output buffer while we unset it, and put the data in the $data variable. The four statements that folow up are showing the data and then write the cache file.

Troubleshooting

This is a very simple class, and the purpose is to learn how you can implement a caching solution for your site. The obligation using this class is that you must use it only in this form :

<?php
 $a = new cache();
 ....
 ....
 ....
 $a->close();
?>

If you have code after the $a->close() statement, the class will not work right. This is because of the exit() statement in the cache() function.

Of course you can take this code and make it work for your own needs.

A quick solution is to remove the exit() statement in the cache() function and then use the class this way :

<?php
 $a = new cache();
 if ( $a->caching )
 {
 ....
 ....
 ....
 }
 $a->close();
?>

Hope this helped.

 
Leave a comment

Posted by on June 8, 2011 in Mixed, PHP

 

Creating web services using PHP

First of all I want to explain or define what is web service ? You can think of web services as DLL files over the web you write the code then compile it and every one can use it whatever the language they are using , but in the web you don’t compile anything . Actually when I started using webservices , I was writing c# code so .Net was doing every thing for me. I couldn’t understand what is happening behind the scene I just type [webservice] above the function and everything is running. So In this article i ‘m going to explain what is happening.

How it works?

1) WSDL

First you have to define what you are serving. Think of it as a menu in a restaurant. You can define this by creating WSDL file (web service definition language). You actually define what are the functions you are using.

2) SOAP

You can consider SOAP as a waiter in a restaurant. He writes your order, delivers it to the kitchen and gets the food back to you, that is actually what the soap does; you encapsulate your request to a standard format that matches the definitions in your WSDL file. And the server in the return encapsulates the result into a standard format based also on the WSDL file; you can consider the WSDL file as the menu in the restaurant. You have to order something from the menu, and the kitchen has to deliver to you what you requested according to the details on the menu.

What do you need?

php soap

If you are using php 5 or more  on windows, go to your php.ini and uncomment the following line extension=php_soap.dll. When run your phpinfo you should see it installed.

If you are using linux, you can install it using the following line:

yum install php-soap

if you are using php 4 you can use nusoap

Creating your first web service

we are going to create a web service for a library , users can search for authors, books , browse each author’s books

Each author has the following :

author_id

author_name

And each book has the following:

book_id

book_name

author_id

We are going to assume that each book is written by only one author to simplify the example

Creating the WSDL file

I’m going now to create the WSDL file “menu”. Here is the code:

<?xml version="1.0" encoding="UTF-8"?>

<wsdl:definitions name="Library" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="Library" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="Library" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"  >

    <xsd:documentation></xsd:documentation>
    <wsdl:types>
     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="Library">
            <xsd:complexType name="Book">

                <xsd:sequence>
                 <xsd:element name="ID" type="xsd:integer"></xsd:element>
                 <xsd:element name="NAME" type="xsd:string" ></xsd:element>

                 <xsd:element name="AUTHOR" type="tns:Author" ></xsd:element>
                </xsd:sequence>
            </xsd:complexType>

            <xsd:complexType name="Author">

                <xsd:sequence>
                 <xsd:element name="ID" type="xsd:integer"></xsd:element>
                 <xsd:element name="NAME" type="xsd:string" ></xsd:element>

              <xsd:element name="BOOKS" type="tns:Book"
               minOccurs="0" maxOccurs="unbounded">
              </xsd:element>

             </xsd:sequence>
            </xsd:complexType>

            <xsd:complexType name="Authors">
                <xsd:sequence>
              <xsd:element name="AUTHOR" type="tns:Author"

               minOccurs="0" maxOccurs="unbounded">
              </xsd:element>
             </xsd:sequence>
            </xsd:complexType>

            <xsd:complexType name="Books">
                <xsd:sequence>
              <xsd:element name="BOOK" type="tns:Book"
               minOccurs="0" maxOccurs="unbounded">

              </xsd:element>
             </xsd:sequence>
            </xsd:complexType>
     </xsd:schema></wsdl:types>
  <wsdl:message name="searchAuthorsRequest">

   <wsdl:part name="NAME" type="xsd:string"></wsdl:part>
  </wsdl:message>
  <wsdl:message name="searchAuthorsResponse">
   <wsdl:part name="AUTHORS" type="tns:Authors"></wsdl:part>

  </wsdl:message>
  <wsdl:message name="searchBooksRequest">
   <wsdl:part name="NAME" type="xsd:string"></wsdl:part>
  </wsdl:message>

  <wsdl:message name="searchBooksResponse">
   <wsdl:part name="BOOKS" type="tns:Books"></wsdl:part>
  </wsdl:message>
  <wsdl:portType name="Library">

    <wsdl:operation name="searchAuthors">
      <wsdl:input message="tns:searchAuthorsRequest"/>
      <wsdl:output message="tns:searchAuthorsResponse"/>
    </wsdl:operation>

    <wsdl:operation name="searchBooks">
     <wsdl:input message="tns:searchBooksRequest"></wsdl:input>
     <wsdl:output message="tns:searchBooksResponse"></wsdl:output>
    </wsdl:operation>

 </wsdl:portType>
  <wsdl:binding name="Library" type="tns:Library">
   <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />

   <wsdl:operation name="searchAuthors">
    <soap:operation soapAction="http://localhost/Blog/Library/library.php" />
    <wsdl:input>
     <soap:body use="literal" namespace="Library" />

    </wsdl:input>

    <wsdl:output>
     <soap:body use="literal" namespace="Library" />
    </wsdl:output>

   </wsdl:operation>

   <wsdl:operation name="searchBooks">
    <soap:operation soapAction="http://localhost/Blog/Library/library.php" />
    <wsdl:input>

     <soap:body use="literal" namespace="Library" />
    </wsdl:input>
    <wsdl:output>
     <soap:body use="literal" namespace="Library" />

    </wsdl:output>
   </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="Library">
    <wsdl:port binding="tns:Library" name="YLibrary">

      <soap:address location="http://localhost/Blog/Library/library.php" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

the wsdl file contains main 4 parts :

  1. types
    You simply define the types that you are going to use , it looks like the variables definition in a PASCAL program.
  2. messages
    Each function in the web service has two messages; one for the input and the other for the output , also you can add one message to handle the exception.
  3. port type
    the port type combines one or more messages to represent a function. For example the “searchBooks” operation combines two messages; one for the input and one for the response.
  4. binding
    In the binding section , you define protocol details for the web service

I will create two classes to hold the data  one for books and the other for authors. Please notice that you have to name the members exactly the same way you did in the WSDL file.

The BookData class

<?php
class BookData {
     public $ID; 
     public $NAME; 
     public $AUTHOR; 
}
?>

The Author Data class

<?php
class AuthorData {
 public $ID; 
 public $NAME;
 public $BOOKS; 
}
?>

now I am going to create wrapper classes

Book class

<?php
class Book {
 private $_nID; 
 private $_strName; 

 public function __construct($ID,$Name){
  $this->SetID($ID); 
  $this->SetName($Name); 
 }
 public function SetID($ID){
  $this->_nID=mysql_real_escape_string($ID); 
 }

 public function GetID(){
  return $this->_nID; 
 }

 public function SetName($Name){
  $this->_strName=mysql_real_escape_string($Name); 
 }

 public function GetName () {
  return $this->_strName; 
 }

 public function CreateBook (){
  //Code to create Book
 }

 public function UpdateBook () {
  //code to update book 
 }

 public function DeleteBook () {
  //code to delete book 
 }
 public function SearchBooks () {
  $SQL = "SELECT * FROM books 
          INNER JOIN authors on books.author_id= authors.author_id
          WHERE books.book_name like '%{$this->_strName}%'";
  $Query = mysql_query($SQL) or die (mysql_error()); 
  $NumOfBooks = mysql_num_rows($Query); 
  $Result= array () ; 
  for ($i=0;$iID=mysql_result($Query, $i,"author_id");
    $Author->NAME=mysql_result($Query, $i,"author_name");
    //we will set this when we search by author name
    $Author->BOOKS=array(); 
    $Book = new BookData(); 
    $Book->ID = mysql_result($Query, $i,"book_id"); 
    $Book->NAME=mysql_result($Query, $i,"book_name");
    $Book->AUTHOR=$Author;

    $Result[]= $Book; 
  }
  return $Result; 
 }
}
?>

Author Class

<?php
class Author {

 private $_nID; 
 private $_strName; 

 public function __construct($ID,$Name){
  $this->SetID($ID); 
  $this->SetName($Name); 
 }

 public function SetID($ID){
  $this->_nID=mysql_real_escape_string($ID); 
 }

 public function GetID(){
  return $this->_nID; 
 }

 public function SetName($Name){
  $this->_strName=mysql_real_escape_string($Name); 
 }

 public function GetName () {
  return $this->_strName; 
 }

 public function CreateAuthor (){
  //Code to create Author
 }

 public function UpdateAuthor() {
  //code to update Author
 }

 public function DeleteAuthpr() {
  //code to delete Author
 }

 public function SearchAuthors() {
  $SQL = "SELECT * FROM authors WHERE authors.author_name like '%{$this->_strName}%'"; 
  $Query = mysql_query($SQL) or die (mysql_error()); 
  $NumOfAuthors= mysql_num_rows($Query); 

  $Result= array () ; 

  for ($i=0;$iID=mysql_result($Query, $i,"author_id");
                                $Author->NAME=mysql_result($Query, $i,"author_name");
    $Author->BOOKS=$this->GetBooksByAuthorID($Author->ID);  
    $Result[]= $Author; 
  }
  return $Result; 
 }

 public function GetBooksByAuthorID($ID){

  $SQL = "SELECT * FROM books WHERE author_id = $ID"; 

  $Query = mysql_query($SQL);  
  $NumOfBooks = mysql_num_rows($Query); 

  $Result = array () ; 

  for($i=0;$iID=mysql_result($Query, $i,"books.book_id");
    $Book->NAME=mysql_result($Query, $i,"books.book_name");

   $Result[]= $Book ; 

  }
  return $Result; 
 }
}
?>

Finally we will create php file who is supposed to receive the request from soap clients and return results. This file is the one written in the soap action attribute in the WSDL file.

library.php

<?php

mysql_connect("localhost","root",""); 
mysql_select_db("library");

function __autoload($ClassName) {
 require_once $ClassName.".php";
}

function searchAuthors ($NAME) {
 $Author = new Author(null, $NAME); 
 return $Author->SearchAuthors();
}

function searchBooks($NAME){
 $Book = new Book(null, $NAME); 
 return $Book->searchBooks();
}

ini_set("soap.wsdl_cache_enabled", "0"); 

$classmap = array(
 "Book"=>"BookData",
 "Author"=>"AuthorData"
);
$server = new SoapServer("Library.wsdl",array("classmap"=>$classmap));
$server->addFunction("searchAuthors"); 
$server->addFunction("searchBooks"); 
$server->handle();
?>

Please notice you have to create a map between your complex types and your classes “the ones that hold the data”.

For example here, I mapped between Book “the complex type in the WSDL file” and BookData “The php class”.

Now everything is ready. Lets call the web service:

index.php

<?php
$client = new SoapClient("http://localhost/Blog/Library/Library.wsdl",array("trace" => 1)); 
try
{
 $response = $client->searchAuthors("Beh");
 //$response = $client->searchBooks("comp");

 var_dump($response);
 echo "Request".htmlspecialchars($client->__getLastRequest())."";
 echo "Response".htmlspecialchars($client->__getLastResponse())."";

}catch(Exception $e){
 var_dump($e);
 echo $client->__getLastRequest();
 echo $client->__getLastResponse();
}
?>
 
Leave a comment

Posted by on June 8, 2011 in Mixed, PHP