Saturday, October 30, 2010

A discussion about asynchronous programming in PHP and further

I read an article about asynchronous programming in PHP. It declares that lacking asynchronous programming is not limitation from PHP language. However, I think this is obviously the limitation of PHP.

Lacking of multi-thread features is the source of the limitation. PHP programmers have argued that they can use named pipe, node.js, libevent, Curl, Zend_Job, and other process control extensions to implement asynchronous functions in PHP. However, these methods are not core PHP feature. Therefore, there is no guarantee that these functions can be run on all platforms on which core PHP can run. For example, I wonder whether libevent can run on IBM i platform or not. Zend Server for IBM i supports Zend_Job. But it is not in Zend Server CE, which is free. Also, some extensions like PCNTL seems a solution based on multi process with shared memory. It is a inter-process implementation. Multithreading is a inner process implementation.

This limitation of PHP is because of the way of running PHP script too. PHP is known that it has less memory leak problem. This is not surprised as each PHP script is loaded into memory only when it need to be executed. After it is executed, it is flushed out of memory. Of course, PHP has no memory leak as it has no memory at all.This is because PHP inherits from perl as CGI programming language. Somebody will argue that PHP actually has optimizers and extensions like memcache. These make PHP looks like have some memory. However, optimizer is for caching operation code. memcache is for caching some data as a persistent storage. They can not make PHP to have real memory.

Since PHP has no memory, core PHP has no function like PipedInputStream, PipedOutputStream, and multi thread etc. As I presented in an old post, its static modifier means different life scope than other languages do. So, lacking of asynchronous programming feature is the limitation from PHP itself. It is confusing to discuss PHP lacks asynchronous feature and deny it is limitation from PHP language itself.

Also, in servlet world, people has been interested in changing "request per thread" architecture because of the challenge from multiplied Ajax calling from browser side. Leading by Jetty, both Jetty and Tomcat 7.0 has implemented asynchronous servlet API already. I will deeply investigate whether PHP is facing same challenge or not. Or, with Fastcgi, PHP does not need to worry about this at all.

Thursday, October 28, 2010

tutorial about setting up multiple breakpoints for different PHP script files in Zend Studio

After trying Zend Studio 7.2 and 8.0 Beta, I have to say that Zend Studio manual does not fully describe its features. Especially, I can not find info about how to properly set up multiple breakpoints in its manual .

What happened is, after initializing a ZF project with default settings in ZS, I find that I can only make debugging break point in the first PHP script, which is /public/index.php . Zend Debugger ignores other breakpoints set in other PHP scripts, where those complex logical are implemented. After studying, I find that we need to change the default debug configurations to make multiple breakpoints to work. The steps are as below,

1) right click your project in PHP Explorer window and select Properties for properties window.
2) Select  "PHP Include Path" --> "Libraries"
3) Remove the default libraries of Zend Framework, which belong to Zend Studio.
4) Add the Zend Framework directory under your local Zend server directory as library. Now you can see the screen like below,
5) Click menu "Run" --> "Debug Configurations..." . select or create your debug configuration settings.
6) Click "Configure..." button under the "server" tab for edit server window.
7) Click "path mapping" tab and create a path mapping entry, which has exactly same path for "server path" and "local path". You will see screen as below,
8) Click "Advanced" tab on "Debug Configurations" window and select radio button "Local copy if available. Otherwise, the server".

Now, you can see that Zend Debugger can stop at breakpoints in PHP scripts other than the first page scripts.

For better understand the debugger in Zend Studio, here is one link: click.

Monday, October 25, 2010

failure on passing SQL statement as parameters into stored procedure and the way to walk around

Recently, I got code 3 error message when I tried to call a stored procedure on IBM i DB2 through System i Navigator. The purpose of this stored procedure is to perform a series queries that are passed in as the input parameter under a predefined schema.  Below is the way to call the stored procedure,
call myStoredProcedure('update dummyTbl set columnA = 1 where columnB = ''Jia''  ')

The error message says that

Message: [SQL7008] dummyTbl in schemaA not valid for 
operation. Cause . . . . . :   The reason code is 3.  
Reason codes are: 
1 -- dummyTbl has no members. 
2 -- dummyTbl has been saved with storage free. 
3 -- dummyTbl not journaled, no authority to the 
journal, or the journal state is *STANDBY.  Files 
with an RI constraint action of CASCADE, SET NULL, 
or SET DEFAULT must be journaled to the same journal. 
The interesting thing is that I get error free when I run the same SQL query in System i Navigator. 

After doing research, I found that, on IBM i DB2, a table is journaled by default if it is created with SQL statement in i Navigator. On the other hand, the table is not journaled by default when it is created under green screen. And the walking around is adding the following statement in the stored procedure before executing the input string that is actually sql statement,
SET TRANSACTION ISOLATION LEVEL NO COMMIT

This could only be temporary walking around solution. To be serious, it is better to review tables setting about journaling and isolation level. However, for an existing complex database system, this walking around might be a good choice too.

Friday, October 22, 2010

Role Based Access Control (RBAC) and Single Sign On (SSO) and Role vs Group

I attended a meeting to discuss about Single Sign On. After listening to their discussion for a while, I noticed a problem of the discussion. It sounds like they intended to implemented Role Based Access Control in the Single Sign On system. However, the problem is that they mixed RBAC and SSO during the discussion. So, I gave out my suggestion that they can put RBAC and SSO into separate discussion at this early stage.

The relationship between RBAC and SSO should be like this,
  1. When we start discussing about design of RBAC and SSO, we should discuss RBAC first. After RBAC is clearly defined. It wont be difficult to implemented it in SSO system.
  2. When we start discussing about SSO implementation, we need to oversee the whole system as a SSO system and think about how RBAC will be implemented in SSO system.
So, we will have a clear and efficient discussion when we have a clear concept about relationship between SSO and RBAC.

Another cause for them to be confused during design is that they mixed concepts about Group and Roles.  There are tons of discussion about difference Group and Roles according to general accepted definitions. Designer will be confused if he mix group and role. For this case, I noticed that they tried to define roles in ActiveDirectory as a hierarchy structure. With this starting point, they were lead to have messy concepts and can not get out of it. However, they immediately have a clear view after I told them that they can think about moving those "group" in AD into a DB2 table as Roles first. Then, they can think about how to implemented their RBAC system. Then, they can move back those roles into AD and only use AD as persistent storage if they really want to do so.

Tuesday, October 19, 2010

Web Service authentication and Http session and Web Service session

I was presented a web service client written with Zend_Soap_Client. It seems that the Web Service runs as Single Sign On service. But, it is a specific SSO invented internally. However, this WS is not protected by even simple authentication processing. When I raised this concern, I was asked "how to pass user name and password to Web Service server?". Well, I think this questions need to be divided into two parts to be answered,
  1. How to authenticate client when it access a Web Service?
  2. Is the Web Service stateful or stateless? 
Regarding the first question, authentication can happen in two different places. The first place is the WSS tag, which is in SOAP message header. The second is the HTTP authentication, which happens outside (front of) Web Service. So, it depends Web Service provider and Web Service consumer to decide where they will put the authentication info to protect the Web Service.

About the second question, I will say Web Service can be both stateful and stateless. Enabling session management in Web service will obviously increase the memory footprint. On the other hand, a stateless Web Service will require less memory. It depends on what kind of Web service it is.

I know it is wired for a programmer to input user name and password or certification file every time when it need to call each function supplied by a same Web service. I think we have to balance among computing time, memory footprint, and easy implementation. Then, we can choose whether we need a stateless WS or stateful WS. Both Axis2 and .Net Web Service can support stateful Web Service.

Thursday, October 14, 2010

Zend_Soap_Client and PHP http client do not share same native code

I was told by a senior PHP consultant that he can not successfully make Zend_Soap_Client call over the SSL. He runs his code on Zend Server running on i Series. Then, I told him that, if I were him, I will try to write a normal HTTP client to access the WSDL file over SSL first. The reason for me to approach in this way because,

  • SOAP is built on the top HTTP. So, SSL should not be business of SOAP. In other words, SOAP client shall rely on the HTTP client implement.
  • I THOUGHT that Zend_Soap_Client uses same native code as PHP http client.

However, I was wrong. He tested and found that he was able to do file_get_contents and retrieve https:// content from the server. Then, I started to trace the source code of Zend_Soap_Client. I found,
  1. Zend_Soap_Client is a wrapper around PHP SOAP extension.
  2. PHP SOAP is a thin layer. It quickly goes to native code at file called soap.php.
  3. Native c code of soap.php has its own logical to deal with proxy and SSL. Click Here to see C source code.
So, I was wrong. I can not regard that Zend_Soap_Client can support SSL just because PHP Http client can support SSL. They probably uses different version of native http client code. From this discussion, I get deeper understanding about architecture of PHP. I will probably write a article to compare Java and PHP.

BTW, PHP 5.3 version of Zend Server 5.0.2 on iSeries does not support Zend_Soap_Client to access web service over the SSL. However, Zend_Soap_Client work with SSL when the Zend Server was rolled back to version 5.0.1 . Zend_Soap_Client coming with Zend server 5.0.4 can be used to access Web service over one-way SSL. I have not tried mutual SSL with Zend_Soap_Client yet. But, it sounds not easy.

Also, to test Zend_Soap_Client access over one-way SSL can be as simple as below,

try {
 $soap_url = 'https://your.host/webservice?wsdl'; 
 
 $soap_client = new SoapClient ( $soap_url);
 
 var_dump ( $soap_client -> __getFunctions () );
 
} catch ( Exception $e ) {
 print_r ( $e );
 exit ();
}

Friday, October 8, 2010

A simple tutorial about creating Zend Framework SOAP Web service server in Zend Studio 7.2

I was studying how to create Web Service in PHP recently. I used Axis1.0, Axis2.0 to create Web service before. I used NuSoap to make a web service to call Sync4J admin service too. I like Axis' wsdl2java and java2wsdl tool set very much. In PHP, there is similar tool too. However, this time, I decide to implemented Web service under Zend Framework. After trying, I found it is quiet easy to create a simple Web service in ZF although I found that Zend_Soap_Server is not sophisticated enough to make solution for Enterprise application. For example, it does not have build in support for WS security head. It is actually a wrapper around PHP Soap extension. You can find discussion from Zend wiki by click here.

I will show steps of creating ZF based Web Service in Zend studio as below. Also, I put download link of whole ZS project at the end. We can create this simple demo project as below,
  1. Create a new ZF project in Zend Studio and name it as jiaWS.
  2. Add autoloaderNamespaces[] = "Jia_" in application.ini to allow Zend Autoloader load Jia_* classes.
  3. Creating a action class DummyController under directory /application/controllers. 
  4. creating a function soapAction() in DummyController .
  5. creating a function wsdlAction() in DummyController. 
  6. Creating a Jia_Hello class with sayHello() function under /library/Jia directory.
  7. Creating a Jia_DummyException class under /library/Jia directory for Soap fault processing.
It is done! You need to pay attention on how to specify web service URI in the code if you use different project name and function names. See key source code as below,

Jia_Hello class.
/**
 * This class contains function which will be used by Web service caller.
 * All business logics will be implented or called in these functions.
 * 
 * @author Yiyu Jia
 *
 */
class Jia_Hello {

 /**
  * This function simply return a String when it is called.
  * Note :  the PHPDoc style comment below is very 
  * important as Zend_Soap_AutoDiscover use it to generate WSDL. 
  * 
  * @return string
  */
 public function sayHello(){
  return "hello";
 }
}

DummyController calss
/**
 * This class includes two functions. soapAction() is point called by
 * Web service client. wsdlAction() generates WSDL when it is called.
 * 
 * @author yiyu
 *
 */
class DummyController extends Zend_Controller_Action
{
 /**
  * SOAP action named as soap.
  */
 public function soapAction() {
  // disable layouts and renderers
  $this->getHelper ( 'viewRenderer' )->setNoRender ( true );
  
  // initialize server and set URI
  $server = new Zend_Soap_Server('http://localhost/jiaWS/public/index.php/dummy/wsdl');
  
  // set SOAP service class
  $server->setClass ( 'Jia_Hello' );
  
  // register exceptions for generating SOAP faults
  $server->registerFaultException ( array ('Jia_DummyException' ) );
  
  // handle request
  $server->handle ();
 
 }
 /**
  * function to generate WSDL.
  */
 public function wsdlAction() {
  
  //You can add Zend_Auth code here if you do not want 
  //everybody can access the WSDL file.
 
  // disable layouts and renderers
  $this->getHelper ( 'viewRenderer' )->setNoRender ( true );
  
  // initilizing zend autodiscover object.
  $wsdl = new Zend_Soap_AutoDiscover ();
  
  // register SOAP service class
  $wsdl->setClass ( 'Jia_Hello' );
  
  // set a SOAP action URI. here, SOAP action is 'soap' as defined above.
  $wsdl->setUri ( 'http://localhost/jiaWS/public/index.php/dummy/soap' );
  
  // handle request
  $wsdl->handle ();
 }

}


DummyClient.php
//This code is not a ZF MVC based
//So, we need to load Zend libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass ( 'Zend_Soap_Client' );

//setting options past into Zend_Soap_Client.
$options = array ('location' => 'http://localhost/jiaWS/public/index.php/dummy/soap', 'uri' => 'http://localhost/jiaWS/public/index.php/dummy/wsdl' );

try {
 //Initilizing client object
 $client = new Zend_Soap_Client ( null, $options );
 //calling the Web service function.  
 $result = $client->sayHello ();
 print_r ( $result );
} catch ( SoapFault $exp ) { //catching exception and print out.
 die ( 'ERROR: [' . $exp->faultcode . '] ' . $exp->faultstring );
} catch ( Exception $exp2 ) {
 die ( 'ERROR: ' . $exp2->getMessage () );
}

Source code as Zend Studio project can be downloaded click here

You can find a simple RESTful Web Service demo on my another post, creating RESTful service with Zend_Rest_Route and Zend_Rest_Controller.

Thursday, October 7, 2010

Zend_Soap does not have build-in support for WSS headers.

I am disappointed to find that Zend_Soap_Client does not support WSS tag. When I talked to some PHP programmers, I found that they only talk about HTTP authentication. It is true that we can protect our Web Service by putting HTTP authentication at the front of the Web service. We can further adding SSL on WS. But, all of these methods are belong to HTTP layer. In fact, Web Service standard defines security head tags for authentication and encryption purpose.

It will be disadvantage of ZF not to support WSS tags especially when other languages have supported it. In Java world, we have Axis2 and WSS4J. There are some extensions in PHP to support WSS. But I wish Zend will put WSS support in Zend_Soap soon. Otherwise, there will be doubt when we will apply Zend_Soap in enterprise application solution. I put my message in zend wiki. click here.

Wednesday, October 6, 2010

Be sure to check httpd "AllowOverride" setting for your Zend Framework app

Yesterday, I installed Zend Server CE ver 5.0.3 Windows x86 on my machine. Then, I used Zend Studio 7.2 to create a default ZF project. However, I find that I always got 404 error that means page is not found.

How can it be? Zend Studio actually put whole project files under Apache httpd's htdocs folder already. First thing I suspect is that I dont have .htaccess  file defined or it defines wrong rules? Then, I spend time on finding .htaccess file and checking its rules definition. However, it seems there is nothing wrong but my ZF application can not run!

Finally, I go to Apache httpd configuration folder and open the httpd.conf file and zend.conf file. Here, I found the problem. And it is so trivial and I feel I am stupid that I wasted time on checking .htaccess files. Zend server sets its apache httpd configuration with "AllowOverride None". Therefore, those .htaccess file I keep on checking is totally ignored by httpd! I changed it to be "AllowOverride All" and my ZF application works immediately. This is not a safe configuration. However, it is just a local web server for developing purpose. It is Ok.

I do not know whether this could be called as Zend Server's bug or not. Zend Server or Zend Studio should modify this setting for developers if they declare themselves as seamless integrated development environment for ZF developers. However, it is really not difficult for developers to correct this setting if they keep in mind of this. After getting this lesson, I think I will always remember to check this setting after I freshly install a Zend Server. 

If interested, official site to describe Apache httpd "AllowOverride" configuration is here .