Category Archives: Web Development

Zend DBi announcement is good news for WebSmart and Clover users

For those of you using WebSmart or Clover to access MySQL on IBM i you may have been concerned about Oracle’s announcement earlier this year that they would no longer support MySQL on IBM i. Although we believe this would have had a minimal short term impact we are very pleased by Zend Technologies’ recent announcement of a December release of an IBM i-specific version of the MySQL database that they will develop, maintain and support.

The Zend Server 5.5 for IBM i release will include Zend DBi, which has been described as a ‘drop in replacement’ for MySQL. This is good news for IBM i shops who deploy pre-packaged or already develop PHP and MySQL applications.

Since last December, when Oracle announced plans to drop support for MySQL on many operating systems including i5/OS, IBM i PHP developers have been left wondering who, if anyone, will maintain the database.  The MySQL project is open source, so developers could download and create binaries, but that’s much easier said than done!  With this announcement Zend has moved into this space with the upcoming release of Zend DBi.

Changes that Zend makes to the code base will be posted back to the MySQL open source project.  Zend has no immediate plans to make the Zend DBi project open source though.  The initial release of Zend DBi will be functionally identical to the current release of MySQL shipped with Zend Server 5.1.  Moving forward there is the potential for some divergence as the code base is maintained and features added. We’ll be keeping an eye on these developments.

WebSmart and Clover clients can now have a greater degree of confidence that the classic PHP and iAMP stack will be supported on IBM i although we may have to rename the stack iADP.

More good news is that IBM will continue to support the IBMDB2i storage engine, which enables MySQL data to be stored in DB2/400 and accessed using traditional DB2 functions. For those of you interested in IBMDB2i we’ve developed a free utility called DB2iToMySQL to help you create MYSQL tables with that engine.

If you weren’t aware that you can create web reports over MySQL with Clover Query that’s probably because we just released a new version with that feature last week. You can read more details on the Clover new features page.

Read the full Zend DBi announcement in IT Jungle >>

Improve performance with gzip

I spend a fair amount of time worrying about performance. Within the Professional Services group I work with one of our clients, MedAxiom, developing an increasingly large and complex web application. Yet at the same I want to improve the user experience by speeding things up. One of the simpler ways to make a site faster is enabling gzip compression.

Gzipping components is one of ySlow’s recommendations and Steve Souders also recommends it in his book “High Performance Web Sites”. It’s an Apache module that applies gzip compression to certain output before sending it to the client. Once at the client, the browser unzips the content and displays it to the user. The end result is we’re sending less bytes which takes less time.

I set up a few benchmarks before enabling gzip so I could get an idea of the effect it has. I used Firebug’s Net panel to load each page five times and record the total size of the page and load time, I then took the average of the five loads.  Here are the results:

Page Before After Improvement
Size (kb) Time (ms) Size (kb) Time (ms) Size Time
Nexus home page 1,870 29100 536 14465 71% 50%
Nexus dev home page 2,382 31714 535 17060 77% 46%
Bar graph 633 9885 280 8405 55% 15%
Line graph 619 11450 280 7497 55% 34%

I was blown away by the improvement in load times!  MedAxiom has some pretty heavy Nexus pages so that’s where we saw the greatest improvement.  Yet even on smaller pages we still saw an improvement of 15%-34% in page load times.

Setting up gzip in Apache is pretty easy, you can do it by adding these directives to your Apache config in the appropriate place.

# Load the module that performs the compression.
LoadModule deflate_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM

# Compress all output by default.
SetOutputFilter DEFLATE

# Disable gzipping for images and pdf documents.
# Gzip compression has no effect on these types.
SetEnvIfNoCase Request_URI (gif|jpe?g|png)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary

5 Reasons To Use SQL instead of DDS

Many of us have used DDS for years to define our databases. In recent years SQL has become more prominent on platforms other than the IBM i, but there still seems to be reticent to adopt SQL instead of DDS. Here are five reasons why you should consider using SQL instead of DDS from now on.  IBM also has a great redbook on SQL with lots of great tips on how to use SQL features and how to move from DDS to SQL.

Reason 1: Everyone else is doing it!
I know- when our kids come to us with this reasoning we usually dismiss their argument. However, it’s true that SQL is driving database design and management on almost all major platforms and software development environments.  By learning SQL you will have skills you can transfer to any development project and your employer will benefit with you having cross-platform skills.

Reason 2: IBM is continually enhancing SQL support on IBM i. They have stopped enhancing DDS.
IBM recognizes that SQL is the way of the future. DDS is a proprietary language, used only on the IBM i platform. Any time IBM adds new features to the database they add those features to SQL. For example, enhanced transaction processing is only available in SQL. Improved index management is only available in SQL

Reason 3: SQL described tables and indexes can often perform better than DDS logical files.
This is because DDS-described files check to rebuild/update indexes when data is read from a file, while SQL checks only when the underlying table is updated. Since most applications perform read-only operations 8 times more than read/write ops, this yields a performance advantage

Reason 4: SQL  DDL (Data Description Language) is easy to code, and many tools are available to help you.
With DDS you are limited to SEU or RDP  or BCD’s DbGen (which actually hides the coding for you) for describing your physical and logical files. With SQL there are many tools available, some open source. Or, coding it by hand is simple too.

Reason 5: You can phase in SQL tables and indexes with minimal impact on existing applications.
You can convert your physical and logical files to SQL tables and indexes without having to change the underlying code.  IBM provides a conversion command that lets you extract SQL table definitions from physical files to give you a head start.

The new PHP stack on IBM i Improves Performance and Configuration

The introduction of Zend Core to the IBM i opened a new world of possibilities for IBM i developers trying to create web applications that would make use of their existing DB2 files while hosting them on the same system. Zend Core was the first step on porting a reliable PHP stack to the IBM i world and while it was indeed a great first step, there was also room for improvement.

The Zend Core distribution made use of an Apache instance that ran in the PASE environment, leaving the IBM HTTP Server Powered by Apache working as a reverse proxy mainly passing the requests to the instance in the PASE environment. As more advanced PHP applications were developed, developers and administrators began to struggle with more complex Apache directives and configuration that were needed because of the reverse proxy. Zend and IBM worked on a solution to eliminate this problem: The new Zend Server for IBM i. In addition to eliminating the Apache server in PASE, new and improved caching algorithms were introduced that have the capability to deliver great performance improvements depending on the nature of the applications.

Mike Pavlak goes into further detail explaining Zend Server’s packaging, new architecture, installation and server versions (Community Edition and Commercial Edition) on the “What’s New with PHP on IBM i?” article hosted at SystemiNetwork.

For those of you that are currently using Zend Core, we recommend the upgrade to Zend Server CE. You can read our KB article “Using WebSmart PHP with Zend Server CE” to get information on how to download and setup Zend Server CE.

How To Create a WebSmart Template that Converts Data from DB2 to MySQL

This post shows some of the features in the intelligent templates in WebSmart, and how to use those features to write your own powerful customized templates.

Recently, I wanted to convert the data in DB2 physical files to MySQL tables, so that I could easily take advantage of the IBMDB2i database engine for MySQL. I already have a nifty DB2 to MySQL code generator, which you can download for free from our website.  However, I didn’t have an easy way to import data from files.  So I decided to write a WebSmart program to do it. Using phpMyAdmin, I can then cut and paste the output from this program into the SQL text area, and run it. The output needs to look something like this (for a fictitious file):

INSERT into `CUSTOMERS` (`custno`, `custname`, `crtdate`, `crttime`)
VALUES (1, 'Acme Bolts', '2010-06-02', '15:35:12'),
(2, 'Superior Widgets', '2010-06-03', '16:04:35');

You can import tables into MySQL using the phpMyAdmin interface or a command line interface from the PASE environment on the IBM i. In phpMyAdmin, you choose the ‘Import’ option and select a plaintext file with a .sql extension from somewhere locally. So if I save the above code in a text file called customer.sql, I go to phpMyAdmin, choose my database, click the Import link, select the file customer.sql and voila! I have a customer MySQL table, complete with 2 rows of data. Continue reading

New WebSmart Updates, Examples & KB Articles. Last Call to Sign up for WS ILE Online Training.

We have recently created new WebSmart example programs and published many KB articles that may be useful to you. Also, registration closes on Saturday for the WebSmart ILE online training, and there are some new updates you should be aware of.

WebSmart 8.8 IDE Update
WebSmart IDE version 5983-8198 is available for download. This updated version of the IDE resolves two issues: getparm would not retrieve values into a structure, and some View Data problems with user input values in Clover. We also added additional JavaScript keywords to the context-sensitive F1 help.

WebSmart 8.8 Feature Spotlight: jQuery
Developers wanting to use more powerful web development features will be particularly excited to see that in WebSmart 8.8 we switched our templates to use the jQuery JavaScript library. If you aren’t yet familiar with jQuery it’s well worth spending a few hours reading up on it online and reviewing some of our own online examples. We use it extensively ourselves, both in our software tools and our professional services work.

WebSmart 8.8 is the latest release of the software. Check our web site for an overview of the new features, or view the recorded webinar.

WebSmart 8.2 Updates
Just before releasing WebSmart 8.8 we had created a few updates for WebSmart 8.2. You can find more information about these updates at the WebSmart server and client side updates history pages.

These fixes are included in version 8.8, but if you aren’t ready to upgrade and would rather just apply them as updates to your current installation of version 8.2, email us to request download instructions.

Last call for WebSmart ILE Online Training
Registration for next week’s first WebSmart ILE online training course ends this Saturday. You can attend these 2 hour courses from the convenience of your office at the low cost of $149 per course. You can register for individual courses or all of the following topics: WebSmart templates, intro to PML, passing parameters, getting user input and validating the data, stateless programming and security. Enroll or learn more >>.

New Code Samples
We have published several code samples you can use as you create WebSmart applications:

  • Example 214 illustrates how to use jQuery to quickly display list record details in a pop-up window without loading a separate page.
  • In Example 213 we helped a client resolve a validation problem where users were submitting data that included specific characters they could not have in their files.
  • Example 206 describes the steps to create a web service using PHP and SOAP.

Let us know if you have any questions or comments on these, or need help implementing them!

New KB Articles
Our Tech Team has also been busy writing new KB articles. Here is a sampler:

  • A solution to a problem with PHP programs timing out before fully loading very large pages.
  • Information on how to work with PDF and Excel files in your PHP programs.
  • How to check which WebSmart service programs are currently used by your applications (a great new feature in WS 8.8!)
  • A way to add compiler directives to your programs via the PML.
  • Advice on where to look if you have issues with user-written functions after an upgrade.
  • Suggestions on how to use SQL scalar functions for enhanced functionality in the PML.
  • Information on the option to log program execution time.
  • An approach to limiting the number of records returned by a Clover report.
  • A technique for adding post-processing actions (deleting a work file) to Clover programs.

These are just a few of the new articles. There are also many others that include troubleshooting and error information for obscure compile and runtime errors.

Web Application Security – What is XSS and SQL injection?

RPG programmers who are new to web development have probably come accross the terms “Cross Site Scripting (XSS)” and “SQL Injection”, and can probably relate them to web application security topics. If you are concerned about security, and most likely you are, further research is needed in order to understand and prevent these risks .

What exactly is XSS? How can it be prevented? What is an example of SQL injection? Do I have the correct code to prevent such exploits on my application? Without a doubt, these are some of the many questions that come to mind. To get a better understanding of these topics and other security concerns, I strongly recommend that you take a look at the article “Common Security Mistakes in Web Applications”, hosted by Smashing Magazine.

This is probably one of the best articles I’ve read in terms of its simplicity and clarity. It provides you with straightforward examples and a solid explanation of each concept. Even though the article refers to PHP coding techniques, the same concepts will apply for web applications developed with other programming languages or tools, including WebSmart ILE. Enjoy!

Check for Flash-enabled browsers (using JavaScript)

Something most web developers take for granted is the ability of our user’s browser to render Flash. When working with BCD’s product suite, this is particularly true whenever we do any development with SmartCharts. But as you may be aware, there are some browsers which can not actually render Flash objects – namely the iPhone and iPad versions of Safari. These users not only fail to see any of your Flash content, but they also tend to receive a popup error message for every flash object you put on a page. So, in addition to missing out on some key functionality of your page, they also get an annoying alert (or three, or five, or ten…). Continue reading

jQuery UI Autocomplete, JSON and PHP

In case you are not familiar with the term ‘autocomplete,’ it refers to the kind of functionality you get with Google mail when typing a ‘to’ email address, or in Google Suggest.  As you type characters in the search box, it ‘autocompletes’ by providing you a list of matches. The list gets refined the more you type.  We also have  a WebSmart example you can try out live.  Autocomplete widgets can help make your applications more user-friendly, because they make it much easier for users to find items in large sets of data.

We’ve used Autocomplete plugins in a number of our web applications (both for customers and internal use) for some time now. I just stumbled upon the relatively new jQuery UI Autocomplete plugin. There is some good example code at the jQueryUI site.  Another good tutorial on how to use it is this one.

This post explains how to code it for a typical usage. Note that although I am using PHP here, you can accomplish exactly the same thing with PML and DB2 SQL in WebSmart ILE.

Here’s a sample image from a work in progress (new customer log system using jQuery, AJAX, PHP and MySQL). I’ve blurred the customers, as this is real data from our files.

 

 

Let’s look at the code required to implement this. First, the client-code (jQuery and JavaScript).

Client Code

	jQuery("#sercompany").autocomplete({
			minLength: 3,
	 	    delay : 400,
			source: function(request, response) { 

				jQuery.ajax({
				   url: 	 "index.php",
				   data:  {
				   			mode : "ajax",
				   			component : "consearch",
				   			searcharg : "company",
				   			task : "display",
				   			limit : 15,
				   			term : request.term
				   	},
				   dataType: "json",

				   success: function(data) 	{

					 response(data);
				  }	

				})
	 	   },

		   select:  function(e, ui) {
				var keyvalue = ui.item.value;
				alert("Customer number is " + keyvalue); 

			}
		});

The important pieces here are the source property and the select event. The source property really defines 2 key aspects of the autocomplete widget: the source (input) of the data to populate, and how to put it in the autocomplete box (formatting, etc).

First, it defines the source of the data. This can be a local Javascript array – useful for small, relatively static data sets such as State abbreviations. It can also be a string with a value of a URL. The URL will point to a script (see below for example code) that gets invoked via AJAX and returns an array of items. While this may seem the obvious choice for most cases, it’s really not that useful because you have no control over how you format your response data. The third possibility, as shown in the example code above, is an anonymous function. This is the most useful coding pattern. The function accepts two parameters- request and response. Request is an object that has a property called term, whose value is whatever the user types in to search for. So, if the user types ‘AME’, then request.term == ‘AME’. Response is a callback function name that implicitly accepts one parameter, the data to display in the autocomplete results box. This is poorly explained and documented on the jQuery UI site. I only really understood this by reading Dan Wellman’s article. Look at the client code above and you’ll see this line:

  response(data);

That’s a call to the manufactured callback function. You’ll notice, also, that in order to actually do anything, you have to explicitly code the ajax call in the callback function for the source property. This is quite a different coding pattern than what we used with the ‘old’ jQuery autocomplete plugin, but the whole design of this code is so much more elegant and flexible.

The other key piece in the client-side code is the select event. This event is triggered when the user clicks on one of the values in the list. In my example code this just causes an alert box to popup that shows the value of the customer number. The select callback function accepts 2 parameters- the event object (not sure why you’d want that) and the ‘selected item’ object (which I’ve called, by convention, ‘ui’). Note that ui has an object called ‘item’ as one of its properties, which in turn has ‘value’ as a property. Hence: ui.item.value refers to the value of the selected line. You can have other, custom properties besides the 2 standard ones (‘value’ and ‘label’), as shown in this example.

I could not find formal documentation describing ui.item, only example code.

In the real world, the next step would be to do either a redirect or an AJAX call to a script/program that lets me work with my selected customer. I’d likely include the customer key in the url, for example:

  var surl = "index.php?task=edit&custno=" + ui.item.value;
  $.get(surl);
  ...

Next, let’s look at the server code.

Server Code

	$searcharg  = getparm('searcharg');
	$limit = getparm('limit');
	if (!$limit) $limit=10;
	$sercontact = '';
	$sercompny = '';
	$term = getparm('term'); 

	 	$sercompny = strtoupper($term);
		$query = "SELECT  CLCLNU, CLCLNA FROM CS_CLTF WHERE clclna like '%" . trim($sercompny) . "%' order by CLCLNA";  

	$query = $query." LIMIT  $limit";  // Limit results based on the limit parameter from the ajax call. 

	$rows = $db->get_results($query);  // Populate result set
		// While we retrieve a row from the result set:
	$count=0;
	if ($rows)
	{
		foreach($rows as $row)
		{
			$companies[$count] = array("value" => $row->CLCLNU, "label" =>  $row->CLCLNA);
			$count++;
		}
		echo  json_encode($companies);
	}

(FYI I’m using the EZSql library here to do my SQL coding. EZSql is a PHP library that makes coding SQL statements simpler, and supports multiple databases. A comparable library is PDO, part of Zend Frameworks. EZSql is Free and Open Source).

Note the use of json_encode. What this does is produce a JSON-formatted  array of  objects. Each object has a property of “value” (the customer number – key to the customer table) and “label” (customer name- what appears in the autocomplete). Even though I assign these values to an associative array, json_encode treats it like an object when it translates it (which makes sense when you think about it, and is documented on php.net as intended behavior).

To be a little more clear, the returned data from the PHP script to the AJAX callback will look something like this:


[{"value":"3215","label":"COMMUNICATION INC."},
{"value":"1572","label":"ABADOCOMS"},
{"value":"8243","label":"ACME MANUFACTURING COMPANY"},
{"value":"5713","label":"ABCDEFS COMPANIES, INC."},
{"value":"4869","label":"ABERYSTWYTH AVENUE COMPANY"},
{"value":"223","label":"ALLKINDS COMPRESSOR"},
{"value":"3705","label":"MIGHTY INSURANCE COMP"}]

It seems to me this Autocomplete plugin is way better than the jQuery autocomplete plugin I’ve used before, particularly since it uses the jQueryUI CSS framework to style the autocomplete dropdown box. It’s more flexible, you can define the code in one object call instead of two, and it’s more likely to be supported and maintained by the jQueryUI team.

Stop giving a rendering option to IE 8 users

IE 8 has the dubious advantage of multiple rendering engines to choose from via the “Compatibility Mode” options. Personally, I like this feature, but what I’ve discovered is that a lot of users don’t know this feature exists which leads to the problem of them viewing everything in IE 7 mode by having the “Display all websites in Compatibilty View” setting turned on.

I’m not sure if this option is turned on by default on a fresh install of IE 8 or if users turn it on when they setup IE 8 for the first time (and I mean really, who wouldn’t choose compatibility?). The bottom line though, is if a user has upgraded to IE 8 you want to give them the best experience you can by using the most modern rendering engine.

Microsoft gave us a way to specify the rendering engine by using the X-UA-Compatible http header or meta tag. You can use this to force IE 8 to use the IE 8 rendering mode even if the user has compatibility mode turned on. So, if you’re building a new site, why give your IE 8 users the option to render your beautiful css and html in IE 7 mode?

Here’s how to use the meta-tag option, this tag should be at the top of the <head> section of your page:

<meta http-equiv=”X-UA-Compatible” content=”IE=8″ />

Or you can set the http header in your Apache config:

Header onsuccess set “X-UA-Compatible” “IE=8″

If you want to limit the http header to a subset of your domain you can use environment variables in Apache:

SetEnvIf Request_URI “/myapp/” is_my_app=1

Header onsuccess set “X-UA-Compatible” “IE=8″ env=is_my_app