drl47263 2017-04-07 11:32
浏览 41
已采纳

对PHP中的简单开关感到困惑(5.5.38)

I have setup the following class which mimics one I am currently working on and trying to fix.

The goal

To return a fee (value) based on an initial value that is passed in.

The issues

I have two issues with the current code below:

  1. When the first value that is passed in is 0 (zero) 12p is returned which is incorrect - it should be caught by the first case and return 15p.

  2. I am yet to tackle it but I want to return the issuance fee for the last case that is satisfied (if the next ones are not defined). For the example below; the last restriction to be set is the $lower_3 variable - which means that any value passed in that is greater than 31* should return a fee of 10p. I am however seeing that null is being returned as the checks just fall through to the last case.

The code

<?php

class IssuanceScheme
{
    private $lower_1 = 0;
    private $upper_1 = 20;
    private $issuanceFee_1 = '15p';

    private $lower_2 = 21;
    private $upper_2 = 30;
    private $issuanceFee_2 = '12p';

    private $lower_3 = 31;
    private $upper_3 = null; //50;
    private $issuanceFee_3 = '10p';

    private $lower_4 = null; //51;
    private $upper_4 = null; //75;
    private $issuanceFee_4 = null;

    private $lower_5 = null; //76;
    // no $upper_5
    private $issuanceFee_5 = null;

    public function calculateIssuanceFee($volume)
    {
        $issuanceFee = $this->issuanceFee_1;

        switch ($volume) {
            case ($volume >= $this->lower_1 && $volume <= $this->upper_1):
                $issuanceFee = $this->issuanceFee_1;
                break;
            case ($volume >= $this->lower_2 && $volume <= $this->upper_2):
                $issuanceFee = $this->issuanceFee_2;
                break;
            case ($volume >= $this->lower_3 && $volume <= $this->upper_3):
                $issuanceFee = $this->issuanceFee_3;
                break;
            case ($volume >= $this->lower_4 && $volume <= $this->upper_4):
                $issuanceFee = $this->issuanceFee_4;
                break;
            case ($volume >= $this->lower_5):
                $issuanceFee = $this->issuanceFee_5;
                break;
        }

        return $issuanceFee;
    }
}

$issuanceScheme = new IssuanceScheme;

// 15p
echo sprintf("Passed in: %s, Exp: %s, Got: %s", 0, '15p', $issuanceScheme->calculateIssuanceFee(0));
echo sprintf("Passed in: %s, Exp: %s, Got: %s", 5, '15p', $issuanceScheme->calculateIssuanceFee(5));
echo sprintf("Passed in: %s, Exp: %s, Got: %s", 10, '15p', $issuanceScheme->calculateIssuanceFee(10));
echo sprintf("Passed in: %s, Exp: %s, Got: %s", 15, '15p', $issuanceScheme->calculateIssuanceFee(15));
echo sprintf("Passed in: %s, Exp: %s, Got: %s", 20, '15p', $issuanceScheme->calculateIssuanceFee(20));

// 12p
echo sprintf("Passed in: %s, Exp: %s, Got: %s", 25, '12p', $issuanceScheme->calculateIssuanceFee(25));
echo sprintf("Passed in: %s, Exp: %s, Got: %s", 30, '12p', $issuanceScheme->calculateIssuanceFee(30));

// 10p
echo sprintf("Passed in: %s, Exp: %s, Got: %s", 50, '10p', $issuanceScheme->calculateIssuanceFee(50));
echo sprintf("Passed in: %s, Exp: %s, Got: %s", 60, '10p', $issuanceScheme->calculateIssuanceFee(60));
echo sprintf("Passed in: %s, Exp: %s, Got: %s", 75, '10p', $issuanceScheme->calculateIssuanceFee(75));
echo sprintf("Passed in: %s, Exp: %s, Got: %s", 100, '10p', $issuanceScheme->calculateIssuanceFee(100));

The result

Passed in: 0, Exp: 15p, Got: 12p // Error, expected is 15p
Passed in: 5, Exp: 15p, Got: 15p
Passed in: 10, Exp: 15p, Got: 15p
Passed in: 15, Exp: 15p, Got: 15p
Passed in: 20, Exp: 15p, Got: 15p
Passed in: 25, Exp: 12p, Got: 12p
Passed in: 30, Exp: 12p, Got: 12p
Passed in: 50, Exp: 10p, Got: // Not implemented (see goal 2, and not below)
Passed in: 60, Exp: 10p, Got:
Passed in: 75, Exp: 10p, Got:
Passed in: 100, Exp: 10p, Got:

The second goal hasn't been implemented but I want to return the last issuance fee that was satisfied. In this case 10p should be returned as the values passed in are greater than 31.

  • 写回答

3条回答 默认 最新

  • duandao1931 2017-04-07 11:43
    关注

    You misunderstand switch statement

    switch($var) {
        case $val:
            //something
    

    Means

    if $var == $val then do //something

    So in your code it's:

    switch ($volume) {
        case ($volume >= $this->lower_1 && $volume <= $this->upper_1):
            $issuanceFee = $this->issuanceFee_1;
            break;
    

    which means

    if $volume == ($volume >= $this->lower_1 && $volume <= $this->upper_1) then do $issuanceFee = $this->issuanceFee_1;

    Which is not true for $volume=0, because ($volume >= $this->lower_1 && $volume <= $this->upper_1) is true, so you get condition $volume == true which is 0 == true.

    You need to reorganize your code probably into if {} elseif {} else {} statements.

    For the second issue, you could change $volume <= $this->upper_1 to ($this->upper_1===null || $volume <= $this->upper_1), and the same for other levels.

    That will skip upper limit check if it's set to null (which means something like unlimited).

    public function calculateIssuanceFee($volume)
    {
        $issuanceFee = $this->issuanceFee_1;
        if ($volume >= $this->lower_1 && ($this->upper_1===null || $volume <= $this->upper_1)) {
            return $this->issuanceFee_1;
        }
        if ($volume >= $this->lower_2 && ($this->upper_2===null || $volume <= $this->upper_2)) {
            return $this->issuanceFee_2;
        }
        if ($volume >= $this->lower_3 && ($this->upper_3===null || $volume <= $this->upper_3)) {
            return $this->issuanceFee_3;
        }
        if ($volume >= $this->lower_4 && ($this->upper_4===null || $volume <= $this->upper_4)) {
            return $this->issuanceFee_4;
        }
        if ($volume >= $this->lower_5) {
            return $this->issuanceFee_5;
        }
    
    }
    

    Here's working example: https://3v4l.org/uamib

    Passed in: 0, Exp: 15p, Got: 15p 
    Passed in: 5, Exp: 15p, Got: 15p 
    Passed in: 10, Exp: 15p, Got: 15p 
    Passed in: 15, Exp: 15p, Got: 15p 
    Passed in: 20, Exp: 15p, Got: 15p 
    Passed in: 25, Exp: 12p, Got: 12p 
    Passed in: 30, Exp: 12p, Got: 12p 
    Passed in: 50, Exp: 10p, Got: 10p 
    Passed in: 60, Exp: 10p, Got: 10p 
    Passed in: 75, Exp: 10p, Got: 10p 
    Passed in: 100, Exp: 10p, Got: 10p
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料