Now, let's look at defining parms and calling programs.
With the excitement of the holidays over, it's now time to continue with our review of how to call an RPG program from within a PHP script. We had started this two columns ago by looking at how to do this using the old Aura/Easycom toolkit that had been incorporated into Zend Server prior to release 5.6. That toolkit was procedural in nature, so it was pretty intuitive to look at. My last column got us into the new, true Zend toolkit, which is object-oriented and so may look a bit strange to many of us.
What We've Covered So Far
In that last exciting episode, we got our hands wet with the first part of the code that's required in a PHP script to access an RPG program. And, if you have remembered anything through the holiday season, you know that this first portion consisted of two basic tasks.
- First, bringing the toolkit code into your script via the require_once operator so that the necessary classes and such are available to you
- Second, setting up a variable, in this case one that we called $conn, that would contain an instance of the ToolkitService class and specifically the ToolkitServiceParams variable
require_once 'ToolkitService.php';
$conn = ToolkitService::getInstance('*LOCAL', 'MYUSER', 'MYPASS');
$conn->setToolkitServiceParams(array('stateless'=>true));
If I thought the above looked too weird, I would be tempted to go back and re-read the previous installment. 'Course, I would also be tempted to keep going in the hope that somehow it would all suddenly make sense, so I guess it's up to you. So much of "understanding" something is just recognizing familiar patterns. That is, when a procedural programmer sees Total$ = Total$ + Order$, they know that this is really an evaluate statement where we're adding the value of this particular order to a field that is going to carry the value of all orders being looked at, and it seems patently obvious. Same thing is true of the junk above. It all makes sense if you understand it.
The question is, what comes next? And the answer is…
Defining the Parms to Be Passed to the RPG Program
We'll start by setting two variables, one to '1' and the other to blanks. Note that there's no indication how long these are or what type they are. This is an implicit definition: indeterminate length, data type alphanumeric. PHP does allow us to be more specific using the casting feature, but we don't need to in this case, so why bother? We'll see in a moment that these are the parameters that will be passed to the RPG program.
$code = '1';
$desc = '';
The next two statements look kind of weird, but they're also defining parameters that will go with the call to the RPG program. Why are there two of them? Because we're using a call in this example script that passes two parms to the RPG program. The first thing you notice is that the parm is not $parm, which would refer to a single parameter value, but rather $parm[], which is an array. Each of these statements then sets a parameter in the array $parm[].
And the $conn->? This means, as it did in part 1 of this article, that we want to get an instance of ToolkitService, specifically the AddParameterChar, so that we can use that in the statement.
Finally, the AddParameterChar is a method (an object-oriented function) within ToolkitService that defines a parameter. It (the method) has five parameters associated with it (input/output direction, parm size, a spot for a developer comment, the parm name, and the parm value). In our case, we're going to be passing two parms in the $parm[] array to the RPG program: a 10-digit 'code' field whose value will be in the $code variable we defined above, and a 10-digit 'description' field where the value comes from the $desc variable. And, since the direction value for both is 'both', this parm is not only passed, but passed back to the script.
$param[] = $conn->AddParameterChar('both', 10, 'CODE', 'CODE', $code);
$param[] = $conn->AddParameterChar('both', 10, 'DESC', 'DESC', $desc);
See how everything is really coming together here? Man, we're rollin' now, baby.
Calling the RPG Program
In the next step, we finally get around to calling the RPG program that we need. And we do this similar to the way we call a program in ILE using the EVAL command rather than the CALLP. That is, we set a variable, in this case $result, and use the $conn-> to access the method PgmCall. We pass four parameters to the PgmCall method: the program name of what we are calling, the library in the i where this is being kept, the parms that are being sent, the program return value (set to null in our case), and the service program name (if we're dealing with a service program, which in this case we aren't).
$result = $conn->PgmCall("COMMONPGM", "ZENDSVR", $param, null, null);
Evaluating the Result of the Call
It would be nice if that was all there was to it, but once the program has been called, then eventually it will be done and control will return to the PHP script, and we want to know two things. First, did the call work? That is, did we find the RPG program we were calling and did it kick off? And second, what was the output of that program? Since we'll tend to use the RPG programs to edit and access data, it's only logical that data should be returned from it.
f($result) {
$outputParams = $result['io_param'];
echo "Code: {$outputParams['CODE']}. Desc: {$outputParams['DESC']} ";
} else { echo "Error calling COMMONPGM.";}
This code is fairly common for checking the results of a call, and a similar format would be used whether you had called an RPG program using the toolkit or had just issued a more standard call to SQL to retrieve some data. Basically, we're doing an if/else statement where if something is returned in the $result variable, we perform the top half of the if statement, and if nothing was returned, we know the call failed and we execute the stuff after the else.
What makes it confusing is the braces ({}), which are used to enclose the if and the else parts of the statement. Within the braces, you can have multiple PHP statements, each one delimited by the semi-colon. Remember that every time you see a semicolon you have come to the end of a PHP statement. In this case, if you receive results from your call, they're moved to the variable $outputParams and a message (the echo command) is displayed on your page. If things don't go so well, then an error message is displayed on the page.
What's important is not what's specified in this example. If things go well, you may not want to display a message; you might just want to set the returned parms so they show up on the page and call it good. It's up to you.
What Does It All Mean?
As you can see, there are a number of things to consider.
First, it's my hope that, after looking at the object-oriented code in these two articles, you have come away with a small bit of understanding but mostly a feeling that "OO ain't so bad." It really isn't bad, just different. And you might as well start getting used to it because it definitely will ratchet your skills up to the next level.
Second, whether you have to use the new OO toolkit or the old procedural one depends on what version of the Zend Server you're on. If you're prior to 5.6 (or have upgraded to 5.6 from a prior release), then you have the old toolkit. If you came in on Zend Server 5.6 or above, then you have the OO one.
And third, and maybe most importantly, whether you have to use it at all depends on how you're going to structure your applications. Remember, PHP is not a substitute for RPG. You will be using them both, and the question then becomes which one will be the control language. That is, in order to interweave the two together, you'll need to use some sort of modular programming approach rather than just a big ol' RPG program (BORP), probably something like the MVC model. The question then becomes which language you'll use for the controller part. Will PHP be your main language, from which you call RPG programs that will retrieve, maul, and edit data before sending it to PHP, or will you use RPG to control what is going on and call PHP only when it's time to build a page? With the former, you'll need to use the toolkit; with the latter, you can simply call your PHP scripts from RPG using QShell and the PHP Command Line Interface technique.
The bad part is it forces you to make some decisions before you start your design. The good part is there's a lot of alternatives to choose from. Or maybe it's vice versa.
LATEST COMMENTS
MC Press Online