skip to Main Content

I have the below php from my website which pulls data from an xml object to output a list of adoptable dogs. For some reason though, when updating my site from php 7.4 to 8.0, the foreach loop gives the following error "Warning: foreach() argument must be of type array|object, null given on line 54"

In my troubleshooting, it seems that the line in question has always evaluated to null even when using php 7.4, the foreach loop only seems to care in php 8.

Can someone help me make this code run in php 8? I have tried many things to no avail, but I am a total php amateur so I am hoping someone else can easily spot a fix.

Here is the structure of the xml the code is pulling from:

SimpleXMLElement Object 
    ( 
        [XmlNode] => Array 
            ( 
                [0] = SimpleXMLElement Object 
                        ( 
                            [adoptableSearch] => SimpleXMLElement Object               
                                 (
                                      [ID] => 12354566
                                      [Name] => Paco
                                      [Species] => Dog
                                      [Sex] => Male
                                      [PrimaryBreed] => Chihuahua
                                      [SecondaryBreed] => N/A
                                      [SN] => Spayed
                                      [Age] => 49
                                      [Photo] => https//g.petango.com/photos/128937931827.jpg
                                      [Location] => Shelter 2
                                      [OnHold] => No
                                      [Special Needs] => SimpleXMLElement Object
                                           (
                                           )

                                      [NoDogs] => SimpleXMLElement Object
                                           (
                                           )

                                      [NoCats] => SimpleXMLElement Object
                                           (
                                           )

The problematic line in the code is this:
foreach ($xmlWSIN->XmlNode->$counter->adoptableSearch as $output)

Since $xmlWSIN->XmlNode->$counter->adoptableSearch is null, the foreach() wont run in php 8, but will in 7.4 which is so strange.

Here is the full code for the page:

$urlWSBase      = get_field('api_base_url', 'option');
$urlWSComplete  = "";
$daysAgo1       = date('m/d/yy',strtotime("-1 days"));
$error          = "No";
$urlWSAuthKey   = get_field('api_key', 'option');
$urlWSComplete  = createAdoptableSearch($urlWSBase,$urlWSAuthKey, '1');

if (strlen($urlWSAuthKey) != 50) { 
    $error = "Yes";
    echo "<font color='red'>Not a Valid AuthKey, please double check and resubmit</font><br>";
    exit();
}
$selfURLIN      = '';

$page_single = get_posts(array(
    'post_type' => 'page',
    'meta_key' => '_wp_page_template',
    'meta_value' => 'single_pet.php',
    'posts_per_page' => 1,
));

if ( $page_single ) {
    $page = current( $page_single );
    $selfURLIN = get_permalink($page->ID);
}

$outputWS = file_get_contents( $urlWSComplete, false, stream_context_create( $arrContextOptions ) );
//If outputWS is not a boolean FALSE value
if ($outputWS !== false) {
    $xmlWS = simplexml_load_string($outputWS);
    $xmlWSArray = json_decode(json_encode((array)simplexml_load_string($outputWS)),1);
    if ($xmlWS === false) {
        echo "Failed loading XML: ";
        foreach(libxml_get_errors() as $error) {
            echo "<br>", $error->message;
        }
    } 
}
else {
    echo "There seems to be an error!";
}

function outputAdoptableSearch($selfURLIN,$urlWSAuthKeyIN,$xmlWSIN) {
$xmlArrayCount = count($xmlWSIN);
$counter = 0;

while ($counter < $xmlArrayCount - 1) {
    foreach ($xmlWSIN->XmlNode->$counter->adoptableSearch as $output) {
        $xmlSecondaryBreed = $xmlSpecialNeeds = $xmlNoDogs = $xmlNoCats = $xmlNoKids = "Not Defined";
        $xmlAnimalID        = $output->ID;
        $xmlName            = $output->Name;
        $xmlPhoto           = $output->Photo;
        $xmlSpecies         = $output->Species;
        $xmlSex             = $output->Sex;
        $xmlPrimaryBreed    = $output->PrimaryBreed;
        $xmlAgeMonths       = $output->Age;
        $xmlAnimalType      = $output->AnimalType;
        $xmlAgeGroup        = $output->AgeGroup;
        
        $formated_age = petAgeCalc( $xmlAgeMonths );
        $xmlAnimalDetailsLink = $selfURLIN . '?animalID='. $xmlAnimalID;
        $species_lowercase = strtolower($xmlSpecies);
        $sex_lowercase = strtolower($xmlSex);
        $breed_lowercase = strtolower($xmlPrimaryBreed);

        if( strpos( $xmlPhoto, '_TN1.jpg' ) ) {
            $explode_url = explode('_TN1.jpg', $xmlPhoto);

            $pet_pic = $explode_url[0] . '.jpg';
        } else {
            $pet_pic = $xmlPhoto;
        };


echo  '<li>
        <a href="' . $xmlAnimalDetailsLink . '">
        <div style="background-image: url(' . $pet_pic . ')" class="pet-pic"></div>
        </a>
        <p>' . $xmlName . '</p>
        <p>' . $formated_age . '</p>
        <p>' . $xmlSex . '</p>
        <p>' . $xmlPrimaryBreed . '</p>
        <a class="button more-info" href="' . $xmlAnimalDetailsLink . '">More Details</a>
    </li>';   

$counter++; 
 }
}

I cannot understand why the below modification to while loop in the outputAdoptableSearch function won’t fix the issue. The page simply wont load and will time out after 5 minutes with the below modification.

while ($counter < $xmlArrayCount - 1) {
    foreach ($xmlWSIN->XmlNode->$counter as $output) {
        $xmlSecondaryBreed = $xmlSpecialNeeds = $xmlNoDogs = $xmlNoCats = $xmlNoKids = "Not Defined";
        $xmlAnimalID        = $output->adoptableSearch->ID;
        $xmlName            = $output->adoptableSearch->Name;
        $xmlPhoto           = $output->adoptableSearch->Photo;
        $xmlSpecies         = $output->adoptableSearch->Species;
        $xmlSex             = $output->adoptableSearch->Sex;
        $xmlPrimaryBreed    = $output->adoptableSearch->PrimaryBreed;
        $xmlAgeMonths       = $output->adoptableSearch->Age;
        $xmlAnimalType      = $output->adoptableSearch->AnimalType;
        $xmlAgeGroup        = $output->adoptableSearch->AgeGroup;
        
        $formated_age = petAgeCalc( $xmlAgeMonths );
        $xmlAnimalDetailsLink = $selfURLIN . '?animalID='. $xmlAnimalID;
        $species_lowercase = strtolower($xmlSpecies);
        $sex_lowercase = strtolower($xmlSex);
        $breed_lowercase = strtolower($xmlPrimaryBreed);

        if( strpos( $xmlPhoto, '_TN1.jpg' ) ) {
            $explode_url = explode('_TN1.jpg', $xmlPhoto);

            $pet_pic = $explode_url[0] . '.jpg';
        } else {
            $pet_pic = $xmlPhoto;
        };

2

Answers


  1. Chosen as BEST ANSWER

    Thanks so much for everyone's input. I was able to implement a fix by changing the below line:

    foreach ($xmlWSIN->XmlNode->$counter->adoptableSearch as $output)

    to

    foreach ($xmlWSIN->XmlNode[$counter][0] as $output)


  2. I think you just need to wrap your foreach loops in a if statement to be sure that you don’t feed the loop with wrong information.

    Please try the code below:

    if(is_array($my_variable)){
        foreach($my_variable as $whatever){
             // your code here
        }
    }
    

    With this you will be sure that your foreach will loop around an array.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search