How could I make sure that the startProcess(); function is being called, but without halting the execution for myFunction(). I'll guess that there's a way to call a function and prevent it from returning it's value to thereby accomplishing this?
Pseudo-code:
function myFunction() {
startProcess();
return $something;
}
function startProcess() {
sleep(5);
// Do stuff that user doesn't should have to wait for.
}
You can't do it. There are some a few functions in PHP that allow async I/O, but nothing like the concurrency you require.
The reason for existing no language support is that PHP is designed to execute short-lived scripts, while the concurrency is managed by the HTTP daemon.
See also:
cur_mult_init
pcntl_fork (unix only)
http://wezfurlong.org/blog/2005/may/guru-multiplexing
To make a small addition to Artefecto's answer, there are some people who've attempted to recreate a sort of threads situation. You can find some information on it using google, but I doubt it'll be helpful as it's just too experimental and probably pretty unreliable.
Found one link that might be helpful for you.
http://w-shadow.com/blog/2008/05/24/improved-thread-simulation-class-for-php/
As far as I can tell from your question and tags, you want to do some background processing, meaning, essentially, multiple threads.
Unfortunately, PHP doesn't do this. There are some IO functions that are asynchronous, but in general you cannot do concurrent processing in PHP.
What is it you want startProcess() to do? There are many ways to keep the user from having to wait.
Emails are a good example: the thread that runs mail() spins until the message is accepted or rejected; you don't want a user to have to wait for that. So you queue up the task, and then process your queue on cron.
function myFunction() {
addToQueue();
return $something;
}
function addToQueue() {
// add stuff to the queue of tasks
}
function runQueue() {
// process the queue of tasks; called by cron.
}
Have you looked at Gearman for farming out this kind of background task?
I'm going to take a shot in the dark here, but does this function look like it could be a solution for your overall goal ?
http://php.net/manual/en/function.register-shutdown-function.php
Related
I'm working on something that script need to wait for do childFunc and after that return the result of childFunc and after that, the script continue. Something like async and await in javascript.
<?php
$loginResponse = $system->login($username, $password);
if ($loginResponse !== null && $loginResponse->isTwoFactorRequired()) {
$twoFactorIdentifier = $loginResponse->TwoFactorInfo()->getTwoFactorIdentifier();
// I need to wait here that myChaildFucn LoadView and get data from user and then after some process retuen result!!!!
$verificationCode = myChaildFucn();
$system->checkTwoFactorLogin($username, $password, $twoFactorIdentifier, $verificationCode,);
}
Salaam,
(if you want to speak Persian, I'm okay but I prefer to answer by English to ensure other people who has same your problem can find the solution)
so as you know, PHP is a synchronous engine and we have to use ajax to split our requests or use some functions to simulate Asynchronous performances.
anyway...
we have two options to solve this issue generally:
use sleep function : if you are sure about your delay timing, so just use it and define a delay to stop your app for seconds, otherwise It's not a good idea for your situation.
use foxyntax_ci in https://github.com/LegenD1995/foxyntax_ci : if you have SPA or using REST API, It's your best option!! actually it has some libraries on codeigniter and help you to build your queries, working with files, session, cookies, config authorization and ... with Asynchronous function from javascript. (NOTE: It's Alpha version but it hasn't bugs, just needs to review in media function to improve performance).
I have 2 functions, let's call them login and doSomething and currently, I implemented them this way,
$member=$this->login();
$this->doSomething($member);
//show welcome page
When a user logs in, I want to do some stuff but it takes around 20 seconds or more to complete. Is there any ways where after login() is run, it will show the welcome page immediately while the method doSomething() is being executed separately. The method doSomething() doesn't return any values thus does not affect the welcome page.
Please try the following.
ob_start();
$member = $this->login();
ob_end_flush();
ob_flush();
flush();
$this->doSomething($member);
If you do not want to print anything after login, you can use:
ob_start();
$this->doSomething($member);
ob_end_clean();
Also using Ajax from the front site's login page(after loading), you can start processing
$this->doSomething($member);
in another ajax call in the back end silently.
There are other ways for achieving threading, pseudo threading like behaviour.
But these are the easiest one for your scenerio :)
You can check WorkerThreads also.
Their implementation example documentation are available in the net.
If you really, really want to run it in parallel, then you need to run it in a sperate process. That means you are running it in different scope, so while the code you invoke might contain $this->doSomething($member), that "this" won't be this "this".
Assuming that is possible, then your question is a duplicate of this one (but beware - the accepted answer is not good). Note that you will run in blocking problems if both parts of the script depend on a session.
I have sript php with three function like this:
public function a($html,$text)
{
//blaa
return array();
}
public function b($html,$text){
//blaa
return array();
}
public function c($html,$text){
//blaa
return array();
}
require_once 'simple_html_dom.php';
$a=array();
$html=new simple_html_dom();
$a=$this->a($html,$text);
$b=$this->b($html,$text);
$c=$this->c($html,$text);
$html->clear();
unset($html);
$a=array_merge($a, $c);
$a=array_merge($a, $b);
a($html,$text) takes 5 seconds before giving a result
b($html,$text) takes 10 seconds before giving a result
c($html,$text) takes 12 seconds before giving a result
Thus the system takes 27 seconds before geving me a result, but I want take my result in 12 seconds. I can't use threads because my hosting does not support threads. How can I solve this problem?
PHP does not support this out of the box. If you really want to do this, you have two basic options (yep, it's going to be dirty). If you want a serious solution depending on your actual use-case, there is another option to consider.
Option 1: Use some AJAX-trickery
Create a page with a button that triggers three AJAX-calls to the different functions that you want to call.
Option 2: Run a command
If you're on UNIX, you can trigger a command from the PHP script to run a PHP script (php xyz.php) and that actually runs it on a different thread.
Serious option: use queues
Seriously: use a queue system like rabbitMQ or BeanstalkD to do these kind of things. Laravel supports it out of the box.
If the wait time is caused by blocking IO (waiting for server response) then curl_multi might help.
From the code you posted, though, it doesn't look like is your problem.
It looks more like simple html dom is taking a long time to parse your html. That's not too surprising because it's not a very good library. If this is the case you should consider switching to DomXPath.
You might wanna look into jQuery deferred objects.... $.when should handle this kinda of situation.
Hopefully someone here can help me out - basically I have a logging class that I'm updating (Made it ages ago), and I want to make sure it logs messages under 98-99% of circumstances. However right now it doesn't handle exit()s, it basically just writes to a file (Opening, writing, and closing) every time a message/error is sent to the logger.
What would be the best way to handle exit()s, and be efficient in terms of disk writes? Right now I'm looking at __destruct in the logger class (With fopen, fwrite, and fclose being called in it), however I'm not quite sure if this is safe, or efficient.
Edit: What about set_error_handler()? I remember reading years ago that this was very slow and not very good for custom errors/messages (Like SQL issues)
If you wish to log something when your script ends, you should take a look at PHP's register_shutdown_function():
function shutdown()
{
// .. log code here.
}
register_shutdown_function('shutdown');
You should avoid using the __destruct() method as there is no guarantee that it will be called when you expect it to be called.
You could also take a look at PHP's built in error_log() method to write the contents to the actual PHP error log file (this is possibly more reliable than writing your own logger).
References:
http://php.net/manual/en/function.register-shutdown-function.php
http://php.net/manual/en/function.error-log.php
I always use some global function, e.g.
function BeforeExit () {
//do stuff like logging
exit;
}
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