Mutiple consecutive outputs instead of one in a function in PHP - php

I am learning about static variables in PHP and came across this code in PHP manual.
<?php
function test() {
static $count = 0;
$count++;
echo $count;
if ($count < 10) {
test();
}
$count--;
}
?>
I couldn't understand the purpose of last $count--;. So, I wrote a different version of the function below:
<?php
function test() {
static $count = 0;
$count++;
echo $count;
if ($count < 10) {
test();
}
echo 'I am here!';
$count--;
}
test();
?>
The output of above code is:
12345678910I am here!I am here!I am here!I am here!I am here!I am here!I am here!I am here!I am here!I am here!
Why isn't the output just the line below because we go past the if condition only once.
12345678910I am here!
If we are going past the if condition multiple times, then shouldn't the output be:
1I am here!2I am here!3I am here!4I am here!5I am here!6I am here!7I am here!8I am here!9I am here!10I am here!
Thanks.

This is more about recursion than static variables. However:
Why the numbers are written out first and the text afterwards? Let's break each run of the function. For simplification, I'll only use example with 2 calls (if ($count < 2))
1st call starts, $count is incremented to 1
prints 1
Within the 1st call, the condition $count < 2 is met, so it calls test() (so that's going to be the 2nd call)
2nd call starts, $count is incremented to 2 (if it weren't static, it wouldn't keep the value from the higher scope)
prints 2
Within the 2nd call, the condition $count < 2 is NOT met, so it skips the if block
prints I am here! and ends the 2nd call
Now the 1st call is done running the recursive function so it continues
prints I am here! and ends the 1st call

When you're calling test() within the method that doesn't stop the execution of the rest of the code in the method.
The reason, as far as i can see, it doesn't output a number after each string of "i am here" is because you're calling the method test() before the output. So each time it's waiting for that method to complete before moving on to the next string.
If you were to move the $count echo to after it I believe it'd output as expected.
Does that answer your question at all?

Related

can't figure out why a function parameter's value isn't passed to the function

I have a function in a codeigniter controller that calls a model function with 3 parameters. Of the 3 passed parameters, response_num comes across blank when it should be an integer value.
Hoping someone else's eyes can spot the trouble!
Thanks! (I'm still learning php and codigniter).
Here is the calling function in the controller:
for($i=1; $i < $possible_results_count; $i++) {
print_r("iteration: ".$i);
$g1 = $this->Response_model->get_possible_results_for_response($i, $this->session->userdata("assess_id"), $this->session->userdata("user_id"));
print_r("Sum for ".$i."=".$g1["response_value"]);
if($g1["response_value"] >= $sensitivity) {
$results[$i] = $userdata["possible_results"][$i]; //
$result_count++;
// print_r("added [".$userdata["results"][$i]."]");
}
$total_results = $result_count;
if ($total_results >= $min_result_count) {
// print_r("found 3 gifts-breaking for loop");
break;
}
}
The called function in the model:
public function get_possible_results_for_response($*response_num*=FALSE, $assess_id, $registrant_id){
print_r("response_num=".$response_num."; assess_id=".$assess_id."; registrant_id=".$registrant_id);
$i is the variable in the calling functions for loop.
the print_r's show all variables are correct except for the parameter that was passed as $i, it is blank.
$i tracks the iteration count and passes it to the model for a db lookup using $i to determine which record to use in calculations.
Solved!!!
duh!!! Right after I posted this question, I decided to initialize $i ($i=0) just before the for loop and it worked, the value was passed to the calling function. Apparently using $i in the for loop without initializing works for the for loop, but not as a regular variable unless it is initialized.
Live and Learn :)

Can't understand function and reference behaviour

I have this code.
$add = (function () {
$counter = 0;
return function () use(&$counter) {return $counter += 1;};
})();
echo $add(); //1
echo $add(); //2
echo $add(); //3
Expected Output:
111
Original Output:
123
Inside the function $counter=0 is assigned by 0 so the &$counter should be 0.
So when i called it second time it sees $counter=0 and so that &$counter will be 0, Isn't it?
Why it is incrementing?
It does not call $counter=0 for the second time. You call it just once when initiating the first function. When you call $add(), you call every time the second function (that is in your return statement) which just uses the modified value of $counter that you passed by reference. If you would add echo $counter; after the $counter = 0; you will see that.
What do you mean by "sees"? The first time you execute $add(), the inner counter is counted up. As you used a reference pointer (through adding the ampersand in use(&$counter)) to the original $counter, this is also manipulated, so after executing this once, the counter variable no longer contains a zero.
When you remove that ampersand, the innermost function uses a fresh counter each and every time, such that your expected output is met
Because you pass a reference to the function the initial $counter = 0; value is also increased each time you add 1 to it using $counter += 1; that's why your result is "123".
To get "111" you need to pass a variable to a function $counter, not a reference.

PHP function to print how many times a function is called

I am trying to make a function that counts how many times it has been called
Here is my code:
<?php
function print_calls() {
count(print_calls);
}
print_calls();
?>
I want it to display how many times the function is called like
print_calls(); // 1
print_calls(); // 2
print_calls(); // 3
Something like this?
<?php
function callCount(){
static $calls=0;
echo $calls++;
}
callCount();
?>
You can use a static variable for this:
function print_calls() {
static $callCount=0;
printf("%d\n", ++$callCount);
}
Note that this only keeps the counts for the current process, so if you use this in a web server the count will be reset for each page you access. If you need persistent counts, you would have to write it to a file or use a $_SESSION variable.
Global variables may be dangerous. Be carefoul.
You can define a variable as counter and a function that uses that external variable.
php > $counter = 0;
php > function ciao() { global $counter; $counter++; echo $counter; }
From now, ... each time you call that function it print the variable incremented. This happens because the scope of $counter is not local to the function but global to the file.
php > ciao();
1
php > ciao();
2
php > ciao();
3
php > ciao();
4
php > ciao();
5

Unable to increment a global variable

I need a variable to be passed along several functions & if statements, i'm going to keep it short.
I start off with initializing a static counter which i will use to keep track of the case number in my mysql database;
static $counter = 1;
then i write my function in which i try to simply increment my global variable (this is in an if statement inside my function);
$counter++;
Now my code compiles and runs perfectly but the counter seems to never increment and give every case id 1.
Anyone know how i managed to mess this up?
EDIT (Current structure):
<?php
static $counter = 1;
function frontend($connection){
global $counter;
(...)
if(isset($_POST['submit'])){
(...)
if(isset($_POST['betaald'])){
$counter++;
}
}
} ...
Now this code makes a neat database of all i need except the counter which seems to be unchangeable.
Explain more about your code and see the example.
<?php
function keep_track() {
STATIC $count = 0;
$count++;
print $count;
print "<br />";
}
keep_track();
keep_track();
keep_track();
?>
This will produce the following result −
1
2
3

PHP misunderstanding number of tickable statements using PHP ticks?

I know what ticks are in PHP, but looking at the output of the following code:
<?php
function myfunc() {
static $n = 1;
print "$n) Tick<br>";
$n++;
}
register_tick_function("myfunc");
declare(ticks=1);
echo 'echo<br>';
The output is:
1) Tick
2) Tick
echo
3) Tick
It tells me that the registered tick function 'myfunc' is executed 3 times. But, based on this answer -> PHP using Declare ? What is a tick?:
You get a tick for each line ; and each block {}
Shouldn't it be:
1) Tick
echo
2) Tick
? As there are only two statements:
declare(ticks=1);<-- Statement 1
echo 'echo<br>';<-- Statement 2
Why 3??? If I remove the ";" from declare, like this:
declare(ticks=1)
echo 'echo<br>';
I get the only one execution of the registered tick function:
echo
1) Tick
So what is the definitely rule to count the tickable statements in order to understand how many times a registered tick function is executed? (I am asking it because of this example and because PHP manual actually doesn't cover the topic on counting tickable stats)
EDIT: Another strange behaviour in my opinion is this:
<?php
function myfunc()
{
static $n = 1;
print "$n) Tick<br>";
$n++;
}
register_tick_function("myfunc");
declare(ticks = 1)
echo 'Start<br>';
echo 'echo<br>';
which outputs:
Start
1) Tick
echo
The tick function is executed once, but the statements are at least 2 (if not counting the "end of the script" as #Marc B has pointed out)
what I finelly found is:
function myfunc()
{
static $n = 1;
print "$n) Tick<br>";
$n++;
}
register_tick_function("myfunc");
declare(ticks = 1) {
//echo 'Start<br>';
echo 'echo<br>';
}
outputs 2 ticks, one for block {} and 1 for echo.
if you uncomment 'Start'
that will bring 1 more tick as you expected.
So I think the best practice is to always use
declare(ticks=1) { }
with block brackets
You don't put a semicolon after the declare, so your declare statement works only for the next statement (for one only echo). It is the same behaviour, as with using a block in curly brackets after declare - that block is then regarded as the only statement to execute. You have the same with control structures: while(true)x(); and while(true){x();y();}, just in the case with declare semicolon after it creates an implicit block around all the remaining script.

Categories