XMLSERVICE/Toolkit *LIBL

Goto Main Page

change XMLSERVICE 1.7.3+

The default setting for SBMJOB of all XMLSERVICE jobs was changed to INLLIBL(*CURRENT) better follow the user profile of QSQSRVR job. If you are having difficulty with private connections libl you may want to try this version.

setting *LIBL - what do i do?

Few other topics dealing with web programs cause more frustrations then setting IBM i library list (*LIBL), but if you follow a few rules it all works.

*LIBL conflict between web scripts and IBM i PGMs

Any good conflict needs a basic difference in philosophy causing all the trouble.

  • ‘’’Stateless’’’ - web scripts typically wish to run stateless (PHP), with no environmental settings (such as *LIBL) set on the server
  • ‘’’State Full’’’ - IBM PGMs generally run state full (RPG/Cobol/CLP), meaning need *LIBL to run at all

Rule of toolkit web *LIBL …

The following rules apply to all toolkit DB2 connections persistent (db2_pconnect, odbc_pconnect) and non-persistent (db2_connect, odbc_connect).

  • ‘’’Stateless’’’ - PHP scripts using Toolkit without internalKey (IPC) MUST set *LIBL on every request before calling PGMs (see specific examples)
  • ‘’’State Full’’’ - PHP scripts using Toolkit with internalKey (IPC) set *LIBL only once for life of job before calling PGMs (see specific examples)

1) Specific examples for New PHP Toolkit

  • ‘’’Stateless’’’ - set *LIBL every single request
// *** stateless occurs when no internalKey (e.g. '/tmp/packers') was specified ***
// *** also when ->setToolkitServiceParams('stateless'=>true)) is called
try { $ToolkitServiceObj = ToolkitService::getInstance($database, $user, $password); }
catch (Exception $e) { die($e->getMessage()); }
$ToolkitServiceObj->setToolkitServiceParams(array(
'plug'=>"iPLUG32K"));         // max size data i/o (iPLUG4K,32K,65K.512K,1M,5M,10M,15M)

// stateless - MUST do this every single script after connect/getInstance()
//             even if using persistent connections (db2_pconnect, odbc_pconnect)
$ToolkitServiceObj->CLCommand("CHGLIBL LIBL(FREDFLIN WILMAFLIN) CURLIB(FREDFLIN)");

// another option might be to call a setup program that sets *LIBL for you.
  • ‘’’State Full’’’ - set *LIBL once and forget it
$internalKey = '/tmp/packers';
try { $ToolkitServiceObj = ToolkitService::getInstance($database, $user, $password); }
catch (Exception $e) { die($e->getMessage()); }
$ToolkitServiceObj->setToolkitServiceParams(array(
'InternalKey'=>$internalKey,  // *** RIGHT HERE internalKey/IPC
                            // *** run state full ...
                            //     use SBMJOB command run in new job
                            //     PHP can call again, again, again
                            //     with /tmp/packers and get ...
                            //     same job every time
                            //     same library list (*LIBL)
                            //     same PGMs with open files, etc.
                            //     ... exactly like 5250 sign-on screen
'plug'=>"iPLUG32K"));         // max size data i/o (iPLUG4K,32K,65K.512K,1M,5M,10M,15M)


// state full - MUST do this ONCE ONLY after start/sbmjob of XMLSERVICE job
//              then forget about it (unless you choose to change libl) ...
$ToolkitServiceObj->CLCommand("CHGLIBL LIBL(FREDFLIN WILMAFLIN) CURLIB(FREDFLIN)");
  • ‘’’persistent connections’’’ - later releases PHP Toolkit allow reused/shared connections with other work, including persistent connections, but internalKey (IPC) rules remain the same
if ($i5persistentconnect) $conn = db2_pconnect($database,$user,$password);
else $conn = db2_connect($database,$user,$password);

try { $ToolkitServiceObj = ToolkitService::getInstance($conn); }
catch (Exception $e) { die($e->getMessage()); }

$internalKey = '/tmp/packers';
$ToolkitServiceObj->setToolkitServiceParams(array(
'InternalKey'=>$internalKey,  // *** RIGHT HERE internalKey/IPC
                            // *** run state full ...
                            //     use SBMJOB command run in new job
                            //     PHP can call again, again, again
                            //     with /tmp/packers and get ...
                            //     same job every time
                            //     same library list (*LIBL)
                            //     same PGMs with open files, etc.
                            //     ... exactly like 5250 sign-on screen
'plug'=>"iPLUG32K"));         // max size data i/o (iPLUG4K,32K,65K.512K,1M,5M,10M,15M)
  • ‘’’plug size’’’ - later releases PHP Toolkit 1.2.4+ calculates the correct plug name via ‘plugSize’, taking db type (ODBC or DB2) into account.
if ($userPickFast) $conn = db2_pconnect($database,$user,$password);
else $conn = odbc_pconnect($database,$user,$password);

try { $ToolkitServiceObj = ToolkitService::getInstance($conn); }
catch (Exception $e) { die($e->getMessage()); }

$internalKey = '/tmp/packers';
$ToolkitServiceObj->setToolkitServiceParams(array(
'InternalKey'=>$internalKey,  // *** RIGHT HERE internalKey/IPC
                            // *** run state full ...
'plugSize'=>"32K"));          // max size data i/o (iPLUG4K,32K,65K.512K,1M,5M,10M,15M)

2) Specific examples for XMLSERVICE

  • ‘’’Stateless’’’ - set *LIBL every single request
if ($i5persistentconnect) $conn = db2_pconnect($database,$user,$password);
else $conn = db2_connect($database,$user,$password);
if (!$conn) die("Bad connect: $database,$user");
$stmt = db2_prepare($conn, "call $libxmlservice.iPLUG4K(?,?,?,?)");
if (!$stmt) die("Bad prepare: ".db2_stmt_errormsg());
$ipc = "";       // *** RIGHT HERE MISSING internalKey/IPC
$ctl = "*here";  // *** run stateless ...
                //     here in any available database job
                //     must set *LIBL evey time
// stateless - MUST do this every single script after connect/getInstance()
//             even if using persistent connections (db2_pconnect, odbc_pconnect)
$clobIn =
"<?xml version='1.0'?>
<script>
<cmd>CHGLIBL LIBL(FREDFLIN WILMAFLIN) CURLIB(FREDFLIN)</cmd>
</script>";
$clobOut = "";
$ret=db2_bind_param($stmt, 1, "ipc", DB2_PARAM_IN);
$ret=db2_bind_param($stmt, 2, "ctl", DB2_PARAM_IN);
$ret=db2_bind_param($stmt, 3, "clobIn", DB2_PARAM_IN);
$ret=db2_bind_param($stmt, 4, "clobOut", DB2_PARAM_OUT);
$ret=db2_execute($stmt);
  • ‘’’State Full’’’ - set *LIBL once and forget it
if ($i5persistentconnect) $conn = db2_pconnect($database,$user,$password);
else $conn = db2_connect($database,$user,$password);
if (!$conn) die("Bad connect: $database,$user");
$stmt = db2_prepare($conn, "call $libxmlservice.iPLUG4K(?,?,?,?)");
if (!$stmt) die("Bad prepare: ".db2_stmt_errormsg());
$ipc = "/tmp/packers"; // *** RIGHT HERE internalKey/IPC
$ctl = "*sbmjob";      // *** run state full ...
                    //     use SBMJOB command run in new job
                    //     PHP can call again, again, again
                    //     with /tmp/packers and get ...
                    //     same job every time
                    //     same library list (*LIBL)
                    //     same PGMs with open files, etc.
                    //     ... exactly like 5250 sign-on screen
// state full - MUST do this ONCE ONLY after start/sbmjob of XMLSERVICE job
//              then forget about it (unless you choose to change libl) ...
$clobIn =
"<?xml version='1.0'?>
<script>
<cmd>CHGLIBL LIBL(FREDFLIN WILMAFLIN) CURLIB(FREDFLIN)</cmd>
</script>";
$clobOut = "";
$ret=db2_bind_param($stmt, 1, "ipc", DB2_PARAM_IN);
$ret=db2_bind_param($stmt, 2, "ctl", DB2_PARAM_IN);
$ret=db2_bind_param($stmt, 3, "clobIn", DB2_PARAM_IN);
$ret=db2_bind_param($stmt, 4, "clobOut", DB2_PARAM_OUT);
$ret=db2_execute($stmt);

3) Specific examples for New PHP Toolkit CW layer

  • ‘’’Stateless’’’ - set *LIBL every single request, but for CW, specify libraries in reverse order (via ADDLIBLE)
$options = array(I5_OPTIONS_INITLIBL => 'WILMAFLIN FREDFLIN' );
$conn = i5_connect($host, $user, $password, $options);
// or persistent (which is also stateless): still must specify library each time
$conn = i5_pconnect($host, $user, $password, $options);
  • ‘’’State Full’’’ - set *LIBL once and forget it
session_start();

// if we previously saved a connection number in PHP session, use it.
// otherwise, use 0 (which means create a new connection)
$conNum = (isset($_SESSION['conectionNum']) ? $_SESSION['conectionNum'] : 0;

// I5_OPTIONS_PRIVATE_CONNECTION:  connection is private for the session
// I5_OPTIONS_IDLE_TIMEOUT: After a delay of the specified number of seconds with no activity, the job will end.
$options = array(I5_OPTIONS_PRIVATE_CONNECTION => $conNum,
                I5_OPTIONS_IDLE_TIMEOUT       => "60");

// connect as a private connection, starting with a persistent conn
$conn = i5_pconnect ($host, $user, $password, $options);

if (!$conn) {
    echo "Something went wrong: <PRE>" . print_r(i5_error(), true) . "</PRE>";
    $_SESSION['conectionNum'] = 0; // reset number
} else {
    // connected successfully

    // if original conNum was 0, let's retrieve the new number.
    if ($conNum == 0) {

        // Session variable was 0: Get connection ID and store it in session variable.
        $ret = i5_get_property(I5_PRIVATE_CONNECTION, $conn);

        if (!$ret) {
            echo "Something went wrong: <PRE>" . print_r(i5_error(), true) . "</PRE>";
        } else {

            // We have a good new private connection. Store connection ID in session variable
            $_SESSION['conectionNum'] = $ret;

            // and set library list, too.
            i5_command("CHGLIBL LIBL(FREDFLIN WILMAFLIN) CURLIB(FREDFLIN)");
        }
    }
}