【问题标题】:PHP function returning 0 if in loop [duplicate]如果在循环中,PHP函数返回0 [重复]
【发布时间】:2020-12-07 04:27:48
【问题描述】:

我有一个简单的 PHP 函数,可以计算整数中特定数字的个数

function countOccurrence($number, $digit){
    $result = 0;
    while ($number > 0){
        $lastDigit = $number % 10;
        if($lastDigit === $digit){
            $result++;
        }
        $number = ($number - $lastDigit)/10;
    }
    return $result;
}

它自己完全可以正常工作[用 countOccurrence(1111, 1) 测试并返回 4]

但是当我在循环中使用它时,它总是返回 0。

if (isset($_POST['submit'])){
    $startNum = $_POST['startNum'];
    $endNum = $_POST['endNum'];
    $findNum = $_POST['findNum'];
    $occur = 0;

    echo 'from ' . $startNum . ' to ' . $endNum . ' find how many times ' . $findNum . ' occurs';
    echo '<br>';

    $numRange = makeArray($startNum, $endNum);
    foreach ($numRange as $number){
        $test = countOccurrence($number, $findNum);
        echo 'number: ' . $number . ' find: ' . $findNum . ' countOccurrence('.$number.', '.$findNum.'): ' . $test . '<br>';
    }

    echo '<br>';
    echo '<p>The digit ' . $findNum . ' occurred ' . $occur . ' times within the range</p>';
    echo '<br>';
    echo 'countOccurrence(1111, 1) = ';
    $test = countOccurrence(1111, 1);
    echo $test;
}

我从中得到的结果是“number: 1 find: 1 countOccurrence(1, 1): 0”等等

我不确定这里哪里出了问题,因为当我手动测试函数时它看起来还不错

编辑:这是我的完整代码

<html lang="en">
    <head>
        <title>Number Counter</title>
        <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
    </head>
    <body>
        <div class="container">
            <form id="form" class="form-group" action="" method="post">
                <div class="form-group">
                    <label for="startId">Start Num</label>
                    <input type="number" name="startNum" id="startId" class="form-control">
                </div>

                <div class="form-group">
                    <label for="endId">End Num</label>
                    <input type="number" name="endNum" id="endId" class="form-control">
                </div>

                <div class="form-group">
                    <label for="findId">Find Num</label>
                    <input type="number" name="findNum" id="findId" class="form-control">
                </div>

                <input type="submit" name="submit">
            </form>
        </div>
    <script src="bootstrap/js/jquery-3.5.1.min.js"></script>
    <script src="bootstrap/js/jquery.validate.min.js"></script>
    <script src="bootstrap/js/bootstrap.min.js"></script>
    <script src="validate.js"></script>
    </body>
</html>

<?php

function countOccurrence($number, $digit){
    $result = 0;
    while ($number > 0){
        $lastDigit = $number % 10;
        if($lastDigit === $digit){
            $result++;
        }
        $number = ($number - $lastDigit)/10;
    }
    return $result;
}

function makeArray($startNum, $endNum){
    $numRange = array();
    for($ctr = $startNum; $startNum <= $endNum; $startNum++){
        array_push($numRange, $startNum);
    }
    return $numRange;
}

if (isset($_POST['submit'])){
    $startNum = $_POST['startNum'];
    $endNum = $_POST['endNum'];
    $findNum = $_POST['findNum'];
    $occur = 0;

    echo 'from ' . $startNum . ' to ' . $endNum . ' find how many times ' . $findNum . ' occurs';
    echo '<br>';

    $numRange = makeArray($startNum, $endNum);
    foreach ($numRange as $number){
        $test = countOccurrence($number, $findNum);
        echo 'number: ' . $number . ' find: ' . $findNum . ' countOccurrence('.$number.', '.$findNum.'): ' . $test . '<br>';
    }

    echo '<br>';
    echo '<p>The digit ' . $findNum . ' occurred ' . $occur . ' times within the range</p>';
    echo '<br>';
    echo 'countOccurrence(1111, 1) = ';
    $test = countOccurrence(1111, 1);
    echo $test;
}


编辑:感谢您的回答!我最终将 $_POST 值解析为 int ,而不是像这样获得预期值

    $startNum = (int) $_POST['startNum'];
    $endNum =  (int) $_POST['endNum'];
    $findNum =  (int) $_POST['findNum'];

【问题讨论】:

  • 您还需要在问题中包含您的 makeArray() 函数。以及更多关于您的输入数据和预期结果的示例。并且可能是您的表单代码,因为您没有在示例中显示 $_POST 获得的内容。
  • @TimBrownlaw 可能是我的机器出错,因为我在另一台机器上复制了完全相同的代码并得到了预期的结果。但我仍然会更新我的代码
  • 你也可以使用substr_count(1111, 1),更简单一点:)
  • range($startNum, $endNum) 而不是makeArray

标签: php


【解决方案1】:
function countOccurrence($number, $digit){
    $result = 0;
    while ($number > 0){
        $lastDigit = $number % 10;
        if($lastDigit === $digit){ // <-- bug is here
            $result++;
        }
        $number = ($number - $lastDigit)/10;
    }
    return $result;
}

由于您在进行严格比较,因此这些值永远不会相等。原因如下:

当您从 $_POST 获取数据时,它始终是一个字符串。所以你打电话给countOccurrence(1111, '1'),它会返回0 :)

正如我在 cmets 中提到的,你可以用这些替换你的函数:

如果您想坚持自己的功能。将输入转换为 int,然后使用 intval 将其传递给您的函数。

附加信息

为了防止这种情况在未来发生。看看这个post。它是php的一个比较新的特性,是针对this类型的场景引入的。

【讨论】:

  • 请考虑(在发布新答案之前)是否可以通过参考 Stack Overflow 上预先存在的答案来解决问题。只要有可能,请不要回答问题 - 而是将页面作为副本关闭。如果您有新的和有价值的见解要添加到现有页面,请改为在那里发布答案。
  • 好的,我将在您提到的帖子中提供此信息。
  • 它可能已经存在了。我发布了两个不同的副本以涵盖此页面上提到的两个问题:1. 比较 2. 计数技术。我认为现有答案很好地涵盖了这些页面。多余的答案将被标记和删除,因此除非您有新的和有价值的内容要添加,否则不值得发布。
  • 不,不是:)
  • 您指的是哪个页面?第一个副本有 21 个答案(答案很臃肿——其中一些非常全面)。第二个副本有 6 个答案。
【解决方案2】:

这是你的小熊熊所在的地方......

if($lastDigit === $digit){

您在这里期望的是按值和类型进行比较 (===)。

您可以使用 gettype(); 验证这一点

while ($number > 0) {
    $lastDigit = $number % 10;
    echo '$lastDigit is a '.gettype($lastDigit);
    echo ' $digit is a '.gettype($digit);
    echo '<br>';

    if ($lastDigit === $digit) {
        $result++;
    }
    $number = ($number - $lastDigit) / 10;
}

来自 POST 的值总是字符串类型。所以 $digit 是一个字符串,而 $lastDigit 是一个数字(整数)。使用 === 会失败,因为它们不是同一类型。

因此,由于 PHP 具有自己进行类型转换的能力...将 === 更改为 == 将起作用。即。

if ($lastDigit == $digit) {

PHP 将尝试将 RHS 值转换为 LHS 类型,然后执行比较。

所以现在您只是进行比较,PHP 正在将 $digit 转换为整数。

一种更安全的方法是强制施法。 因此,您可以将 $digit 从字符串转换为整数,并使用您现有的代码。

function countOccurrence($number, $digit) {
    $result = 0;

    $digit = intval($digit); // Force $digit to be an integer
    while ($number > 0) {
        $lastDigit = $number % 10;
        echo '$lastDigit is a '.gettype($lastDigit);
        echo ' $digit is a '.gettype($digit);
        echo '<br>';
        if ($lastDigit === $digit) {
            $result++;
        }
        $number = ($number - $lastDigit) / 10;

        echo ' $number is a '.gettype($number);
    }

    return $result;
}

因此从中吸取的教训是,在使用 === 时,请确保您的类型也相同。

【讨论】:

  • 谢谢!!我最终只是像这样解析 $_POST 中的值 $startNum = (int) $_POST['startNum'];你提到的其他东西也非常有用!
  • @Tim 请考虑(在发布新答案之前)是否可以通过参考 Stack Overflow 上的现有答案来解决问题。只要有可能,请不要回答问题 - 而是将页面作为副本关闭。如果您有新的和有价值的见解要添加到现有页面,请改为在此处发布答案。
猜你喜欢
  • 2014-10-02
  • 2017-07-31
  • 2011-08-18
  • 2015-08-29
  • 2012-03-09
  • 1970-01-01
  • 2015-08-14
  • 2011-05-10
  • 1970-01-01
相关资源
最近更新 更多