I have a PHP that receives a parameter (for example 4000) it uses to query a DB with. After executing whatever it needs to do, I want the PHP to call itself so it can do the exact same thing but this time with the new value (for example 8000). Ofocurse I need the first instance to stop/exit/halt.
How can I do this? Include is irrelevant and exec is good for other types of execution (unless I'm wrong here)
Thanks
If you are not required to output anything from the script, you could do the following:
Perform the task while not running into script timeout
Set a location header to the script itself with modified parameters
exit
If you want the script to produce output, you can use the Javascript function location.href instead of the location header. For this, output something like the following snippet at the end of your script:
// php functionality above
?>
<script language="JavaScript">
location.href = "<?php echo $_SERVER['SCRIPT_NAME']; ?>?param=<php echo $param_value; ?>";
</script>
Modify this to fulfill your needs. The header is more suitable for non-interactive setups like the links2 browser, whereas the JavaScript you would use if you want to see whats going on.
You could use recursive functions, which simply means calling the same function from that function. Simple example based on the numbers you gave:
<?php
function do_something( $arg )
{
// Just do something (example)
echo $arg . "\n";
$arg = $arg + 4000;
// Stop doing it when the argument is above 8000
if( $arg > 8000 )
{
return;
}
// Do it again
do_something( $arg );
}
do_something( 4000 );
You can make the script call itself by using the header() method.
Let's say you want to retrieve a batch of 24 rows at every run of a script named whatever.php.
You tell whatever.php to look out for a $_GET parameter. If there is none, you tell it to start from zero when querying the database ("...LIMIT 24"). After you've done what you needed to use header() method in order to call whatever.php again:
header('Location:whatever.php?offset=25');
Now the whatever.php, when called, will know that it must impose an offset to the sql LIMIT ("...LIMIT 25, 24"). After the script done it's job again, you call it again with the header() method:
header('Location:whatever.php?offset=50');
Hope this helps you...
Related
I have a JavaScript functions which calls a PHP function through AJAX.
The PHP function has a set_time_limit(0) for its purposes.
Is there any way to stop that function when I want, for example with an HTML button event?
I want to explain better the situation:
I have a php file which uses a stream_copy_to_stream($src, $dest) php function to retrieve a stream in my local network. The function has to work until I want: I can stop it at the end of the stream or when I want. So I can use a button to start and a button to stop. The problem is the new instance created by the ajax call, in fact I can't work on it because it is not the function that is recording but it is another instance. I tried MireSVK's suggest but it doesn't worked!
Depending on the function. If it is a while loop checking for certain condition every time, then you could add a condition that is modifiable from outside the script (e.g. make it check for a file, and create / delete that file as required)
It looks like a bad idea, however. Why you want to do it?
var running = true;
function doSomething(){
//do something........
}
setInterval(function(){if(running){doSomething()}},2000); ///this runs do something every 2 seconds
on button click simply set running = false;
Your code looks like:
set_time_limit(0);
while(true==true){//infinite loop
doSomething(); //your code
}
Let's upgrade it
set_time_limit(0);
session_start();
$_SESSION['do_a_loop'] = true;
function should_i_stop_loop(){
#session_start();
if( $_SESSION['do_a_loop'] == false ) {
//let's stop a loop
exit();
}
session_write_close();
}
while(true==true){
doSomething();
should_i_stop_loop(); //your new function
}
Create new file stopit.php
session_start();
$_SESSION['do_a_loop'] = false;
All you have to do now is create a request on stopit.php file (with ajax or something)
Edit code according to your needs, this is point. One of many solutions.
Sorry for my English
Sadly this isn't possible (sort of).
Each time you make an AJAX call to a PHP script the script spawns a new instance of itself. Thus anything you send to it will be sent to a new operation, not the operation you had previously started.
There are a number of workarounds.
Use readystate 3 in AJAX to create a non closing connection to the PHP script, however that isn't supported cross browser and probably won't work in IE (not sure about IE 10).
Look into socket programming in PHP, which allows you to create a script with one instance that you can connect to multiple times.
Have PHP check a third party. I.E have one script running in a loop checking a file or a database, then connect to another script to modify that file or database. The original script can be remotely controlled by what you write to the file/database.
Try another programming language (this is a silly option, but I'm a fan of node). Node.js does this sort of thing very very easily.
I am wanting to call a php file using exec.
When I call it I want to be able to pass a variable through (an id).
I can call echo exec("php /var/www/unity/src/emailer.php"); fine, but the moment I add anything like echo exec("php /var/www/unity/src/emailer.php?id=123"); the exec call fails.
How can I do this?
Your call is failing because you're using a web-style syntax (?parameter=value) with a command-line invokation. I understand what you're thinking, but it simply doesn't work.
You'll want to use $argv instead. See the PHP manual.
To see this in action, write this one-liner to a file:
<?php print_r($argv); ?>
Then invoke it from the command-line with arguments:
php -f /path/to/the/file.php firstparam secondparam
You'll see that $argv contains the name of the script itself as element zero, followed by whatever other parameters you passed in.
try echo exec("php /var/www/unity/src/emailer.php 123"); in your script then read in the commandline parameters.
If you want to pass a GET parameter to it, then it's mandatory to provide a php-cgi binary for invocation:
exec("QUERY_STRING=id=123 php-cgi /var/www/emailer.php");
But this might require more fake CGI environment variables. Hencewhy it is often advisable to rewrite the called script and let it take normal commandline arguments and read them via $_SERVER["argv"].
(You could likewise just fake the php-cgi behaviour with a normal php interpreter and above example by adding parse_str($_SERVER["QUERY_STRING"], $_GET); on top of your script.)
this adapted script shows 2 ways of passing parameters to a php script from a php exec command:
CALLING SCRIPT
<?php
$fileName = '/var/www/ztest/helloworld.php 12';
$options = 'target=13';
exec ("/usr/bin/php -f {$fileName} {$options} > /var/www/ztest/log01.txt 2>&1 &");
echo "ended the calling script";
?>
CALLED SCRIPT
<?php
echo "argv params: ";
print_r($argv);
if ($argv[1]) {echo "got the size right, wilbur! argv element 1: ".$argv[1];}
?>
dont forget to verify execution permissions and to create a log01.txt file with write permissions (your apache user will usually be www-data).
RESULT
argv params: Array
(
[0] => /var/www/ztest/helloworld.php
[1] => 12
[2] => target=13
)
got the size right, wilburargv element 1: 12
choose whatever solution you prefer for passing your parameters, all you need to do is access the argv array and retrieve them in the order that they are passed (file name is the 0 element).
tks #hakre
I know this is an old thread but it helped me solve a problem so I want to offer an expanded solution. I have a php program that is normally called through the web interface and takes a long list of parameters. I wanted to run it in the background with a cron job using shell_exec() and pass a long list of parameters to it. The parameter values change on each run.
Here is my solution: In the calling program I pass a string of parameters that look just like the string a web call would send after the ?. example: sky=blue&roses=red&sun=bright etc. In the called program I check for the existence of $argv[1] and if found I parse the string into the $_GET array. From that point forward the program reads in the parameters just as if they were passed from a web call.
Calling program code:
$pars = escapeshellarg($pars); // must use escapeshellarg()
$output = shell_exec($php_path . ' path/called_program.php ' . $pars); // $pars is the parameter string
Called program code inserted before the $_GET parameters are read:
if(isset($argv[1])){ // if being called from the shell build a $_GET array from the string passed as $argv[1]
$args = explode('&', $argv[1]); // explode the string into an array of Type=Value elements
foreach($args as $arg){
$TV = explode('=', $arg); // now explode each Type and Value into a 2 element array
$_GET[$TV[0]] = $TV[1]; // set the indexes in the $_GET array
}
}
//------------------------
// from this point on the program processes the $_GET array normally just as if it were passed from a web call.
Works great and requires minimal changes to the called program. Hope someone finds it of value.
I have a scenario where in our php file accepts parameters from the command line.
For example we say,
php test.php 'hello'
Now the above runs on command prompt. Suppose now we want to invoke this from client end however ofcourse i do not want the System system call as that would be a bad design, i just want to directly call the function which accepts parameters from the client end and ofcourse client can be anything maybe .Net or PHP so how can I caccomplish that?
Thanks!
Put your script on a web server and accept the argument via HTTP GET or POST.
It would look something like http://hostname/test.php?argument=hello. Then, in your test.phpscript, pass the $_GET['argument'] to your function:
myfunction($_GET['argument']);
Don't forget to sanitize the input!
you may use a function that will manage command line argiments:
$param_1 = isset($argv[1]) ? $argv[1] : null;
if ($param_1 == 'function1')
function1()
elseif...
and so on.
You can make a wrapper script that puts GET parameters from your client into the command line argument array.
Let's say your client makes a request like:
hostname/testWrapper.php?params[]=hello¶ms[]=goodbye
Your wrapper script testWrapper.php could then look like
<?php
$params = $_GET['params'];
foreach ($params as $i => $param)
$_SERVER['argv'][$i + 1] = $param;
$_SERVER['argc'] = count($_GET['params'] + 1);
include ('test.php');
?>
This assumes that your test.php uses $_SERVER['argv/argc']to read command line arguments. It may use $argv and $argc instead (if 'register_argc_argv' is enabled in your php.ini), in which case you just use those in your wrapper script instead of $_SERVER[...].
Notice that we have to insert the parameters with an offset of 1 (i.e. $params[0] becomes $_SERVER['argv'][1]. This is because when the script is called from the command line, the first parameter $_SERVER['argv'][0] is the script name.
Lastly, unless you are absolutely sure that your test.php sanitizes the parameters, you have to do it in the wrapper script.
The question sort of says it all - is there a function which does the same as the JavaScript function setTimeout() for PHP? I've searched php.net, and I can't seem to find any...
There is no way to delay execution of part of the code of in the current script. It wouldn't make much sense, either, as the processing of a PHP script takes place entirely on server side and you would just delay the overall execution of the script. There is sleep() but that will simply halt the process for a certain time.
You can, of course, schedule a PHP script to run at a specific time using cron jobs and the like.
There's the sleep function, which pauses the script for a determined amount of time.
See also usleep, time_nanosleep and time_sleep_until.
PHP isn't event driven, so a setTimeout doesn't make much sense. You can certainly mimic it and in fact, someone has written a Timer class you could use. But I would be careful before you start programming in this way on the server side in PHP.
A few things I'd like to note about timers in PHP:
1) Timers in PHP make sense when used in long-running scripts (daemons and, maybe, in CLI scripts). So if you're not developing that kind of application, then you don't need timers.
2) Timers can be blocking and non-blocking. If you're using sleep(), then it's a blocking timer, because your script just freezes for a specified amount of time.
For many tasks blocking timers are fine. For example, sending statistics every 10 seconds. It's ok to block the script:
while (true) {
sendStat();
sleep(10);
}
3) Non-blocking timers make sense only in event driven apps, like websocket-server. In such applications an event can occur at any time (e.g incoming connection), so you must not block your app with sleep() (obviously).
For this purposes there are event-loop libraries, like reactphp/event-loop, which allows you to handle multiple streams in a non-blocking fashion and also has timer/ interval feature.
4) Non-blocking timeouts in PHP are possible.
It can be implemented by means of stream_select() function with timeout parameter (see how it's implemented in reactphp/event-loop StreamSelectLoop::run()).
5) There are PHP extensions like libevent, libev, event which allow timers implementation (if you want to go hardcore)
Not really, but you could try the tick count function.
http://php.net/manual/en/class.evtimer.php is probably what you are looking for, you can have a function called during set intervals, similar to setInterval in javascript. it is a pecl extension, if you have whm/cpanel you can easily install it through the pecl software/extension installer page.
i hadn't noticed this question is from 2010 and the evtimer class started to be coded in 2012-2013. so as an update to an old question, there is now a class that can do this similar to javascripts settimeout/setinterval.
Warning: You should note that while the sleep command can make a PHP process hang, or "sleep" for a given amount of time, you'd generally implement visual delays within the user interface.
Since PHP is a server side language, merely writing its execution output (generally in the form of HTML) to a web server response: using sleep in this fashion will generally just stall or delay the response.
With that being said, sleep does have practical purposes. Delaying execution can be used to implement back off schemes, such as when retrying a request after a failed connection. Generally speaking, if you need to use a setTimeout in PHP, you're probably doing something wrong.
Solution: If you still want to implement setTimeout in PHP, to answer your question explicitly: Consider that setTimeout possesses two parameters, one which represents the function to run, and the other which represents the amount of time (in milliseconds). The following code would actually meet the requirements in your question:
<?php
// Build the setTimeout function.
// This is the important part.
function setTimeout($fn, $timeout){
// sleep for $timeout milliseconds.
sleep(($timeout/1000));
$fn();
}
// Some example function we want to run.
$someFunctionToExecute = function() {
echo 'The function executed!';
}
// This will run the function after a 3 second sleep.
// We're using the functional property of first-class functions
// to pass the function that we wish to execute.
setTimeout($someFunctionToExecute, 3000);
?>
The output of the above code will be three seconds of delay, followed by the following output:
The function executed!
if you need to make an action after you execute some php code you can do it with an echo
echo "Success.... <script>setTimeout(function(){alert('Hello')}, 3000);</script>";
so after a time in the client(browser) you can do something else, like a redirect to another php script for example or echo an alert
There is a Generator class available in PHP version > 5.5 which provides a function called yield that helps you pause and continue to next function.
generator-example.php
<?php
function myGeneratorFunction()
{
echo "One","\n";
yield;
echo "Two","\n";
yield;
echo "Three","\n";
yield;
}
// get our Generator object (remember, all generator function return
// a generator object, and a generator function is any function that
// uses the yield keyword)
$iterator = myGeneratorFunction();
OUTPUT
One
If you want to execute the code after the first yield you add these line
// get the current value of the iterator
$value = $iterator->current();
// get the next value of the iterator
$value = $iterator->next();
// and the value after that the next value of the iterator
// $value = $iterator->next();
Now you will get output
One
Two
If you minutely see the setTimeout() creates an event loop.
In PHP there are many libraries out there E.g amphp is a popular one that provides event loop to execute code asynchronously.
Javascript snippet
setTimeout(function () {
console.log('After timeout');
}, 1000);
console.log('Before timeout');
Converting above Javascript snippet to PHP using Amphp
Loop::run(function () {
Loop::delay(1000, function () {
echo date('H:i:s') . ' After timeout' . PHP_EOL;
});
echo date('H:i:s') . ' Before timeout' . PHP_EOL;
});
Check this Out!
<?php
set_time_limit(20);
while ($i<=10)
{
echo "i=$i ";
sleep(100);
$i++;
}
?>
Output:
i=0 i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8 i=9 i=10
Is it possible to "call" a PHP script in a loop like this ?
...
while (...)
{
...
header("Location:myscript.php");
...
}
...
Nope. header("Location: ...") is supposed to redirect the browser to a different page, so only one of the calls you make will take effect.
What do you want to do?
You can always include the script from another to execute it's logic:
include('myscript.php');
In principle, this shouldn't require refactoring any myscript.php code. Be forewarned - myscript.php and the containing script will share the same global namespace, which may introduce bugs. (For instance, if the container outputs HTML and myscript calls session_start() a warning will be generated).
What you propose should work fine, however not in the way you expect. The header() function simply sends information to the browser in a single batch before the script content (You modify the http headers). So when the script finishes execution the browser will go to the specified page, hence only the last call to header('Location... will have any effect and that effect will only happen when the php script has finished executing.
A good way to do what I think you want to do would be to encapsulate the functionality of 'myscript.php' into a function.
include 'myscript.php';
while (...)
{
...
myscriptFunction();
...
}
...
You can call header() in a loop, but with the location header, the browser will only follow one.
location:<url> tells the browser to go to the url specified. it is known as a 301 redirect. Why you would call it in a loop, I don't know.
No. Rather pass it as a request parameter, assuming you're trying to redirect to self. E.g.
<?php
$i = isset($_GET['i']) ? intval($_GET['i']) : 10; // Or whatever loop count you'd like to have.
if ($i-- > 0) {
header("Location:myscript.php?i=" . $i);
}
?>
I however highly question the sense/value of this :)
Update, you just want to include a PHP script/template in a loop? Then use include() instead.
while ( ... )
include('myscript.php');
}
If it contains global code, then it will get evaluated and executed that many times.