-1

I am aware that this is a common error and has more than likely been answered, but the issue I am having is when the function is executed it's returning the $down_time variable as null when a new website becomes offline on this line $diff_in_seconds = $now_time->getTimestamp() - $down_time->getTimestamp(); however when I run the function again in my terminal the error then goes. Basically it's returning $down_time variable as null before it is updated into the database, which I'm confused about since the update query is executed first. I would really appreciate the help and guidance thanks.

    public static function run()
    {
        $dept_emails = array(
            19 => 'test@email.co.uk'
        );

        $active_clients = Client::get_active_clients();

        foreach ($active_clients as $client) {
            $websites = $client->websites;

            $services = $client->services;

            foreach ($websites as $website) {
                $website_url = $website->url;
                $website_url_parse = parse_url($website_url);
                $new_website_url = "https://" . $website_url;
                $website_status = Client::get_website_status($new_website_url);

                if(array_key_exists('host', $website_url_parse)) {
                    $website_url = $website_url_parse['host'];
                }

                if($website_status == false) {
                    $new_website_url = "http://" . $website_url;
                    $website_status = Client::get_website_status($new_website_url);
                }


                $now = date('Y-m-d H:i:s');
                $now_time = DateTime::createFromFormat('Y-m-d H:i:s', $now);

                $down_time = DateTime::createFromFormat('Y-m-d H:i:s', $website->down_at);


                $result = DB::update('clients_websites')
                    ->set(array(
                        'last_checked' => $now
                    ))
                    ->where('id', '=', $website->id)
                    ->execute();

                if ($website_status) {
                    // Website is back online, send email
                    if($website->down_at != null && $website_status == true){


                        $diff_in_seconds = $now_time->getTimestamp() - $down_time->getTimestamp();
                        // Website has been down for more than 5 minutes
                        if($diff_in_seconds >= 300){

                            Cli::write("Emailing: " . $website->url . " is back online");

                            $result = DB::update('clients_websites')
                                ->set(array(
                                    'down_at' => null,
                                    'up_at' => date('Y-m-d H:i:s'),
                                ))
                                ->where('id', '=', $website->id)
                                ->execute();

                            $notify_emails = array();

                            foreach ($services as $service)
                            {
                                $service_id = $service->service_id;
                                if (in_array($service_id, $dept_emails))
                                {
                                    $notify_emails[] = $dept_emails[$service_id];
                                }
                            }

                            $message = "Hi " . $website->url . " is back online.";
                            $email = Model_Mail::send_email($dept_emails, "" . $website->url . " is back online", $message);
                        }

                    } else {
                        // Website is online insert up time in to DB
                        Cli::write("Online: " . $website->url . " is online");

                        $result = DB::update('clients_websites')
                            ->set(array(
                                'down_at' => null,
                                'up_at' => date('Y-m-d H:i:s'),
                            ))
                            ->where('id', '=', $website->id)
                            ->execute();
                    }

                } else {
                    // Website is down insert down time in to DB
                    Cli::write("Offline: " . $website->url . " is offline");

                   if(is_null($website->down_at)){
                        $result = DB::update('clients_websites')
                            ->set(array(
                                'down_at' => date('Y-m-d H:i:s')
                            ))
                            ->where('id', '=', $website->id)
                            ->execute();

                            $query = DB::select('*')->from('clients_websites')->where('id', '=', $website->id)
                                ->and_where_open()
                                ->where('down_at', 'IS NOT', NULL)
                                ->and_where_close()
                                ->execute();

                        $down_time = DateTime::createFromFormat('Y-m-d H:i:s',  $query['down_at']);
                        $down_time_email = $down_time->format('d-m-Y H:i:s');
                        $diff_in_seconds = $now_time->getTimestamp() - $down_time->getTimestamp();

                        if($diff_in_seconds >= 300){

                            Cli::write("Emailing: " . $website->url . " is offline");

                            $notify_emails = array();

                            foreach ($services as $service)
                            {
                                $service_id = $service->service_id;
                                $active = $service->end_date;
                                if (in_array($service_id, $dept_emails ) && ($active == null || $active > $now))
                                {
                                    $notify_emails[] = $dept_emails[$service_id];
                                }
                            }

                            $message = "Hi " . $website->url . " has been down since " . $down_time_email . ".";
                            $email = Model_Mail::send_email($dept_emails, "" . $website->url . " is down", $message);

                            $result = DB::update('clients_websites')
                                ->set(array(
                                    'down_email_sent' => date('Y-m-d H:i:s')
                                ))
                                ->where('id', '=', $website->id)
                                ->execute();
                        }
                    }
                }
            }
        }
    }
BrandonK
  • 63
  • 6
  • 1
    Show us the contents of `$website->down_at` please – ADyson May 29 '20 at 12:07
  • _"the update query is executed first"_ ... the only update query shown in your page is very clearly **after** the `$down_time = ` line. But even so, it wouldn't cause either `$down_time` or `$website->down_at` to change their value. If you're talking about the different query, you'll need to clarify because we can't help you with things we can't see. – ADyson May 29 '20 at 12:09
  • 1
    Does this answer your question? [Reference - What does this error mean in PHP?](https://stackoverflow.com/questions/12769982/reference-what-does-this-error-mean-in-php) – Nico Haase May 29 '20 at 12:09
  • @NicoHaase I think OP understands roughly what the error means, they've realised the variable is null, they're struggling to understand why it's like that, or perhaps struggling to understand how to debug it effectively. So I don't know if that's really a helpful duplicate in this case. – ADyson May 29 '20 at 12:11
  • The actual function is quite long so I can't show the whole code is there a way I can show you the whole function so you can understand – BrandonK May 29 '20 at 12:20
  • I have added the function so basically it does a foreach which loops through the websites to check the status code is returning 200, however when it detects if a website is offline it returns down time as null but when the function is executed again it works fine because it's retrieved the date. – BrandonK May 29 '20 at 12:36
  • And what have you tried to spot the error and fix it? – Nico Haase May 29 '20 at 12:52
  • I used var_dump($down_time); to output the time which is null, feel like the update query is being delayed, but I don't know why it gets the date second time it is executed – BrandonK May 29 '20 at 13:16
  • "when the function is executed again it works"...probably because `$result = DB::update('clients_websites') ->set(array( 'down_at' => date('Y-m-d H:i:s')` doesn't occur until later, as you've already said yourself. So clearly the solution to that is to check whether `$website->down_at` is null before you pass it to CreateFromFormat. If it's null, then don't try to create a date object from it! – ADyson May 29 '20 at 14:35
  • I don't know precisely the nuances of the logic you want to implement, but it seems fairly obvious to me that any code which creates or refers to `$down_time` needs to be inside the `if($website->down_at != null... ` block of code, so that it only tries to use that value when it's definitely populated. This ought to be a fairly self-evident truth in any computer program (whether simple or complex) - you can't use data which doesn't exist, so you shouldn't try. If you're unsure whether the data will exist at runtime, then check first before you try to use it. – ADyson May 29 '20 at 14:37
  • I have tried this method but keep getting the same outcome, I then tried doing a select query after the update query to refresh the data in the database so retrieve the date ```$query = DB::select('*')->from('clients_websites')->where('id', '=', $website->id) ->and_where_open() ->where('down_at', 'IS NOT', NULL) ->and_where_close() ->execute(); ``` but still returned the same error. – BrandonK May 30 '20 at 10:22
  • You'll need to show us precisely all the changes you made before we can figure out why it still didn't work as you expected – ADyson May 30 '20 at 18:25
  • I have updated the code above so basically I put all the code below inside this if statement ```if(is_null($website->down_at))``` so inside this if statement it runs the update query, then after it runs the select query, however it doesn't seem to get the down time despite doing that select query. Which I'm confused because there is a date in the database. – BrandonK May 30 '20 at 19:00

1 Answers1

1

Figured this out at the beginning of the website foreach I defined a new variable $time_now = date('Y-m-d H:i:s'); which was then used in the update for query for the down_at time and assigned to $down_time variable.

$result = DB::update('clients_websites')
                            ->set(array(
                                'down_at' => $time_now
                            ))
                            ->where('id', '=', $website->id)
                            ->execute();
                    }

                    $down_time = DateTime::createFromFormat('Y-m-d H:i:s', $time_now);
BrandonK
  • 63
  • 6