1

I'm learning PHP and I would like to display a different price for my product according to the day of the week. For example on Mondays the price should be 50% off, on Wednesdays it should have a 10% more expensive and so on. I was thinking of using a function with a switch statement but I can't make it to work. Hope somebody can give me some tips!

    function day_of_week($day) {
    $day = "Monday";

    switch ($day) {
        case "Monday":
            $key['price'] / 2;
            break;
        case "Wednesday":
            $key['price'] * 1.1;
            break;
        case "Friday":
            if($key['price'] >= 200) {
                $key['price'] - 20;
            }   
    }

}
Today's price:
<?php echo day_of_week($day); ?>
  • 3
    Don’t assign a value to $day within the function. It will overwrite whatever you pass to the function parameter. – Leander Iversen Oct 14 '18 at 12:08
  • @LeanderIversen Hi! I've put it outside the function but nothing is changing. Where should I put it? –  Oct 14 '18 at 12:11
  • 1
    Many problems. You're overwriting `$day` so it will always be "Monday". Where did `$key` come from? You aren't doing anything with the result of whatever calculation you perform on `$key['price']`. You're not returning the result from your function. – rickdenhaan Oct 14 '18 at 12:11
  • Outside the function is fine. You also need a return statement, e.g return $key[‘price’] / 2. – Leander Iversen Oct 14 '18 at 12:13

2 Answers2

1

As mentioned in comments there were many issues like $day reinitializing again and $key not in the function scope and not returning anything etc...

Following is the working code:

<?php
$day = date('l');
$key['price'] = 2000;
function day_of_week($day , $price) {

    switch ($day) {
        case "Monday":
            return $price / 2;
        case "Wednesday":
            return $price * 1.1;
        case "Friday":
            if($price >= 200) {
                return $price - 20;
            }
    }
    return $price;
}
echo "Price for ".$day.": ".day_of_week($day, $key['price']);

 ?>

Another possible way!

<?php
/**
 * Created by PhpStorm.
 * User: Ussaid Iqbal
 * Date: 10/14/18
 * Time: 4:09 PM
 */
$day = "Wednesday";
$key["price"] = 2000;

function day_of_week($day) {
    global $key;
    switch ($day) {
        case "Monday":
            return $key["price"] / 2;
        case "Wednesday":
            return $key["price"] * 1.1;
        case "Friday":
            if($key["price"] >= 200) {
                return $key["price"] - 20;
            }
    }
    return $key["price"];
}
echo "Today's price: ".day_of_week($day);

 ?>
Ussaid Iqbal
  • 786
  • 1
  • 7
  • 16
  • It is working! Many thanks! Can you explain me how $key['price'] = 2000 works? I don't really understand it. –  Oct 14 '18 at 12:22
  • The `break;` for "Wednesday" isn't really necessary since you have a return before it :-) – M. Eriksson Oct 14 '18 at 12:24
  • I assumed it was stored in an array now that array is defined outside of the function lets say globally so to access that variable you need to pass it through the function or call **global $WhateverVariableYouNeedInsideFunction;** at the start of function. – Ussaid Iqbal Oct 14 '18 at 12:28
  • 2
    Just a note about the `$price`-variable. It should be passed to the function (like this answer suggests). Using `global` is an anti-pattern and should always be avoided whenever possible (which it more or less always is if you write your code using best practices). – M. Eriksson Oct 14 '18 at 12:31
  • @MagnusEriksson `global` constants are fine while using `global` for non-constant variables should be avoided. :-) – Ussaid Iqbal Oct 14 '18 at 12:34
  • If you have variables as constants which you pass around using `global`, you have a code smell already. Variables are variable, constants are constant. Constants are global by design and don't need `global`. Like I said, if you need to use the `global` keyword, you're most likely not following best practices to begin with. – M. Eriksson Oct 14 '18 at 12:39
  • Your comments were a bit unclear :-) I was only talking about the `global` keyword. – M. Eriksson Oct 14 '18 at 12:41
  • @UssaidIqbal Thanks! The only problem I am getting is that eventhougt it is Sunday today, the program keeps applying the 50% off which should only be on Mondays. –  Oct 14 '18 at 12:42
  • @Nebula just tested it's working fine, check the updated answer along with the day printed! – Ussaid Iqbal Oct 14 '18 at 12:44
  • @MagnusEriksson I am still a learner, and i learn by helping others. So maybe you are right, can you explain further why we should avoid using global? – Ussaid Iqbal Oct 14 '18 at 12:52
  • @UssaidIqbal he just told you why – DevMoutarde Oct 14 '18 at 13:02
0

You could create an anonymous object as a controller to do this. It would require creating anonymous functions and using call_user_func_array() to execute the closure.

$priceChart = (object)
[
    'monday' => function($price) {
        return (int) $price / 2;
    },
    'wednesday' => function($price) {
        return (int) $price * 1.1;
    },
    'friday' => function($price) {
        return (int) $price > 200 ? (int) $price - 20 : (int) $price;
    }
];

$price = 20.00; // Can be of type string
$currentDay = 'WednEsdAy'; // Capitals do not matter or use date('l');
$newPrice = isset($priceChart->{strtolower($currentDay)}) ? call_user_func_array($priceChart->{strtolower($currentDay)}, [$price]) : $price;

You can see a working example over at 3v4l.

Jaquarh
  • 6,493
  • 7
  • 34
  • 86