Schedule scripts without using CRON

2019-02-06 08:45发布

I know there are many posts about using CRON to run a php file. But, in the world of shared hosting, and ease of setup for a user, I don't want to have to mess with that.

I found another solution online that has to do with sockets. Just wanted to get everyones take on this, and tell me if this is a good or bad idea. Sounds like it works well.

Thoughts?

//Open socket connection to cron.php
$socketcon = fsockopen($_SERVER['HTTP_HOST'],80,$errorno,$errorstr,10);
if($socketcon) {
$socketdata = "GET /cron.php HTTP 1.1\r\nHost: ".$_SERVER['HTTP_HOST']."\r\nConnection: Close\r\n\r\n";
fwrite($socketcon,$socketdata);
//Normally you would get all the data back with fgets and wait until $socketcon reaches feof.
//In this case, we just do this:
fclose($socketcon);
} else {
//something went wrong. Put your error handler here.
}

cron.php:

//This script does all the work.
sleep(200);
//To prove that this works we will create an empty file here, after the sleep is done.
//Make sure that the webserver can write in the directory you're testing this file in.
$handle = fopen('test.txt','w');
fclose($handle);

Found the script from a blog post: http://syn.ac/tech/13/creating-php-cronjobs-without-cron-and-php-cli/

7条回答
姐就是有狂的资本
2楼-- · 2019-02-06 09:03

It's not a bad method, but you need to ensure that by closing the socket it isn't just terminating the script before it finishes. You can set sockets to non-blocking.

I would still use a cron job, even if it is a bit of a pain.

查看更多
地球回转人心会变
3楼-- · 2019-02-06 09:05

Thats a functional but weird solution that assures you need to have your machine connected all the day running the first script. If you want that, I would recommend you to use a shell script using wget or curl for that purpose.

For example:

#!/bin/sh

curl -O http://www.myserver.com/cron.php 2>&1 > /var/log/remote.cron.log

But I think the solution you would love to implement if you dont have to run very syncronizedly is a check in the end of your index.php to see when it ran the script the last time, if it was more than two hours ago, then include('cron.php'). You can also store the timestamp of when ran the script in an environmental variable, to avoid performance penalty.

查看更多
神经病院院长
4楼-- · 2019-02-06 09:07

It took me several days to find a working solution without having race conditions and/or flooding my own server, but finally I think this should work:
http://www.programmierer-forum.de/phpcron-cronjobs-ohne-crontab-t348377.htm

查看更多
何必那么认真
5楼-- · 2019-02-06 09:09

This produces a different effect than cron.

A cron job runs during certain times which you have set ahead of time.

Your method basically is a kind of "fork" or "asynchronous call" to a PHP script. Doing it via HTTP like you are doing here is a cheap and easy technique. I use it myself. It's different from cron in that it launches the "background process" immediately.

A few comments, though:

  1. First of all, you should be calling ignore_user_abort() in the "background" script. Otherwise, in many environments your script will be aborted when the "calling" script closes the socket.

  2. Secondly, you can actually check the $_SERVER['HOST'] variable in the "background" script, and in this way you can have scripts which are not exposed to the internet (basically issue requests to localhost and check for that in the background script). You can then presumably trust requests coming from your own machine, and skip all the security checks, sessions, and so forth.

  3. Thirdly, who says that the "background" script has to be run with PHP? PHP has a lot of weaknesses if you are going to use it as a "background" process. The main weakness is that it blocks on I/O. So if you are going to be sending emails, updating database rows, or whatever, you are basically pausing your script every time you send a request. Whereas with Node.js, for example, you can fire off I/O commands asynchronously and keep going. If you're going to use PHP, at least make sure to send 10 emails at a time, or update 10 rows at a time, or something.

  4. Finally, you might want to display a progress bar on the browser if a background script is doing something. So you're going to need to use a common data store (like your database) to record the progress for the task.

查看更多
劳资没心,怎么记你
6楼-- · 2019-02-06 09:11

A cron job basically is a cron job. you set it up, and the OS runs the job for you. I am not sure how the PHP script you got from the site works, but if it requires human intervention, then its not really called a cron job. If you don't want to use cron, you can use a loop, then use the date functions of PHP to set up a date and time. Pseudocode

while (1) {
    $d=date("d");
    if ( $d == "01" ){
        //run every 1st of month
        //code to run here
    }
}
查看更多
小情绪 Triste *
7楼-- · 2019-02-06 09:14

As far as I understand from reading that blog post and looking at the code, this is not really a way around not having cron access, this is a way to avoid someone waiting for the server to respond on a long query. If you absolutely must have a certain script executed say every 10 minutes or so, then you'll need to use cron . If you just want to avoid having users wait for a long query to finish then this hack might work. Even with this method, I still think you're going to hit time limits if your script takes longer than what PHP allows to finish.

Reviewing wp-cron.php(mentioned in the blog link), it looks as though it is relying entirely on users visiting the site to trigger checks against a timestamped set of jobs.

These techniques are not going to be very reliable unless you have another server pinging at specific intervals. The main goal of the technique is to avoid a user waiting say like 15 seconds for clean-up or maintenance scripts to run every once in awhile, rather than a true replacement for all uses of cron.

查看更多
登录 后发表回答