Function doesn't save variable - php

I'm trying to add 1 to a number each time a function is called, but for some reason, the total number is always same.
Here is my current code:
<?php
$total;
function draw_card() {
global $total;
$total=$total+1;
echo $total;
}
draw_card();
draw_card();
?>

Personally, I would not use globals, but if I was forced at gunpoint I would handle state within the function, so outside variables did not pollute the value. I would also make an arbitrary long key name which I would not use anywhere else.
<?php
function draw_card($initial = 0) {
$GLOBALS['draw_card_total'] = (
isset($GLOBALS['draw_card_total']) ? $GLOBALS['draw_card_total']+1 : $initial
);
return $GLOBALS['draw_card_total'];
}
// optionally set your start value
echo draw_card(1); // 1
echo draw_card(); // 2
https://3v4l.org/pinSi
But I would more likely go with a class, which holds state by default, plus its more verbose as to whats happening.
<?php
class cards {
public $total = 0;
public function __construct($initial = 0)
{
$this->total = $initial;
}
public function draw()
{
return ++$this->total;
}
public function getTotal()
{
return $this->total;
}
}
$cards = new cards();
echo $cards->draw(); // 1
echo $cards->draw(); // 2
echo $cards->getTotal(); // 2
https://3v4l.org/lfbcL

Since it is global already, you can use it outside the function.
<?php
$total;
function draw_card() {
global $total;
$total=$total+1;
//echo $total;
}
draw_card();
draw_card();
draw_card();
echo "Current Count :", $total;
?>
Result :
Current Count :3
This will increment the number of times you call the function.
Since you echoed the result/total each time without a delimiter, you might have considered the output to be 12(Assumption)

Functions have a scope.. you just need to bring $total into the scope of the function... best to not do it globally but as an argument.
$total = 0;
function draw_card($total) {
return $total + 1;
}
$total = draw_card($total);
//Expected Output = 1
$total = draw_card($total);
//Expected Output = 2

Related

Where does the additional 0 come from

I have been a developer for more than 5 years but this seems to be confusing and strange. I tried to use two functions having echo on each function. Then, I call those functions and echoed again. Why does this code below displays 5100 instead of 510 only? Where does the additional 0 come from?
<?php
function firstNum()
{
echo 5;
}
function secondNum()
{
echo 10;
}
echo firstNum() + secondNum(); //Output is 5100
Your code is echoing 5 then 10 then the sum of null plus null.
When you don't use a return php will return null from the function call.
You mean to do this: (Demo)
function firstNum()
{
return 5;
}
function secondNum()
{
return 10;
}
echo firstNum() + secondNum(); //Output is 15
You can remove the echos in the function to have a better understanding of what is returned: (Demo)
function firstNum()
{
//echo 5;
}
function secondNum()
{
//echo 10;
}
var_export(firstNum());
echo "\n";
var_export(secondNum());
echo "\n";
var_export(null+null);
Output:
NULL
NULL
0

How can I access a variable inside another function?

I have two functions that print some values. I need to use the variable $mv in the second function. However, $mv can only be defined in the first function. I have tried all types of PHP global examples and none of them has allowed the $mv variable to be used or visible or accessible in the second function.
function printMobilePrev(&$mobileprevresults) {
if (count($mobileprevresults->getRows()) > 0) {
$mv = $mobileprevRows[0][0];
$mobileprevRows = $mobileprevresults->getRows();
echo '<p>Previous period (sessions): '.$mobileprevRows[0][0].'..............................';
} else {
print '<p>No results found.</p>';
}
}
function printMobileCurr(&$mobilecurrresults) {
if (count($mobilecurrresults->getRows()) > 0) {
$mobdiff = ($mobcur - $mv);
$mobpctchg = ($mobdiff / $mobprev) * 100;
$mobilecurrRows = $mobilecurrresults->getRows();
echo '<p>Previous period (sessions): '.$mobileprevRows[0][0].'..............................';
echo '<p>Previous period (sessions): '.$mv.'..............................';
echo '<p>Current period (sessions): '.$mobilecurrRows[0][0].'..............................';
if ($mobdiff > 0){
echo '<p>Percent increase: '.$mobpctchg.'..............................';
} else {
echo '<p>Percent decrease: '.$mobpctchg.'..............................';
}
} else {
print '<p>No results found.</p>';
}
}
You can use the global scope:
That is what you want to do:
$mv = 0;
function function1()
{
global $mv;
$mv = 'whatever';
//code
}
function function2()
{
global $mv;
// use $mv;
}
You have to predefine that variable OUTSIDE any function, and then you can use Global to get that to any function.
You can pass it by reference. For example
function doSomething(&$mv) {
$mv = 1;
}
function doSomethingElse($mv) {
return $mv;
}
$mv = 0;
doSomething($mv);
echo doSomethingElse($mv); //Output: 1
You could return $mv after your print and save that in a var to pass to the next function:
$printMobilePrev = printMobilePrev();
function printMobilePrev(&$mobileprevresults) {
$mv = $mobileprevRows[0][0];
...
print '<p>No results found.</p>';
return $mv;
...
}
$printMobileCurr = printMobileCurr(&$mobilecurrresults,$mv);
function printMobileCurr(&$mobilecurrresults,$mv) {
......
}
Most likely you have to make a correct use of globals.
declare your $mv variable as global before asigning it a value on your first function
global $mv;
$mv = $mobileprevRows[0][0];
use global at the begining on your second function before using it
function printMobileCurr(&$mobilecurrresults) {
if (count($mobilecurrresults->getRows()) > 0) {
global $mv;

PHP using variables outside of a function

I was wondering if someone could help me out.
I'm writing some PHP functions where I would like to use a variable inside a function and then use the updated variable outside of the function.
eg
$subTotal += $priceToShow * $ct_qty;
adminCharge($subTotal);
function adminCharge($loggedInfoprice, $subTotal){
if (($loggedInfoprice == 5)||($loggedInfoprice == 6)){
$packagingCurrency = "$";
$packagingPrice = "63";
$packagingPricing = $packagingCurrency.$packagingPrice;
}else {
$packagingCurrency = "£";
$packagingPrice = "30";
$packagingPricing = $packagingCurrency.$packagingPrice;
}
if(isset($packagingPrice)){
$subTotal = $subTotal + $packagingPrice;
}
}
<?php echo $subTotal; ?>
The echo'd $subTotal only seems to show the value from before the function.
Is it possible to extract both $subTotal and $packagingPricing from the function?
Thanks in advance.
Updated the function
function adminCharge(&$subTotal){
// do things
}
or
$subTotal = adminCharge($subTotal);
function adminCharge($subTotal){
//do things
return $subTotal;
}
In the first case, you pass $subTotal variable as a reference, so all all changes will be reflected to "outside" variable.
In the second case, you pass it and return new value, so is easy to understand why is working.
Please, pay attention
First solution - however - can lead you to side effect that will be difficult to understand and debug
Update
If you want to "extract" (so return) two variables, you can do the following
list($subTotal,$packagingPrice) = adminCharge($subTotal);
function adminCharge($subTotal){
if(isset($packagingPrice)){
$subTotal = $subTotal + $packagingPrice;
}
return array($subTotal, $packagingPrice);
}
function adminCharge($subTotal, $packagingPrice){
if(isset($packagingPrice)){
$subTotal = $subTotal + $packagingPrice;
}
return $subTotal;
}
Use it like this:
$subTotal = adminCharge($subTotal, $packagingPrice);
You don't return anything, so you could use globals but i wouldn't recommend it.. Take a look though, because that's what your asking for: http://www.php.net/global
In my opinion, change your function:
function adminCharge($subTotal){
global $packagingPrice
if(isset($packagingPrice)){
$subTotal = $subTotal + $packagingPrice;
}
return $subTotal;
}
$subTotal += $priceToShow * $ct_qty;
$subTotal = adminCharge($subTotal);
Also keep in mind you didn't had $packagingPrice in your function, so i added it with global. Otherwise it wouldn't work :)
You have to understand the variable scope read here.
In short, there are 3 options.
Use global keyword:
$a = 0;
function foo(){
global $a;
$a += 1;
}
Use pass by reference:
$a = 0;
function foo(&$b){
$b += 1;
}
foo($a);
Collect return value of the function:
$a = 0;
function foo($b){
return $b + 1;
}
$a = foo($a);
you need to use pass the variable by reference or global
option 1
function adminCharge(&$subTotal){
if(isset($packagingPrice)){
$subTotal = $subTotal + $packagingPrice;
}
return array($subTotal, $packagingPrice);
}
option 2
function adminCharge()
{
global $subTotal;
if(isset($packagingPrice))
{
$subTotal = $subTotal + $packagingPrice;
}
return array($subTotal, $packagingPrice);
}

Why global is null in function?

I get this strange problem....
All the page has this code only.
global $currentPage; is null and i dont know why...
<?php
$pager = $_PARAMS["this"];
$pages = 5;
$currentPage = 1;
$tst="ap";
$nearPages = 5;
//Prologic
?>
<div class="pager">
<?php
$nearPagesHalf = ($nearPages - 1) / 2;
drawNumbers(1, 1);
if ($currentPage - $nearPagesHalf <= 0) {
}
drawNumbers($pages, $pages);
?>
<?php
function drawNumbers($from, $to) {
global $currentPage;
for ($i = $from; $i <= $to; $i++) {
echo $currentPage;
if ($i == $currentPage) {
?> <span class="pageNumbers current"><?= $i ?></span>
<?php
} else {
?>
<a href="#">
<span class="pageNumbers"><?= $i ?></span>
</a>
<?php
}
}
?>
<?php
}
function drawDots($from, $to) {
}
?>
</div>
THE PROBLEM
echo $currentPage; prints 1
function drawNumbers($from, $to) {
global $currentPage;
echo $currentPage; prints nothing
I bet you're executing this code by including this file inside another function.
So you need to mark the first variable occurrence as global too.
Btw, global variables are weird, the more simple and correct way to pass the data to the function is to use function parameters.
The $currentPage defined at the top does not live in global space. Why don't you just pass the $currentPage as the first parameter to the drawNumbers function? It's much cleaner that way:
drawNumbers( $currentPage, 1, 1 );
function drawNumbers($currentPage, $from, $to) {
// no need define $currentPage here since it's passed
}
I had a similar problem, but the solution is not on this page so I am putting here in order to help anyone who might show up looking.
My global variable was an object and it worked fine when calling the global vairable from a method AFTER the variable was defined.
class object{
function __construct($v1, $v2){
}
function methodA(){
global $a;
var_dump($a);
}
}
$a = new object($var1, $var2);
$a->methodA(); //Object...
However, when trying to use the global variable before the constructor has return it does not work.
class object{
function __construct($v1, $v2){
$this->methodA();//NULL
}
function methodA(){
global $a;
var_dump($a);
}
}
$a = new object($var1, $var2);
This looks like a dunce-cap situation, but my site is a lot more complex than this simplified scenario. So it took me a while to figure out that I was calling it before it was defined.

How do I save the original argument in a recursive function in PHP?

I'm in PHP working on an Euler problem. I have this function so far:
<?php
$biggest = 0;
$counter = 1;
function test($i){
global $biggest;
global $counter;
if ($i == 1) {
echo "I'm done! Took me $biggest steps";
}
else {
if ($i%2 == 0) {
$counter = $counter + 1;
if ($counter>$biggest) {
$biggest = $counter;
}
test($i/2);
}
else {
$counter = $counter + 1;
if ($counter>$biggest) {
$biggest = $counter;
}
test(3*$i+1);
}
}
}
test(13);
?>
I have the problem mostly licked, but I can't seem to get back at the original input. The question is "When you have a number, if odd get 3n+1, when even, get n/2, do until returns 1. What starting value yields the most "steps" before you get to one?" I currently am returning the number of steps, but I keep resetting $i as I recurse, so I can't record what starting # yielded my $biggest number of steps.
How can I keep track of that number, but also not have it destroyed at the next instance of the loop? (I'll eventually wrap this in a for ($i=1, $i<1000000, $i++) loop)
Thanks!
A common approach is to pass the original argument through each time, so that when eventually you get to your base case, you still have it available. A primitive (and almost entirely unrelated example):
<?php
function fact($n) {
if($n == 1) return 1;
else return $n * fact($n - 1);
}
?>
This is an extremely basic implementation of the factorial function in PHP. Now say you wanted for whatever reason to have the initial value available in the final step: you'd build a wrapper function fact($n) that would call something like memory_fact($n, $initial):
<?php
function fact($n) {
return memory_fact($n, $n);
}
function memory_fact($n, $initial) {
if($n == 1) return 1;
else return $n * memory_fact($n - 1, $initial);
}
?>
This way, memory_fact always knows where it started.
It's easy, just pass it around as a parameter! Here's some python-ish pseudocode:
def func(start, arg):
if foo(arg):
return func(start, arg+1)
else:
return [start, arg]
You don't need the globals; globals are evil. Try returning something useful from test(). Also, you'll find the test() above wastes many cycles. Try using memoization.
Here's a memoization example for calculating Fibonacci numbers:
function fib($n) {
static $data = array(1, 1);
if (!isset($data[$n])) {
$data[$n] = fib($n-1) + fib($n-2);
}
return $data[$n];
}
Note that there are other time-efficent constant-space approaches to handle Fibonacci numbers (including one in O(log n) time), but the Collatz conjecture is a little trickier.

Categories