8

I use jQuery to count the value of a textarea on the fly:

function count_chars () {
    count_chars=$('#text_textarea').val().length;
}

...then on submit serialize the form, send the text of the textarea via ajax to a php file which then validates the text on the server side. However, I got problems with newlines and spaces.

Of course, if I just get the text "as it is" from the textarea, php will count each new line as two or 4 characters (\n, ...). So I tried to replace them with something like this:

strlen(str_replace(array("\r", "\n"), ' ', $text)))

or this:

strlen(preg_replace('/\s+/', ' ', trim($text)))

However, if I got e.g. 10 paragraphs and jQuery returns 2500 characters, php will either return 2510 or 2490, depending if I replace new lines with a space or remove them completely. So the difference is 20, but there are only 10 new lines...?

What am I missing? How can I get php to return the same result as jQuery? Where is the problem, in php or in jQuery?

Chris
  • 3,756
  • 7
  • 35
  • 54
  • What character encoding do you use? Which OS does your client run on? (Windows uses different line endings than unix). – Maerlyn Aug 14 '12 at 10:38
  • @Maerlyn: well, it will run on a webserver where I have no idea right now wether it is windows or linux, it is just shared hosting... the character set is utf8, but does it matter here? – Chris Aug 14 '12 at 10:39
  • You'll probably have to normalize line feeds in both places. I don't think you can control what browser inserts by default when user hits "Return". – Álvaro González Aug 14 '12 at 10:39
  • @Chris - `strlen()` countes *bytes*, not *characters*. It's unsuitable for your task if you use UTF-8. – Álvaro González Aug 14 '12 at 10:40
  • @ÁlvaroG.Vicario: oh, thank you... did not know that! is there a php function that is more suitable? – Chris Aug 14 '12 at 10:41
  • 3
    @Chris utf8 is a multibyte charset, you'll need to use `mb_strlen` to count characters and not bytes. – Maerlyn Aug 14 '12 at 10:41
  • @Maerlyn: thank you for your answer! unfortunately mb_strlen returns the same as I commented on Dogbert: 12345, 5 spaces and 5 new lines -> jQuery says 15, php 20... – Chris Aug 14 '12 at 10:51

1 Answers1

3

This should work:

strlen(str_replace("\r", '', $text)))

Explanation:

strlen(str_replace(array("\r", "\n"), ' ', $text)))

Here, you're replacing \r and \n with a space, so the character count doesn't really change.

strlen(preg_replace('/\s+/', ' ', trim($text)))

Here you are reducing continous whitespace into a single ' '.

Dogbert
  • 212,659
  • 41
  • 396
  • 397
  • 2
    You could explain to him why `/\s+/` doesn't do the trick here. That is with `/\s+/` he was collapsing the spaces. And I will go with `preg_replace('/(?:\r|\n)/', ' ', trim($text))` just to be sure. – Prusse Aug 14 '12 at 10:43
  • thank you, Dogbert! It still gives me wrong results, unfortunately. I typed 12345, then 5 spaces and 5 new lines - jQuery said 15, php said 20... – Chris Aug 14 '12 at 10:49
  • @Chris, it seems to work for me, for both `\r\n` and `\n` line endings. Could you post a small piece of php/js code that demonstrates the problem? http://codepad.org/ta5g8eUk – Dogbert Aug 14 '12 at 10:57
  • @Dogbert: you wrote `str_replace("\r",...`, did you mean `str_replace("\r\n",...`?? Because this now works for me, thank you very much! :) – Chris Aug 14 '12 at 11:15