Calling procedures and service programs with the PHP Toolkit for IBM i
Calling procedures in RPG service programs, including getting the return value, is a powerful feature of the PHP Toolkit. The sample script below demonstrates how it’s done.
Note: Make sure your procedure name is 100% correct. It is case-sensitive. If you get an error, run the following command (replacing LIBNAME/PGMNAME with your library and program names) and look for your procedure name in the output. The command:
DSPSRVPGM SRVPGM(LIBNAME/PGMNAME) DETAIL(*PROCEXP)
The example below includes ‘boilerplate’ code to show best practices for connecting to the toolkit and checking for a successful connection. The illustration of how to call a procedure is in the second half.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
<?php require_once('ToolkitService.php'); // connect to toolkit using DB2 credentials (can also leave blank for default authority) try { $conn = ToolkitService::getInstance('*LOCAL', 'MYUSER', 'MYPASS'); } catch (Exception $e) { // Determine reason for failure. // Probably database authentication error or invalid or unreachable database. $code = $e->getCode(); $msg = $e->getMessage(); switch ($code) { case 8001: // "Authorization failure on distributed database connection attempt" // Usually means a wrong DB2 user or password echo 'Could not connect due to wrong user or password.'; break; case 42705: echo 'Database not found. Try WRKRDBDIRE to check.'; break; default: echo 'Could not connect. Error: ' . $code . ' ' . $msg; break; } //(switch) die; // couldn't connect...handle this however you wish } //(try/catch) // set stateless mode for easy testing (no 'InternalKey' needed). // (setOptions() introduced in v1.4.0) $conn->setOptions(array('stateless'=>true)); /* If you wish to test this script but you don't have a real service program, * use parseOnly and parseDebugLevel as shown below. * No program will be called and you'll get your original values back. * Simply uncomment the next line to try this great testing feature of the toolkit. */ //$conn->setOptions(array('parseOnly'=>true, 'parseDebugLevel'=>1)); // define several input/output params $params = []; // start with empty array $params[] = $conn->AddParameterChar('in', 1,'Division', 'DIV', 'A'); $params[] = $conn->AddParameterChar('in', 6,'Product', 'PROD', '123456'); $params[] = $conn->AddParameterPackDec('both', 7, 2, 'Quantity', 'QTY', '4.53'); $params[] = $conn->AddParameterZoned('out', 5, 2, 'Price', 'PRICE', '0'); // define a procedure return param. Can be any type, even a data structure $retParam = $conn->AddParameterInt32('out', '4-byte int', 'MYRESULT', '13579'); /* Call service program procedure. * In this example, assume your program is MYLIB/MYPGM and has a procedure/function 'myproc' * (procedure name is case-sensitive). * Note: specify optional procedure name in parameter 5, an array with associative index 'func'. */ $result = $conn->PgmCall('MYPGM', 'MYLIB', $params, $retParam, array('func'=>'myproc')); if (!$result) { echo 'Error calling program. Code: ' . $conn->getErrorCode() . ' Msg: ' . $conn->getErrorMsg(); } echo 'Called program successfully.<BR><BR>'; echo 'Input/output params: QTY: ' . $result['io_param']['QTY'] . ' PRICE: ' . $result['io_param']['PRICE'] . '<BR>'; echo 'Procedure return param MYRESULT: ' . $result['retvals']['MYRESULT']; /* The above will output something like: Called program successfully. Input/output params: QTY: 4.53 PRICE: 0.00 Procedure return param MYRESULT: 13579 */ |
For more information on the toolkit, see our toolkit information page or get in touch.
your php concept is really nice and innovative thanks for sharing those information’s
Hello,
I just started to use ToolKit to retrieve data from iSeries.
Ii is easy to use, I call RPG program or CL Command and retrieve parameters correctly.
Only one problem.
When instance connection, I pass username and password, but when i try to call program, the call is execute sa QUSER and not with the correctly username of connection.
Why ?
Thanks for your answer.
Antonio, in your RPG program you need to look at the “current user” field, not “user.” See the incoming data structure for “current user.”
Thank you for your answer.
I undestand that “CURUSER” is the right field to use, but at work i have an ERP Software that work already in company and we have many programs that use USER for check the users.
If I try to use an connection stateless = false, the field USER passed correclty but ISERIES display me all time the message CPF1240, the job XTOOLKIT ended abnormally.
The first calling end fine, from the second error appears.
Don’t use “disconnect.”
Hello, thnks, its a great code, so i have a situation, my pgm its on zendsvr lib, but my database its on another library, so i recieve the code RNX1216, how i can use something like I5_OPTIONS_INITLIBL=>”OTHERLIB” on i5_connect
Willian,
You need to set a library list. There are several ways, but the easiest is to connect with a user profile that has an initial library list in its job description.
Alan
Thnx a lot! thats work!
Hello, thnks, its a great code, so i have a situation, my pgm its on zendsvr lib, but my database its on another library, so i recieve the code RNX1216
Hello, thnks, its a great code, so i have a situation, my pgm its on zendsvr lib, but my database its on another library, so i recieve the code RNX1216, how i can use something like I5_OPTIONS_INITLIBL=>”OTHERLIB” on ToolkitService like on i5_connect
Nice, Alan! Love the new toolkit features, as usual!