I'm trying, put in header("Content-Type: text/html; charset=utf-8"); but not work
<?PHP
header("Content-Type: text/html; charset=utf-8");
function randStr($rts=20){
$act_chars = "ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ";
$act_val = "";
for($act=0; $act <$rts ; $act++)
{
mt_srand((double)microtime()*1000000);
$act_val .= $act_chars[mt_rand(0,strlen($act_chars)-1)];
}
return $act_val;
}
$dene = randStr(16);
print "$dene";
?>
output
K��A�CÞZU����EJ
There are several mistakes. Don't use []
or strlen()
on a multibyte string. Use mb_substr()
and mb_strlen()
.
Also set the internal encoding of the multibyte extension to UTF-8
:
mb_internal_encoding("UTF-8");
You could also set the encoding on a per-function basis. See the specific function signatures for further details.
Here is an improved version of your code:
header('Content-Type: text/html; charset=utf-8');
mb_internal_encoding("UTF-8");
function randStr($rts = 20) {
$act_chars = 'ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ';
$act_val = '';
$act_chars_last = mb_strlen($act_chars);
for($act = 0; $act < $rts; $act++) {
$act_val .= mb_substr($act_chars, mt_rand(0, $act_chars_last), 1);
}
return $act_val;
}
$dene = randStr(16);
print $dene;
Replaced double quotes by single quotes (saves a tiny amount of time)
Removed mt_srand()
calls because they are automatically done as of PHP 4.2.0 (thanks to feeela for mentioning that in a comment)
Saved the string length - 1 in a variable, so PHP doesn't need to recomputed it in every loop step.
If you want more insights on that topic, checkout the link from deceze in the answer below: What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text.
The problem is that you're assembling a random gobbledygook of bytes and are telling the browser to interpret it as UTF-8. The standard PHP str
functions assume one byte = one character. By randomly picking a multi-byte string apart with those you're not going to get whole characters, only bytes.
If you need encoding aware functions operating on a character level rather than a byte level, use the mb_*
functions.
Instead of using the mb_*
functions, you could alternatively set the following variables in php.ini
if you have access to it:
# following mbstring-variables should be set via php.ini or vhost-configuration (httpd.conf);
# does not work per directory/via .htaccess
mbstring.language = Neutral
mbstring.internal_encoding = UTF-8
mbstring.func_overload = 7
That way you could use your current function as it is and use strlen
or similar functions as if they were a mb_strlen
function.
See php.net – Function Overloading Feature for more details.
See also: