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);
}
Related
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
Can you please take a look at this script and let me know why I am getting the
Undefined variable: step1
error?
<?php
$step1;
function getNums($num1, $num2){
$diff = $num2 - $num1;
$steps =[
round($num1 + $diff/4),
round($num1 + $diff/2),
round($num1 + $diff*.75),
$num2
];
$step1 = $steps[1];
}
getNums(50, 400);
echo $step1;
?>
The code inside your function is in a different scope than the code running outside of it, which is why you are getting an error about $step1 being undefined - it is being defined outside the function. If you want to be able to refer to it inside your function you will either need to pass it in as an argument to your function by reference or make the variable global.
Pass by reference
function getNums( $num1, $num2, &$step1 ){
// ... your code
}
// pass the variable by reference
getNums( 50, 400, $step1 );
echo $step1;
Using global
// accessible globally
global $step1;
function getNums( $num1, $num2 ){
global $step1;
// ... your code, with $step1 accessible
}
getNums( 50, 400 );
echo $step1;
Why don't you pass it by reference?
<?php
$step1;
function getNums($num1, $num2, &$step1){
$diff = $num2 - $num1;
$steps =[
round($num1 + $diff/4),
round($num1 + $diff/2),
round($num1 + $diff*.75),
$num2
];
$step1 = $steps[1];
}
getNums(50, 400,$step1);
echo $step1;
?>
This should work
Please see my code below, I am trying to put a function containing an if statement within str_replace, however, it is not injecting it into the script, thank you in advance for your help. Basically I need to replace [price] in the string with this if statement.
function price(){
if ($_SESSION['vat'] == "ex"){
echo('£'.$row_products['price'].'Ex. VAT');
} ?>
<?php if ($_SESSION['vat'] == "inc"){
$total_price = $row_products['price'] *= (1 + $VATrate / 100);
echo('£');
printf("%.2f", $total_price);
echo('Inc. VAT');
}
}
$main_description = str_replace('[price]', price(), $row_products['description']);
Not tested but something along the lines of this should do the trick:
function price() {
if ($_SESSION['vat'] == "ex"){
return '£'.$row_products['price'].'Ex. VAT';
}
if ($_SESSION['vat'] == "inc"){
$total_price = $row_products['price'] *= (1 + $VATrate / 100);
return sprintf("%s %.2f %s", "£", $total_price, 'Inc. VAT');
}
}
You can't echo result inside a function you need to return a value. Your function should look something like this:
function price() {
$result = ''
if ($_SESSION['vat'] == "ex"){
$result .= '£'.$row_products['price'].'Ex. VAT' . "\n"
}
if ($_SESSION['vat'] == "inc") {
$total_price = $row_products['price'] *= (1 + $VATrate / 100);
$result .= '£';
$result .= sprintf("%.2f", $total_price);
$result .= 'Inc. VAT';
}
return $result;
}
You concatenate the string an then return it at the end.
The commentary is in the comments:
// When you create functions do not assume that variables
// will just magically be available inside it. If you need
// to use some variable inside a function then define them
// as arguments.
function price($price, $vat) {
// Never use a variable or array index without
// first making sure that it exists! You will
// get error messages if they do not exist.
if ( ! isset($_SESSION['vat'])) {
trigger_error('The session variable "vat" is not set');
}
// Since you use 'ex' and 'inc' to figure out if the
// VAT is included or not, what happens it the value
// is neither of those? Maybe $_SESSION['vat'] should be
// a boolean value instead? (I.e. true or false, as
// opposed to one of N values.)
$vatInfo = 'VAT may or may not be included...';
// VAT excluded
if ($_SESSION['vat'] === 'ex') {
$vatInfo = 'Ex. VAT';
}
// VAT included
elseif ($_SESSION['vat'] === 'inc') {
$vatInfo = 'Inc. VAT';
// The value of the $price variable will not be changed
// after this so we can just overwrite it here.
$price = ($price * (1 + $vat / 100));
}
// When it comes to money it is nice to format it so
// that it looks good to the user. number_format() was
// made for this.
$price = number_format($price, 2);
// And *return* it, as opposed to echo'ing it.
return "£{$price} {$vatInfo}";
}
// Pass in the price and VAT rate as arguments so that
// they can be used inside the function.
$price = price($row_products['price'], $VATrate);
$main_description = str_replace('[price]', $price, $row_products['description']);
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.
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.