Professional Documents
Culture Documents
Jon Paris
Jon.Paris @ Partner400.com
www.Partner400.com
SystemiDeveloper.com Your Partner in IBM i Education
1
Notes
This presentation may contain small code examples that are furnished as simple examples to provide an
illustration. These examples have not been thoroughly tested under all conditions. We therefore, cannot
guarantee or imply reliability, serviceability, or function of these programs.
All code examples contained herein are provided to you "as is". THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
DISCLAIMED.
The authors, Jon Paris and Susan Gantner, are co-founders of Partner400, a firm specializing in
customized education and mentoring services for AS/400 and iSeries developers. After individual careers
with IBM, including working at both the Rochester and Toronto laboratories, Jon and Susan are now
devoted to educating developers on techniques and technologies to extend and modernize their
applications and development environments.
Jon and Susan author regular technical articles for the IBM publication, IBM Systems Magazine, i5 edition,
and the companion electronic newsletter, iSeries Extra. You may view articles in current and past issues
and/or subscribe to the free newsletter at: http://IBMsystemsMag/iseries/.
2
Agenda
What is PHP
And how it operates on IBM i
The Basics of the PHP language
PHP variables
Control Structures
Array Processing
Other Examples
Notes
While we can't even begin to cover the entire PHP language in a single session, we hope to give you a
taste of what the language brings to the table. Just enough to allow you to see just why PHP has quickly
become the language of choice for implementing web based solutions on IBM i. Hopefully it will encourage
you to study it further.
Far easier to learn than Java - and with a huge array of free education and software available - PHP is a
great fit for the RPG shop that needs to deploy applications to the web quickly.
To facilitate your further studies we highly recommend "The IBM i Programmer's Guide to PHP" by Jeff
Olen and Kevin Schroeder - published by MC Press. A lot of good basic PHP information and excellent
examples of the IBM i specific functions. Some of the IBM i examples in this handout are based on
examples from the book. And yes - they are used with permission from the authors.
4
What is PHP ?
A scripting language for developing Web applications
But can also be used stand-alone in command line mode
Originally PHP stood for "Personal Home Page"
Just like RPG, it has come a long way from its roots
PHP is now a recursive (or self-referential) acronym
i.e. the first "P" in PHP stands for PHP
The formal definition is - PHP: Hypertext Preprocessor.
At heart a procedural language
But V4 added OO capabilities
! Easier for an RPGer to learn than a pure OO language like Java
! Use as much or as little OO as you need
6
PHP Operation on IBM i
PHP itself runs in the PASE environment
Communicates with the world via a native Apache server
! Set up for you during the install
! By default on port 10088
! That way it does not interfere with your regular HTTP server
Apache
HTTP
Server Zend Server
DB2
Access
Native
Functions PASE
Notes
When you install Zend Server a number of components are installed for you.
1) An Apache web server which is configured by default to accept requests on port 89 i.e. http://www.MyWebSite.com:89. This
default is chosen in order to avoid any conflict with any existing web server operating on the conventional port 80.
2) The Zend Server PHP engine which handles all PHP requests and interfaces with the IBM i operating system.
3) (Optional) MySQL - since this is the database of choice for most Open-Source PHP applications you are probably going to need it.
Not only that, but with the advent of the DB2 Storage engine, you will be able to process your MySQL data with your regular RPG
programs and vice versa.
Not only are the components installed, but the necessary configuration files are set up so that the resulting environment should "just
work". You can test the install by seeing if you can connect to the port 89 server (http://YourServerName:89), which should give you
access to the demo programs and the Zend configuration console.
8
A Simple PHP Script
<?php
$myName = "Jon Paris";
$location = "Mississauga, Ontario, Canada";
$experience = 40;
$languages = array("RPG IV", "PHP", "Java", "COBOL", "CL", "Basic");
echo "This script was written by $myName.<br>";
echo "He lives in $location and has been playing with computers for
over $experience years.<br>";
echo "Here are a few of the languages he has used so far in his
career:<br>";
foreach ($languages as $language) {
print "$language<br>";
}
echo "<br><br>Print_r output<br>";
print_r($languages);
echo "<br><br>Var_dump output<br>";
var_dump($languages);
?>
10
Understanding the Script - Part 1
<?php
$myName = "Jon Paris";
$location = "Mississauga, Ontario, Canada";
$experience = 40;
...
?>
11
Notes
A PHP script begins with the characters <?PHP - this identifies the beginning of what is called a PHP
"code island". As you will see later, code islands can be imbedded into HTML pages and it is this marker
that allows the system to differentiate between the PHP and HTML components of the file.
At the start of the script proper we simply assign a value to the variable $myName. As you can see, PHP
has no equivalent to RPG's D-specs - variables are simply defined by being used.
Of course it is good practice to group your variables' definitions, but the language does not enforce it. In
fact PHP will happily allow you to reference a variable before it has been defined, but a good editor such
as Zend Studio will warn you about this. In fact it is possible to have PHP treat such events as an error or
warning depending on your PHP error handling settings. Look up the function error_reporting() in the PHP
manual if you want to know more. The default setting for most web servers is to ignore such errors as
PHP has a well defined default behavior for such instances.
12
Understanding the Script - Part 2
...
echo "<p>This script was written by $myName.</p>";
echo "<p>He lives in $location and has been playing with computers for
over $experience years.</p>";
echo "<p>Here are a few of the languages he has used so far in his
career:</p>";
...
Scripts add content to the page through the use of print and echo
The two are interchangeable for all practical purposes
Variables within literal strings are replaced by their content
As long as the string is delimited by double quotes like this
If single quotes are used no substitution takes place
13
Notes
The echo function is being used here to add content to the web page. Strictly speaking echo is a language
construct in PHP and so does not require the use of parentheses around its parameters, although you will often
see them used. We could also have used the print function as the two are used interchangeably (see below)
Note that the literal string being output is enclosed within double-quotes. Because of this any variables found
within it will be replaced by their content when output. So what will appear on the web page is "This script was
written by Jon Paris.". Had we used single-quotes the output would have been "This script was written by
$myName.".
To achieve similar blending of literals and variables in RPG takes a lot more work. In this case we would have
had to code something like this:
While this may not seem a big difference in a simple case like this, it makes it much harder to keep track of
spacing, punctuation etc. and I'm sure you can see how much simpler the PHP approach makes things,
particularly when building more complex strings.
print and echo - what's the difference? The only significant difference between the two is that echo can take
multiple parameters whereas print only takes one. For all practical purposes the two are used pretty much
interchangeably, the choice as to which to use being mostly a matter of style and personal preference. For
those of you who just "have to know" the full scope of the differences, you can find most of the gory details
here: ((http://www.faqts.com/knowledge_base/view.phtml/aid/1/fid/40)).
14
A Simple PHP Script - Part 3
...
$languages = array("RPG IV", "PHP", "Java", "COBOL", "CL", "Basic");
...
foreach ($languages as $language) {
print "$language<br>";
}
Notes
Now we come to one of my favorite PHP constructs - foreach.
This provides a really simple way to iterate over an array and apply the same processing to each element
in turn. In our example we are telling PHP to take each of the elements in the $languages array and assign
each in turn to the variable $language.
The code block within the { ... } brackets is then executed using that variable. We will talk more about the
use of brackets in conditional expressions on later charts. All we are going to do in this case is to output
the content of the variable - this time using the print construct.
16
A Simple PHP Script - Part 4
...
echo "<br><br>Print_r output<br>";
print_r($languages);
The text in red below shows
echo "<br><br>Var_dump output<br>";
part of the actual output from
var_dump($languages);
the two functions
?>
Array ( [0] => RPG IV [1] => PHP [2] => Java [3] => COBOL ...
Notes
Before ending the discussion on this first script lets take a look at two great PHP debugging tools. Because PHP is so different in many
ways from RPG, particularly in areas such as arrays, I found these two invaluable in my early explorations. Both fulfill the same basic
function (to dump the contents of a variable) but they differ in the amount of detail that they provide. In some ways they are similar to
RPG's DUMP operation code, but provide a degree of granularity not possible with DUMP. The resulting output is also a lot easier to
navigate.
The first is the print_r() function. As you can see we simply pass the name of the variable we want to know about ($languages) as a
parameter to the function. As a result, PHP will extract the contents of the array and format it for display. In our example the result will be:
Array ( [0] => RPG IV [1] => PHP [2] => Java [3] => COBOL [4] => CL [5] => Basic )
This tells us that the variable we passed was an array, and that the first element (i.e. The one with index [0]) contained the value "RPG
IV". The second contained "PHP" and so on. I find it convenient to think of the "=>" combination as meaning "points to" - in other words,
[0] "points to" the value "RPG IV".
The second of the debugging functions we are using here is var_dump(). It provides more detail than print_r() in that it identifies the data
type of each element in the array and the length of its content. This can be very useful in cases where the content contains spaces since
by default the browser treats consecutive spaces as a single space when displaying data. The output from our example looks like this:
array(6) { [0]=> string(6) "RPG IV" [1]=> string(3) "PHP" [2]=> string(4) "Java" [3]=> string(5) "COBOL" [4]=> string(2) "CL" [5]=> string(5)
"Basic" }
The (6) at the beginning tells us that there are 6 elements in the array. Similarly the length and data type of each element in the array is
identified.
When you first try using some functions (like web services, or database retrieval) it is really helpful to output the content of each variable
in turn as you develop your code. Of course a good debugger (like the one in Zend Studio) can also show you the same information -
but sometimes it is just easier to incorporate it into the script.
18
More on PHP Variables
Variable names are cAsE_sEnSiTiVe!
So are function and object names etc.
But (most?) PHP reserved words are not
! So for example IF, if, If and iF are all accepted - at least by Zend
versions
The name can include underscore, letters, and numbers
e.g. $_a_PHP_name, $AnotherName, $And_yet_1_more
But cannot begin with a number
There are only seven types of variables
A variable's type is determined by the value placed in it
! And yes - that does mean that it can change type!
! Dont panic - this is a good thing - More on this in a few minutes
19
20
Other PHP Data Types
Compound types
array
! Arrays are very very powerful in PHP
! Nothing like RPG arrays
object
! Object references are very similar to array references
! Once you know how to handle arrays, Objects are easy to
understand
Resources
You will use these a lot
They are "handles" to things created outside of PHP itself
! For example a database connection, an image file
! Or more importantly a System i connection, program object, etc.
21
Notes
Note that although PHP (like most multi-platform languages) does not have an equivalent to packed decimal.
Indeed the only numeric type that can accommodate decimal places is floating point. However, it does support
decimal math when needed. We wont go into it in detail in this session but heres a brief example to point you
in the right direction should you need it in the future.
Support is in the form of the BC Math functions such as bcadd, bcsub, bcmul, etc. These operate on decimal
numbers represented as strings. This is similar to the way Java (for example) handles this situation. Here's a
simple example of addition:
<?php
$a = '1.234';
$b = '5';
?>
Notice that the optional third parameter is supplying the precision (decimal places) required in the final answer.
The example above outputs the results to the browser screen, but they could equally have been stored in
variables. While not as elegant as a simple "echo ($a + $b);" you will find that you need to use this functionality
far less often than you may think at first glance.
22
Changing a Variable's Type
Variables in PHP are dynamically typed
One minute they can be a character field
The next they are an integer!
Much of the power of the language derives from this ability
But is can cause "interesting" debugging challenges
Just like the MOVE op-code in RPG!!
Take a look at the example below
The type of $myVar changes based on the way in which it is used
<?php
echo "<h3>The ever changing variable</h3>";
$myVar = "1"; // variable is a string with the value 1
echo "<br>\$myVar is now <b>" .gettype($myVar) . "</b> value $myVar<br>";
$myVar = $myVar + 2; // now it is an integer with the value 3!
echo "<br>\$myVar is now <b>" .gettype($myVar) . "</b> value $myVar<br>";
$myVar = $myVar / 2; // and now floating point with the value 1.5
echo "<br>\$myVar is now <b>" .gettype($myVar) . "</b> value $myVar<br>";
?>
23
Output Result
24
Conditional Expressions in PHP
The equality test operator is ==
At first most RPGers will fall into the trap of using a simple "="
Sadly the resulting code is usually syntactically valid
It just doesnt do what you want as the example demonstrates
Another difference is that in PHP expressions must be in parens ( )
Although this practice is also highly recommended for RPG code
<?php
$age = 60;
$limit = 70;
$fare = 100;
echo "Right now your age is $age<br>";
25
26
Control Structures - SWITCH
Switch / Case / Default is similar to RPG's Select / When / Other
But can only test the content of a single variable
This will be familiar to you if you know COBOL or C or ...
Beware - you will probably need to insert break operations to make Switch/
Case work the way you expect it to!
<?php
switch ($ageGroup) {
case (1):
echo "You are in group 1";
break;
case (5):
echo "A member of group 5 no less!";
break;
default:
echo "Some other group namely $ageGroup";
break; }
?>
27
<HTML>
<BODY>
<H2>
Using the for loop
</H2>
<?php
for ($counter = 0; $counter < 5;
$counter++){
echo "<BR>I'm doing this five times.<BR>";
echo "That was #" . ($counter + 1);
}
if ($counter > 4)
echo "<BR>I guess that worked OK!";
?>
</BODY>
</HTML>
28
Arrays
Simple arrays can be defined in a number of ways
The array() function shown below is very easy to use
It certainly beats compile time tables
Alternatively elements can simply be added as in the C++ example
The value will be placed in the next empty location (i.e. the 6th element)
The array will dynamically expand if needed
Or loaded into a specific location as with CL below
Note: Indexes start at 0 (zero) - not 1 as in RPG!
<?php
$languages = array("RPG400", "RPG IV", "COBOL", "Java", "PHP");
print_r($languages); // print_r is a very useful debugging tool
echo "<br><br>";
$languages[] = "C++"; // This adds another element to the array
$languages[6] = "CL"; // And this loads "CL" into location 6
Var_dump($languages); // var_dump is also useful in debugging
?>
29
Output Result
Array ( [0] => RPG400 [1] => RPG IV [2] => COBOL
[3] => Java [4] => PHP )
<?php
$languages = array("RPG400", "RPG IV", "COBOL", "Java", "PHP");
foreach ($languages as $language) {
echo "<p>$language</p>"; }
?>
31
Notes
Arrays are one of my favorite features in PHP. The flexibility afforded by being able to store any kind of
data in an array element - including another array - makes for a very flexible and powerful programming
environment.
ForEach is the easiest way to loop through an array and process the contents. You don't need to concern
yourself with the number of elements etc. because PHP will skip "empty" elements and automatically stop
when the end of the array is reached.
32
More on Arrays - Other Functions
foreach is just one of over 60 array functions
You can sort arrays
! In strict code sequence or in natural sequence
You can search them
Create an array from a text file
! Or create a text file from an array
Compare two arrays for differences, or matches, or ...
Array can contain other arrays
Thats how 2 and 3 dimensional arrays are created
Arrays have a cursor and can be navigated like a file
Examples on the next page
33
Notes
There are some incredibly powerful array functions available in the standard PHP function library. Also as
you will learn, arrays are at the heart of almost everything we do in PHP from database access, to web
services, to calling RPG programs!
Take the time to thoroughly explore PHP's arrays - it may also give you some ideas on how to further
exploit arrays in your RPG code!
34
Navigating Arrays
<?php
$myArray = array("Car", "Truck","Motorcycle","Plane","Bicycle");
echo "<p>Here's the complete array </p>";
print_r($myArray);
echo "<br><br>";
echo "Current: ", current($myArray), "<br>";
echo "Next: ", next($myArray), "<br>";
echo "One after that: ", next($myArray), "<br>";
echo "Prev: ", prev($myArray), "<br>";
echo "End: ", end($myArray), "<br>";
echo "Resetting the array.<br>";
reset($myArray);
echo "Current: ", current($myArray), "<br>";
?>
Output Result
Array ( [0] => Car [1] => Truck [2] => Motorcycle [3] => Plane [4] => Bicycle )
Current: Car
Next: Truck
Prev: Truck
End: Bicycle
Current: Car
36
Associative Arrays
A really powerful feature
Allows you to associate a key with an array element
Elements can then be accessed via their key or sequentially
See the highlighted line for an example of keyed access
To do this in RPG requires matched arrays and a lot more coding
And we don't have the same range of functions available in PHP
Associative Arrays are commonly used in PHP interfaces
For example database, web services, and most IBM i functions
<?php
$programmers = array("RPG IV" => 600, "COBOL" => 99,
"Java" => 195, "PHP" => "lots of");
print_r($programmers);
echo "<br><br>";
foreach ($programmers as $programmer => $count) {
echo "<p> There are $count $programmer programmers</p>"; }
echo "<p>I repeat there are " . $programmers["RPG IV"]
. " RPG IV Programmers</p>"
?>
37
Output Result
Array ( [RPG IV] => 600 [COBOL] => 99 [Java] => 195 [PHP] => lots of )
38
Agenda
A few examples
XML, Web services, email
39
<HTML><BODY><CENTER>
<H1>Reading All Form Data</H1>
<FORM GET ACTION="Pick-A-Food.php">
What's your name? <INPUT NAME="Name" TYPE="TEXT"><BR><BR>
Select your favorite fruit(s):
<SELECT NAME="Food[]" MULTIPLE>
<OPTION>Apple</OPTION>
<OPTION>Hamburger</OPTION>
<OPTION>Pear</OPTION>
<OPTION>Plum</OPTION>
<OPTION>Pomegranate</OPTION>
</SELECT>
<BR><BR><INPUT TYPE="SUBMIT" NAME="SUBMIT" VALUE="Enter">
</FORM>
</CENTER></BODY></HTML>
40
Retrieving Form Input Data
Input method to be used (GET or POST) is specified on the Form
It determines which superglobal array will contain the data
! $_GET[ ] or $_POST[ ]
! There is also $_REQUEST[ ] which contains the input from all sources
- But it represents a security risk and should only be used during testing
Our form used the GET method so all data is in $_GET[ ]
The count() function identifies the number of foods selected
And $_GET['Name'] retrieves the name entered
<HTML><BODY><CENTER>
<H3>Retrieving Data From Forms</H3>
<?php
$foodCount = count($_GET['Food']);
41
42
IBM i Record I/O Functions - Part 1
Note: This part is just
<html> HTML - no PHP yet
<body>
<h2>Simple Full Table Test - i5 Native APIs</h2>
<table border="1" width="670">
<tr>
<th width="110">Customer</th>
<th width="260">Name</th>
<th width="240">City</th>
<th width="60">State</th>
</tr> Report errors using
IBM i specific
<?php
information
function iErrMsg($msgText) {
errInfo = i5_error();
echo '<tr><td colspan ="4">', $msgText, '<br>Message code: ',
$errInfo[0], ' IBM i Message No: ', $errInfo[2],
'<br>Text:', $errInfo[3], '</td></tr>';
die();
}
43
i5_close($i5conn);
?>
Close out the
</table>
</body> Table etc.
</html>
44
Simple Database Example
This uses SQLite which is built into V5+ releases of PHP
<?php
$db = sqlite_open("db.sqlite");
$query = sqlite_query($db, 'SELECT * FROM names WHERE salary > 45000
ORDER BY lastname, firstname');
// Output table headers
echo "<table border=1 width=40%>
<th>Id<th>Name<th>Location<th>Salary";
// Get results as an array with the column name as the index
$result = sqlite_fetch_all($query, SQLITE_ASSOC);
// Iterate through the retrieved rows and output row data
foreach ($result as $entry)
{
echo "<tr><td>{$entry['id']}</td>
<td>{$entry['lastname']}, {$entry['firstname']}</td>
<td>{$entry['location']}</td>
<td align=right>{$entry['salary']}</td></tr>";
}
// Wrap up the table
echo "</table>";
sqlite_close($db);
?>
45
/Free
XML-INTO company %XML( XML_Input1: 'doc=file case=any' );
for i = 1 to xmlElements;
dsply company(i);
endfor;
<?php
$Customers = simplexml_load_file("\\Partner400\\Customers.xml");
46
RPG IV XML Processing Example
The previous chart left out this part of the RPG version
RPG requires the data to be predefined - PHP does it dynamically
D progStatus SDS
D xmlElements 20i 0 Overlay(progStatus: 372)
D i s 10i 0
D customers DS Qualified
D recordCount 3p 0
D customer LikeDS(customer) Dim(99)
D customer DS Qualified
D type 10a
D company 32a
D address LikeDS(address)
D address DS
D street 32a
D city 24a
D state 2a
D zip 5s 0
47
<HTML>
<BODY>
<CENTER>
<H1>Send me some email</H1>
<FORM METHOD=POST ACTION="phpemail.php">
Please enter your message and click Submit:<BR>
<TEXTAREA NAME="message" COLS="50" ROWS="5">
</TEXTAREA><BR>
<INPUT TYPE="SUBMIT" VALUE="Submit">
</FORM>
</CENTER>
<BODY>
</HTML>
48
Simple Script to Send e-Mail
The mail() function is used to send the mail
The first parameter is the recipient's address
The second is the subject line
And the third is the message body
Note that it is retrieved from the FORM text area "message"
<HTML>
<BODY>
<CENTER>
<H1>Sending email</H1>
Your email was sent.<BR>
<?php
$result = mail("contact@partner400.com",
"Test PHP Mail", $_REQUEST["message"]);
?>
</CENTER>
<BODY>
</HTML>
49
$input = 100;
$wsdl = 'http://www.webservicex.net/CurrencyConvertor.asmx?wsdl';
$result = $client->ConversionRate($currencies);
$rate = $result->ConversionRateResult;
$answer = $input * $rate;
PHP provides quick and easy access to Web Services such as this
It is a currency conversion service
PHP's SOAP APIs make it simple to add such functionality to your scripts
50
Useful (hopefully) References
Web Sites:
www.zend.com
For tutorials, documentation, samples, forums, and all of the i5 specifics
www.php.net
The on-line PHP manual is amazing!
Books:
PHP in a Nutshell - Paul Hudson - O'Reilly Press
Spring Into - PHP 5 - Steven Holzner - Addison Wesley
The IBM i Programmer's Guide to PHP - Jeff Olen and Kevin Schroeder -
MC Press
Other:
Countless tutorials and samples on the web. Just "Google it"
Load Zend Server Community Edition on your PC
http://www.zend.com/en/community/zend-server-ce
And don't forget to download Zend Studio while you are there
51
Agenda
?
Please e-mail Jon at:
Jon.Paris @ Partner400.com
for any questions
The IBM i specific APIs described
earlier and shown on the following
pages will shortly be replaced. They
are shown here just to give you an
idea of the range of functionality.
52
i5_ APIs
Connection Management Data retrieval
i5_connect i5_fetch_array
I5_pconnect i5_fetch_assoc
i5_close i5_fetch_object
I5_pclose i5_fetch_row
i5_adopt_authority i5_info
i5_error i5_field_len
i5_errormsg i5_field_name
CL calls i5_field_scale
i5_command i5_field_type
i5_cmdget i5_list_fields
i5_num_fields
Program Calls i5_result
i5_program_prepare
i5_program_call
i5_program_close
53
i5_ APIs
Native file access Native file access (contd.)
i5_open i5_free_file
i5_addnew i5_new_record
I5_edit i5_delete_record
I5_delete i5_update_record
i5_cancel_edit i5_get_keys
i5_setvalue
System Values
i5_update
i5_get_system_value
i5_range_from
i5_range_to Data Areas
i5_range_clear i5_data_area_create
i5_data_seek i5_data_area_read
i5_seek i5_data_area_write
i5_bookmark i5_data_area_delete
54
i5_ APIs
Data Queues Output Queues
i5_dtaq_open i5_outq_open
i5_dtaq_put i5_outq_read
i5_dtaq_read i5_outq_close
i5_dtaq_close
Spool File
Jobs i5_spool_open
i5_jobs_joblog i5_spool_get_data
i5_jobs_joblog_close i5_spool_from_data
i5_jobs_list_start i5_spool_from_file
i5_jobs_list_close i5_spool_close
55