Uruchom ten kod, może zobaczysz gdzie problem:
detect_encoding.php
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8">
</head>
<body>
<pre>
<?php
$login = "rootkękęóąśł";
echo $login . PHP_EOL;
for($i=0; $i<mb_strlen($login); ++$i) {
echo $login[$i] . " = " . mb_detect_encoding($login[$i]) . PHP_EOL;
}
echo PHP_EOL;
$allowedCharacters = array(
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o','p', 'a', 's', 'd',
'f', 'g', 'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n','m',
'ę', 'ó', 'ą', 'ś', 'ł', 'ż', 'ź', 'ć', 'ń',
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
'_'
);
for($i=0; $i<sizeof($allowedCharacters); $i++) {
echo $allowedCharacters[$i] . " = " . mb_detect_encoding($allowedCharacters[$i]) . PHP_EOL;
}
echo PHP_EOL;
echo "\xc4\x99";
echo "\xc3\xb3"; // itd.
?>
</pre>
</body>
</html>
Miałem ten sam problem jeszcze w php 5xx, ale widzę, że w 7xx jest dalej.
Nie ma "automatycznej" konwersji, trzeba dalej kombinować.
Żeby porównać jakiekolwiek znaki diakrytyczne danego języka (polskie ę, ó, ś, ł itd.) muszą mieć identyczne kodowanie. Do porównania lepiej użyć odpowiedni regexp niż tablice pojedynczych znaków, bo możesz sprawdzić od razu całą zawartość zmiennej $login bez sprawdzania jej $login[$i] litera po literze.
How to deal with Polish Characters while using regex?
Wtedy cały ten kod:
function IsLetterMalicious($_letter)
{
$allowedCharacters = array(
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o','p', 'a', 's', 'd',
'f', 'g', 'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n','m',
'ę', 'ó', 'ą', 'ś', 'ł', 'ż', 'ź', 'ć', 'ń',
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
'_'
);
for($i=0; $i<sizeof($allowedCharacters); $i++)
{
if(strcmp($_letter, $allowedCharacters[$i]) ==0)
{
return False;
}
}
return True;
}
for($i=0; $i<strlen($login); $i++)
{
echo($login[$i]);
if(IsLetterMalicious($login[$i]))
{
echo($login[$i]);
} // Tutaj wyświetla się 'k?k?' zamiast 'kękę' a wcześniej normalnie 'kękę' widoczne było na stronie, po tym "booleanie" nagle coś się psuje.
}
Zamieniasz do tego:
$login = "rootkękęóąśł";
if (preg_match("twoj_regexp", $login)) {
echo "dozwolone znaki";
} else {
echo "zawiera niedozwolone znaki";
}
Zdaję sobie sprawę, że posługiwanie się regułami regexp nie jest łatwe, mimo wszystko polecam to rozwiązanie. [ preg_match ] [ Regular Expressions (Perl-Compatible) ]. Edycja, testowanie (w raz z wytłumaczeniem) regexp online.
(Mam taki regexp "zrobiony" , ale na chwilę obecną go nie podam, może za jakiś czas, nie chcę Ciebie jak i innych pozbawić tej przyjemności zrobienia tego samodzielnie).
Możesz dalej próbować z tablicą, tu pomocne polecenia php: [ array_map() ] [ utf8_decode ] [ mb_detect_encoding ] [ in_array ] [ mb_substr ] [ mb_strlen ]
How to convert php array to utf8?
PHP convert string to hex and hex to string
How to print Hexadecimal UTF-8 characters in PHP
Kodowanie polskich znaków
PHP and UTF-8 - polecam cały ten artykuł [ PHP Best Practices ]