2

Consider

$foo = "abcdefg";

echo $foo[0]; //outputs a

So it seems like strings are like array of characters but then why

foreach($foo as $char)
{
echo $char;
}

does not work and gives following Warning ??

Warning: Invalid argument supplied for foreach() 
9
  • The old notation (still working but deprecated) was echo $foo{0}; I never understood why they changed it. Commented Sep 10, 2011 at 13:00
  • @Jacco: It isn't deprecated ;) Commented Sep 10, 2011 at 13:10
  • @NikiC: Are you triple sure? I was under that same impression. Commented Sep 10, 2011 at 13:11
  • @Jon: I am ;) codepad.viper-7.com/X0lgFz (It was deprecated a short time during 5.3 development. I don't know why they reverted it, maybe just an accident.) Commented Sep 10, 2011 at 13:12
  • 1
    @jacco I just checked it and its working and I will prefer {} over [] with string since it makes me think it as a array :) Commented Sep 10, 2011 at 13:25

4 Answers 4

1

Adding string iteration support to foreach was discussed but declined. There were mainly two reasons for this decision:

  • It makes applications harder to debug. Usually you don't want to iterate over the characters of a string. You need that only very rarely. So if you do iterate over a string you probably just made a programming mistake - and PHP will tell you so. If string iteration were introduces this kind of error would be hard to catch.
  • What is a "character"? Should PHP iterate over each single byte? Should it iterate over characters (which can be multiple bytes)? If so, what should it do if it encounters a malformed multibyte sequence? And where does it get the charset from?

To solve both problems there was a proposal to introduce a TextIterator, which you pass a string and a charset. That way you can't accidentally iterate a string and the byte vs character problem doesn't exist. I'm not sure though what the state of the TextIterator is currently.

Sign up to request clarification or add additional context in comments.

4 Comments

TextIterator sounds like a great idea. :)
it would be cool if PHP interpreter could have taken care of this inside foreach for us now it seems wired to not to think string as array of characters .
You often need to interate by graphemes (user-visible characters), not by mere code point (programmer-visible character) let alone by uselessly stupid code units (computer-visible character). You can use regexes to step through a string a grapheme at a time using \X.
@tchrist: Note though that PHP aint Perl. In PCRE \X matches only extended unicode sequences (i.e. a non-mark character followed by an arbitrary number of mark-characters), whereas Perl goes all the way of matching extended grapheme clusters.
1

NikiC's answer covers why doing this directly is not possible.

If you want to iterate over a string as if it were an array, you can be explicit by using str_split:

foreach(str_split($foo) as $char) 
{ 
    echo $char; 
} 

Warning: str_split is not encoding-aware, so you will end up iterating over bytes and not over characters. Iterating over characters is a little more involved, as there is no equivalent multibyte split function. You can roll your own using the regex-enabled mb_split, look at the comments from PHP.net for ideas.

There are other answers here suggesting you should cast the string to an array, but I don't understand why that would work. The documentation is pretty explicit:

For any of the types: integer, float, string, boolean and resource, converting a value to an array results in an array with a single element with index zero and the value of the scalar which was converted. In other words, (array)$scalarValue is exactly the same as array($scalarValue).

And indeed, doing this does not work as suggested.

Comments

0

Even though their characters can be addressed using square brackets, strings aren't arrays. Emphasis mine:

Characters within strings may be accessed and modified by specifying the zero-based offset of the desired character after the string using square array brackets, as in $str[42]. Think of a string as an array of characters for this purpose.

Comments

-1

it is called "syntax sugar".

For example, in 5.4 you'll be able to do like this echo func()[0];
That doesn't mean that a function is really an array of charactes.
It's just a syntax.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.