Search code examples
phparraysforeachsimplexmldo-while

PHP - repeat retrieve XML if value is not correct


I have a code in PHP to works with XML:

    $data_measuranment = file_get_contents($value, false, $context);
    $xml=simplexml_load_string($data_measuranment);
    $json = json_encode($xml);
    $array[] = json_decode($json,TRUE);

The values of my array ($array[]) depend on the time:

[1] => Array
        (
            [@attributes] => Array
                (
                    [end] => 1520439534044
                    [start] => 1520439300000
                    [step] => 300000
                )

            [columns] => Array
                (
                    [values] => Array
                        (
                            [0] => NaN
                            [1] => NaN
                        )

                )

            [timestamps] => Array
                (
                    [0] => 1520439300000
                    [1] => 1520439600000
                )

        )
 ...

If I execute the code some seconds ago. My array works:

[1] => Array
        (
            [@attributes] => Array
                (
                    [end] => 1520439565293
                    [start] => 1520439300000
                    [step] => 300000
                )

            [columns] => Array
                (
                    [values] => Array
                        (
                            [0] => 12
                            [1] => NaN
                        )

                )

            [timestamps] => Array
                (
                    [0] => 1520439300000
                    [1] => 1520439600000
                )

        )
...

The only value important for my is array[key][columns][values][0]=12

So, I need a code to wait some seconds and execute again the pull for the API and finish when the value array[1][columns][values][0] is different to NaN. I tried to do that with this code but not works:

do
{
    foreach ($array as $valor)
    {
        $term= $valor['columns']['values']['0'] ;
        if ($term === 'NaN')
        {
            unset($array);
            sleep(10);
            $data_measuranment = file_get_contents($value, false, $context);
            $xml=simplexml_load_string($data_measuranment);
            $json = json_encode($xml);
            $array[] = json_decode($json,TRUE);
        }
    }

}while (isset($array))

I need this: When the foreach read the value "$valor['columns']['values']['0']" and check is NaN. The code wait 10 seconds and retreive new array with file_get_contents, then check the condition again. If all values of $valor['columns']['values']['0'] are different of NaN continue the script.

Thank you.


Solution

  • Let's restate your requirements:

    1. Fetch the XML from the remote server.
    2. If all values of $valor['columns']['values']['0'] are not equal to NaN, continue the script.
    3. Else, wait 10 seconds and try again.

    You have correctly identified step 3 as requiring a do ... while loop to go back to the beginning, and step 2 as requiring a foreach loop to examine each value in the result.

    The problem is that you've added too much logic into the foreach loop, so that steps 1 and 3 are happening inside step 2. Instead, you need to perform step 2 in its entirety, and then decide whether to continue with the code, or sleep and try again.

    You may find it helpful to break the code up into separate functions - step 2 should just be examining the data and returning an indication of whether it is "good" or "bad", and step 1 should just be fetching the data and parsing it with SimpleXML:

    # Variable to control do...while loop
    $have_good_data = false;
    do
    {
        # Step 1
        $data_measuranment = file_get_contents($value, false, $context);
        $xml = simplexml_load_string($data_measuranment);
    
        # Step 2; this could be moved into a function that returns $have_nans
        $have_nans = does_data_contain_nan($xml);
    
        # Step 3
        if ( $have_nans ) {
           sleep(10);
        } else {
           $have_good_data = true;
        }
    } while ($have_good_data)
    

    The function for step 2 might look something like this:

    function does_data_contain_nan(\SimpleXMLElement $xml) {
        foreach ($xml->children() as $valor)
        {
            $term = (string)$valor->columns->values[0];
            if ($term === 'NaN')
            {
                 // once we find a NaN, we don't need to look at the other values
                 return true;
            }
        }
        // We got to the end of the loop without finding a NaN!
        return false;
    }