Help me understand these errors...

Here are the errors that showed up in the log of a recent "mailing" of some statements:

[10-Aug-2016 15:02:53 America/Chicago] PHP Notice:  Undefined index: message in /var/www/ on line 505
[10-Aug-2016 15:02:53 America/Chicago] PHP Notice:  Undefined index: legal_front in /var/www/ on line 506
[10-Aug-2016 15:02:53 America/Chicago] PHP Notice:  Undefined index: legal_back in /var/www/ on line 507
[10-Aug-2016 15:02:53 America/Chicago] PHP Notice:  Undefined index: legal_color in /var/www/ on line 508

Here's the function that's apparently coughing and sputtering:

protected function toPipeDelim($st){

        //Loop through and create the PipeDelim field
        $file = "";
            Add Statement Segment
        // Set the Silly Variables cause some folks don't like reading the array object in the string generation
        $totalcharges = number_format($st['TotalCharges'], 2, '.', '');
        $totaladjustments = number_format($st['TotalAdjustments'], 2, '.', '');
        $totalpayments = number_format($st['TotalPayments'], 2, '.', '');
        $stbalance = number_format($totalcharges+$totalpayments+$totaladjustments, 2, '.', '');
        $amountdue = ($st['AmountDue'] == '0')?$stbalance:number_format($st['AmountDue'], 2, '.', '');
        if($st['duedate'] == '0'){
            $duedate = 'Due Upon Receipt';
        } else {
            $duedate = date('m/').$st['duedate'].date('/Y');
            if(strtotime($duedate) < strtotime('now')) {
                $duedate = Date('m/d/Y', strtotime("$duedate + 1 month"));
            $duedate = 'Due on ' . $duedate;
        $statementdate = date('m/d/Y');
        $planbalance = number_format($st['planbalance'], 2, '.', '');

        $message = $st['parameters']['message'];
        $mmessage = $st['parameters']['legal_front'];
        $lmessage = $st['parameters']['legal_back'];
        $mmessagecolor = $st['parameters']['legal_color'];

        $statementpin = $st['statementid'] != '' ? "T".$st['statementid'] : "PREVIEW";
        $templateid = $st['templateid'];
        $accountid = $st['AccountID'];
        $accountnumber = $st['PracticeAccountID']."-".$accountid;
        $statementurl = "https://".strtolower($st['ClientTetrisID'])."$statementpin";
        $lastclaimdate = $st['lastclaimdate'] ? date('m/d/Y',strtotime($st['lastclaimdate'])) : '';

        $file .= "S2|$templateid|$totalcharges|$totalpayments|$totaladjustments|$stbalance|$amountdue|$duedate|$statementdate|$statementpin|$accountid|$accountnumber|$statementurl|$message|$lastclaimdate|$mmessagecolor|$mmessage|$lmessage\r\n";
            Add Client Segment
           // Set the Silly Variables cause some folks don't like reading the array object in the string generation
        $practicename = $st['PracticeName'];
        $clientname = $st['ClientName'];
        $logofile = strtolower($st['ClientTetrisID']).".jpg";
        $phonenumber = $st['twiliophone'];
        /* Temporary option to disinguish if the account has an encounter in placementgroup 1353 for the URMC lockbox move */
        if(($st['1353'] == null && $st['ClientID'] == '21')){
          $lad1 = "P.O. Box 1079";
          $lad2 = "";
          $ladcity = "Manchester";
          $ladstate = "TN";
          $ladzip = "37349";
          $lad1 = $st['lockboxAddress1'];
          $lad2 = $st['lockboxAddress2'];
          $ladcity = $st['lockboxCity'];
          $ladstate = $st['lockboxState'];
          $ladzip = $st['lockboxZip'];
        $portalurl = "https://".strtolower($st['ClientTetrisID'])."";
        $rad1 = "PO BOX 291569";
        $rad2 = "";
        $radcity = "Nashville";
        $radstate = "TN";
        $radzip = "37229";
        $fax = '8885511910';
        $email = '';
        $hours = 'Open Monday - Friday 8am - 6pm Central';
        $file .= "C3|$practicename|$clientname|$logofile|$portalurl|$phonenumber|$lad1|$lad2|$ladcity|$ladstate|$ladzip|$rad1|$rad2|$radcity|$radstate|$radzip|$fax|$email|$hours\r\n";

            Set the Guarantor Information
        $gfname = $st['patientfname'];
        $glname = $st['patientlname'];
        $patssn = $st['patientssn'];
        $gmi = $st['patientinitial'];
        if($st['patientdob'] != null){
            $gdob = date('Ymd', strtotime($st['patientdob']));
            $gdob = $st['patientdob'];
        if($st['patientdod'] != null){
            $gdod = date('Ymd', strtotime($st['patientdod']));
            $gdod = $st['patientdod'];
        $gaddress1 = $st['maddress1'];
        $gaddress2 = $st['maddress2'];
        $gaddress3 = $st['maddress3'];
        $gcity = $st['mcity'];
        $gstate = $st['mstate'];
        $gzip = $st['mzip'];
        $gphonenumber = $st['phonenumber'];

        $file .="G4|$glname|$gmi|$gfname|$gdob|$gaddress1|$gaddress2|$gaddress3|$gcity|$gstate|$gzip|$gphonenumber|0|$patssn\r\n";

            Set the Patient Information
            $file .="P5|$glname|$gmi|$gfname|$gdob\r\n";

            New and old txn info
            foreach($st['newtxns'] as $newtxn){
                if($newtxn['balance'] > 0){
                    $practclaimid = $newtxn['practclaimid'];
                    $type = $newtxn['txntype'];
                    $physicianid = $newtxn['physicianid'];
                    $description = $newtxn['description'];
                    $amount = number_format($newtxn['amount'], 2, '.','');
                    $lefttopay = number_format($newtxn['balance'], 2, '.','');
                    $date =date('Ymd',strtotime($newtxn['date']));

                    $file .= "N6|$practclaimid|$physicianid|$date|$type|$description|$amount|$lefttopay\r\n";
            foreach($st['oldtxns'] as $oldtxn){
                if($oldtxn['left_to_pay'] > 0){
                    $practclaimid = $oldtxn['encountercode'];
                    $physicianid = ($oldtxn['provider'])?$oldtxn['provider']:"";
                    $description = $oldtxn['description'];
                    $dos = date('Ymd', strtotime($oldtxn['dos']));
                    $charges = number_format($oldtxn['total_charges'],2,'.','');
                    $adjs = number_format($oldtxn['total_adjustments'],2,'.','');
                    $payments  = number_format($oldtxn['total_payments'],2,'.','');
                    $balance = number_format($oldtxn['left_to_pay'],2,'.','');

                    $file .= "A6|$practclaimid|$physicianid|$description|$dos|$charges|$adjs|$payments|$balance\r\n";

          Are they Elegible for a Payment Plan?  If So, let's add that segment.
        if($stbalance >= '180' && $st['duedate'] == '0'){
            $opt1 = number_format(ceil($stbalance/3),2,'.','');
            $opt2 = number_format(ceil($stbalance/6),2,'.','');
            $opt3 = number_format(ceil($stbalance/9),2,'.','');
            $file .= "O7|$opt1|$opt2|$opt3\r\n";

          Are they on a Payment PLan?  If So, Let's add that segment.
        if($st['duedate'] != '0' ){
            $progress = number_format(($planbalance-$stbalance)/$planbalance, 2);
            $remaining = ceil($stbalance/$amountdue);
            $file .= "P8|$amountdue|$progress|$stbalance|$remaining\r\n";

        return $file;

Open in new window

First off, the concern right now is that these "notices" resulted in the failure of the script failing. That's not my impression based on the manual ( But still, an "undefined index" seems like it could be a dealbreaker.

"legal_front," "legal_back" etc are all parameters coming from the "StatementParameter" table. "message" is a value in the "parameter" column. In most cases, the "value" column will have a value, but in some there isn't a value. See the screenshot below:

Is that where my error is coming from? The fact that I've got some parameters that don't have a corresponding value in the StatementParameter table? Or, is an "undefined index" go deeper than that and I'm contending with something that goes beyond an empty column?
brucegustPHP DeveloperAsked:
Who is Participating?
Ray PaseurCommented:
You may  be running up against some very old and incompetently written PHP programming.  PHP, in its design to be "easy" decided that Notices, which include such things as undefined variables and array indexes, should be suppressed by default.  As a result a lot of novice programmers believed that undefined information "just worked" like the falsy values -- zero, NULL, FALSE, etc.  They never learned that undefined  could also mean unpredictable  and they wrote their programming with the Notice messages turned off, assuming that everything would be OK.

Today, in the 21st century, we don't do that any more.  We find and correct the issues that underlie Notice messages.  We test variables with isset() or empty() to see if they exist before we use them.

Here's my heretical guess at what might give you quick mitigation.  Try setting error_reporting() to the PHP default which is more or less like error_reporting(E_ALL & ~E_NOTICE);.  If the programming was written with the PHP default error_reporting as a baseline assumption, you might find that this change suppresses spurious output, and after that, the script works to produce the PDF.

It may not be necessary to understand  the errors - it may be enough to just make the messages go away.
Julian HansenCommented:
 $message = $st['parameters']['message'];

Open in new window

The error is saying that the index message does not exist in the parametes array in the $st object.

What you need to do is a var_dump, print_r, var_export of $st at the start of the function - so you can see what the object actually looks like.

Once we have seen what is actually being passed in we can trace it back to where toPipeDelim is called from.

Get us the dump of $st so we can see what it looks like.
brucegustPHP DeveloperAuthor Commented:
Wise counsel...

Stand by...
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

brucegustPHP DeveloperAuthor Commented:
Alright, gentlemen, here's what I've got:

First off, a screenshot of the example I've isolated in a sandbox:

severity screenshot
You can see the "var_dump" at the top. It looks like this, just so you don't have to squint:

string(320) "S2|4|0.00|0.00|0.00|0.00|0.00|Due Upon Receipt|08/11/2016|T2067159|12160119|21316-12160119||Thank you for choosing Barton County Memorial Hospital, Lamar, MO. We hope to serve you again in the future.||black|This statement does not include any accounts with a collection agency. "
A PHP Error was encountered

Severity: Notice

Message: Undefined offset: 17

Filename: StatementImager/StatementImage.php

Line Number: 107

string(0) "" string(438) "We offer a Charity Care Program to assist patients with their account balance. For information on applying or qualifying please call us at 888-551-1910 or email service@patientfocus.|Barton County Memorial Hospital is committed to providing our patients with the best care possible and working with you to arrange payments on all accounts. BCMH is a certified Medicare and Missouri/Kansas Medicaid Provider. Non-approved/covered services," string(308) "C3|Barton County Memorial Hospital|Barton County Memorial Hospital, Lamar, MO|bcmh.jpg||4172326938|Payment Processing Center|P.O. BOX 305172 DEPT #126|Nashville|TN|37230|PO BOX 291569||Nashville|TN|37229|8885511910||Open Monday - Friday 8am - 6pm Central" string(72) "G4|STEPHENSON| |PENNY|19700128|700 MADISON| | |GOLDEN CITY|MO|64748| |0|" string(30) "P5|STEPHENSON| |PENNY|19700128" string(0) ""

Open in new window

The "S2" case is the one where an error is being thrown. It breaks down like this:

S2| - case
4| - template id
0.00| - total charges
0.00| - total payments
0.00| - total adjustments
0.00| - balance
0.00| - amount due
Due Upon Receipt| - due date
08/11/2016| - statement date
T2067159| - statement pin
12160119| - account id
21316-12160119| - account number| - URL
Thank you for choosing Barton County Memorial Hospital, Lamar, MO. We hope to serve you again in the future.| - message
| - last claim date
black| - legal copy color
This statement does not include any accounts with a collection agency. " - legal copy

What's missing, according to the code is at line #107, which is this:

$statement['statement']['legal_copy_back']   = $line[17];

So, there should be something after "legal copy color, " and there's nothing there. I've got to do some digging to see what's actually in the table, but I'm smelling something that says I need to do an "isset" before I attempt to refer to them in order to avoid the errors, correct?
Ray PaseurCommented:
I need to do an "isset" before I attempt to refer to them...
Yes, in a perfect world, that is one correct way to write the code.  But this code did not come from a perfect world at all.

My recommendation would be to turn off the reporting of Notice messages.  Then try the script again.  That's an easy step and might provide a quick fix.  You might also want to ask the customer if this script has ever worked correctly!

If Notice suppression does not fix it, or the customer says the script has never worked, then going into the world of isset() -- or providing default values -- is likely to be one of the paths to resolution.
Julian HansenCommented:
So from the output it looks like you are expecting an array but you are getting a string which indicates that whatever process is calling the function is not preparing the $st parameter correctly.

It looks like you should be parsing the string into an array before sending it to the function.

If this is part of an already working code base then what is different about this situation that the string is not being parsed into the correct array format before being submitted to the function?

You could explode the array and then assign the respective elements to named keys and then pass the result through - but that seems a bit pedestrian for code that should have this base covered already - so I am interested to see the code that does the actual calling of the function.
brucegustPHP DeveloperAuthor Commented:
Guys, the next day I was able to confirm the script worked fine. It wasn't a PHP / syntax issue. It was a database issue that our DBO was able to remedy. Your counsel helped me be able to talk some of the concerned parties of the ledge and while there may still be some issues that need to be cleaned up, it works and that's the bottom line for now.

Thank you!
Julian HansenCommented:
You are welcome Bruce,
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.