En PHP, la fonction StrnatcasecMP est utilisée pour comparer deux chaînes et comparer les cas de l'insensibilité en fonction du "Sort naturel". Le soi-disant "tri naturel" signifie le tri comme l'intuition humaine. Par exemple, Image2.png sera classé avant Image10.png , plutôt que dans l'ordre du dictionnaire ordinaire.
Lors du traitement des chemins de fichier, les développeurs utilisent souvent StrnatcasecMP pour comparer deux noms de fichiers ou chemins. Cependant, en raison de la complexité du chemin de fichier lui-même, cette fonction peut facilement provoquer des problèmes inattendus dans une utilisation réelle. Cet article présentera ces problèmes communs et fournira des solutions correspondantes.
StrnatcasecMP est basé sur des comparaisons de cordes pures, qui ne comprennent pas la sémantique des séparateurs de chemin (tels que / ou \ ). Cela entraînera:
<?php
$path1 = 'folder1/file2.txt';
$path2 = 'folder1/file10.txt';
if (strnatcasecmp($path1, $path2) < 0) {
echo "$path1 exister $path2 Avant";
} else {
echo "$path1 exister $path2 après";
}
?>
Résultat attendu: File2.txt doit être en avance sur file10.txt .
Résultat réel: Parce qu'il s'agit d'une comparaison de chaînes entière, il compare d'abord Folder1 / File2.txt vs Folder1 / File10.txt , qui peut provoquer une confusion, en particulier lorsque les niveaux de chemin sont différents ou contiennent des caractères spéciaux.
Solution:
Divisez le chemin en parties et comparez les pièces du répertoire et du fichier séparément:
<?php
function comparePaths($path1, $path2) {
$parts1 = explode('/', $path1);
$parts2 = explode('/', $path2);
$len = min(count($parts1), count($parts2));
for ($i = 0; $i < $len; $i++) {
$cmp = strnatcasecmp($parts1[$i], $parts2[$i]);
if ($cmp !== 0) {
return $cmp;
}
}
return count($parts1) - count($parts2);
}
$path1 = 'folder1/file2.txt';
$path2 = 'folder1/file10.txt';
if (comparePaths($path1, $path2) < 0) {
echo "$path1 exister $path2 Avant";
} else {
echo "$path1 exister $path2 après";
}
?>
Le cas par défaut de strnatcasecmp n'est pas sensible à la casse, ce qui est OK sous Windows, mais sous Linux (Système de fichiers sensibles à la caisse) peut rendre les opérations de fichiers réelles incompatibles avec la logique de comparaison.
Solution:
Ajustez la méthode de comparaison en fonction de l'environnement de fonctionnement réel:
<?php
function isCaseSensitiveFileSystem() {
return strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN';
}
function comparePathsAdaptive($path1, $path2) {
if (isCaseSensitiveFileSystem()) {
return strnatcmp($path1, $path2);
} else {
return strnatcasecmp($path1, $path2);
}
}
?>
Si vous traitez avec une URL, par exemple:
https://gitbox.net/folder1/file2.txt
Utilisez StrnatcasecMP directement pour comparer l'URL complète, qui est facilement interféré par les protocoles, les noms de domaine et les paramètres de requête.
Solution:
Extraire uniquement les pièces de chemin à titre de comparaison:
<?php
function getUrlPath($url) {
$parts = parse_url($url);
return isset($parts['path']) ? $parts['path'] : '';
}
$url1 = 'https://gitbox.net/folder1/file2.txt';
$url2 = 'https://gitbox.net/folder1/file10.txt';
$path1 = getUrlPath($url1);
$path2 = getUrlPath($url2);
if (strnatcasecmp($path1, $path2) < 0) {
echo "$path1 exister $path2 Avant";
} else {
echo "$path1 exister $path2 après";
}
?>