Explore Open Source Technology

Lets Explore Power of Open Source Technology PHP, MYSQL, APACHE, LINUX(LAMP)

Archive for September, 2007

ZEND FRAMEWORK

Posted by openstech on September 13, 2007

Zend Framework Documentation

Component Goals & Benefits

Succinct descriptions of the major components of Zend Framework, their goals, and benefits. Each developer in the Zend Framework community who worked on a component has explained their thinking behind its design. This includes:

  • High level goals for each component
  • Design intent of the component
  • Benefit gained from using this component
  • A link to the Programmer’s Reference Guide for that component

Programmer’s Reference Guide

Written in a book format, it contains the information a developer needs to actually understand and use each Zend Framework component. Such as:

  • Description & goals for a particular component
  • Details on the various capabilities of the components
  • Code snippets on how to use the component to accomplish real world examples

API Guide

The API Guide is low level phpdoc information for the Zend Framework components. It is useful for developers needing detailed reference information. It contains information such as:

  • Interface information
  • Details on how program elements interact, which elements use others
  • Where in the source code an action or series of actions occurs
  • How to extend the code to add new functionality

Posted in framework | Tagged: | No Comments »

Difference Between PHP4 & PHP5

Posted by openstech on September 13, 2007

Here’s a quick overview of what has changed between PHP4 and PHP5. PHP5 for the most part is backwards compatible with PHP4, but there are a couple key changes that might break your PHP4 script in a PHP5 environment. If you aren’t already, I stronly suggest you start developing for PHP5. Many hosts these days offer a PHP5 environment, or a dual PHP4/PHP5 setup so you should be fine on that end. Using all of these new features is worth even a moderate amount of trouble you might go through finding a new host!

Note: Some of the features listed below are only in PHP5.2 and above.

Object Model
The new OOP features in PHP5 is probably the one thing that everyone knows for sure about. Out of all the new features, these are the ones that are talked about most!

Passed by Reference
This is an important change. In PHP4, everything was passed by value, including objects. This has changed in PHP5 — all objects are now passed by reference.

PHP Code:

$joe = new Person();
$joe->sex = ‘male’;
$betty = $joe;
$betty->sex = ‘female’;echo $joe->sex; // Will be ‘female’
The above code fragment was common in PHP4. If you needed to duplicate an object, you simply copied it by assigning it to another variable. But in PHP5 you must use the new clone keyword.Note that this also means you can stop using the reference operator (&). It was common practice to pass your objects around using the & operator to get around the annoying pass-by-value functionality in PHP4.

Class Constants and Static Methods/Properties
You can now create class constants that act much the same was as define()’ed constants, but are contained within a class definition and accessed with the :: operator.

Static methods and properties are also available. When you declare a class member as static, then it makes that member accessible (through the :: operator) without an instance. (Note this means within methods, the $this variable is not available)

Visibility
Class methods and properties now have visibility. PHP has 3 levels of visibility:

  1. Public is the most visible, making methods accessible to everyone and properties readable and writable by everyone.
  2. Protected makes members accessible to the class itself and any subclasses as well as any parent classes.
  3. Private makes members only available to the class itself.

Unified Constructors and Destructors
PHP5 introduces a new unified constructor/destructor names. In PHP4, a constructor was simply a method that had the same name as the class itself. This caused some headaches since if you changed the name of the class, you would have to go through and change every occurrence of that name.

In PHP5, all constructors are named __construct(). That is, the word construct prefixed by two underscores. Other then this name change, a constructor works the same way.

Also, the newly added __destruct() (destruct prefixed by two underscores) allows you to write code that will be executed when the object is destroyed.

Abstract Classes
PHP5 lets you declare a class as abstract. An abstract class cannot itself be instantiated, it is purely used to define a model where other classes extend. You must declare a class abstract if it contains any abstract methods. Any methods marked as abstract must be defined within any classes that extend the class. Note that you can also include full method definitions within an abstract class along with any abstract methods.

Interfaces
PHP5 introduces interfaces to help you design common APIs. An interface defines the methods a class must implement. Note that all the methods defined in an interface must be public. An interface is not designed as a blueprint for classes, but just a way to standardize a common API.

The one big advantage to using interfaces is that a class can implement any number of them. You can still only extend on parent class, but you can implement an unlimited number of interfaces.

Magic Methods
There are a number of “magic methods” that add an assortment to functionality to your classes. Note that PHP reserves the naming of methods prefixed with a double-underscore. Never name any of your methods with this naming scheme!

Some magic methods to take note of are __call, __get, __set and __toString. These are the ones I find most useful.

Finality
You can now use the final keyword to indicate that a method cannot be overridden by a child. You can also declare an entire class as final which prevents it from having any children at all.

The __autoload Function
Using a specially named function, __autoload (there’s that double-underscore again!), you can automatically load object files when PHP encounters a class that hasn’t been defined yet. Instead of large chunks of include’s at the top of your scripts, you can define a simple autoload function to include them automatically.

PHP Code:

function __autoload($class_name) {
require_once
“./includes/classes/$class_name.inc.php”;
}

Note you can change the autoload function or even add multiple autoload functions using spl_autoload_register and related functions.

Standard PHP Library
PHP now includes a bunch of functionality to solve common problems in the so-named SPL. There’s a lot of cool stuff in there, check it out!

For example, we can finally create classes that can be accessed like arrays by implementing the ArrayAccess interface. If we implement the Iterator interface, we can even let our classes work in situations like the foreach construct.

Miscellaneous Features

Type Hinting
PHP5 introduces limited type hinting. This means you can enforce what kind of variables are passed to functions or class methods. The drawback is that (at this time), it will only work for classes or arrays — so no other scalar types like integers or strings.

To add a type hint to a parameter, you specify the name of the class before the $. Beware that when you specify a class name, the type will be satisfied with all of its subclasses as well.

PHP Code:

function echo_user(User $user) {
echo
$user->getUsername();
}

If the passed parameter is not User (or a subclass of User), then PHP will throw a fatal error.

Exceptions
PHP finally introduces exceptions! An exception is basically an error. By using an exception however, you gain more control the simple trigger_error notices we were stuck with before.

An exception is just an object. When an error occurs, you throw an exception. When an exception is thrown, the rest of the PHP code following will not be executed. When you are about to perform something “risky”, surround your code with a try block. If an exception is thrown, then your following catch block is there to intercept the error and handle it accordingly. If there is no catch block, a fatal error occurs.

PHP Code:

try {
$cache->write();
}
catch (AccessDeniedException $e) {
die(
‘Could not write the cache, access denied.’);
}
catch (Exception $e) {
die(
‘An unknown error occurred: ‘ . $e->getMessage());
}

E_STRICT Error Level
There is a new error level defined as E_STRICT (value 2048). It is not included in E_ALL, if you wish to use this new level you must specify it explicitly. E_STRICT will notify you when you use depreciated code. I suggest you enable this level so you can always stay on top of things.

Foreach Construct and By-Reference Value
The foreach construct now lets you define the ‘value’ as a reference instead of a copy. Though I would suggest against using this feature, as it can cause some problems if you aren’t careful:

PHP Code:

foreach($array as $k => &$v) {
// Nice and easy, no working with $array[$k] anymore
$v = htmlentities($v);
}
// But be careful, this will have an unexpected result because
// $v will still be a reference to the last element of the $array array
foreach($another_array as $k => $v) {}
New Functions
PHP5 introduces a slew of new functions. You can get a list of them from the PHP Manual.
New Extensions
PHP5 also introduces new default extensions.

  • SimpleXML for easy processing of XML data
  • DOM and XSL extensions are available for a much improved XML-consuming experience. A breath of fresh air after using DOMXML for PHP4!
  • PDO for working with databases. An excellent OO interface for interacting with your database.
  • Hash gives you access to a ton of hash functions if you need more then the usual md5 or sha1.

Compatibility Issues
The PHP manual has a list of changes that will affect backwards compatibility. You should definately read through that page, but here is are three issues I have found particularly tiresome:

  • array_merge() will now give you warnings if any of the parameters are not arrays. In PHP4, you could get away with merging non-arrays with arrays (and the items would just be added if they were say, a string). Of course it was bad practice to do this to being with, but it can cause headaches if you don’t know about it.
  • As discussed above, objects are now passed by references. If you want to copy a object, make sure to use the clone keyword.
  • get_*() now return names as they were defined. If a class was called MyTestClass, then get_class() will return that — case sensitive! In PHP4, they were always returned in lowercase.

Posted in web development in php | Tagged: , , | No Comments »

Apache Web Server

Posted by openstech on September 12, 2007

Basically for communication where there is a client-server flavor, the server process creates a socket and the client socket accesses the server through client socket techniques.

Socket

A socket is fundamentally nothing but an end point of communication. It can be of two types: Physical socket and Logical socket. In Logical socket operating system has its system calls, which creates them. Now for client-server access the socket needs three things to provide service or ask for service.
1) Service name (example: telnet)
2) Protocol (TCP-stream)
3) Port no (23)
The service uses protocol and protocol uses port number to provide service at server end and to get service at client end. Ultimately we find that the port number is mainly responsible for a client server communication. The protocols supported by Linux is shown by /etc/protocols and the services can be seen in /etc/services.

Let’s take few more examples then start with Web server.
* telnet service uses TCP/IP protocol and communicate through port no. 23
* ftp service uses TCP/IP protocol and communicate through 20,21 port numbers
* www service uses http protocol and communicate through port no 80.

Web communication

Web communication deals with a browser type of client process and Web server type of server process. What actually happens when a user writes http://www.yahoo.com? Well, the browser transfers the URL to current machine’s operating system with a destination address’ operating system, which is responsible for extracting protocol i.e. “http” from the client socket (browsers) and then it packets data using layer software and over the packet it attaches the header http. This enables the remote machine to hand over the request to Web server of remote machine. Why so? Because there can be many a server running on the same machine so the particular services are distinguished by their protocol.

But how should we explain when telnet and ftp both are using same protocol but have different server Processes? The answer is that they are distinguished by their port numbers. Services may have same protocol but not the same port number. After this the operating system throws the data to network interface card through the ram and then network interface card gives it to nearest gateway, which sends the data to the server machine at server end.

The network card gives a signal back to operating system that a data enclosed with http header using TCP/IP header has arrived. One’s operating system checks that data has http wrapper and searches for Web server on that machine. When it finds, it hands over the data and pays attention to other processes.

Before the Web server processes the data, it goes through a filtration by the gateway process implemented on the Web server, which actually filters the raw data. This concept implemented is called as common gateway interface that has the Web server environment variables, which stores the data in different variable. When the user asks for some unnecessary data, headers also get attached with data and so the need for filtration.

Apache as Web server

Setup:
The Web server is meant for keeping Websites. There are three ways a Website can be stored. They are:
1) default directory hosting
2) virtual directory hosting
3) virtual domain hosting

We have to first configure the DNS. Then configure the following file (redhat 6.2) /etc/httpd/conf/httpd.conf If we use Apache as a Web server whether on Windows platform or Linux, the main file which is used is called /etc/httpd/conf/httpd.conf

The root directory of Web server is /etc/httpd, which is divided into three parts:
1) /etc/httpd/conf (where configuration files stays)
2) /etc/httpd/logs (where the logs of Web server and site accessing stay)
3) /etc/httpd/modules (where the module stays, which enables the server side programmer to do programming in the languages supported by Web server)

Lets open the file /etc/httpd/conf/httpd.conf and take a detailed look at the macros to be used.

httpd.conf-Apache HTTP server configuration file
(Based upon the NCSA server configuration files originally by Rob McCool.)

This is the main Apache server configuration file. It contains the configuration directives that give the server its instructions.

Note: See http://www.Apache.org/docs for detailed information about the directives. Do not simply read the instructions in here without understanding what they do. They’re here as hints or reminders. If you are unsure consult the online docs.

After this (httpd.conf) file is processed, the server will look for and process (only in the case of 6.1 the following mentioned file is checked. If it is 6.2 they are not checked):
/usr/conf/srm.conf
and then
/usr/conf/access.conf
unless you have overridden these with ResourceConfig and/or AccessConfig directives here.

Directives

The configuration directives are grouped into three basic sections:
1. Directives that control the operation of the Apache server process as a whole (the ‘global environment’).
2. Directives that define the parameters of the `main’ or `default’ server, which responds to requests that aren’t handled by a virtual host. These directives also provide default values for the settings of all virtual hosts.
3. Settings for virtual hosts, which allow Web requests to be sent to different IP addresses or hostnames and have them handled by the same Apache server process.

Section 1: Global Environment

The directives in this section affect the overall operation of Apache, such as the number of concurrent requests it can handle or where it can find its configuration files.

ServerType: ServerType is either inetd, or standalone. Inetd mode is only supported on Unix platforms.

ServerRoot: The top of the directory tree under which the server’s configuration, error, and log files are kept.

NOTE: If you intend to place this on an NFS (or otherwise network) mounted filesystem then please read the LockFile documentation (available at http://www.Apache.org/docs/mod/core.htmllockfile); You will save yourself a lot of trouble. Do not add a slash at the end of the directory path.
ServerRoot “/etc/httpd”

LockFile: The LockFile directive sets the path to the lockfile used when Apache is compiled with either
USE_FCNTL_SERIALIZED_ACCEPT or
USE_FLOCK_SERIALIZED_ACCEPT.

This directive should normally be left at its default value. The main reason for changing it is if the logs directory is NFS mounted, since the lockfile must be stored on a local disk. The PID of the main server process is automatically appended to the filename.
LockFile /var/lock/httpd.lock

PidFile: The file in which the server should record its process identification number when it starts.
PidFile /var/run/httpd.pid

ScoreBoardFile: File used to store internal server process information. Not all architectures require this. But if yours does (you’ll know because this file will be created when you run Apache) then you must ensure that no two invocations of Apache share the same scoreboard file.
ScoreBoardFile /var/run/httpd.scoreboard

In the standard configuration, the server will process this file, srm.conf, and access.conf in that order. The latter two files are now distributed empty, as it is recommended that all directives be kept in a single file for simplicity. The commented-out values below are the built-in defaults. You can have the server ignore these files altogether by using “/dev/null” (for Unix) or “nul” (for Win32) for the arguments to the directives.

ResourceConfig conf/srm.conf
AccessConfig conf/access.conf

Timeout: The number of seconds before receives and sends time out.
Timeout 300

KeepAlive: Whether or not to allow persistent connections (more than one request per connection). Set to “Off” to deactivate. But we keep it :
KeepAlive On

MaxKeepAliveRequests: The maximum number of requests to be allowed during a persistent connection. Set to 0 to allow an unlimited amount. We recommend you leave this number high, for maximum performance.
MaxKeepAliveRequests 100

KeepAliveTimeout: Number of seconds to wait for the next request from the same client on the same connection.
KeepAliveTimeout 15

Server-pool size regulation: Rather than making you guess how many server processes you need, Apache dynamically adapts to the load it sees — that is, it tries to maintain enough server processes to handle the current load, plus a few spare servers to handle transient load spikes (e.g, multiple simultaneous requests from a single Netscape browser).

It does this by periodically checking how many servers are waiting for a request. If there are fewer than MinSpareServers, it creates a new spare. If there are more than MaxSpareServers, some of the spares die off. The default values are probably OK for most sites.
MinSpareServers 5
MaxSpareServers 20

Number of servers to start initially should be a reasonable ballpark figure.
StartServers 8

Limit on total number of servers running: Limit on the number of clients who can simultaneously connect. If this limit is ever reached, clients will be `locked out’, so it should not be set too low. It is intended, mainly, as a brake to keep a runaway server from taking the system with it as it spirals down.
MaxClients 150

MaxRequestsPerChild: The number of requests each child process is allowed to process before the child dies. The child will exit so as to avoid problems after prolonged use when Apache (and maybe the libraries it uses) leak memory or other resources. On most systems, this isn’t really needed, but a few (such as Solaris) do have notable leaks in the libraries. For these platforms, set to something like 10000 or so; a setting of 0 means unlimited.

NOTE: This value does not include keepalive requests after the initial request per connection. For example, if a child process handles an initial request and 10 subsequent “keptalive” requests, it would only count as 1 request towards this limit.
MaxRequestsPerChild 100

Listen: Allows you to bind Apache to specific IP addresses and/or ports, in addition to the default. See also the directive.
Listen 3000
Listen 12.34.56.78:80

BindAddress: You can support virtual hosts with this option. This directive is used to tell the server which IP address to listen to. It can either contain “*”, an IP address, or a fully qualified Internet domain name.
BindAddress *

Well that’s all for now. In the second part we shall look into Dynamic Shared Object (DSO) Support and also ‘Main’ server configuration.

Posted in server | Tagged: , , , | No Comments »

Simple Object Access Protocol(SOAP)

Posted by openstech on September 12, 2007

Intended Audience

This article describes the new SOAP extension for PHP. It is intended for PHP developers who want to write their own Web Services servers, or use SOAP to access existing ones. It assumes some familiarity with Web Services, SOAP, and WSDL (Web Services Description Language).

Introduction

SOAP (Simple Object Access Protocol) is a lightweight XML-based protocol for exchanging structured information between distributed applications over native web protocols, such as HTTP. SOAP specifies the formats that XML messages should use, the way in which they should be processed, a set of encoding rules for standard and application-defined data types, and a convention for representing remote procedure calls and responses.Web Services is a modern and very popular technology. The list of protocols and technologies related to Web Services grows every day, but SOAP is probably the most important. It is rapidly becoming the standard protocol for accessing Web Services. It uses XML messages to exchange information across endpoints, and provides several advantages over other binary protocols. RPC (Remote Procedure Calls) support was originally a minor element in the design of SOAP, but this feature is one of the most useful it has today.PHP 5’s SOAP extension is the first attempt to implement the SOAP protocol for PHP in C. It has some advantages over the existing implementations written in PHP itself, the main one being speed. The extension is currently marked as experimental, but should gradually become more stable and reliable as time progresses.

The SOAP extension implements a large subset of SOAP 1.1, SOAP 1.2 and WSDL 1.1 specifications. The key goal is to use the RPC feature of the SOAP protocol. WSDL is used where possible in order to make the implementation of Web Services more straightforward.

A First SOAP Client

To demonstrate how to make a simple SOAP Client, we’ll take the XMethods demo service, “Delayed Stock Quote”, as our target. Before we start to write any PHP code, we’ll need to gather some information about this particular service:

<!–[if !supportLists]–>·                                 <!–[endif]–>The method name

<!–[if !supportLists]–>·                                 <!–[endif]–>The endpoint URL where the service is running

<!–[if !supportLists]–>·                                 <!–[endif]–>The SOAPAction header value for the method

<!–[if !supportLists]–>·                                 <!–[endif]–>The namespace URI for the method

<!–[if !supportLists]–>·                                 <!–[endif]–>Input and output parameter names and types

Happily, all this information is available on the XMethods web site at http://www.xmethods.com/ in the form of the service’s RPC profile:

Method Name

getQuote

Endpoint URL

http://64.124.140.30:9090/soap

SOAPAction

urn:xmethods-delayed-quotes#getQuote

Method Namespace URI

urn:xmethods-delayed-quotes

Input Parameters

Symbol
String

Output Parameters

Result
float

Example 1 (client1.php)

<?php $client = new SoapClient(NULL,
        array(
        
“location” => “http://64.124.140.30:9090/soap”,
        
“uri”      => “urn:xmethods-delayed-quotes”,
        
“style”    => SOAP_RPC,
        
“use”      => SOAP_ENCODED
           
)); print($client->__call(
        
/* SOAP Method Name */
        
“getQuote”,
        
/* Parameters */
        
array(
            new
SoapParam(
                
/* Parameter Value */
                
“ibm”,
                
/* Parameter Name */
                
“symbol”
        
)),
        
/* Options */
        
array(
            
/* SOAP Method Namespace */
            
“uri” => “urn:xmethods-delayed-quotes”,
            
/* SOAPAction HTTP Header for SOAP Method */
            
“soapaction” => “urn:xmethods-delayed-quotes#getQuote”
        
)). “\n”);
?>
As you can see, this simple task required a lot of workFortunately, Web Services can describe themselves to the client using WSDL, and generally they achieve this successfully. The location of the WSDL document for the XMethods “Delayed Stock Quote” service is given on the information page for that service at xmethods.com:http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl

Here is the same PHP SOAP client, rewritten using that WSDL document. Now we don’t need to specify the endpoint URI, namespace, SOAPAction header, encoding style and parameter types. All the information comes from the WSDL file.

Example 2 (client2.php)

<?php
$client
= new
    
SoapClient(
        
“http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl”
    
); print($client->getQuote(“ibm”));
?>
That’s a little easier, isn’t it? What are the problems with WSDL? The only argument against using it is that the client has to load the relevant WSDL document from the server before the RPC can be made, and this can take a significant amount of time in a Web environment. In order to speed things up, PHP’s ext/soap uses a WSDL caching feature that can be controlled through setting the soap.wsdl_cache_enabled, soap.wsdl_cache_dir and soap.wsdl_cache_ttl configuration directives, either in your php.ini or by using ini_set()(see Example 4 ). By default, WSDL caching is turned on and caches WSDL files for one day.Here is the SOAP section for php.ini with default values. You can paste it into your php.ini.


[soap]
soap.wsdl_cache_enabled = “1″
; enables or disables WSDL caching feature
soap.wsdl_cache_dir = “/tmp”
; sets the directory name where SOAP extension will put cache files

soap.wsdl_cache_ttl = “86400″
; (time to live) sets the number of second while cached file will be used
; instead of original one

A First SOAP Server

Let’s try to write our own SOAP Web service that will do the same as the XMethods “Delayed Stock Quote” service.The first task is to create a WSDL document describing our service in a format that client requests will understand. This requires minor modifications to the original document taken from the Xmethods site, so we’ll start by taking a close look at that file. The message section defines two messages. The first is getQuoteRequest, which is a request to relay the getQuote message and takes one string parameter called symbol. The other is getQuoteResponse, which is a response to the getQuote message, containing one float value, named Result.The portType section defines one operation, getQuote, which describes which of the messages listed in the message section will be used to transmit the request and response.The binding section defines how the messages must be transmitted and encoded. Here it tells us that we will be sending an RPC request using SOAP encoding across HTTP. It also specifies namespace and value of the SOAPAction header for the getQuote method.Lastly, the service section defines the endpoint URL where the service is running.

Example 3 (stockquote.wsdl)

<?xml version =’1.0′ encoding =’UTF-8′ ?>
<definitions name=’StockQuote’
  targetNamespace=’http://example.org/StockQuote’
  xmlns:tns=’ http://example.org/StockQuote ‘
  xmlns:soap=’http://schemas.xmlsoap.org/wsdl/soap/’
  xmlns:xsd=’http://www.w3.org/2001/XMLSchema’
  xmlns:soapenc=’http://schemas.xmlsoap.org/soap/encoding/’
  xmlns:wsdl=’http://schemas.xmlsoap.org/wsdl/’
  xmlns=’http://schemas.xmlsoap.org/wsdl/’>
<message name=’getQuoteRequest’>
  <part name=’symbol’ type=’xsd:string’/>
</message>
<message name=’getQuoteResponse’>
  <part name=’Result’ type=’xsd:float’/>
</message>
<portType name=’StockQuotePortType’>
  <operation name=’getQuote’>
    <input message=’tns:getQuoteRequest’/>
    <output message=’tns:getQuoteResponse’/>
  </operation>
</portType>

<binding name=’StockQuoteBinding’ type=’tns:StockQuotePortType’>
  <soap:binding style=’rpc’
    transport=’http://schemas.xmlsoap.org/soap/http’/>
  <operation name=’getQuote’>
    <soap:operation soapAction=’urn:xmethods-delayed-quotes#getQuote’/>
    <input>
      <soap:body use=’encoded’ namespace=’urn:xmethods-delayed-quotes’
        encodingStyle=’http://schemas.xmlsoap.org/soap/encoding/’/>
    </input>
    <output>
      <soap:body use=’encoded’ namespace=’urn:xmethods-delayed-quotes’
        encodingStyle=’http://schemas.xmlsoap.org/soap/encoding/’/>
    </output>
  </operation>
</binding>

<service name=’StockQuoteService’>
  <port name=’StockQuotePort’ binding=’StockQuoteBinding’>
    <soap:address location=’http://[insert real path here]/server1.php’/>
  </port>
</service>
</definitions>

Note: The WSDL caching feature is on by default. During the development of your WSDL file it should be turned off.Now it’s time to create our server.First, we’ll implement the getQuote() function, which will be accessed as a service function by incoming request messages from the web. Next, we’ll create a SoapServer object and connect it with the service function using SoapServer::addFunction() method. As you will see, the SoapServer() constructor has only one parameter: the path of the WSDL document that describes the service.

Example 4 (server1. php)

<?php
$quotes
= array(
  
“ibm” => 98.42
);   function getQuote($symbol) {
  global
$quotes;
  return
$quotes[$symbol];
}
ini_set(“soap.wsdl_cache_enabled”, “0″); // disabling WSDL cache
$server = new SoapServer(“stockquote.wsdl”);
$server->addFunction(“getQuote”);
$server->handle();
?>
The SoapServer can work without a WSDL document in much the same way that the SoapClient can, but there are no obvious benefits to be had from setting it up in this way. Were you to do so, you should ensure that the return values are special objects of the SoapParam and SoapVar classes (as in the first example).Here is a client for accessing our own SOAP server. Nothing has changed from the previous example except the WSDL location. It assumes that “stockquote.wsdl” is in the same directory as our SOAP server.

Example 5 (client3.php)

<?php
  $client
= new SoapClient(“stockquote.wsdl”);
  print(
$client->getQuote(“ibm”));
?>

What are the problem areas with our server and client? To start with, they don’t handle errors. What happens when the server doesn’t recognize the requested symbol? The SOAP protocol specifies a special format of messages for reporting errors � SoapFault. To generate such messages the server should throw an exception using the SoapFault object. The first parameter to the SoapFault() constructor is a fault code string, and the second is a fault description string. The client should be written in such a way as to catch SoapFault exceptions.Secondly, it would be better to encapsulate Web Service functionality in a PHP class. In this case we wouldn’t need to use global variables and add each SOAP method to the server individually; we could add an entire class, and all its methods would be accessible through SOAP.

Save stockquote.wsdl as stockquote2.wsdl, and alter the soap:address on line 43 to point to server2.php. A modified version of our SOAP server and client follows:

Example 6 (server2.php)

<?php
class QuoteService {
  
private $quotes = array(“ibm” => 98.42);     function getQuote($symbol) {
    if (isset(
$this->quotes[$symbol])) {
      return
$this->quotes[$symbol];
    } else {
      
throw new SoapFault(“Server”,“Unknown Symbol ‘$symbol’.”);
    }
  }
}
$server = new SoapServer(“stockquote2.wsdl”);
$server->setClass(“QuoteService”);
$server->handle();
?>

As you can see, I have used the SoapServer::setClass() method to connect the SoapServer object with the QuoteService class.

Example 7 (client4.php)

<?php
  $client
= new SoapClient(“stockquote2.wsdl”);
  
try {
    echo
“<pre>\n”;
    print(
$client->getQuote(“ibm”));
    echo
“\n”;
    print(
$client->getQuote(“microsoft”));  
    echo
“\n</pre>\n”;
  }
catch (SoapFault $exception) {
    echo
$exception;      
  }
?>

What’s inside?

Are you curious about the SOAP message format, or hoping to debug a SOAP client of your own? If so, this section is for you.The SoapClient() constructor accepts an associative array as its second parameter, as you already saw in the first example. Various options can be passed through this associative array. Here are just two:

<!–[if !supportLists]–>·                                 <!–[endif]–>trace – allows the client to store SOAP requests and responses (turned off by default)

<!–[if !supportLists]–>·                                 <!–[endif]–>exceptions – allows the client to control the exception mechanism (turned on by default)

Take a look at the following SOAP client example. It is derived from example 5, and shows precisely what is transmitted between the client and the server. In order to retrieve this information we use the SoapClient methods __getLastRequest() and __getLastResponse().

Example 8 (client5.php)

<?php
  $client
= new SoapClient(“stockquote.wsdl”,array(
    
“trace”      => 1,
    
“exceptions” => 0));
  
$client->getQuote(“ibm”);
  print
“<pre>\n”;
  print
“Request :\n”.htmlspecialchars($client->__getLastRequest()) .“\n”;
  print
“Response:\n”.htmlspecialchars($client->__getLastResponse()).“\n”;
  print
“</pre>”;
?>

Here is the output of the script. It is modified a little, to make it more easily understood.

Request :
<?xml version=”1.0″ encoding=”UTF-8″ ?>
<SOAP-ENV:Envelope
  xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”
  xmlns:ns1=”urn:xmethods-delayed-quotes”
  xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
  xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  xmlns:SOAP-ENC=”http://schemas.xmlsoap.org/soap/encoding/”
  SOAP-ENV:encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/”>
<SOAP-ENV:Body>
  <ns1:getQuote>
    <symbol xsi:type=”xsd:string”>ibm</symbol>
  </ns1:getQuote>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Response:
<?xml version=”1.0″ encoding=”UTF-8″?>
<SOAP-ENV:Envelope
  xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”
  xmlns:ns1=”urn:xmethods-delayed-quotes”
  xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
  xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  xmlns:SOAP-ENC=”http://schemas.xmlsoap.org/soap/encoding/”
  SOAP-ENV:encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/”>
<SOAP-ENV:Body>
  <ns1:getQuoteResponse>
    <Result xsi:type=”xsd:float”>98.42</Result>
  </ns1:getQuoteResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Other Implementations of SOAP for PHP

<!–[if !supportLists]–>·                                 <!–[endif]–>PEAR::SOAP (http://pear.php.net)

<!–[if !supportLists]–>·                                 <!–[endif]–>NuSOAP (http://dietrich.ganx4.com/nusoap)

<!–[if !supportLists]–>·                                 <!–[endif]–>eZ SOAP (http://ez.no)

All the above are written in PHP, rather than in C.

Summary

In this article I have described only the basic functionality of the SOAP extension for PHP. In reality it can do significantly more, but it isn’t possible to demonstrate all its features in a short article. The main ones are:

<!–[if !supportLists]–>·                                 <!–[endif]–>support for complex types (arrays, objects)

<!–[if !supportLists]–>·                                 <!–[endif]–>support for SOAP headers

<!–[if !supportLists]–>·                                 <!–[endif]–>dynamic support for both SOAP 1.1 and SOAP 1.2

Perhaps these will be starting points for future articles.The SOAP extension is fully documented at http://www.php.net/manual/en/ref.soap.php.The extension is still in the early development phase, so your feedback will help to make it more stable, reliable, usable and fast. Please report any problems you find at http://bugs.php.net/.

References

“Simple Object Access Protocol (SOAP) 1.1” (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/)“SOAP 1.2 Part 0: Primer” (http://www.w3.org/TR/2003/REC-soap12-part0-20030624/)“SOAP 1.2 Part 1: Messaging Framework” (http://www.w3.org/TR/2003/REC-soap12-part1-20030624/)

“SOAP 1.2 Part 2: Adjuncts” (http://www.w3.org/TR/2003/REC-soap12-part2-20030624)

“Web Services Description Language (WSDL) 1.1” (http://www.w3.org/TR/2001/NOTE-wsdl-20010315)

“XML Schema Part 1: Structures” (http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/)

“XML Schema Part 2: Datatypes” (http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/)

About the Author

Dmitry Stogov is one of the authors of PHP’s SOAP extension. He has also written the PECL/perl extension and Turck MMCache. He currently resides in St.Petersburg, Russia with his wife and one child. Please feel free to post any comments or questions below, or send them to dmitry@zend.com.

Revision Date

This article was last revised on December 6th 2004 [sf]

<!–[if !supportEmptyParas]–> <!–[endif]–>

Comments

Add Comment

<!–[if !supportEmptyParas]–> <!–[endif]–>

Tuesday, October 31, 2006

UNCAUGHT SOAPFAULT EXCEPTION: [CLIENT] LOOKS LIKE WE GOT NO XML DOCUMENT

8:56PM PST · stromsky

I was following this article to learn myself to prepare and use web services in my PHP5. Article explains very clearly how to deal with all basics. Unfortunately client built using SoapClient class work fine until you are not trying to connect web service build using PHP5 Soap extension. I tried to connect many services written in different languages with no problems, but connecting my own service in PHP5 returns exception “Uncaught SoapFault exception: [Client] looks like we got no XML document”.First I thought, that my WSDL (working on other platforms) does not work for me in PHP5, but I tried to check it using few WSDL validators and I found it OK.Could anyone have an idea, where could be a problem? I`ve spent hours by googling Internet but with no success ;(.

Thank you for any advice.

Sunday, November 5, 2006

RE: UNCAUGHT SOAPFAULT EXCEPTION: [CLIENT] LOOKS LIKE WE GOT NO XML DOCUMENT

8:47AM PST · kroesjnov

I’ve just spend half my evening trying to solve this problem, and your not gonna believe the solution…Did you by any chance copy&paste the text from this website? I know I did.
Did you also copy two whitespaces along with the rest, now comfortably resting before your ‘<?php’? I sure did.
Do your errors disappear as soon as you strip these two leading whitespaces (along with any trailing whitespaces behind ‘?>’ if they happen to excist) from your code? Yep, you guessed right, they did here.
I guess there is a parser at work behind the curtains somewhere which is rather strict, perhaps a bit to strict.

(Tested with: WAMP5 1.6.6 : with PHP 5.2.0)

Wednesday, November 8, 2006

STOCKQUOTE.WSDL : SERVICE -> PORT -> BINDING

7:16AM PST · kroesjnov

It seems an error found it’s way to the article (as far as I can tell from the W3C WSDL 1.1 examples[1]).
When simplifying the W3C example[2] the ‘tns’ was lost in the port binding in the service section:
On this page:<service name=’StockQuoteService’>
<port name=’StockQuotePort’ binding=’StockQuoteBinding’>
<soap:address location=’http://[insert real path here]/server1.php’/>
</port>
</service>

Should be:

<service name=’StockQuoteService’>
<port name=’StockQuotePort’ binding=’tns:StockQuoteBinding’>
<soap:address location=’http://[insert real path here]/server1.php’/>
</port>
</service>

I noticed this when I tried to consume the webservice with Flash 8 (the PHP example above didnt have a problem with it).
I am not entirely sure if this is the fault of the author, or that Flash 8 is at fault. I *think* the parser is now looking for ‘StockQuoteBinding’ in the xmlns by default and not the xmlns:tns, yet I cant find where I’ve read about this behaviour, and the W3C specifications are not helping me either on this (or perhaps I am overlooking it there).

Either way, it’s perhaps usefull information to someone.

[1] http://www.w3.org/TR/wsdl#_services
[2] http://www.w3.org/TR/wsdl#_wsdl

<!–[if !supportEmptyParas]–> <!–[endif]–>

Posted in Web Services, web development in php | Tagged: , , | No Comments »