📜 ⬆️ ⬇️

Background script execution in PHP without crontab

Puzzled me here to write a demon in PHP. Those. a script that will be given a number of times in a given number of hours at a random time (always random) to perform certain actions, and all this without using cron.

I have never bothered before, but after setting the task, I began to think that it was impossible so that the php script should be called by the browser ... well, the task is set, it must be done.

The first thought is to disable the script execution time limit. Forbidden hoster.
')
The second thought is to repeat the Ajax request periodically (yes at least once a second). - it is impossible (the requirement of the customer).

It turned out, in fact, that the browser should not be opened, and cron cannot be used, and the script should work independently of the user, indefinitely. Naturally, he should at least ship the system.

1. A pack of cigarettes, night, google, docks, books, manuals ....
goto 1 ...

At the exit I get:
Task_1:
Implement the script execution time generator based on the specified number of times and the number of hours. Keep somewhere these times.

Task_2:
Work after closing browser

Task_3:
Do not crash after the end of the script time limit

Task_4:
Perform some actions at the right time.

So…
We write the initial data in the config:

session_start(); //   $num_starts = 120; //       $hours = 1; //  ,       $num_starts . $time_sec = $hours*3600; //      $time_to_start = array(); // ,     ignore_user_abort(1); //      


Next, write a function that will help us generate launch times.
In it, we generate a random number from 0 to the number of seconds in the original interval.
 /****** * @desc    . */ function add_time2start() { global $time_sec, $time_to_start; $new_time = time()+rand(0, $time_sec); if (!in_array($new_time, $time_to_start)) { //       -  $time_to_start[] = $new_time; } else { add_time2start(); //      -  . } } 


Next, we will generate and write to the session an array of launch times. Pre-sort the array in ascending order, so that the early time first went on (I did not manage to create a time machine yet).

 $k = 1; if ($_SESSION["num_st"] == "" || $_SESSION["num_st"][$num_starts-1] < time()) { // ,            . do { add_time2start($k); $k++; } while ($k < = $num_starts); sort($time_to_start, SORT_NUMERIC); $_SESSION["num_st"] = $time_to_start; } 


Now we need to make the script work, not paying attention to the maximum execution time set by the server.
The principle is:
1) Determine the start time of the script;
2) We determine the established limit on the execution time.
3) We start the cycle, inside which we count the current time and calculate the total script operation time, check the current time with the values ​​in the start-up time array, and if there is a match, perform the specified actions (I have them in the exec.php file). To run the files use sockets.
4) Repeat the cycle until the script running time is close to the maximum allowed. I set - until the maximum time will be 5 seconds.

So ... we consider the initial data on time:

 $start_time = microtime(); //     $start_array = explode(" ",$start_time); //     $start_time = $start_array[1]; //     $max_exec = ini_get("max_execution_time"); //      

Actually, the cycle. Comments in the code.

 do{ $nowtime = time(); //   ////          ...... if (in_array($nowtime, $_SESSION["num_st"])) { //         $http = fsockopen('test.ru',80); ///            fputs($http, "GET http://test.ru/exec.php?".session_name()."=".session_id()."&nowtime=$nowtime HTTP/1.0\r\n"); fputs($http, "Host: test.ru\r\n"); fputs($http, "\r\n"); fclose($http); } ////    //     ,       $now_time = microtime(); $now_array = explode(" ",$now_time); $now_time = $now_array[1]; //       $exec_time = $now_time - $start_time+$exec_time; ///    usleep(1000000); // ,    .     . if (file_exists("stop.txt")) exit; //  ,      //  5 ,   . } while($exec_time < ($max_exec - 5)); 


Well, if the allowed time comes to an end, then we end the cycle and safely run the same script by the other process (in 5 seconds we’ll just keep within)

 //           $http = fsockopen('test.ru',80); fputs($http, "GET http://test.ru/index.php?".session_name()."=".session_id()."&bu=$max_exec HTTP/1.0\r\n"); fputs($http, "Host: test.ru\r\n"); fputs($http, "\r\n"); fclose($http); 


Actually, it's done.
Then I had a lot of problems in the performance of the very actions - there it was necessary to write a robot to search for links on the specified links.

When I added everything, I was puzzled by a useful application ... You can use it as a service. He can monitor something on the network and notify you, for example, by mail. And do not need any cron'ov.

The script can still be optimized - it did not work on the revision.
By the way, this is what I could not tear myself away from - the browser will still have to be opened in order to initially run the script.

Source: https://habr.com/ru/post/132609/


All Articles