Kirill Kirill - 3 months ago 16
PHP Question

Monitor a webpage behind authentification for a text

Here is the deal. I have a requirement to monitor certain password-protected webpage for changes and play sound alarm when size of the page is different from what I know (i.e. it was modified).
Here is the chunk of code that i've come up with.

<?php

$e = curl_init();
curl_setopt($e, CURLOPT_URL, 'http://example.com/Account/LogOn');
curl_setopt($e, CURLOPT_POST, 1);
curl_setopt($e, CURLOPT_POSTFIELDS, 'UserName=xxx@example.com&Password=password');
curl_setopt($e, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($e, CURLOPT_REFERER, 'http://example.com');
curl_setopt($e, CURLOPT_RETURNTRANSFER, 1);
curl_exec($e);

$sizevalue = 2399;

do {
curl_setopt($e, CURLOPT_URL, 'http://example.com/panel.php');
$content = curl_exec($e);
$numberofchars = strlen($content);
sleep(15);
} while ($numberofchars = $sizevalue);

curl_close($e);
echo '
<audio controls="controls" autoplay="autoplay">
<source src="/path/to/your/audio.mp3" type="audio/mp3">
<source src="/path/to/your/audio.ogg" type="audio/ogg">
<embed src="/path/to/your/audio.mp3">
</audio>';
php?>


Problem 1. Correct me if I am wrong, but as I understand, instead of connecting server, posting username and password only once, leaving the connection alive and using that auth key from
cookie.txt
for later actions it constantly sends the username and password to the login form for every turn of the cycle. How do I fix this?

Problem 2. I need the script to give me some temporary status because at the moment if certain condition is not met it basically turns into infinite loop and server hosting the script gives me timeout error.

Problem 3. What would be the simplest way to implement sound alarm? OGG file playback? Youtube redirection?

Answer

Problem 1: curl_multi_exec is not really necessary in your case. Keeping the curl handle open should suffice.

Problem 2: sleep() or usleep() works well for this purpose

Problem 3: You could just output html markup. Another option is to embed a flash file or video that plays an alarm sound automatically. Depends where this is running and for what purpose.

Note, scripts like this are not best run in the browser. It's better to setup a cron script that checks urls at set intervals and does not use do while loops or sleep.

Here's your code written with these corrections and a few examples.

<?php
set_time_limit(0); // this script will now run forever. but a safer value might be something like X hours or X number of minutes. 
$e = curl_init();
curl_setopt($e, CURLOPT_URL, 'http://example.com/Account/LogOn');
curl_setopt($e, CURLOPT_POST, true);
curl_setopt($e, CURLOPT_POSTFIELDS, 'UserName=xxx@example.com&Password=password');
// you'll need both CURLOPT_COOKIEJAR and CURLOPT_COOKIEFILE if you plan on NOT using curl's internal cookie handling
curl_setopt($e, CURLOPT_COOKIEJAR, 'cookie.txt'); // this is where we write the cookie data
curl_setopt($e, CURLOPT_COOKIEFILE, 'cookie.txt'); // this is where we read the cookie data to use
curl_setopt($e, CURLOPT_REFERER, 'http://example.com/');
curl_setopt($e, CURLOPT_RETURNTRANSFER, true);
// you can omit the next two lines if you think they won't be needed
curl_setopt($e, CURLOPT_FOLLOWLOCATION, true); // in case the remote server does some kind of http redirection, like a 301 redirect
curl_setopt($e, CURLOPT_MAXREDIRS, 3); // The maximum amount of HTTP redirections to follow, in case the remote server is badly configured and has an endless redirection loop
curl_exec($e);

$sizevalue = 2399;
$maximum_checks = 30; // I've added this as a cap for the loop, so that you only run it this many times.
$checks = 0;
$seconds = 15;

do {
     $checks++;
     curl_setopt($e, CURLOPT_URL, 'http://example.com/panel.php');
     $content = curl_exec($e);

     $numberofchars = strlen($content);

     // optionally... instead of the strlen method above you could also use 
     // http://php.net/manual/en/function.curl-getinfo.php
     if (!curl_errno($e)) {
        $info = curl_getinfo($e);
        echo 'content-length of download, read from Content-Length: field :' . $info['download_content_length']."<br>\n";
        $numberofchars = $info['download_content_length'];
     }
     if ($checks === $maximum_checks) {
        exit('No changes after '.($seconds * $maximum_checks).' seconds<br>'.PHP_EOL);
     }
     sleep($seconds); // wait for 15 seconds

} while ($numberofchars != $sizevalue); // fix up your TRUTH expression, don't forget it is != for proper comparison in your case. Without it you go into an infinite loop.

curl_close($e); 

// if our php script got this far then 
echo '
<audio controls="controls" autoplay="autoplay">
  <source src="/path/to/your/audio.mp3" type="audio/mp3">
  <source src="/path/to/your/audio.ogg" type="audio/ogg">
  <embed src="/path/to/your/audio.mp3">
</audio>';


?>