tags:

views:

202

answers:

3

I use document.getElementById("text").value.length to get the string length through javascript, and mb_strlen($_POST['text']) to get the string length by PHP and both differs very much. Carriage returns are converted in javascript before getting the string length, but I guess some characters are not being counted.

For example,

[b]15. Umieszczanie obrazka z logo na stronie zespołu[/b]

This block of text is calculated 57 in javascript and 58 in PHP. When the text gets long, the difference increases. Is there any way to overcome this?

A: 

I notice that there is a non-standard character in there (the ł) - I'm not sure how PHP counts non-standard - but it could be counting that as two. What happens if you run the test without that character?

slightlymore
Without that it is accurate, I have already been suspecting that it is about the encoding... Is there an equivalent function for Javascript?
TheOnly92
@TheOnly92, why do you want to fix it in the end that is doing it correct already? Isn't it better to tell the PHP end how it should calculate the length correctly (see the Matthew's comment to your question).
Fredrik
The fact is my database storage collation doesn't take utf8 into account I think, it counts those character lengths as 2...
TheOnly92
A: 

I have found an mb_strlen equivalent function for Javascript, maybe this might be useful for someone else:

function mb_strlen(str) {
    var len = 0;
    for(var i = 0; i < str.length; i++) {
        len += str.charCodeAt(i) < 0 || str.charCodeAt(i) > 255 ? 2 : 1;
    }
    return len;
}

Thanks to all that tried to help!

TheOnly92
Who knew that multi byte characters were encoded using 3 bytes?! First time I heard of it..
PP
@PP It is of course incorrect and the function will only work for mixes of characters either in the 0-127 range or in a character set that doesn't fit in two. I really thing @TheOnly92 should solve it right instead.
Fredrik
-1. `ç` takes 2 bytes in UTF-8.
KennyTM
Sorry for the mistake, just edited it.
TheOnly92
Still wrong. `™` takes 3 bytes.
KennyTM
Okay, so all characters larger than or equals to 2048 takes 3 bytes...
TheOnly92
@TheOnly92: All characters that needs two bytes to be represented as UTF-8 will take two bytes, all that needs three bytes will take three bytes and those who takes four bytes will take four bytes, etc, etc. The limit between 2 and 3 should be much higher than 2048 though.
Fredrik
@Fredrik Well then, what do you suggest to make the function more perfect?
TheOnly92
@TheOnly92 You either need to do proper UTF-8 decoding and count the bytes or you shouldn't do it at all because javascript already calculate the length correctly for you. If you want the length to be correct in php you should call mb_strlen() with the correct arguments there, just like you have already got answers explaining.
Fredrik
Okay, what is the proper way of UTF-8 decoding for javascript? I'm counting bytes with PHP as well.
TheOnly92
+1  A: 

If you're trying to get the length of an UTF-8 encoded string in PHP, you should specify the encoding in the second parameter of mb_strlen, like so:

mb_strlen($_POST['text'], 'UTF-8')

Also, don't forget to call stripslashes on the POST-var.

Maarten Sander