Getting the first character of a string with $str[0]

398,324

Solution 1

Yes. Strings can be seen as character arrays, and the way to access a position of an array is to use the [] operator. Usually there's no problem at all in using $str[0] (and I'm pretty sure is much faster than the substr() method).

There is only one caveat with both methods: they will get the first byte, rather than the first character. This is important if you're using multibyte encodings (such as UTF-8). If you want to support that, use mb_substr(). Arguably, you should always assume multibyte input these days, so this is the best option, but it will be slightly slower.

Solution 2

The {} syntax is deprecated as of PHP 5.3.0. Square brackets are recommended.

Solution 3

Lets say you just want the first char from a part of $_POST, lets call it 'type'. And that $_POST['type'] is currently 'Control'. If in this case if you use $_POST['type'][0], or substr($_POST['type'], 0, 1)you will get C back.

However, if the client side were to modify the data they send you, from type to type[] for example, and then send 'Control' and 'Test' as the data for this array, $_POST['type'][0] will now return Control rather than C whereas substr($_POST['type'], 0, 1) will simply just fail.

So yes, there may be a problem with using $str[0], but that depends on the surrounding circumstance.

Solution 4

My only doubt would be how applicable this technique would be on multi-byte strings, but if that's not a consideration, then I suspect you're covered. (If in doubt, mb_substr() seems an obviously safe choice.)

However, from a big picture perspective, I have to wonder how often you need to access the 'n'th character in a string for this to be a key consideration.

Solution 5

In case of multibyte (unicode) strings using str[0] can cause a trouble. mb_substr() is a better solution. For example:

$first_char = mb_substr($title, 0, 1);

Some details here: Get first character of UTF-8 string

Share:
398,324

Related videos on Youtube

Tatu Ulmanen
Author by

Tatu Ulmanen

Web programmer from Finland.

Updated on July 25, 2020

Comments

  • Tatu Ulmanen
    Tatu Ulmanen almost 4 years

    I want to get the first letter of a string and I've noticed that $str[0] works great. I am just not sure whether this is 'good practice', as that notation is generally used with arrays. This feature doesn't seem to be very well documented so I'm turning to you guys to tell me if it's all right – in all respects – to use this notation?

    Or should I just stick to the good ol' substr($str, 0, 1)?

    Also, I noted that curly braces ($str{0}) works as well. What's up with that?

    • Máster
      Máster over 6 years
      plus 1 for the "good ol' substr($str, 0, 1)" .
  • VolkerK
    VolkerK over 14 years
    docs.php.net/language.types.string : Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose. However, this syntax is deprecated as of PHP 5.3.0. Use square brackets instead, such as $str[42].
  • Marco Demaio
    Marco Demaio about 12 years
    @VolkerK: at the link you provided I noticed they removed the note on the PHP manual they left only: Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose. So I'm wondering if they decided that using {} is NOT deprecated anymore as of PHP 6
  • Tomer W
    Tomer W almost 11 years
    Does PHP $str[0] take into account that there can be 2Byte long chars? UTF and such? (even though substr() does not help with it either!)
  • Vic
    Vic over 10 years
    If you want to be extra super safe, you should go with mb_substr($str, 0, 1, 'utf-8') so you don't truncate a multibyte string.
  • biziclop
    biziclop over 10 years
    Link to the docs: php.net/manual/en/…
  • trante
    trante over 10 years
    Although this is shorter and is easier to remember than substr($str, 0, 1), this confuses who reads the code.
  • Tino
    Tino about 10 years
    @MarcoDemaio The link now tells the what MichaelMorton says.
  • xtempore
    xtempore almost 10 years
    The choice between square-brackets and substr() is largely a matter of preference, but be aware that the result is different when applied to an empty string. If $s = "" then $s[] === "", but substr($s, 0, 1) === false.
  • chris
    chris over 9 years
    If $s = "" then $s[0] will generate a "Notice: Uninitialized string offset: 0" whereas substr($s, 0, 1) will not.
  • Abhisek Malakar
    Abhisek Malakar over 9 years
    I have a problem with such char Arrays. As we can access $str[0], but why we can't access foreach($str as $c)... .
  • Will B.
    Will B. almost 9 years
    As a side note to circumvent this particular issue and in either case one should always perform data validation. if (true === is_string($_POST['type']))
  • Ellert van Koperen
    Ellert van Koperen almost 8 years
    Nice test! Some numbers from a 3 year old Xeon: the average float microtime using "array[]" is 2.2427082061768E-7 the average float microtime using "substr()" is 3.9647579193115E-7 the average float microtime using "array{}" is 2.1522283554077E-7
  • PypeBros
    PypeBros almost 8 years
    for accurate measurements, you should imho better do microtime out of the loop, and don't mix the different approaches within the same loop.
  • Willy Stadnick
    Willy Stadnick almost 8 years
    @PypeBros can you elaborate about the advantages of your approach and perhaps share the code? thanks
  • PypeBros
    PypeBros almost 8 years
    assuming that microtime() measures with precision p, that is, microtime() - p < real time < microtime+p, doing before=mt(); 1000_testsA; after=mt() allows you to compute execution of 1 iteration with precision p/1000.
  • PypeBros
    PypeBros almost 8 years
    not mixing execution of testA and testB within the same loops means you are capable of detecting e.g. the fact that testB is a cache-killer while testA is cache-friendly. When they're both in the same loop, they are measured to have the very same timings because testB polluted testA's caching.
  • PypeBros
    PypeBros almost 8 years
    similarly, I'd avoid generating strings or randoms within the testing loops and have them ready in an array nearby.
  • Mark Amery
    Mark Amery about 7 years
    -1; while vague enough that it's not outright false, saying that "Strings can be seen as Char Arrays" is pretty misleading; they have pretty much nothing in common besides being indexable with [0]- or {0}-style indexes. Array functions don't work on strings (nor vica-versa), and the special syntax for appending to arrays ($some_array[] = $new_element) doesn't work on strings.
  • Mark Amery
    Mark Amery about 7 years
    -1; the OP's question was whether this syntax was a bad practice, and you've responded by... repeating the syntax, without any commentary? This is not an answer.
  • Mark Amery
    Mark Amery about 7 years
    -1; leaving aside the questionable timing mechanism (it would be better to time many operations than to time them one at a time; I worried upon reading this that just the time taken doing the microtime() call would make up most of the time difference, although experimentally that seems to not be true), there's no reason to care about the tiny speed difference here. It's a fraction of a millionth of a second; when is this ever going to matter?
  • Mark Amery
    Mark Amery about 7 years
    No, a string is not an array of characters (at least as PHP uses those two terms). -1.
  • gattsbr
    gattsbr about 7 years
  • Mark Amery
    Mark Amery about 7 years
    @gattsbr internally they are, but as far as the model that PHP exposes goes, they're a fundamentally different thing. Accessing an offset using square bracket notation is pretty much the only operation that they have in common with arrays; string functions don't work on arrays, nor vica versa, and the array append syntax ($arr[] = $new_element) doesn't work on strings. As such, I don't think conceiving of strings as character arrays is useful.
  • gattsbr
    gattsbr about 7 years
    @markamery better get on rewriting the php.net manual then to include such a minuscule technicality.
  • VolkerK
    VolkerK about 7 years
    "gives no indication of deprecation" - Indeed, the deprecation message has been removed in revision 304518 - The curly-brackets-string-index-accessor-syntax does not emit any deprecation notice, although the original notice have been on and off for PHP 5.x, it does not in the current version, thrus we should not label it as deprecated. Related to bug #52254 - svn.php.net/repository/phpdoc/en/trunk/language/types/…
  • Fr0zenFyr
    Fr0zenFyr over 6 years
    Any proof of concept and citation for Strings can be seen as character arrays? I don't find array functions working for String!! EDIT: just noticed that @MarkAmery already pointed that out. However, a citation is still needed.
  • Odin Thunder
    Odin Thunder over 6 years
    Can we use array_shift($string) to get the first char?
  • Odin Thunder
    Odin Thunder over 6 years
    No, we can`t :)
  • Fr0zenFyr
    Fr0zenFyr about 6 years
    As of today (10th May'18), a quote from the liked PHP docs: Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose. Seems like this syntax is going to stay for a while.
  • SunB
    SunB about 5 years
    Thank you for this solution! if the first character is unicode, [] wont work
  • RobinHood70
    RobinHood70 about 3 years
    And it's been updated again. It's now deprecated as of PHP 7.4.0 and removed in 8.0.0.