How to update div color dynamically everythime php function is re-run in html page

Viewed 222

I am trying to have a div which will show the server status with green or red background color. The background color should change when the php function sets a $status variable to green or red, which will be used in the div to set the background-color parameter! This is working when I reload the webpage but I would like to run the php function in intervals and update the color of the div field automatically without reloading the webpage.

See what I have till now:

<!DOCTYPE HTML>
<html>
<head>
<h1>Measurements - graphs</h1>
<?php
function getStatus() {
    $status = "#008000";
    $latestFile = '/my/web/logs/logging_rotation.out';
    
    if (file_exists($latestFile)) {
        $fileTime = filectime($latestFile);
        $now = microtime(true);
        $timediff = $now - $fileTime;
    }
    if ($timediff < 60) {
            $status = "#008000";
    } else {
        $status = "#FF0000";
    }
    return $status;
}   
?>
<div style="height: 20px; background-color: <?php echo getStatus()?>;">
Server status
</div>
</head>
<body>
</body>
</html>

So, what I miss now is a way to run php getStatus in intervals and that should update the background-color and it should update the div field. Is there a way to do that?

After some first suggestions I modified my code to:

<script>
    console.log('Starting doSomething'); // test printout
    async function doSomething() {
        const url = "status.php";
        await fetch(
            url,
            {
                method: "POST",
                body: new URLSearchParams("function=serverStatus")
            }
        )
        .then(response => response.text())
        .then((response) => {
            console.log(response); // printout response
            document.getElementById('serverStatus').style.backgroundColor = response; //set the response from the php function as the background color
        })
        .catch(err => console.log('s/g went wrong', err));
    }
</script>
<script>
    setInterval(doSomething, 1000);
</script>
<div id="serverStatus" style="height: 20px;">Server status</div>

But, it seems that the doSomething() is not executed because I don't see any of the console.log printouts!

All the above page is saved as mypage.php and I test this in two ways:

  1. reload the mypage.php in a browser.
  2. execute the mypage.php via php command:

php mypage.php > test.html

In both cases I don't get any of the printouts in doSomething().

Is this the correct way to test this kind of php pages?

Update after some further tries and now it works, no changes in the status.php, the issue was the path to status.php:

<script>
    async function doSomething() {
        const url = "/status.php"; // this is the correct path
        await fetch(
            url,
            {
                method: "POST",
                body: new URLSearchParams("function=serverStatus")
            }
        )
        .then(response => response.text())
        .then((response) => {
            console.log(response);
            document.getElementById('serverStatus').style.backgroundColor = response; //set the response from the php function as the background color
        })
        .catch(err => console.log('s/g went wrong', err));
    };
    setInterval('doSomething()', 1000); // correct call of doSomething()
</script>
<h2>Measurements - graphs</h2>
<div id="serverStatus" style="height: 20px;">Server status</div>

Both below answers and solutions are working! Regarding the second solution I modified it to:

<script>
  setInterval(function() {
    fetch('/status.php').then(response=>response.text()).then(function(text){
      document.getElementById('serverStatus').style.backgroundColor = text;
    })
  }, 1000) // in milliseconds
</script>
<h2>Measurements - graphs</h2>
<div id="serverStatus" style="height: 20px;">Server status</div>

status.php:

<?php
    $status = "#008000";
    $latestFile = '/my/web/logs/logging_rotation.out';
    if (file_exists($latestFile)) {
        $fileTime = filectime($latestFile);
        $now = microtime(true);
        $timediff = $now - $fileTime;
    }
    if ($timediff < 60) {
        $status = "#008000";
    } else {
        $status = "#FF0000";
    }
    exit($status); //return the result to the JS
?>

I do like both solutions, because one is using asynchronous programming and the other one is really compact! I guess in my case the asynchronous programming has more a knowledge benefit then actually for my website and just checking if my server is still up & running by checking if the elapsed time of last modification of the log file is under 60s.

Thanks again

2 Answers

You will need 2 javascript functions.

  1. setTimeout()
    https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval
    This will call a function at an interval
  2. fetch()
    https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
    This make an http call to the server

Example

<script>
var myDiv = document.getElementById('serverStatus');
  setInterval(function() {
    fetch('status.php').then(response=>response.text()).then(function(text){
      myDiv.style.backgroundColor = text;
    })
  }, 1000) // in milliseconds
</script>

or if you are feeling adventurous:

const myDiv = document.getElementById('serverStatus');
setInterval(async () =>
  myDiv.style.backgroundColor = await (await fetch('status.php')).text(),
  1000 // ms
);

your status.php only needs to return the color code

You can do this using javascript.

Add an ID to your <div>, lets say <div id="serverStatus" style="height: 20px; background-color: <?php echo getStatus()?>;">, and then add a timed function to a <script> section at the bottom:

<script>
    setInterval(doSomething, 5000); // Time in milliseconds 
</script>

Then create the js for calling the PHP function and updating the background color:

<script>
    async function doSomething() {
        await fetch('myPhpFile.php', { 
            method: "POST", 
            body: new URLSearchParams("function=serverStatus")
        })
        .then(response => response.text())
        .then((response) => {
            document.getElementById('serverStatus').style.backgroundColor = response; //set the response from the php function as the background color
        })
        .catch(err => console.log('s/g went wrong', err));
    }
</script>

This will use the Fetch API to run a function in a PHP file called "myPhpFile.php". I formulated this as below, using your PHP from above and only adding checks to see that this is the function you are calling:

<?php
    If(isset($_POST['function'])) { //checks that the parameter function is set
        if($_POST['function']=="serverStatus") { //checks that this is the function asked for
            $status = "#008000";
            $latestFile = '/my/web/logs/logging_rotation.out';
    
            if (file_exists($latestFile)) {
                $fileTime = filectime($latestFile);
                $now = microtime(true);
                $timediff = $now - $fileTime;
            }
            if ($timediff < 60) {
                $status = "#008000";
            } else {
                $status = "#FF0000";
            }
            exit($status); //return the result to the JS
        }
    }
?>

I'll note that I have not tested the PHP function you are using to get the filetime, but the javascript is one that is in use, as well as the basic model of the php.

Related