"PHP offers many opportunities and avenues to leverage existing i5 investments. One such area to leverage is the existing i5 applications and programs. This presentation will guide you through examples utilizing PHP to both invoke RPG/COBOL/CL programs web-enable 5250 applications."
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Modernizing i5 Applications
1. Extending RPG with PHP
Exploiting RPG Applications in new ways
Jon.Paris @ Partner400.com
www.systemideveloper.com
www.Partner400.com
2. Topics
Before we discuss the options ...
• A quick look at what are other users doing with PHP in i land
Updating business practices with new free/low-cost tools
• Everything from Help Desk software to User Documentation
Extending your RPG application set
• Using PHP to do things RPG can't do
- Or at least can't do as easily
- e.g. E-mail, XML processing, Creating Spreadsheets, File Uploads
• , etc. from new web applications
Refacing 5250 with the latest option - Zend 5250 Bridge
• A new option for putting 5250 applications to work in new ways
- For example as Web Services
- Or in a new quot;Web Facedquot; role
3. What are i Users Doing ?
Consolidation:
• Re-hosting PHP applications currently running on Windows or Linux
that access data in DB2
• Speed up applications while reducing complexity and increasing
reliability
Modernization:
• Using PHP to web-enable green screen applications.
New application development:
• Create new applications with PHP
- Intranet, Extranet, Reporting, Websites, Wikis and ...
Leveraging PHP portfolio:
• Run commercial or open source PHP applications on i5/OS.
4. Cabel
Background
• Provide services for local banks
- Strategy, organisation, management and IT consulting
Requirement
• Urgent need to web-enable core green screen applications
• Allow customers to access information without forcing them to install
software.
• Reduce number of screens & modify application flow for ease of use
Solution:
• Zend Bridge +
- Customized the 5250 PHP demo page to front-end the application
• Provided connections to customers via web services
• Integrated web data content
Benefits
• Rapidly deployment of a web solution
• Leveraged green screen business logic and DB2/400 data
• Extended and enhanced functionality (documents, images, etc.)
• Integration with customers without affecting their systems
5. Ruger
Background
• Manufacturer of sporting and law enforcement firearms
• i not viewed as part of future plans
Requirement
• Launch an on-line auction site - yesterday!
- www.rugerauction.com
Solution
• Purchased and deployed a low-cost PHP-based package
• Four RPG developers with no PHP background customized and
deployed it in a month
Benefits
• Implemented on time and on budget
• Laid the foundation for integration of i into future plans
6. Parts Depot
Background
• One of the largest distributors and resellers of automotive aftermarket
parts and paints in the U.S.
Requirement
• Update business partner applications ranging from price quotations to
fulfillment to the reviewing of historical data.
Solution
• Three System i 520s support the business.
- Production, Development and HA
• Developed new web application with PHP integrating with backend
RPG applications
7. Cremer
Background
• Distribute and manufacture disposable health care products in Brazil
Requirement
• Improve customer sat with a streamlined call center application
- Inventory, prices, credit status, invoice details
• Reduce software costs
Solution
• Developed new PHP web-based call center application which
accesses DB2 on i5/OS V5R3
Benefits
• Reduction in software costs
• Rapid development – even though initially no in-house PHP skills
• Faster access to DB2 information
8. Icon Fitness
Background
• World's largest home fitness manufacturer
• Brands include NordicTrack, HealthRider, Reebok, and Pro-Form
Requirement
• Quickly develop fitness/nutrition web sites to meet January demand
peak
- www.ifit.com and www.iconfitness.com
Solution
• Developed new consumer web sites with PHP
• Ties into existing WebSphere Commerce Server
9. Updating with new free/low-cost tools
Customer Relationship Management
Help Desk
Portal
Portal Portal
Course Management System
e-Commerce
Wiki
Bulletin Board
Content Management System
11. MANTIS
Help Desk Software
• http://mantis400.com
Uses native DB2 under i5/OS
• Data usable from RPG, Query, COBOL, SQL...
Available under GNU GPL Open Source license
• I.e. It is FREE FOREVER
Create/manage Internal and External Support Issues
• Any web browser, any client operating system
• E-mail notification as Issues are progressed
Supported by Curbstone Corporation
• They have used it in-house to track problems for a number of years
12. Wikis - PMWiki
(:table width=800 align=center:)
(:table width=800 align=center:)
(:cell:)
(:cell:)
http://localhost:8888/pmwiki/images/Partner400Logo31.jpg
http://localhost:8888/pmwiki/images/Partner400Logo31.jpg
(:cellnr:)
(:cellnr:)
!!Welcomeato Partner400's Sample Documentation Web Site
QuickTime™ and to Partner400's Sample Documentation Web Site
!!Welcome
QuickTime™ and a
(:cellnr:) picture.
decompressor
(:cellnr:)
are needed decompressor
to see this
are needed to see this picture. - quot;Documentationquot;.
Yes the D-word - quot;Documentationquot;.
Yes the D-word
Here you will find links to a number of web pages that will link you to
Here you will find links to a number of web pages that will link you to
articles that we have written, sample programs, and a few other bits
articles that we have written, sample programs, and a few other bits
and pieces such as travel guides and information for conference
and pieces such as travel guides and information for conference
planners.
planners.
*Click here for [[Articles ||a list of articles that we have written]]
*Click here for [[Articles a list of articles that we have written]]
*Here for [[Samples ||Sample programs]]
*Here for [[Samples Sample programs]]
*And here [[Other ||for all the other stuff]]
*And here [[Other for all the other stuff]]
(:tableend:)
(:tableend:)
13. Extending your RPG application set
In areas where RPG native support is weak or non-existent
• e.g. XML, E-mail, Sockets, CGI
- All of these can be done via native support (XML)
- Or open source or third-party tool kits
- But can be complex to use
¨ And for some people the lack of formal support is an inhibitor
By providing new interfaces to native functions
• I5 Toolkit and DB2 support provide comprehensive access
• Integrate system functionality into:
- Web services
- New browser applications
14. Comparing XML Processing in RPG and PHP
At first glance both programs look very similar
• But all is not quite as it seems
/Free
/Free
XML-INTO company %XML( XML_Input1: 'doc=file case=any' );
XML-INTO company %XML( XML_Input1: 'doc=file case=any' );
for i = 1 to xmlElements;
for i = 1 to xmlElements;
dsply company(i);
dsply company(i);
endfor;
endfor;
<?php
<?php
$Customers = simplexml_load_file(quot;Partner400Customers.xmlquot;);
$Customers = simplexml_load_file(quot;Partner400Customers.xmlquot;);
foreach ($Customers->Customer as $customer) {
foreach ($Customers->Customer as $customer) {
print quot;$customer->Company<br>quot;;
print quot;$customer->Company<br>quot;;
} ?>
} ?>
15. The quot;Missingquot; Part of the Comparison
The previous chart left out this part of the RPG version
D progStatus SDS
D• xmlElements SDS
D RPG requires the data
progStatus to be20i 0 Overlay(progStatus: 372)
predefined
D xmlElements 20i 0 Overlay(progStatus: 372)
• PHP does for you dynamically 0
D i s 10i
D i s 10i 0
D customers DS Qualified
D customers DS Qualified
D recordCount 3p 0
D recordCount 3p 0
D customer LikeDS(customer) Dim(99)
D customer LikeDS(customer) Dim(99)
D customer DS Qualified
D customer DS Qualified
D type 10a
D type 10a
D company 32a
D company 32a
D address LikeDS(address)
D address LikeDS(address)
D address DS
D address DS
D street 32a
D street 32a
D city 24a
D city 24a
D state 2a
D state 2a
D zip 5s 0
D zip 5s 0
D XML_Input1 256a Inz('/Partner400/Customers.xml')
D XML_Input1 256a Inz('/Partner400/Customers.xml')
16. Easy Extensions - Web Services
This example uses two web services
• One to obtain the price of a stock in US$
• The other to obtain the current US$ -> Cdn$ exchange rate
All you need to know is the name of the method
• All the underlying work is done for you
<?php
<?php
$QuoteClient = new SoapClient(
$QuoteClient = new SoapClient(
quot;http://services.xmethods.net/soap/urn:xmethods-delayedquotes.wsdlquot;);
quot;http://services.xmethods.net/soap/urn:xmethods-delayedquotes.wsdlquot;);
$CurrencyClient = new SoapClient(
$CurrencyClient = new SoapClient(
quot;http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdlquot;);
quot;http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdlquot;);
$IBM_Price = $QuoteClient->getQuote(quot;ibmquot;);
$IBM_Price = $QuoteClient->getQuote(quot;ibmquot;);
$US_Cdn_Rate = $CurrencyClient->getRate(quot;usaquot;, quot;canadaquot;);
$US_Cdn_Rate = $CurrencyClient->getRate(quot;usaquot;, quot;canadaquot;);
print(quot;IBM stock price is $$IBM_Price - that is $quot;
print(quot;IBM stock price is $$IBM_Price - that is $quot;
. ($IBM_Price * $US_Cdn_Rate) . quot; in Cdn$quot;);
. ($IBM_Price * $US_Cdn_Rate) . quot; in Cdn$quot;);
?>
?>
17. Easy Extensions - Web Services
This example uses one of the Google web services
• The spelling suggestion
The Google related logic is all on this page
• The next page simply shows the input form
<?php
<?php
if (isset($_POST['submit'])) {
if (isset($_POST['submit'])) {
$input = $_POST['input'];
$input = $_POST['input'];
$signature = quot;oJ+6HjxQFHKudrUwGI99RrEjLmQ5jrv1quot;;
$signature = quot;oJ+6HjxQFHKudrUwGI99RrEjLmQ5jrv1quot;;
$google = new SoapClient(quot;GoogleSearch.wsdlquot;);
$google = new SoapClient(quot;GoogleSearch.wsdlquot;);
$response = $google->doSpellingSuggestion($signature, $input);
$response = $google->doSpellingSuggestion($signature, $input);
If (!$response) $response = quot;Google hasn't a clue what you mean!quot;;
If (!$response) $response = quot;Google hasn't a clue what you mean!quot;;
} else { // This is just a form request so set field defaults
} else { // This is just a form request so set field defaults
$input = '';
$input = '';
$response = '';
$response = '';
}
}
?>
?>
18. Easy Extensions - Google (contd)
It is possible to do this in RPG using Scott Klement's HTTPAPI
• Or one of the other libraries
But the amount of code required is substantially greater
<html>
<html>
<head>
<head>
Google Spelling API Test Page!
Google Spelling API Test Page!
<br><br>
<br><br>
Enter your test string and press Submit to see
Enter your test string and press Submit to see
what Google thinks of it<br><br>
what Google thinks of it<br><br>
<form action=quot;<?php echo $_SERVER['PHP_SELF'] ?>quot; method=quot;postquot;>
<form action=quot;<?php echo $_SERVER['PHP_SELF'] ?>quot; method=quot;postquot;>
Input String: <input type=quot;textquot; name=quot;inputquot; value=quot;<?php echo $input ?>quot; />
Input String: <input type=quot;textquot; name=quot;inputquot; value=quot;<?php echo $input ?>quot; />
<br>
<br>
<br><br>Google responds <b><?php echo $response;?></b>
<br><br>Google responds <b><?php echo $response;?></b>
<br><br>
<br><br>
<input type=quot;submitquot; name=quot;submitquot; value=quot;submitquot; />
<input type=quot;submitquot; name=quot;submitquot; value=quot;submitquot; />
</form>
</form>
</head>
</head>
19. Business Application Framework
ATK has an interesting approach to Frameworks
• It focuses on business applications www.atk-framework.com
There is now an i5 specific version (i.e. DB2 enabled)
• But the web site is only in Dutch at present (www.i7.nl)
Ivo Jansch is presenting on the topic on Thursday
• quot;PHP in the Enterprisequot;
21. i5/OS Extensions and Toolkit
Connection Management
Connect, change user, close….
DB2 UDB access via SQL and Record level I/O
Fetch as array, get field lengths, field type, ...
Create records, update, set ranges, ...
Command, Program and Procedure calls
Supports return values
Data Areas, Data Queues, Message Queues
Create, read, write, delete... Many examples
Many examples
System values available in the
available in the
manuals, forums, and
manuals, forums, and
Including date, time, …
other on-line sources
other on-line sources
Spool Queues and files
List, Read, ...
25. Using Native Record Level I/O
Dynamically accessing fields just cannot be done in RPG
// Get input data
// Get input data
$dbfile = $_POST['tbl'];
$dbfile = $_POST['tbl'];
$dblib = $_POST['lib'];
$dblib = $_POST['lib'];
if ($dbfile == '') $dbfile = quot;JONSDEMOSquot;;
if ($dbfile == '') $dbfile = quot;JONSDEMOSquot;;
if ($dblib == '') $dblib = quot;CUSTOMERSquot;;
if ($dblib == '') $dblib = quot;CUSTOMERSquot;;
$conn = i5_connect(quot;localhostquot;, quot;PARTNER400quot;, quot;PASSWORDquot;);
$conn = i5_connect(quot;localhostquot;, quot;PARTNER400quot;, quot;PASSWORDquot;);
// Open the file
// Open the file
$file = i5_open(quot;$dblib/$dbfilequot;, I5_OPEN_READ | I5_OPEN_SHRRD);
$file = i5_open(quot;$dblib/$dbfilequot;, I5_OPEN_READ | I5_OPEN_SHRRD);
if (!$file)
if (!$file)
die(quot;Error while attempting to open file mode=READ $i5_error()quot;);
die(quot;Error while attempting to open file mode=READ $i5_error()quot;);
// Print header row using field names
// Print header row using field names
$fields = i5_list_fields($file);// returns an array
$fields = i5_list_fields($file);// returns an array
print quot;<table border=1 cellpadding=3><tr bgcolor=#CCCCCC>quot;;
print quot;<table border=1 cellpadding=3><tr bgcolor=#CCCCCC>quot;;
// Parse the array
// Parse the array
foreach ($fields as $value)
foreach ($fields as $value)
{ print quot;<th>$value</th>quot;;
{ print quot;<th>$value</th>quot;;
}
}
26. Using Native Record Level I/O (cont.)
This works beautifully and doesn't annoy the SQL phobic!
// Print records
// Print records
$rec = i5_fetch_row($file, I5_READ_FIRST); // get array
$rec = i5_fetch_row($file, I5_READ_FIRST); // get array
while ($rec) // while there is a record...
while ($rec) // while there is a record...
{
{
?>
?>
<!-- Print each record -->
<!-- Print each record -->
<tr>
<tr>
<td><?php echo $rec[0]; ?></td>
<td><?php echo $rec[0]; ?></td>
<td><?php echo $rec[1]; ?></td>
<td><?php echo $rec[1]; ?></td>
<td><?php echo $rec[2]; ?></td>
<td><?php echo $rec[2]; ?></td>
<td><?php echo $rec[3]; ?></td>
<td><?php echo $rec[3]; ?></td>
<td><?php echo $rec[4]; ?></td>
<td><?php echo $rec[4]; ?></td>
<td><?php echo $rec[5]; ?></td>
<td><?php echo $rec[5]; ?></td>
</tr>
</tr>
<?php
<?php
$rec = i5_fetch_row($file, I5_READ_NEXT);
$rec = i5_fetch_row($file, I5_READ_NEXT);
} // loop
} // loop
print quot;</table>quot;;// finish off the table
print quot;</table>quot;;// finish off the table
?>
?>
27. i5 Function Sample - WRKSPLF
Originally released via the i5 Zend Core forum
• Find it by Googling with quot;php wrksplf site:zend.comquot;
Simple simulation of WRKSPLF built with i5 APIs
• Adds the ability to email or convert to PDF a spool file entry
The basic process it uses is:
• i5_connect( ) to connect
• i5_spool_list( ) to build list of spool files for the requested user
• i5_spool_list_read( ) to read the entries in the spool queue
• i5_spool_list_close( ) to close the spool link
• i5_close( ) to close the connection
If a spool file is selected for display:
• i5_spool_get_data( ) retrieves the spool records
29. Using RPG programs in new ways
The latest option - Zend 5250 Bridge
• A new approach for putting Green-screen applications to work in new ways
- For example as Web Services
- In a new quot;Web Facedquot; role
- Via Portals and Mash Ups
What is the quot;Bridgequot;
• How do you get it
• Technical Overview of components
The Bridge Demonstration Programs
• Green Screen Emulator
• Simple Web Interface
• AJAX style Web Interface
A brief example of the basic procedural APIs
• A different kind of 5250 Programming!
The Bridge is a Toolkit of possibilities
• Not a Silver Bullet quot;Solutionquot;
• Where might the future take us?
30. What is the quot;Bridgequot;
Three sets of APIs that allow a PHP script to drive a 5250 session
• Tow sets of APIs
- Object Oriented
- Procedural - these are the ones we will be focusing on
Multiple 5250 sessions can be connected to a single script
• So you could combine the data from several green screen
applications in a single browser window!
• You could also include data from another system's 5250 application
by using a Telnet connection
Bridge is available as part of Zend Platform
• Or as a quot;sandboxquot; single session version in a unlicensed version of
Platform (i.e. One for which the trial period has expired)
31. Product Advantages
Doesn't require WebSphere Application Server
• So CPW requirements are lower
No 5250 workload
• Use batch for green screen programs instead of interactive
Easy to install
• No application source required – works on display file objects
No charge for one connection
• Play in the sandbox until you can convince the boss to purchase
Modernize the application
• Using AJAX and other advanced web based technologies
Telnet enabled
• Can be used to telnet to other systems and blend results into a single
interface
32. Technical Overview
Supplied as a PHP library
• Contains a set of PHP functions/classes to access 5250 data
• Includes a number of demonstration programs
Allows you to run any 5250 applications under PHP control
• Utilizes IBM's WebFacing server
• Part of i5/OS TCP/IP
All screen data available ...
• Input and Output fields, positions and attributes
34. 5250 Bridge - quot;GreenScreenquot; Demo
quot;Green Screenquot;
quot;Green Screenquot;
demo now uses
demo now uses
hover help to show
hover help to show
number and type of
number and type of
field
field
inputField 0
This is the default appearance
35. 5250 Bridge - quot;GreenScreenquot; Demo
CUSTOMIZE
STYLE
.
But add a little style(sheet) ...
37. Subfile Demonstration Programs
Basic quot;vanillaquot;
Basic quot;vanillaquot;
version uses
version uses
procedural functions
procedural functions
quot;Fancyquot; version uses
quot;Fancyquot; version uses
Object interface
Object interface
38. Very Simple Bridge Demo Script (1)
<?php
set_include_path('/usr/local/Zend/5250/API/');
require_once('Zend/ProceduralApi.php');
// Open a connection to the Zend 5250 Bridge, for a job with id 'simple'
$bridge = zend_5250_open('simple');
$response = @zend_5250_connect($bridge); Can be used as a
Can be used as a
standard quot;What's on the
standard quot;What's on the
$inpfields = zend_5250_get_input_fields($response); screen?quot; routine to be
screen?quot; routine to be
plugged in where needed
plugged in where needed
$outfields = zend_5250_get_output_fields($response);
during development
during development
print quot;<table width='800'><th>id<th>row<th>column<th>length
<th>value<th>color<th>type<th>font<th>formatquot;;
foreach ($inpfields as $field) {
print quot;<tr align='center'><td>$field[id]</td><td>$field[row]</td>
<td>$field[column]</td><td>$field[length]</td>
<td>$field[value]</td><td>$field[color]</td>
<td>$field[type]</td><td>$field[font]</td>
<td>$field[format]</td></tr>quot;;
}
39. Very Simple Bridge Demo Script (2)
print '<tr><td align=quot;centerquot; colspan=quot;9quot;><h3>Output Fields</h3></td></tr>';
foreach ($outfields as $field) {
print quot;<tr align='center'><td>$field[id]</td><td>$field[row]</td>
<td>$field[column]</td><td>$field[length]</td>
<td>$field[value]</td><td>$field[color]</td>
<td colspan='3'> </td></tr>quot;;
}
print quot;</table>quot;;
print quot;nn<h3>Var_Dump of $inpfields</h3>nnquot;;
var_dump($inpfields);
print quot;nn<h3>Var_Dump of $outfields</h3>nnquot;;
var_dump($outfields);
zend_5250_disconnect($bridge);
?>
40. Display from Simple Bridge Demo
Each field on the screen is returned as an array element:
• Each element is in turn an array containing:
- Field id, Position (Row and Column), Length, Value, Color, type, etc.
41. Extract From Zend's Basic Subfile Demo
<?php
$status = zend_5250_get_output_field_value($response, 15);
if ($status == 1) {
echo quot;User is active<br />nquot;;
} elseif ($status == 2) {
echo quot;User is inactive<br />nquot;; }
?>
Serial number: <?php echo zend_5250_get_output_field_value($response, 11); ?>
<br />
Application name: <?php echo zend_5250_get_output_field_value($response, 13); ?>
<br /><br />
Number of sign on: <?php echo zend_5250_get_output_field_value($response, 20); ?>
<br />
<?php
$lang = zend_5250_get_output_field_value($response, 27);
if ($lang == 'E') {
$lang = 'English'; Convert single
Convert single
elseif ($lang == 'F') {
character response to
character response to
$lang = 'Francais';
} else {
full text
full text
$lang = 'Unknown'; }
echo quot;Preffered language: $lang<br />nquot;;
?>
42. Early Lessons Learned
Input and Output seem backwards
• quot;Inputquot; is the data you send to the 5250 application
- What you receive as input from the browser you will send on as input to
the 5250 application
• quot;Outputquot; is what you receive from the 5250 application
- You may or may not pass it on as-is to the browser user
Remember that the 5250 application won't directly see the input
• Your script must pass it on
You need to be able to identify screen layouts in some way
• Or you won't have a clue which screen is quot;talkingquot; to you
• The data from the bridge API does not include any format information
- You get the whole screen content - regardless of which format originated it
43. Early Lessons Learned (contd.)
Additional tools to determine field Id numbers are needed
• Latest modification to Zend's 5250 demo screen is helpful
• I am looking at the possibility of using a DSPFFD Outfile
- Build a database associated with each screen that uses row/column
coordinates to associates field names and the sequence identifier
¨ Subfiles and overlapping fields are a nuisance
- Result could be queried to map data to field name in script
- Using Outfile because corresponding API is really ugly
• Until there are more tools var_dump( ) and print_r( ) are your friends
Large scale projects are not for the faint hearted
• If we learnt nothing else from the early days of WebFacing ...
Remember that you will have to adapt to buffer layout changes
• But level checks should protect you from harm!
44. Procedural Bridge Functions (1)
zend_5250_open()
• Starts a session for the provided job id
zend_5250_connect()
• Creates a connection to the 5250 bridge using user name, password etc.
zend_5250_is_connected()
• Returns true if bridge is already connected
zend_5250_set_input_field()
• Sets data into an input field
- I.e It does the keyboard entry!
zend_5250_submit()
• Sends request to the 5250 bridge with a key (Enter, F keys, page up, etc.)
• Call after all input field values have been set
45. Procedural Bridge Functions (2)
zend_5250_disconnect()
• Disconnects the 5250 bridge
zend_5250_set_focused_field()
• Sets the focus of the page to a specific field
zend_5250_get_focused_field()
• Returns the field currently in focus
zend_5250_get_input_fields()
and zend_5250_get_output_fields()
• Returns all input or output fields available
zend_5250_get_input_field()
and zend_5250_get_output_field()
• Returns a specific input or output field by ID
46. Procedural Bridge Functions (3)
zend_5250_get_input_fields_count()
and zend_5250_get_output_fields_count()
• Returns the count of input or output fields available
zend_5250_get_application_error()
• Returns information about an application error if one has occurred
zend_5250_get_error()
• Returns a function error if it occurred
zend_5250_get_screen_size()
• Returns the size of the screen (width x height)
zend_5250_get_color_palette()
• Returns an array containing the i5 5250 Bridge color palette
47. Where Might The Future Take Us?
Think of Bridge is a quot;Toolkit of Possibilitiesquot;
• You could experiment with a web front end to an existing application
• Combine multiple applications into a single view
- Or subset the functionality of an application as in the subfile demo
• Use a portion of a 5250 application as a web service
• Build a different kind of 5250 application
- One that was never intended to drive a green screen!
- It certainly simplifies session persistence issues
What about tool builders?
• Zend and other parties may use the toolkit as a foundation for new
web enablement tools
- Perhaps an Open-Source project?
• Perhaps a starting point for a new web enabled RPG
48. Questions - Thoughts - Lunch ?
There will be tables at lunch for quot;iquot; folks to
meet and greet each other and the quot;iquot; Zend
team members
?