AS400 IBM i Series Soap Call with PHP and Varying Length Parameter

November 8th, 2013

We are setting up a SOAP service to connect our AS400 (IBM i Series) to the web (PHP in our case). A couple of the parameters are of type Variable Length string, which asks for a Length and a String. This is not the length of the given string (what is being posted from SOAP) but rather the destination length of the field with a padded string. So say there is a COMMENT parameter on the AS400 has length 240 characters. The SOAP post parameter must give 240 for the length and then pad the string with spaces to make sure it is 240 characters long.

Here is my PHP class helper VaryString, and how to use it. (Note: you may need to replace “function VarayString” with “function __construct” depending on your version of PHP and if you are using a framework like Symfony.)

class VaryString{
	function VaryString($length,$string){
		$this->_Length = $length;
		$this->_String = substr(str_pad($string,$length),0,$length);

class SOAPData{
	function SOAPData($user,$comments){
		$this->USER = $user
		$this->COMMENTS = new VaryString(240,$comments);

To create the rest of the PHP SOAP client follow this sample from IBM: IBMi-Modernizing-WebService and look on page 292. It uses the PHP SoapClient to make the SOAP call and builds the request uses classes to structure the data. Think of each class as an XML node until you get down to the actual node values. So depending on the WSDL, many classes may need to be nested to match the XML the AS400 web service is looking for.

Hosting Symfony2 Applications on IIS 7.5

November 8th, 2013

Download PHP
IIS: If you are using PHP with IIS you should use the Non-Thread Safe (NTS) versions of PHP.
Extract the ZIP, I like to use C:\php (or the data drive if your server is setup with multiple drives).
Add PHP to Windows Path:
Start -> Right Click on Computer -> Properties -> Advanced system settings
Advanced tab -> Environment Variables…
System variables -> Path -> Edit
Add C:\php; to the end
Create\Update C:\php\php.ini (copy php.ini-development or php.ini-production) to suit your needs.

Install PHP
Important: Example #4, #5 are needed for correct file permissions. This will come in later when we move our Symfony project directory to Inetpub.

Optional: Fix 500 Internal Server Errors
So you can see the actual PHP error messages when you test the Symfony project, Click on the Default Web Site -> Error Pages -> Edit Feature Settings… -> Detailed errors. May need to restart IIS.

Point Default Website to Symfony ProjectCopy the Symfony project directory into C:\inetpub. Run the icacls command from #5 on the Install PHP tutorial to allow PHP to run the scripts.

icacls C:\inetpub\SymfonyProject /grant IUSR:(OI)(CI)(M)

Then, in IIS Manager, click on Default Web Site -> Basic Settings… -> Set Physical Path: to web directory in the Symfony project. Hit OK.

Alternatively, if you are hosting a collection of applications (say for a portal) you can create a Virtual Directory to the web folder. Right click Default Web Site -> Add Virtual Directory -> Set the Alias and Physical Path.

URL Rewriting
Download and Install IIS7 URL Rewrite Extension. You will need to close and reopen IIS Manager to see the new extension.
Click on “Default Web Site” -> URL Rewrite -> Import Rules. Copy and paste the rules below, adjusting “web/app_dev.php” to point to the appropriate file for your project. I noticed the stock .htacces that came with Symfony had errors importing, so I use this simplified version.

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ web/app_dev.php [QSA,L]

Batch Rename Files Recursively in Linux

April 25th, 2013

I had to recently rename a bunch of files on my web-server. They were uploaded with spaces, parenthesis, and other non-web-safe characters. I searched around and finally found the way to rename files insecurely from the command line in Linux. The below example renames all files that have space and replaced it with an underscore within the current directory.

sudo find . -type f -exec rename -v s/" "/"_"/g {} \;

Southwest’s New Cramped Interior Response

November 16th, 2012

Here is the response I got from Southwest regarding their new interior with less room. Predictably, they did not talk about the decrease in leg room, which was my only complaint. Yippy for lighter material, made from recycled content, and lower seats so small people “the average Customer” can stretch their legs. I call bull shit! How exactly does lowering the seats let someone stretch their legs?

I wish they would just admit that I’m the rare customer and they make more money by ignoring my demographic and adding a row to fit more people. I can understand that. But instead, I get some bull shit communication-marketing PR response that doesn’t answer my question.

Dear Samuel,

The focus when redesigning our aircraft interior was to increase Customer comfort while being more environmentally responsible. We’re so sorry to learn you were disappointed with your inflight experience.

Our sleek, new interior was crafted using recycled materials to maximize personal space, while enhancing the Customer experience. Among the various comfort-driven features are adapted seats (designed to foster improved posture and lumbar spine support) and fixed winged headrests for superior neck and head alignment—a gift to our cat nappers. Thinner armrests mean a little more room between seats on the same row, and the lowered seats should make it easier for the average Customer to stretch his/her legs. Another huge positive is, with each plane weighing less, we have drastically reduced fuel consumption and emissions making our aircraft hugely eco-friendly. By Evolving, we have shown our commitment to clean up environmentally.

We have received numerous positive comments from Customers and regret that, in your particular case, you didn’t find our new interior comfortable. It is our sincerest hope that you will not let these cabin changes forever deter you from choosing Southwest for your travel needs. We treasure your friendship and will always revel in the privilege of sharing greener skies with you.


Courtney, Southwest Airlines

Southwest Added Row, Less Leg Room

November 15th, 2012

Southwest recently started adding another row to their airplanes and replacing their old seats. This makes what little leg room available even less. So less in fact that I, at 6 foot 3 inches, must sit with my knees pressing against the seat in front of me. Most of my friends are taller than me! Just to vent my frustration I sent an email to Southwest Airlines. I will post their response here.

Dear Southwest,

I used to enjoy flying with you. I even paid you an an extra $10 for a better chance at an exit row. But if I didn’t get the exit it, it was OK because I would still fit in the other seats. So on my long flight back from Detroit I noticed new seats. The exit row was taken, so I sat in an aisle seat. To my surprise, my knees hit the seat in front of me! I am only 6 foot 3 inches tall. And most of my friends are taller than me.

The only saving grace you guys have now is the no change fees. Which I thankfully used to cancel my next Southwest flight and go for another airline. I even bought some Southwest stock I was flying you guys so much. Sold that.

I get you need to make a profit and the average American height is a pudgy 5 foot 10, but the last airline I sat in and didn’t fit was Skybus. And no one flies them anymore.

Sam Stevens

Liferay – Detecting Client IP Address

June 15th, 2012

Been working with Liferay portal recently and it too me a long time to finally figure out how to get the clients IP address in the portlet. VforLiferay had a good post but I was missing a few things. It must be after “<portlet:defineObjects />” and renderRequest is the request object to send to the PortalUtil. Oh and of course, don’t forget:

<%@ page import=”com.liferay.portal.util.*” %>

<portlet:defineObjects />
HttpServletRequest Lrequest = PortalUtil.getHttpServletRequest(renderRequest);
String clientIp = PortalUtil.getOriginalServletRequest(Lrequest).getRemoteAddr();
out.print( clientIp);

Creating and Deploying a Portlet in Liferay Tutorial

March 29th, 2012

If Liferay is not running, then go to command prompt, as administrator, navigate to:


And run:


To create a portlet, use the command prompt, as administrator, go into


And run:

create.bat usc-test "USC Test"

This will create a directory usc-test-portlet that you can edit.

To deploy, in the same directory run:

ant deploy usc-test-portlet

It should go through the process. If it says build fails with this message:

[copy] Copying 1 file to C:\Apache\liferay-portal-6.1.0-ce-ga1\deploy
Target "usc-test-portlet" does not exist in the project "portlets".

But it actually does not fail, in fact it is deployed.

To add your portlet, login to the portal, and in the top bar you should see

+ Add -> More… -> Sample -> USC Test

If the portlet is already added and you are making edits, simply refresh the browser (it may take a few seconds to deploy).

Liferay Documentation:

Detect Multiple Displays in Adobe AIR

June 13th, 2011

To find the resolution of multiple monitors, you can loop through the Screen.screens array and then get the bounding rectangle of each monitor screen. Typically AIR counts from left to right (0 index the right most monitor) but I haven’t tested this on every monitor configuration.

import flash.display.Screen;

for(var i:int = 0; i < Screen.screens.length; i++)
    var x = Screen.screens[i].bounds.left;
    var y = 0;
    var width = Screen.screens[i].bounds.width;
    var height = Screen.screens[i].bounds.height;

Firebug Tutorial: Debugging CSS

February 18th, 2011

A few of my students at a work and some other friends often come to me with CSS debugging questions. I always turn to Firebug, and amazing Firefox add-on that let’s you analyze everything about a webpage from DOM, source HTML, CSS, Javascript, AJAS request, etc.  This little tutorial will demonstrate the basic techniques I use to figure out why the styling of elements isn’t quite working how it aught to.  Of course, to do this you will need Firefox and Firebug add-on.

Once you have this, navigate to the web page in question, for this example let’s look at:  Here you will notice the bullet list is very spaced out and not displaying from left to right. Hmm, I remember setting #nav to display:inline, I wonder why its not working. Let’s open up the Firebug console by clicking on the little bug icon in the bottom right corner of Firefox. Now click on the Inspect button, this will be the blue mouse pointer on top of a rectangle in the top left of the Firebug window.  After this is clicked, hover over the word “Home.” Notice how there is a blue border around that element and the firebug window changes and displays information about that element.

Notice that the #nav ul li element only has padding: 30px.  If you hover over the div #nav element, this is where the display:inline was. To make a list display from left to right, the LI elements must have the style display:inline.  Thanks to the inspect tool, we were able to see what CSS styles were assign to the element in question.

With Firebug, we can also do live edits to make sure we are correct. Double click on the area just to the right of padding: 30px and a new text box should pop up. In here type “display: inline”. Notice how Firebug auto-completes for you, as well as updates the webpage with the changes. Now the page should have a horizontal navigation bar below the header. Note that the line number of the CSS declaration is displayed in the information panel. This is very helpful in finding the actual line in the code to update.

You can also click on the HTML to the left of the style information to view that elements information. Click around and you should start to get a feel for the power of Firebug. Try adding some borders to the navigation bar, adjusting the margin and padding and see how everything is effected.