Mar 29

Enabling PHP on Leopard

Posted by James Netherton | Saturday 29 March 2008 12:32 PM | In PHP,Mac

This post refers to the default Apache HTTP server that ships with Leopard. By default it doesn't load PHP5 which also comes pre-installed with Leopard. Here's how to enable the PHP module.

Open up a terminal session and run through the following steps:

1. sudo vi /private/etc/apache2/httpd.conf
2. Search for the string "php" by typing /php [return]
3. Hopefully you'll have found the line starting, #LoadModule php5_module
4. Remove the # symbol before the LoadModule statement
5. Exit vi and save the file, :wq!

That should be all there is to it. You can start the mac web server and you'll be able to start serving up PHP templates. You will probably also want to do some customisation of PHP.ini. Here's how I did this:

cd /private/etc/
sudo mv php.ini.default php.ini

You're then free to start editing the ini file.

This isn't the greatest solution to get PHP running on Mac. It appears the compiled PHP version shipped with the Mac is missing some useful modules such as SOAP.

 

Oct 15

Watch out for whitespace in PHP SOAP classes

Posted by James Netherton | Monday 15 October 2007 8:49 PM | In PHP

A small gotcha when I was testing out the native PHP SOAP libraries. No doubt this is documented somewhere and more seasoned PHP programmers will be aware of this.....

Whilst testing out a simple webservice that I had created, I had problems invoking the service methods that I had defined. The error message was suggesting that the SOAP response was not well formed XML. On investigating further, I noticed that a number of characters were missing off of the SOAP XML response. Specifically the closing '/>' characters to close the XML document root node.

After much head scratching, I turned to Google where it took me a long time to track down the cause of the problem. In my web service class file, I had a number of blank lines after the closing '?>' scriplet block. For every blank line, a character would be stripped off the SOAP response XML.

After I cleaning up the whitespace I started getting valid responses again.

 

Sep 17

Drupal Localizer Gotcha

Posted by James Netherton | Monday 17 September 2007 5:00 AM | In PHP

I recently released a Drupal installation that has four language variations, each running off its own domain.

Within the localizer module configuration, the option exists to switch between languages by detecting the current hostname. Doing this comes with the clause:

If this option is active all the other switching options will be ignored.

This seems to be partially true. One crucial setting that wasn't being ignored was:

Redirect front page to the localized version

I had this option checked, assuming that it would be overridden by switching languages by hostname. Turns out, the setting wasn't being overridden. Whenever I tried to navigate to the root on any of my language variant domains, I kept getting redirected to the homepage of the default language.

It took me a while to track down what was going on. The module I was using is a couple of versions out of date now, maybe it's been fixed in the latest release.

 

Jun 06

HTTP_RAW_POST_DATA with nusoap on PHP 5.2.2

Posted by James Netherton | Wednesday 06 June 2007 1:02 PM | In PHP

I just fixed a weird issue where I had a Flex client invoking a PHP Nusoap SOAP web service.

Whenever the client was making requests to the PHP page, I kept getting the SOAP service overview HTML content being returned. I var_dumped the $HTTP_RAW_POST_DATA and it was returning NULL.

I had to change:

$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';

to:

$HTTP_RAW_POST_DATA = file_get_contents("php://input");

Everything started working correctly after making this change.

Apparently there is a bug in PHP 5.2.2 with HTTP_RAW_POST_DATA and SOAP.

 

Jun 02

Quercus: PHP on ColdFusion 8!!!

Posted by James Netherton | Saturday 02 June 2007 7:09 PM | In PHP,ColdFusion

As a short follow up to my PHP on Java post. Sean Corfield has posted an example of scripting PHP within ColdFusion!

Read all about it here.

 

May 24

Quercus: PHP on Java!

Posted by James Netherton | Thursday 24 May 2007 9:13 PM | In PHP,Java

That's right, thanks to Caucho, you can run PHP scripts on the Java platform! It uses the Resin application server to compile PHP scripts down into Java bytecode.

Read all about it here. Some of the highlights are:

- Applications can take advantage of features like connection pooling, distributed sessions, load balancing, and proxy caching

- PHP applications can choose to use Java libraries and technologies like JMS, EJB, SOA frameworks, Hibernate, and Spring

- Quercus claims to outperform mod_php by about 4x some applications

- Make use of Java profilers to get in-depth information about the PHP application performance

- Write PHP extensions in Java

It works very nicely indeed. I had Drupal 4.7 up and running with almost zero fuss. I had to remove a particular PEAR library dependency for a module that I wrote. I'm pretty sure I could replace this with a custom Java PHP extension though.

As Resin is a Java application server, you can also run ColdFusion! I deployed CF in WAR form and so far, it all seems to be 100% working. I've got blogcfc and a couple of other applications working.

Hopefully I'll post some more after I've had a chance to experiment further.

 

May 07

My first Drupal module

Posted by James Netherton | Monday 07 May 2007 10:04 PM | In PHP

Sadly my first Drupal module isn't one I'll be able to open source for the community. It's been an interesting experience developing it though.

The process of creating a module appears to be quite complex at first, and the online docs aren't all that great at explaining how all of the pieces in the Drupal module API fit together.

After doing some reading and taking a peek at some of the existing Drupal module code, it's not as complicated as it first seems.

Essentially, all you have to do is override a number of Drupal 'hook' functions and provide your own implementation logic to give the module its functionality.

Drupal provides hook functions for all aspects of the module lifecycle - installation, configuration, adding, editing and deletion of content. This makes it easy to write custom installation code which gets executed the first time Drupal discovers the module.

Another other nice touch is that you don't have to write much (or any) module configuration logic. By using the Drupal form API, you can easily build up a web form to capture all of the module configuration settings. Drupal will also magically save and retrieve the settings for you!

The only thing I don't like is that with so many hook functions available, there's quite a lot of potential for code bloat. I had my module up to over 1000 lines of code, relatively quickly. I managed to trim this back substantially in the end.

I haven't come across any modules where any of the code is split up into includes or classes. I don't know whether this is best practice for writing modules, but it would cut down on the amount of code that ends up within the .module file and generally make things easier to manage and maintain.

Now to get my head around writing themes!

 

Mar 30

Consuming ColdFusion webservices from PHP

Posted by James Netherton | Friday 30 March 2007 3:27 PM | In PHP,ColdFusion

If you expose a ColdFusion component as a webservice and have arguments or a return type of type struct. In the resulting webservice WSDL, the struct is represented as a complexType.

To see what I mean, I've created an example CF webservice component:

<cfcomponent>

   <cffunction name="exampleMethod" access="remote" returntype="struct">
      <cfargument name="personName" type="string"/>
      <cfargument name="personDetails" type="struct"/>

   </cffunction>

</cfcomponent>

Here's a snippet of how the struct data type is represented within the WSDL:

<!-- Here are the service parameters -->
<wsdl:message name="exampleMethodRequest">
<wsdl:part name="personName" type="xsd:string"/>
<wsdl:part name="personDetails" type="apachesoap:Map"/>
</wsdl:message>

Note that the personDetails parameter is of type apachesoap:Map. Here's the definition for apachesoap:Map:

<complexType name="mapItem">
<sequence>
<element name="key" nillable="true" type="xsd:anyType"/>
<element name="value" nillable="true" type="xsd:anyType"/>
</sequence>
</complexType>

As we'd expect, it's a simple key / value hashmap which is essentially what the CF struct is.

No lets add some simple logic into the webservice method that I showed earlier:

<cfcomponent>

   <cffunction name="exampleMethod" access="remote" returntype="struct">
      <cfargument name="personName" type="string"/>
      <cfargument name="personDetails" type="struct"/>

      <!--- Create a response strcure --->
      <cfset var result = structNew()/>

      <!---
          Just build up a big list containing the info we
       got from the personDetails argument
      --->

      <cfset result["personProfile"] = listAppend(result["personProfile"],arguments.personName)/>
      <cfset result["personProfile"] = listAppend(result["personProfile"],arguments.personDetails["age"])/>
      <cfset result["personProfile"] = listAppend(result["personProfile"],arguments.personDetails["gender"])/>
      <cfset result["personProfile"] = listAppend(result["personProfile"],arguments.personDetails["dob"])/>

      <cfreturn result/>

   </cffunction>

</cfcomponent>

Nothing too complicated going on there. The service expects a string argument and a structure which is expected to contain age, gender and dob keys. Creating a webservice call to invoke this service in ColdFusion would be an extremely simple task, but how would one use PHP to invoke this service?

It's more complicated than you probably think due to the usage of structs and complexTypes. After doing some research, returning structs, arrays and query data types from webservices is not best practice. There are many forum posts from PHP, .NET and Java developers who have encountered problems resolving these data types via webservice calls.

So how would one use PHP to pass the personDetails struct parameter to a ColdFusion webservice?

I'll be using nusoap to consume the webservice. Here's the PHP script:

<?php
//Import the SOAP library
require_once('nusoap.php');

//Get a handle to the webservice
$wsdl=new soapclient('http://myserver/example.cfc?wsdl',true);

/*
   Define a class that represents the parameters being passed into the service:

   - personName <string>
   - personDetails <ColdFusion struct>
*/

class complexType{

   //personName is a simple string
   var $personName = 'Homer Simpson';
   
   //personDetails is a CF struct so define as an associative array
   var $personDetails = array('age'=>'35',
                'gender'=>'Male',
                'dob'=>'01/05/1971');
}

//Create an instance of the complexType object
$complex = new complexType;

$proxy = $wsdl->getProxy();

//Call the webservice exampleMethod method and pass in the parameters
$result = $proxy->exampleMethod($complex);

//Display the results contained in the personProfile element
echo($result["exampleMethodReturn"]["personProfile"]);
?>

Notice that the response is returned in an associative array with the top level element being named 'exampleMethodReturn'. If you look at the WSDL for the service, you'll see the definition for this:

<wsdl:message name="exampleMethodResponse">
<wsdl:part name="exampleMethodReturn" type="apachesoap:Map"/>
</wsdl:message>

And that's all there is to it!