루프에서 0을 반환하는 PHP 함수 [중복]
정수에서 특정 숫자의 수를 계산하는 간단한 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'];
답변
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을 반환 할 전화 를하고 있습니다 :)
주석에서 언급했듯이 함수를 다음으로 바꿀 수 있습니다.
- substr_count 대신에
countOccurrence
- range 대신에
makeArray
당신이 당신의 기능을 고수하고 싶다면. intval 을 사용하여 함수에 전달하기 전에 입력을 int로 변환하십시오 .
추가 정보
미래에 이런 일이 발생하지 않도록합니다. 이 게시물을보십시오 . 이 유형의 시나리오 에 도입 된 비교적 새로운 PHP 기능입니다 .
이것은 당신의 작은 벌레 곰이있는 곳입니다 ...
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는 자체적으로 typecast하는 기능이 있으므로 ===를 ==로 변경하면 작동합니다. IE
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;
}
따라서 여기서 얻은 교훈은 ===를 사용할 때 유형도 동일한 지 확인하십시오.