Monday, February 1, 2010

Yii Olde PHP IIS Difficult for Web Services sometimes

I have been trying to set up the Yii framework on my laptop for work on IIS 5.1 so that it will hit a web service (yes, it is work related!). I got to this point after I compared Zend, CakePHP, Seagull, Symfony, and Yii. Obviously, I'm not going to put up the comparison here - for all intents and purposes, I chose Yii. I'm not saying if it's a good choice or a bad choice in here either. This post is about my experiences with it for the past couple of days. It's a nice breather from my normal comics (which I will resume (I even got some cool software for it!)

This does not mean that I won't be doing more comics, but I'm going to start varying my blog content a bit.

A little about me - I do mostly .NET and Java work, and haven't done PHP in years. If it seems I'm bumbling around here, that's because I am.  This is more to document the issues that I found - hopefully, it'll help someone else that stumbles across this article.  If you want to leave a helpful comment, please do!

I'm using PHP 5.3.1 VC9X86 Thread safe found here.
I'm using the Yii framework 1.1.0 found here.
I'm following Larry Ullman's Blog - it has been really helpful as an article to just get started.

1. Install PHP 5.3.1 (yay!  no problems here!)
2. Create a virtual directory in IIS...
Of course, since I just installed PHP, I need to let IIS know that it exists, so I made the following changes as well (Yes, I did try opening up a PHP page without them.  It didn't work so well...):
 3. Download and install Yii!  Since it's just a Zip file, I just grabbed everything and dumped it into the directory my virtual directory was pointed at.
Don't mind the "test" folder under PHP - I created that and I will get to it in a moment.  As you can see, theres demos, framework, and requirements, and 4 other files.

4. Check to see if it worked.  The requirements folder, as I understand, is for just that.  I went to the requirements folder in my localhost: http://localhost/phptest/requirements/: HUZZAH - good enough.
Sweet!  It looks good!
5. I open up my command prompt and navigate to C:\Projects\PHP\framework (the Yii framework) and located yiic.bat.  This bat file creates the basic structure of your website.
Syntax: yiic webapp path/to/directory.
I ran: yiic test C:\Projects\PHP\test

As advertised, it did an awesome job of creating my whole directory!  In fact, if I navigate to http://localhost/phptest/test/, it should open up a working (skeleton) site for me:
Aw, crap.  A Google search gets me this: http://www.yiiframework.com/forum/index.php?/topic/5632-yii-iis-issue/
Apparently, the Assets and Runtime folders that are generated are needed by Yii to cache and persist.  I normally see the permissions on the properties tab of the folder.  However, as my laptop does not have any of that set up, I had to do the following:
Network sharing has to be on for both the assets and the runtime folder.  I opted to bypass the wizard and just do it myself.  This step may be different for you depending on how your environment is set up.

On a refresh of the page, I saw the following error (yeah, another one...  I know, it's actually a warning...)

The culprit is in my php.ini file, where I installed PHP (C:\Program Files\PHP).  Look for the following line:
;date.timezone =

This tells PHP what timezone to use (you can Google it to learn more).  I'm opting to change this line because, apparently, I love running into warnings that are showstoppers...  An alternate would be to change the ini file to not break on mere warnings.  I changed the line to this:

date.timezone = America/Los_Angeles


Note the removal of the semicolon (first character in the line).  Otherwise, this line won't be called.
 
6. Setting up the web service - I created my own web service to work with as I needed it for a demo and may not be able to connect to the internet.  You folks at home can use the sample one provided by the good folks at w3schools - http://www.w3schools.com/webservices/ws_example.asp.  The wsdl can be found here: http://www.w3schools.com/webservices/tempconvert.asmx?WSDL

So, how do I consume a web service?  According to the help docs Yii provides - http://www.yiiframework.com/doc/guide/topics.webservice, it looks like this:

$client=new SoapClient('http://hostname/path/to/index.php?r=stock/quote');
echo $client->getPrice('GOOGLE');
 
This would mean that in order to use the w3schools example, our code would look like this:
 
$client=new SoapClient('http://www.w3schools.com/webservices/tempconvert.asmx?WSDL');
echo $client->CelsiusToFahrenheit('27');
 
The verdict? Not so much.
 
This isn't Yii's fault.  For my research on the internet and lots of trial and error (this example seems to be everywhere), I found the answer.  I don't even remember what website I found it on now.  Apparently, in order to consume a webservice (at least for windows servers), there's more code needed.  The above syntax creates the SOAP request incorrectly, and the service gets nothing instead of '27'.  Not only that, the call returns a stdClass object, causing an error when echo tries to display it.  The error is Object of class stdClass could not be converted to string, in case you're wondering.
 
Let's tackle the calling of the web service first.  What's happening is that, when the SOAP request is being generated, PHP doesn't know where to put the 27.  The CelsiusToFahrenheit call should look like this instead:
$client->CelsiusToFahrenheit(array('Celsius'=>'27'))
The array contains all parameters to be passed in.  'Celsius' tells PHP what the tag to hold 27 is.  I got the tag name from the WSDL description.

This doesn't change the fact that the object returned is an stdClass type.  In order to read the object from it, the code should look like this:
$client=new SoapClient('http://www.w3schools.com/webservices/tempconvert.asmx?WSDL');
echo $client->CelsiusToFahrenheit(array('Celsius'=>'27'))->{'CelsiusToFahrenheitResult'};
The name 'CelsiusToFahrenheitResult' is also found in the WSDL, within the response section.

And that's it (so far)!  I'm not going to put any actual source code here for now.  I may if people are still having problems with this.  So, that's it for now on Web Services using Yii, PHP, and IIS 5.1.  Feel free to use the comments section to ask away.

No comments:

Post a Comment