How top stop PHP recursion? - php

Let's say I have function that calls itself recursivly 3 times for example:
function recursion($n=1){
if($n<3){
echo 1;
recursion($n+1);
}
echo 2;
}
It must print 11222. But can I do something on last iteration to prevent previously iterations, to get 11? Im looking for any solution.

The reason your code is misbehaving is because your recursing() function is flawed.
Whenever you call a function, it gets placed on the stack. When the function finishes, it gets popped off the stack and returns to the caller.
In your example, recursion() checks to see if n < 3, then prints "1" and calls recursion() with n+1. However, the function doesn't stop there. It still runs!
After recursion() is being called with n = 3, the instruction pointer gets back to where the previous call to recursion() was being made, and continues. And what do you tell it to continue with? Well, printing "2" of course.
The Solution
function recursion($n=1){
if($n<3){
echo 1;
recursion($n+1);
}
else {
echo 2;
}
}

Related

is there any way to sleep on each interval specified in php

i want introduce some sleep functionality into my code so that i can call a function at a specified(time or interval).
my desired output:
(1) at first 5sec
im called
(2) at 10sec (i,e 5sec + 5 sec)
im called // at first iteration of loop
im called // at second iteration of loop
right now i'm using
function curl_grab(){
echo "im called<br/>";
}
$arr = ['http://ab.com/','http://bc.com/'];
foreach($arr as $el){
curl_grab($el);
sleep(5);
}
but the problem with the above code is it is dumping everything at a time
like so
im called
im called
i want it one by one
here is demo: http://phpio.net/s/ggr
If you are using a browser to test this code, you will be able to see the output together only, becoz you will see output after execution of php code is completed only. You can execute this in terminal to see the out put when it happens.
Write this code into test.php
function curl_grab(){
echo "im called\n";
}
$arr = ['http://ab.com/','http://bc.com/'];
foreach($arr as $el){
curl_grab($el);
sleep(5);
}
To execute in terminal you can type
$ php /path/to/test.php

Repeat function to verifiy one value and repeat if false

I have this little script and function:
function control($value,$position)
{
if ($_SERVER['REMOTE_ADDR']=="".$value."" && $position==0)
{
print "".$value." $x<br>";
return;
}
else
{
control($value,$position);
usleep(20);
}
}
$x=0;
foreach($aa as $aaa)
{
$exp=explode("-",$aaa);
$exp2=explode("_",$exp[1]);
control($exp2[0],$x);
$x++;
}
The loop takes values from a file and sends them to a function to verify, in the function for example if value is the same as the IP of a user it works and if not it continues to execute the function. If not, the idea it repeats to continue verification; the function stops when finally the function verifies this value and it is ok.
I need this to work in one only load, for this I am thinking to use the sleep and repeat functions because the time difference for verification is very low, but in some moments more than 3 users can need to verify this.
The most important for me is to know I can do this in the function because if I use it in this way all the time the page tells me the connection is down, and I only need to repeat the function when the verification result is not the same, and if it is not the same repeat the function another time inside the loop and sleep and repeat in the wait mode.
Sorry but I try to tell all this the best I can.
Regards and thanks.

Another WebDriverException: Element is no longer attached to the DOM

I have a web page that contains some JavaScript and performs some Ajax calls. When trying to test it using Selenium, I randomly get "PHPUnit_Extensions_Selenium2TestCase_WebDriverException: Element is no longer attached to the DOM" message, maybe once in 5 runs.
Now I'm aware of the race issue between Ajax call and test engine, and I have taken steps to protect from it, but I still have some problem. My scenario is this: I change value of the select element 1 which triggers Ajax call that removes all option sub-elements of the select element 2 and generates new option sub-elements based on the Ajax response. Testing code:
$this->select($this->byId('select1'))->selectOptionByValue('value1');
$this->myWaitForElementToAppear('#select2>option[value="value2"]');
$this->select($this->byId('select2'))->selectOptionByValue('value2');
last line triggers the error. Here is the myWaitForElementToAppear method:
public function myWaitForElementToAppear($selector, $limit = 5) {
$start = time();
while(true) {
if($start + $limit < time()) {
break;
}
try {
$this->byCssSelector($selector);
break;
} catch(PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {}
}
}
If I'm not mistaken, myWaitForElementToAppear method should ensure that desired option has been added by jQuery before it exits and thus allow it to be used on the next line. I should add that I've made sure that time-out doesn't happen here (since my method allows for it to happen) and I'm positive that it's not the case
Edit: I should add that putting sleep(1) after myWaitForElementToAppear call solves the problem, but I don't understand why the additional second is needed. Shouldn't call to myWaitForElementToAppear be enough?
There are some explanations here:
Firstly, time() has a very low precision, only returning the number of
whole seconds that have passed, which makes the whole thing quite
vague. Secondly, PHP has to sit there looping thousands of times while
it waits, essentially doing nothing. A much better solution is to use
the one of the two script sleep functions, sleep() and usleep(), which
take the amount of time to pause execution as their only parameter.
From php.net:
The idea of sleep and usleep is that by letting the cpu run a few idle
cycles so the other programs can have some cycles run of their own.
what results in better response times and lower overall system-load.
so if you have to wait for something, go to sleep for a few seconds
instead of occupying the cpu while doing absolute nothing but
waitting.
And you can use waitUntil from PHPUnit:
/* waitElementToDisappear */
$this->waitUntil(function($testCase) {
try {
$input = $testCase->byCssSelector("#select2>option[value="value2"]");
} catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
if (PHPUnit_Extensions_Selenium2TestCase_WebDriverException::NoSuchElement == $e->getCode()) {
return true;
}
}
}, 5000);
/* waitElementToAppear */
$this->waitUntil(function($testCase) {
try {
$input = $testCase->byCssSelector("#select2>option[value="value2"]");
return true;
} catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {}
}, 5000);

Recursive PHP function doesn't stop and freezes my browser

I have the following recursive function:
$cogs = array('hello', 'how', 'are', 'you');
$wheels = array();
foreach($cogs as $cog)
{
$wheels[] = array($cog);
}
function recursive($placement){
$counter = count($placement);
$nword = '';
for($i = 0; $i < $counter; $i++) {
$nword .= $placement[$i][0];
echo $nword;
}
recursive($placement);
}
recursive($wheels);
Clearly I am doing something wrong as my function just keeps going. I cant figure out why… I am new to recursive functions in PHP so any help on a solution to this would be appreciated. What is the best way to have a safety net so my PHP function does not run forever for any recursive function?
It doesn't stop because recursive is an infinite loop. You've written:
function recursive($placement) {
// Code that doesn't return, and outputs text
recursive($placement);
}
Why do you expect that to ever terminate?
Any recursive function needs to have some condition that eventually will prove true and upon proving true will terminate the recursion.
Your browser is freezing because it likely is having a hard time with the massive amounts of output your PHP script has sent to it.
Most PHP installations will eventually terminate a script that has run for too long. However, as mentioned, your browser may have difficulties if it has to deal with a huge amount of output from the infinite loop.
Because you don't have a stop condition. In your function you print every time the same things (the first position of each vars in the array) and after that you call again the same function with the same input.

How to wait for a variable to return before the next function starts

I have a simple function1 that does a http request to a google api and returns the $result.
I then have another function2 that, if $result isset, should use $result to do some computing and then return $finalresult. .
My problem is that the call to the google api takes a couple of seconds and by the time $result is returned by function1, function2 has already returned $finalresult without taking into consideration $result.
What I am looking to do is to have function1 to run completely and return $result before function2 even begins.
Preferrably I am looking for a solution that is not simply using "sleep()" as this function will not guarantee that $result is actually returned. (Unless there is some way to loop a sleep(1) until $return isset, or something like that)
Sample code for the visual gals and guys
function1_geocode($address); // this function makes a http request to google and returns $result
function2_proximitysearch(){
if (isset($result)){
//inevitably by the time the script gets there, $result hasn't been returned yet therefore none of the "some stuff" code is executed.
//some stuff
}
else {
//some other stuff
}
}
PHP is not asynchronous. Functions are executed one after another.
why don't you have function 1 call function 2 when it is done?
additionally, Mchl is right. function 1 will have to complete before the code executes function 2. Maybe you should set up your code like so:
$foo = 0;
$foo = function1();
if($foo > 0)
function2();
function1()
{
if($something)
$foo = 1;
}
function2()
{
$something = $else;
}
That way it will only call function 2 if function 1 changed the value of $foo.
Of you could post your full code and we'll know what you're trying to do.
PHP isn't threaded, so if you call function1_geocode before function2_proximitysearch, $result should always be set.
It could be that function1_geocode($address) has a bug, or else you might be missing some documentation for how that function is used.
It's possible to kinda simulate asynchronous functionality by, for example saving results in a file to be dealt with by a second page load. But that would have to be specifically designed that way. Within one PHP page load, you can't have a process running in the background.

Categories