Forget about the old Zend Toolkit! Let's start using the new one.
In my last column, I outlined how to call PHP and RPG programs from each other. I used as the basis for this the old i5 Toolkit from Easycom that was part of the Zend product prior to release 5.6, because I figured a lot of people still have that. But I sort of promised that next time I would do the same thing using the new, true Zend Toolkit. Well, it's next time.
The big difference is that while the old toolkit was procedural and pretty understandable, the new Zend Toolkit is object-oriented, so it may not be quite as understandable to most of us at first glance, but I think you will see that it all makes sense eventually. I will just say that the first time you really look at OO code it can be a shock, and the most common thing that happens is people shut down and go on to something else, but I ask you not to do that. Once you get over the initial shock, I think you will be able to learn some really useful things and start your journey to the OO side. To minimize the shock, I will take the PHP code to use the new Zend Toolkit one statement at a time.
If you want more information on this topic (PHP and the i and the new toolkit) you should visit www.alanseiden.com. Alan is an acknowledged expert (at least IBM thinks he is) in these areas and his Web site features some very good articles and references. He also appears to be one of the least annoying people I have ever not met but communicated with.
Grabbing the Toolkit
OK, let's get started. To call an RPG program from a PHP script using the new Zend OO Toolkit, the first thing you have to do is bring in the Toolkit. There are two ways in PHP to do a /Copy—that is, to bring in a section of code and include it in the script. In the PHP world, we generally don't use the word "source" the same way we do with RPG, because with PHP everything is "source; there is no object since it is not compiled. But often you want to include some extra code without having to actually key it in, just as you do in RPG with a /Copy.
To do this, you can use either the include or the require commands. And for each of these, you have either the straight command or the _once option. What's the difference? Thank you very much for asking.
If you try to include code that cannot be found when the script is executed, the include will issue a warning. Consequently, you use the include for stuff that is no big deal if the code can't be found and it doesn't run. Require on the other hand comes right back with a fatal error if the code can't be found and so is used if you absolutely, positively have to have the module run for things to be OK. You know: it's good cop, bad cop.
In addition, as I said, each of these commands comes in two flavors; straight up (include and require) and the "once" version of each (include_once and require_once). The "once" option will load the code only once, even if you specify the command multiple times. This does become important at times, even if just from a performance point of view. What kinds of things would you include (or require)? In our case, it will be code that performs specialized functions, but it could also be class or function definitions. As you may know, OO is very modular, much more so than RPG tends to be (although that's our fault, not theirs), so the ability to pull code or classes or whatnot into a script is very important.
An important thing to note is that when you do the include or require, the code that they pull in will pick up (inherit) any variables that are in the scope at that point. We haven't talked about "inheritance" within OO, but I think you get the basic idea.
So, to summarize, our starting point will be to pull in the toolkit script, using the require_once option because it is important that this code be found, and it would be silly to bring it in multiple times when one will do.
Note the facts that the name of the script, including its extension, is in single quotes and that the whole command ends with a semicolon, which is standard PHP syntax.
And, if you're a real stickler, you know that the above is not a complete path. The rest of the link to ToolkitService.php is actually contained in the include_path setting in the php.ini file (which is a control file in every PHP installation to help you customize how your installation will work).
Define $conn Variable
OK, how is everybody feeling? Everyone still got their paper bag? Anyone's bag full? Great. Just remember, head between the knees.
The next thing we'll do is define a variable. Now the one thing you want to get drilled into that thick skull of yours (no offense intended) is that every time you see a character string prefixed by a $, you know it's a variable. You may be tempted to think it's some sort of function or other thing that does something, but it's only a variable, so there's no sense getting scared.
In the RPG world, we tend to think of variables as carrying data: either some form of numeric or else character. But in PHP, variables can carry a lot more than just data. In this case, we'll set the variable equal to an object that is accessed using a function from the toolkit.
What's important to remember is that while in RPG a variable contains data (either some form of numeric or else character), in PHP we have a lot more flexibility (or power) in terms of what a variable can contain. In this case, we'll be defining a variable that will contain an object. In particular, it will carry an object that we pick up from the toolkit.
To make this easier, I'm going to list the code statements first, and explain each second.
$conn = ToolkitService::getInstance('*LOCAL', 'MYUSER', 'MYPASS');?
Yeah, I know. For a procedural programmer, it looks pretty weird. But you are not just an RPG programmer. You are a code warrior. Attaaaaccccckkkkkk!!!!!!!
For starters, $conn is the variable name. No particular reason for this name, but that's what I chose. You could just as easily have used $whatever or $dave.
The next thing is the class name that we're going to play with: ToolkitService. A class is a collection of objects. You might look at the class sort of the way we do a file, with the objects being the records in the file. You shouldn't do that, because it's a ridiculous simplification, but if you have to do that, whatever.
In most cases, when you define a class, it's defined as "non-static." That is, there can be multiple instances (read: occurrences) of this class in your script, and each one can have different values. That's the way most classes are defined. In this case, however, the ToolkitService class was defined (by Zend when they built the class) as "static." This means a couple of things. First, it means that if there are two instances (occurrences) of this class in a script, they will both have the same values. Second, it means that if you change the value in one instance, the value in the other instance will also be changed. In essence, there can't really be multiple instances.
The cool kids call this type of class an example of the Singleton Design Pattern. That's another thing that's nice about OO and pretty much missing from procedural languages. There are various types of design patterns, and their use helps standardized scripts across different programmers. The Singleton Design Pattern is a bit controversial, and some people don't like it at all, but much of it is a matter of taste. And that's all I'm going to say about it.
OK. At this point, we're defining a variable, $conn, as the object from static class ToolkitService using the getinstance() method (function) to bring in the three values we need.
You might be wondering about the double colon. That's one thing about PHP that can be (is) confusing: the number of oddball operators that they use. In some cases, choosing the right operator is crucial to getting something to work. In other cases (like with the :: ), it's partially a matter of good form.
Technically, the double colon indicates that you're accessing static functions or variables (in our case, we're accessing variables) in a class (that would be the ToolkitService class).
The -> symbol is what you use to refer to a specific instance within a non-static class. You can also use it to access the static variables, but the other PHP kids will make fun of you and beat you up after school, so I wouldn't.
There, see how simple that was? Now on to the second statement.
We recognize the $conn variable. And we know that the -> means I am going to be working with a variable, this time one that's part of the ToolkitServiceParams class. And a little imagination tells us that we're going to be picking up the "stateless" parm in an array in this class and setting it to "true." The stateless parm is something that I'm not going to go into right now, but it basically determines whether this function occurs within this job or whether a second one is set up. If you don't want to go stateless, then you need to set an internal key value as below.
You know what you should be wondering about right now? I said above that the double colon (::) is what you should use when you're dealing with a static class like ToolkitService. But in the second statement, we're using the ->, which I have already said is legal but a good way to get beaten up. And the difference is that in the first statement we're talking about the class and so use :: to show that class is static. But when we're talking about a property of a static class, then it's already static by definition and we can use the -> to refer to it. Small point but it helps it make sense.
Merciful heavens. I'm exhausted. Are we done? Dude, we've covered three statements! No, we're not done, but we've also covered some important things in PHP and OO. Look forward to the next exciting episode, where we finish looking at how to call an RPG program from a PHP script using the new Toolkit.
And try not to look so gloomy. In total, there are probably fewer code lines in this approach than in the one for the old toolkit. It's just that we need more explanation because it looks so freaky weird. Here's what we have so far.
$conn = ToolkitService::getInstance('*LOCAL', 'MYUSER', 'MYPASS');
Does it look a little more familiar now? Hope so. For the rest, see you next column.