Category Archives: IBM i Control Language (CL)

Running a cronjob (automated job) on the IBM i to call PHP

The IBM i is different from Linux environments on how you create a reoccurring batch job. You’ll create a Command Line (CL) Program that calls the PHP script and add that Program to the IBMi’s Job Scheduler. The PHP script will be called via the PHP-CLI which is the command line interpreter that doesn’t use the Apache Web Server. Parameters are passed to the script via the command line and populated in the variables: $argv,$argc.

Steps to create a reoccurring scheduled batch PHP job

1) Create the PHP script,
MyPHPScript.php

<?php
//This example script we'll write to a file so that we can look at it later and
//see if our script got called
$file = '/mydir/test.txt';
$content = file_get_contents($file);
$today = date('F j, Y, g:i a');

$content .= 'The PHP Script was ran on $today n';
file_put_contents($file, $current);
?>

2) Create a CL program that calls the PHP script using PHP-CLI in the PASE (QP2SHELL). Run STRPDM, choose 3 – work with members, choose File: QCLSRC, 3 – copy an existing CLLE/CLP program, 2 – edit the new CL member that you created and put the following in the CL:
MYLIB/MYCLPGM

CALL PGM(QP2SHELL) PARM('/usr/local/zendsvr/bin/php-cli' +
 'batchphp/MyPHPScript.php' +
 'ParameterValue1')

3) Add CL program to job scheduler (ADDJOBSCDE)

ADDJOBSCDE JOB(BATCHNAME) SCDDATE(*NONE) CMD(CALL PGM(MYLIB/MYCLPGM))
SCDDAY(*MON) SCDTIME(‘22:00’) FRQ(*WEEKLY) RCYACN(*NOSBM)
JOBD(MYLIB/MYCLJOBD)

PHP-CLI path: /usr/local/zendsvr/bin/php-cli

4) (Optional) – If the user you’re using doesn’t have permissions to PHP-CLI you’ll also have to run these commands to give them permissions

CHGAUT OBJ('/usr/local/zendsvr/') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)
CHGAUT OBJ('/usr/local/zendsvr/bin/') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)
CHGAUT OBJ('/usr/local/zendsvr/bin/php-cli') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)
CHGAUT OBJ('/usr/local/zendsvr/etc/') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)
CHGAUT OBJ('/usr/local/zendsvr/etc/zce.rc') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)
CHGAUT OBJ('/usr/local/zendsvr/etc/conf.d/') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)
CHGAUT OBJ('/usr/local/zendsvr/etc/conf.d/ibm_db2.ini') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)
CHGAUT OBJ('/usr/local/zendsvr/share/') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)
CHGAUT OBJ('/usr/local/zendsvr/share/ToolkitAPI/') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)
CHGAUT OBJ('/usr/local/zendsvr/share/ToolkitAPI/CW/') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)
CHGAUT OBJ('/usr/local/zendsvr/share/ToolkitAPI/CW/cw.php') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)
CHGAUT OBJ('/usr/local/zendsvr/lib/') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)
CHGAUT OBJ('/usr/local/zendsvr/lib/php_extensions/') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)
CHGAUT OBJ('/usr/local/zendsvr/lib/php_extensions/ibm_db2.so') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)
CHGAUT OBJ('/pathtoyourphp/MyPHPScript.php') USER(YOURUSERNAME) DTAAUT(*RX) OBJAUT(*NONE)

If you need to debug your PHP-CLI config you can do the following:
CALL QP2TERM
In QP2TERM run this command
/usr/local/zendsvr/bin/php-cli -i > phpinfo.html
This will give you the “PHPinfo()” of PHP-CLI which could be different from what your web PHPinfo shows since QTMHHTTP is probably not running this script.

To get a deeper understanding check out Alan Seiden’s slides

Debugging CL: Use this command if you want to check out the variables in your cl as it runs. F5 to step through, F22 to see hex value of the variable your cursor is on. STRISDB PGM(MYCL) UPDPROD(YES) INVPGM(NO)

Note: If you’re getting garbage passed into your CL program look into Parameter Passing. You’ll have to use *TCAT and a null variable to null terminate your strings. Here’s my example of how to null terminate the strings passed to PASE.

PHP-CLI wrapper with null terminated command and file parameter

PGM PARM(&amp;FILENAME)
/* VARS */
DCL VAR(&amp;FILENAME) TYPE(*CHAR) LEN(80)
DCL VAR(&amp;PHPCLIPATH) TYPE(*CHAR) LEN(128)
/* &amp;NULL is longer than variables above to ensure it removes all spaces X'40'*/
DCL VAR(&amp;NULL) TYPE(*CHAR) LEN(208) VALUE(X'00') /*TERMINATE VAR WITH NULL */
/* SET VARS */
/* DATA AREA USED FOR PHP-CLI PATH in case it changes*/
/* PHP-CLI = /usr/local/zendsvr/bin/php-cli*/
RTVDTAARA DTAARA(MYLIB/PHPCLIPATH) RTNVAR(&amp;PHPCLIPATH)
CHGVAR VAR(&amp;PHPCLIPATH) VALUE(&amp;PHPCLIPATH *TCAT &amp;NULL)
CHGVAR VAR(&amp;FILENAME) VALUE(&amp;FILENAME *TCAT &amp;NULL)
/* RUN */
CALL QP2SHELL PARM(&amp;PHPCLIPATH &amp;FILENAME)
ENDPGM