6

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?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Kirill
  • 63
  • 4

1 Answers1

1

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>';


?>
Kenster
  • 23,465
  • 21
  • 80
  • 106
Anthony Hatzopoulos
  • 10,437
  • 2
  • 40
  • 57
  • wow, great contribution. But here's two things: 1. Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set in /home/a5983399/public_html/mainest.php on line 13 – Kirill Dec 11 '12 at 17:49
  • and secondly, i think server timeout is at 60 secs, and i want this script to run for hours. How can i bypass this? – Kirill Dec 11 '12 at 17:52
  • CURLOPT_FOLLOWLOCATION is disabled because your server php is running with [`safe_mode`](http://php.net/manual/en/features.safe-mode.php) enabled or with [`open_basedir`](http://php.net/manual/en/ini.core.php#ini.open-basedir). You can disable those settings but you'll need administrative privlidges. If you don't know about this try asking your web host company to change it. As for the 60 second wait. You can use [`set_time_limit`](http://php.net/manual/en/function.set-time-limit.php). I've updated the code. – Anthony Hatzopoulos Dec 11 '12 at 17:58
  • `while ($numberofchars != $sizevalue);` //infinite loop is exactly what i need. it should run as long as the fetched site hasn't been changed i.e. size is the same. When something is added or removed, audio should kick in. Also the timeout problem is not with the target server, it's with webhosting i am using, so it runs 4 15-second checks and times out. – Kirill Dec 11 '12 at 18:20
  • `Error 324 (net::ERR_EMPTY_RESPONSE): The server closed the connection without sending any data.` I think I now realised that I chose wrong solution because of time-out limitation. While the target server allows to be connected for unlimited amount of time, hosting running the php script doesn't. – Kirill Dec 11 '12 at 18:44
  • the while loop should be fine the way i have it... as for your timeouts (it could be the local server or the remove server) check this too http://stackoverflow.com/questions/2582057/setting-curls-timeout-in-php – Anthony Hatzopoulos Dec 11 '12 at 18:46
  • It's definitely a browser timeout. Changed Mozilla's settings a little. You've been a great help. – Kirill Dec 11 '12 at 19:17