Lors du passage d'une chaîne non nucère, BCCOMP essaiera de convertir la chaîne en un nombre pour la comparaison, ce qui est similaire à la conversion implicite des nombres de points flottants ou des entiers. Les éléments suivants se produisent généralement:
La chaîne commence par un nombre, suivie d'un caractère non numérique: seule la partie d'ouverture est prise comme le nombre de comparaison.
La chaîne ne contient aucun nombre: elle sera traitée comme 0.
Donnez un exemple:
<?php
var_dump(bccomp('123abc', '123')); // Sortir 0,Indique l'égalité,parce que'123abc'Être considéré123
var_dump(bccomp('abc', '0')); // Sortir 0,'abc'Être considéré0
var_dump(bccomp('abc', '1')); // Sortir -1,0 < 1
?>
Ce comportement est très susceptible de conduire à une erreur de jugement lorsqu'il s'agit de chaînes non nucères, surtout lorsque la chaîne ne commence pas par un nombre.
Si vous devez comparer les chaînes numériques pures, utilisez simplement BCCOMP . Cependant, si la chaîne peut contenir du contenu non numerique, il est recommandé de faire ce qui suit en premier:
Utilisez des fonctions PHP régulières ou intégrées telles que IS_NUMERIC pour juger:
<?php
function safe_bccomp($a, $b, $scale = 0) {
if (!is_numeric($a) || !is_numeric($b)) {
throw new InvalidArgumentException("Le paramètre doit être une chaîne numérique");
}
return bccomp($a, $b, $scale);
}
try {
echo safe_bccomp('123abc', '123'); // Faire une exception
} catch (InvalidArgumentException $e) {
echo $e->getMessage();
}
?>
Cela évite la comparaison incorrecte des chaînes non nucères comme 0.
Si la logique métier le permet, vous pouvez utiliser régulièrement pour extraire uniquement les pièces numériques de la chaîne, puis comparer:
<?php
function extract_numeric($str) {
preg_match('/^[+-]?(\d+)(\.\d+)?/', $str, $matches);
return $matches[0] ?? '0';
}
$a = extract_numeric('123abc');
$b = extract_numeric('123');
echo bccomp($a, $b); // 0
?>
Cette méthode convient au cas où le préfixe a des pièces numériques dans la chaîne.
BCComp est conçu pour les chaînes numériques. Lorsque des chaînes non numériques sont passées, elles seront automatiquement converties en nombres, ce qui peut conduire à des résultats de comparaison inexacts.
Avant d'utiliser BCComp , il est recommandé de vérifier si les paramètres sont des chaînes numériques légales.
Lorsqu'une chaîne qui doit être comparée peut contenir d'abord du contenu non numérique, filtrer ou lancer les exceptions pour éviter les erreurs de jugement.
Ce n'est que par la vérification et le prétraitement des entrées raisonnables que nous pouvons nous assurer que BCComp fonctionne correctement en comparaison et éviter les erreurs logiques inattendues.
<?php
// Comparez les pièces numériques dans la chaîne de filtre
function safe_compare($a, $b, $scale = 0) {
preg_match('/^[+-]?(\d+)(\.\d+)?/', $a, $matchA);
preg_match('/^[+-]?(\d+)(\.\d+)?/', $b, $matchB);
$numA = $matchA[0] ?? '0';
$numB = $matchB[0] ?? '0';
return bccomp($numA, $numB, $scale);
}
// Exemple
echo safe_compare('123abc', '123'); // Sortir0
echo safe_compare('abc', '0'); // Sortir0
echo safe_compare('abc', '1'); // Sortir-1
?>