cron alternative php tip - php

i got a file fetch.php
for now i am manually calling it from a bookmark once a day to execute the script.
i want to set kind of like a cron..that just goes to fetch.php once a day..
is it possible..
the fetch.php file has a html and bunch of javascript thats why cron doesn't work..
thanks... if you need clarification let me know..

in the crontab you can run it with a lynx command
example :
lynx -dump http://your.website.com > /dev/null
EDIT:
the problem is that lynxs not run javascript.
so you need to find a command line web browser that support javascript , it Not quite simple.
check a 'links' or 'w3m'
read more about in this post :
http://www.linuxquestions.org/questions/linux-software-2/is-there-a-browser-command-line-tool-for-testing-javascript-websites-359260/

Since JavaScript has to be executed, it sounds like it has to be run in a browser. Unless you're willing to add a lot more complexity, I'd go with one of these routes:
Use cron or Task Scheduler to launch the page in a web browser. Use javascript to have the page close itself (its tab) after it's loaded.
cron: * 9 * * * /usr/bin/firefox "http://localhost/cron.php" (may or may not work)
JavaScript: function all_done() { window.close(); }
Leave a tab open 24/7 and use ReloadEvery or something similar.

Related

Execute multipe PHP scripts simultaneously

Okay I have 50 php scripts each of which will take 20 days to finish I want to write a PHP script to run these 50 scripts simultaneously I did use exec() function in my script but the problem is it runs first script and wait until it is finished before executing the next script. I want to run all of them in parallel.Is there any way to do that?
Thanks
Okay thanks I got my answer after a lot of search
Apart from adding a &, you also need to redirect output to somewhere - otherwise your php process waits until the other process finished, because there could be more output:
exec('/path/to/program & > /dev/null 2>&1')
You put a & between scripts
php /var/www/script1.php & php /var/www/script2.php ........
if have to use only php, more "php'iish" way to do this is Robo (https://robo.li) it is used with codeception, for example.

php background script

Here is my problem : I have an application that allows users to synchronize their data with social networks. The problem is that each synchronization can take up to 10 seconds. So I would like to trigger the synchronization in "background" task, and if possible parallelize all synchronisation.
Currently, my script looks like :
$user = user::login($username, $password);
/* Do some treatments, display the home page */
$user->synchronize();
/* END OF LOGIN SCRIPT */
and in my user.class.php, I have something like
public function synchronize(){
$Networks = socialNetworks::getByUserId($this->userid);
foreach($Networks as $n) $n->synchronize();
}
and finally in the socialNetworks.class.php, I have implemented all the synchronization scripts for each social network (fb, linkedin, google+, ...).
Note that I don't need to wait for the result of the synchronization when logging in.
So I have 2 problems here :
when calling $user->synchronize(); the login script is blocked until the end of the loop
the loop itself is very long, and I would like to launch parallel "threads", to make it faster when calling the synchronize() method (I have some Ajax triggering this action).
What would you suggest to optimize this ?
Thanks.
One option is to use Gearman, and offload this work to it's workers.
You basically create a PHP script that does some work. Then you tell it to do that work from your login script, and the work will be done in the background outside of the request.
Her is an blog post about asynchronous processing with php:
http://robert.accettura.com/blog/2006/09/14/asynchronous-processing-with-php/
<?php
include 'AsynchronousProcessing.php'
launchBackgroundProcess('php /path/to/task1.php');
launchBackgroundProcess('php /path/to/task2.php');
$class->SomeWork();
$class->SomeOtherWork();
?>
There are 2 ways.
Use exec() to make multiple syscalls like exec("php /path/to/script?networkId=1 > /dev/null 2>/dev/null &")
use pcntl_fork() function which works only in Linux.

Yii framework async request

I have ajax request that do 3 missions:
Save Model (DB)
Send Email
Give success or failed message.
Because this mission takes too time. User can wait up to 20 sec for response (success or failed message). And if the user close the browser its stop in one of the operation that current process for the user.
This is bad user experience.
I want user submit his data to my Controller and after it he will get the "success or failed message". And the process will be completely in the server side and its should support multi sessions.
How can I do that?
#hakre What you gave not reduce the time user wait for respond.
I found the best solution for this:
runactions extension for yii
This is extension let you run from controller background actions.
There are several way to use it. The best one for my case is this
public function actionTimeConsumingProcess()
{
if (ERunActions::runBackground())
{
//do all the stuff that should work in background
mail->send()
}
else
{
//this code will be executed immediately
//echo 'Time-consuming process has been started'
//user->setFlash ...render ... redirect,
}
//User information
echo "Submit Success!"
}
And its work but without ajax request, When I make ajax request its not working for some reason.
So I used:
ERunActions::httpPOST($this->createAbsoluteUrl('Form/Submit'), array('to'=>'mail#domain.com', 'subject'=>'This is the subject'));
And its work great but its not the ideal solution for this.
The problem about runactions extension is that it works only with unauthenticated users, you may use the yii backjob extension, but this will require the use of some kind of non-blocking session storage, such as CHttpDbSession.
I am still looking for the right way to do this...
I found one of the best options is to run a server backgroud job:
/usr/bin/php -q longProcess.php > /dev/null 2>&1 &
However, I still need to know how to pass controller and action in cmd line and allow yii to actually use it, something like
/usr/bin/php -q yii-index.php controller action > /dev/null 2>&1 &
Update: I found out the best way is to use a yii console application and run it as a background job. the link below helped a lot:
Yii cron jobs
I use this code now and it is working perfectly:
exec("nohup /protected/yiic mycommand /dev/null 2>&1 &")

Running a second PHP script while keeping the client on same page

I'm creating a app that requires me to run a second php script while the first script is still running.
I'm new to php programing so I'm sure there's a simple function I can use that I'm just not aware of.
Looking forward to any help...
Shane
Since you are new to PHP I'm guessing you're looking for the include/require (and include_once/require_once) language constructs which will execute another PHP script as if it is part of the current script.
Otherwise if you want it to run as a separate process look into exec, shell_exec, or backticks. If you need the other PHP script to run as a background process make sure to redirect stdout somewhere (a file or maybe /dev/null if you don't need it) so that your currently executing script doesn't have to wait for it to finish to continue executing.
This will actually require us to use some Javascript for an ajax call to execute our PHP and return it's data.
I prefer Jquery, which will look similar to this:
function callPHP(){
$.post('./filetocall.php', {variableid: 'id'}, function (response) {
$("#div_for_return_data").val(response);
});
}
filetocall.php can look like anything. It's output will populate the #div_for_return_data
eg:
<?php echo $_GET['variableid']; ?>
Then just call the Jquery function from anywhere.

how to call a function in PHP after 10 seconds of the page load (Not using HTML)

Is there any way to call a function 10 seconds after the page load in PHP. (Not using HTML.)
PHP is a server side scripting language. If you need to check if something has loaded already in the client side, you will need a client-side scripting language like JavaScript.
You might need to use jQuery for your purpose to simplify things.
jQuery is a
slow JavaScript
Library that simplifies HTML document
traversing, event handling, animating,
and Ajax interactions for rapid web
development. jQuery is designed to
change the way that you write
JavaScript.
First, download jQuery. In the head tag of your HTML, add this:
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
// Check if the page has loaded completely
$(document).ready( function() {
setTimeout( function() {
$('#some_id').load('index.php');
}, 10000);
});
</script>
In the body of your HTML, add this:
<div id="some_id"></div>
Not really, no. 10 seconds after your page loaded is (at least) 10 seconds after your PHP script finished, i.e. it is no longer running (apart from tricks that try keeping the connection open, which I don't think will work for a time as long as 10 seconds)!
Therefore, you either need to schedule a cron job on the server side to fire in 10 seconds, or you need a callback from the website, using AJAX.
If I interpret your question as "My page takes a long time to generate, now can I call a PHP function every 10 seconds while it generates" then there are several ways you can approach this...
Time your loop, do something after 10 seconds of work...
$nexttick=time()+10;
$active=true;
while ($active)
{
if (time()>=$nexttick)
{
my_tick_function();
$nexttick=time()+10;
}
//now do some useful processing
$active=do_some_work();
}
It's possible to use a technique like this to implement a progress meter for long running operations, by having your "tick" function output some javascript to update the HTML representing a progress meter.
Using pcntl_alarm...
Alternatively, if you have the Process Control support enabled in your build of PHP, you might be able to use pcntl_alarm to call a signal handler after a certain amount of time has elapsed.
Using ticks...
You can use the declare construct along with register_tick_function to have the PHP engine call your function every x 'ticks'. From the manual:
A tick is an event that occurs for
every N low-level tickable statements
executed by the parser within the
declare block. The value for N is
specified using ticks=N within the
declare blocks's directive section.
This seems weird idea but maybe it's what you are looking for if you want to do it in PHP without touching HTML/JS:
<?php
your_website_here();
flush(); //this sends the output to the client. You may also need ob_flush();
sleep(10); //wait 10 seconds
your_func_here();
?>
The above is preety OK in theory, but in practice it will result in VERY memory consuming app. So be warned.
if you mean after the page has loaded you will need to use javascript/ajax/jquery to do so.
If you really must do it within the same PHP script, the cleanest way would be a fork.
Or if that's not possible, here's a really bad hackish way of doing it:
<?php
ignore_user_abort(1);
page_output_stuff();
// ...
flush();
sleep(10);
do_something_after_script();
?>
If you're doing this to output stuff to the user after a delay, the above can be made to work but it's a really ugly way of doing it. Just use AJAX instead.
This code works. Edited from randell's answer.
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
setTimeout(function() { $('#some_id').load('index.php'); }, 10000);
});
</script>
Thanks to randell
There's no way you can do it with PHP, except maybe using some crontab / loop with sleep() and file_get_contents(). Or use javascript/ajax as previously mentioned.
Php is a servide scripting language, and can't detect if the page is loaded or not. so you have to use client side script javascript.
The closest think I can think of is :
Once your script has finish to execute, it saves an entry in a databases with the time. Then, a daemon (cron style) execute every second each instruction in the databases that is older than 10 seconds.
I wanted to do the same thing, to be notified at each hit my resume got.
With flush() after all data sent then the DB and mail operations: the page on the client is fully rendered but the downloading progress bar is still present until the script is fully terminated.
I wanted to keep the whole stuff server-side (to allow the generated HTML file to be cleanly usable offline without giving errors) so JS wasn't an option.
I eventually ended simply appending a line with parameters to a text file, add a cron job every minute that compares this file size with the latest sent version and this bash script handles all the lenghty functions while the 9k page still loads and renders in a fraction of a second.
Unfortunately this method still has a up to 1 minute delay but still simple:
#!/bin/sh
FLOG=/home/web/traceur/cvaccess.txt
if [ -e $FLOG ]; then
if [ ! -e $FLOG.sent ]; then touch $FLOG.sent; fi;
SENT_LINES=$(wc -l $FLOG.sent | cut -d " " -f 1)
# No disk write if no new-data
if [ $(wc -l $FLOG | cut -d " " -f 1) -gt $SENT_LINES ]; then
cp -f $FLOG $FLOG.intr
NEW_LINES=$(wc -l $FLOG.intr | cut -d " " -f 1)
TO_SEND=$(( $NEW_LINES - $SENT_LINES ))
tail -n $TO_SEND $FLOG.intr > $FLOG.diff
mailx -s "Nouvelle consultation du CV" -r "HAL <hal#jmd-tech.com>" jmarodon#jmd-tech.com < $FLOG.diff
rm $FLOG.diff
mv -f $FLOG.intr $FLOG.sent
fi
fi
And the page is at:
http://www.jmd-tech.com/cv-julien-marodon.html, the PHP code is nothing more than those 3 lines at the end of the previously plain HTML file:
<?php
// Enregistrement log
$ligne=$_SERVER["REMOTE_ADDR"]."\t".$_SERVER["HTTP_USER_AGENT"]."\t".$_SERVER["HTTP_REFERER"]."\t".date("Y-m-d H:i:s");
$fic=fopen("/home/web/traceur/cvaccess.txt","a");
if ($fic) { fwrite($fic,$ligne."\n"); fclose($fic); }
?>
If i wanted to make a near-instant (<1s) or a 10 second delay version, i think the way to go would be using a daemon instead of a cron job and some kind of inter-process communication, probably a listening socket which the PHP script would fsockopen() for sending data and closing (fast), then the daemon proceeds by himself with lenghty operations.

Categories