Sage Pay/Opayo Forms Integration - PHP 8.1 - PHP Fatal Error: Uncaught Error: Attempt to assign property 'start' on null
P粉872182023
P粉872182023 2023-09-07 22:16:21
0
1
596

I'm glad there are similar questions, but I can't get any solution to work with my (inherited) code, so any help you can provide would be greatly appreciated.

We use Sage Pay / Opayo payment gateway via form integration. Upon completion/failure, the customer will be redirected to a URL on our website with an encrypted _GET string. After decryption, call the getToken function ( $values ​​= getToken($Decoded); ) to get the values ​​from the array.

However, not all tags are always populated and I suspect these null values ​​may be the source of the problem.

This code runs fine on PHP 7.1, but throws an exception on PHP 8.1:

[2023-05-03 15:12:15 Europe/London] PHP fatal error: Uncaught error: Trying to assign property 'start' on null in /home/sitename/public_html/ch_functions.php:166 Stack trace: #0 /home/sitename/public_html/not_completed.php(32): getToken('VendorTxCode=AP...') #1 {Main} Throwing in /home/sitename/public_html/ch_functions.php line 166

The code is, what fails on $resultArray[$i]->start = $start; is:

function getToken($thisString) {

    // List the possible tokens
    $Tokens = array("Status","StatusDetail","VendorTxCode","VPSTxId","TxAuthNo","Amount","AVSCV2","AddressResult","PostCodeResult","CV2Result","GiftAid","3DSecureStatus","CAVV", "AddressStatus", "PayerStatus", "CardType", "Last4Digits","BankAuthCode","DeclineCode");

    // Initialise arrays
    $output = array();
    $resultArray = array();
    
    // Get the next token in the sequence
    for ($i = count($Tokens)-1; $i >= 0 ; $i--){
        // Find the position in the string
        $start = strpos($thisString, $Tokens[$i]);
        // If it's present
        if ($start !== false){
            // Record position and token name
            $resultArray[$i]->start = $start;
            $resultArray[$i]->token = $Tokens[$i];
        }
    }
    
    // Sort in order of position
    sort($resultArray);

    // Go through the result array, getting the token values
    for ($i = 0; $i<count($resultArray); $i++){
        // Get the start point of the value
        $valueStart = $resultArray[$i]->start + strlen($resultArray[$i]->token) + 1;
        // Get the length of the value
        if ($i==(count($resultArray)-1)) {
            $output[$resultArray[$i]->token] = substr($thisString, $valueStart);
        } else {
            $valueLength = $resultArray[$i+1]->start - $resultArray[$i]->start - strlen($resultArray[$i]->token) - 2;
            $output[$resultArray[$i]->token] = substr($thisString, $valueStart, $valueLength);
        }           

    }

    // Return the ouput array
    return $output;

}

P粉872182023
P粉872182023

reply all(1)
P粉111927962

You referenced $resultArray[$i] as an object, but the array is empty, so there is no object to reference. In PHP 7.4 and earlier versions you can do the following:

$x = [];
$x[0]->foo = 1;

PHP will dynamically create a stdClass object at $x[0] and then dynamically create the foo property, but will issue a warning:

You are currently suppressing or ignoring this warning. In PHP 8.0, this now generates a fatal error. So just create an empty object before trying to set its value:

if ($start !== false) {
    $resultArray[$i] = new stdClass();
    $resultArray[$i]->start = $start;
    $resultArray[$i]->token = $Tokens[$i];
}

or:

if ($start !== false) {
    $resultArray[$i] = (object) [
        'start' => $start,
        'token' => $Tokens[$i],
    ];
}
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template