I'm pretty new to PHP. This is my first time actually, so I apologize in advance if the question sounds dumb.
I have a php script which fetches data from an external API and updates my database regularly. I know that the best way to do this is to use a cron job. However, I am using an infinite loop which sleeps for a particular time between each update.
Now, I need to allow the user (admin) to start / stop the script and also allow them to change the time interval between each update. The admin does this through a UI. What is the best way to do this? How do I execute the script in the background when the user clicks start and how do I stop the script?
Thanks.
I think the ideal solution would be the following:
Have the background job run as a cronjob every minute (instead of a loop which can cause memory leaks). PHP was not designed to be a daemon.
Set a DB flag in the cronjob for on/off, everytime it runs it checks if its on or off, if off it exists if on it continue.
In the UI you turn that flag on or off depending on what the admin needs.
I think that is the best way to go (and easiest).
You might want to take a look at Threading in PHP -> http://www.php.net/manual/en/class.thread.php
An other option is to either set a SESSION (which is a little tricky, since you won't catch it in the same call) or you generate a file wich tells the script to stop/exit/fail/what ever if that file exists.
Related
I have a PHP script to pull user specific data from a 3rd party source and dump it into a local table, which I want to execute every X mins when a user is logged in, but it takes about 30 seconds to run, which I don't want the user to experience. I figured the best way of doing this would be to timestamp each successful pull, then place some code in every page footer that checks the last pull and executes the PHP script in the background if it was more than X minutes ago.
I don't want to use a cron job to do this, as there are global and session variables specific to the user that I need when executing the pull script.
I can see that popen() would allow me to run the PHP script, but I can't seem to find any information relating to whether this would be run as the visitor within their session (and therefore with access to the user specific global or session variables) or as a separate session altogether.
Will popen() solve my problem?
Am I going about this the right way or is there a better method to execute the script at intervals while the user is logged in?
Any help or advice is much appreciated, as always!
Cheers
Andy
Maybe an idea to put the session data also in a table.
That way you can easily access it from your background process. You only have to pass the session_id() or the user id as argument so the process knows which user it is currently processing.
No, because PHP still needs to wait on the process started by popen() before it can exit
Probably not, because the solution doesn't fit the architectural constraints of the system
Your reasoning for not using a cron job isn't actually sound. You may have given up on exploring that particular path too quickly and drawn yourself into a corner with trying to fit a square peg in a round hole.
The real problem you're having is figuring out how to do inter-process communication between the web-request and the PHP running from your crontab. This can be solved in a number of ways, and more easily then trying to work against PHP's architectural constraints.
For example, you can store the session ids in your database or some other storage, and access the session files from the PHP script running in your crontab, independently of the web request.
Let's say you determine that a user is logged in based on the last request they made to your server by storing this information in some data store as a timestamp, along with the current session id in the user table.
The cron job can startup every X minutes, look at the database or persistence store for any records that have an active timestamp within the given range, pull those session ids and do what's needed.
Now the question of how do you actually get this to scale effectively if the processing time takes more than 30 seconds can be solved independently as well. See this answer for more details on how to deal with distributed job managers/queues from PHP.
I would use Javascript and AJAX requests to call the script from the frontend and handle the result.
You could then set the interval in JavaScript and send an AJAX-Request each interval tick.
AJAX is what you need:
http://api.jquery.com/jquery.ajax/
The use the method "success" to do something after those 30 seconds.
ok, now i have 3 files, which is update_XML.php, showXML.html and data.xml.
i use the update_XML.php to update the data in data.xml, then i use showXML.html to display the data.
my question is how should i call the update_xml.php to update the data.xml automtically?
i only manage to do it manually.
what already in my mind is only use timeout() in html to refresh the showXML.html
but how about the updating part ? use timeout() function too?
i need some advice about this, especially a correct flow.
thx
Depending on if your website is accessible to just you or not, if it's not update_XML.php will be called for every user when using setTimeout();, also JS can be disabled.
Your option is setting up a cron job on your server.
cron jobs are basicly automated tasks on a scheduled base depending on how often you want this cron job to be executed.
Here is some documentation on cronjobs
NOTE this is a tutorial for *nix systems.
I have a MVC framework with a controller in it. A controller downloads images from server. I need to refresh my database with those images every 5 minutes. So, I planned to create php script which downloads the file and persists it to my database. In order to do this every 5 minutes. I will be setting up Cron job.
Now the question is,
What is the best practise to handle errors inside php script?
Because Cron will keep executing at every 5 minutes without knowing that the last queried image is already lost and not being saved.
How do I notify myself that something unusual happend and I need to maintain the DB consistency by my self (Which I don't mind for few instances).
What is the best practise to handle errors inside php script? Because
Cron will keep executing at every 5 minutes without knowing that the
last queried image is already lost and not being saved.
use asserts as described here: http://php.net/manual/en/function.assert.php
How do I notify myself that something unusual happend and I need to
maintain the DB consistency by my self (Which I don't mind for few
instances).
use mail() in asserts
Use try-catch along with database transactions (if possible). You can dump errors to error_log() and either set that up to generate email or add email to your error handler.
In addition to the other comments. I have often found it useful in cron scripts that could run into problems or take longer than the desired execution interval to where multiple execution instances could be running, to provide some text file that indicates last execution time, execution success, etc. that you can inspect to determine if the script should run as scheduled. It could be something as simple as writing a file at script start and deleting it on successful execution, and then checking for this file on next execution to decide whether to run or not.
How can I make a scheduler in PHP without writing a cron script? Is there any standard solution?
Feature [For example]: sent remainder to all subscriber 24hrs b4 the subscription expires.
The standard solution is to use cron on Unix-like operating systems and Scheduled Tasks on Windows.
If you don't want to use cron, I suppose you could try to rig something up using at. But it is difficult to imagine a situation where cron is a problem but at is A-OK.
The solution I see is a loop (for or while) and a sleep(3600*24);
Execute it through a sending ajax call every set interval of yours through javascript
Please read my final opinion at the bottom before rushing to implement.
Cron really is the best way to schedule things. It's simple, effective and widely available.
Having said that, if cron is not available or you absolutely don't want to use it, two general approaches for a non-cron, Apache/PHP pseudo cron running on a traditional web server, is as follows.
Check using a loadable resource
Embed an image/script/stylesheet/other somewhere on each web page. Images are probably the best supported by browsers (if javascript is turned off there's no guarantee that the browser will even load .js source files). This page will send headers and empty data back to the browser (a 1x1 clear .gif is fine - look at fpassthru)
from the php manual notes
<?php
header("Content-Length: 0");
header("Connection: close");
flush();
// browser should be disconnected at this point
// and you can do your "cron" work here
?>
Check on each page load
For each task you want to automate, you would create some sort of callable API - static OOP, function calls - whatever. On each request you check to see if there is any work to do for a given task. This is similar to the above except you don't use a separate URL for the script. This could mean that the page takes a long time to load while the work is being performed.
This would involve a select query to your database on either a task table that records the last time a task has run, or simply directly on the data in question, in your example, perhaps on a subscription table.
Final opinion
You really shouldn't reinvent the wheel on this if possible. Cron is very easy to set up.
However, even if you decide that, in your opinion, cron is not easy to set up, consider this: for each and every page load on your site, you will be incurring the overhead of checking to see what needs to be done. True cron, on the other hand, will execute command line PHP on the schedule you set up (hourly, etc) which means your server is running the task checking code much less frequently.
Biggest potential problem without true cron
You run the risk of not having enough traffic to your site to actually get updates happening frequently enough.
Create a table of cronjob. In which keep the dates of cron job. Keep a condition, if today date is equal to the date in the creonjob table. then call for a method to execute. This works fine like CRON job.
Is it possible to run a php script after every 100ms ? This script will check a database for changes and then the changes will be reflected into some other database. I am already doing it using Triggers. But I want to know if there is any other way to do it without using Cron and Triggers. I will be using Linux for this purpose.
Thanks
Running something every 100ms almost means that it runs all the time , might as well create a daemon that continuously loops and executes
or use triggers. Essentially on every database change it will copy to another table/db.
http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/
It is not possible to do this with cron (it has a max frequency of one minute) and this is a really bad idea. You will be running a whole new php interpreter ten times per second, not to mention doing database connection too.
Far better perhaps would be to run one program that re-uses it's connection and checks every second or so.
Sounds a little like you are trying to make your own database replication or sync between two databases.
You could write a daemon to do it, essentially a script which continually runs in memory somewhere to then run whatever code you want to.
So that daemon would then do the database processing for you, and you wouldn't have to call a script over and over again.
Use your favorite programming language and set up a permanent loop to run it every 100ms, then put the script into inittab with 'respawn' (man inittab for complete syntax). Finally, init q to reload init.
It's best if you write a little daemon for that. Use the pcntl functions to do so. In your case you might get away with:
<?php
while (1) {
usleep(100000);
if (pcntl_fork() == 0) {
include("/lib/100ms-script.php");
exit;
}
// else pcntl_wait(); eventually
}
I'm assuming that this is in reference to some type of web page to be created. If so, this sounds like this is a job for Ajax, not PHP. As you may already know PHP processing is done on the server side. Once processing is complete the page is served up to the client.
With Ajax/JavaScript processing can continue via the browser. You can setup a timer that can then be used to communicate with the server. Depending on the output of the response the page may be updated to reflect the necessary changes.