Получение первого символа строки с помощью $ str [0]

193

Я хочу получить первую букву строки, и я заметил, что $str[0] отлично работает. Я просто не уверен, что это "хорошая практика", поскольку эта нотация обычно используется с массивами. Эта функция, кажется, не очень хорошо документирована, поэтому я обращаюсь к вам, ребята, чтобы сказать мне, все ли в порядке. во всех отношениях – использовать эти обозначения?

Или я должен просто придерживаться хорошего ol 'substr($str, 0, 1)?

Кроме того, я заметил, что фигурные скобки ($str{0}) также работают. Что с этим?

  • 2
    плюс 1 за «добрый старый субстрат ($ str, 0, 1)».
Теги:
string
substring

12 ответов

312
Лучший ответ

Да. Строки можно рассматривать как массивы символов, а способ доступа к позиции массива - использовать оператор []. Обычно нет проблем при использовании $str[0] (и я уверен, что это намного быстрее, чем метод substr()).

Существует только одна оговорка с обоими методами: они получат первый байт, а не первый символ. Это важно, если вы используете многобайтовые кодировки (например, UTF-8). Если вы хотите поддержать это, используйте mb_substr(). Возможно, вы всегда должны принимать многобайтовые входные данные, поэтому это лучший вариант, но он будет немного медленнее.

  • 6
    Учитывает ли PHP $ str [0], что могут быть 2-байтовые длинные символы? UTF и такие? (хотя substr () тоже не помогает!)
  • 67
    Если вы хотите быть mb_substr($str, 0, 1, 'utf-8') , вы должны использовать mb_substr($str, 0, 1, 'utf-8') чтобы не обрезать многобайтовую строку.
Показать ещё 9 комментариев
37

Синтаксис {} устаревает с PHP 6. Рекомендуется использовать квадратные скобки.

  • 13
    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]. доступа к строкам 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].
  • 4
    @VolkerK: по предоставленной вами ссылке я заметил, что они удалили примечание к руководству по PHP, которое они оставили только: Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose. Поэтому мне интересно, решили ли они, что использование {} НЕ устарело с PHP 6?
Показать ещё 3 комментария
19

Предположим, вам просто нужен первый char из части $_POST, давайте назовем его "type". И этот $_POST ['type'] в настоящее время является "Control". Если в этом случае, если вы используете $_POST['type'][0] или substr($_POST['type'], 0, 1), вы получите C назад.

Однако, если клиентская сторона должна была изменить данные, которые они отправляют вам, например, от type до type[], а затем отправить "Control" и "Test" в качестве данных для этого массива, $_POST['type'][0] будет теперь возвращаем Control, а не C, тогда как substr($_POST['type'], 0, 1) просто просто терпит неудачу.

Так что да, может быть проблема с использованием $str[0], но это зависит от окружающих обстоятельств.

  • 2
    В качестве дополнительного примечания, чтобы обойти эту конкретную проблему и в любом случае всегда следует выполнять проверку данных. if (true === is_string($_POST['type']))
12

Мое единственное сомнение в том, насколько применимо этот метод будет в многобайтовых строках, но если это не соображение, то я подозреваю, что вы охвачены. (Если есть сомнения, mb_substr() кажется явно безопасным выбором.)

Однако, с точки зрения большой картины, мне нужно задаться вопросом, как часто вам нужно получить доступ к n-му символу в строке, чтобы это было ключевым соображением.

9

Это зависит от ресурсов, но вы можете запустить script ниже и посмотреть сами;)

<?php
$tests = 100000;

for ($i = 0; $i < $tests; $i++)
{
    $string = md5(rand());
    $position = rand(0, 31);

    $start1 = microtime(true);
    $char1 = $string[$position];
    $end1 = microtime(true);
    $time1[$i] = $end1 - $start1;

    $start2 = microtime(true);
    $char2 = substr($string, $position, 1);
    $end2 = microtime(true);
    $time2[$i] = $end2 - $start2;

    $start3 = microtime(true);
    $char3 = $string{$position};
    $end3 = microtime(true);
    $time3[$i] = $end3 - $start3;
}

$avg1 = array_sum($time1) / $tests;
echo 'the average float microtime using "array[]" is '. $avg1 . PHP_EOL;

$avg2 = array_sum($time2) / $tests;
echo 'the average float microtime using "substr()" is '. $avg2 . PHP_EOL;

$avg3 = array_sum($time3) / $tests;
echo 'the average float microtime using "array{}" is '. $avg3 . PHP_EOL;
?>

Некоторые ссылочные номера (на старой машине CoreDuo)

$ php 1.php 
the average float microtime using "array[]" is 1.914701461792E-6
the average float microtime using "substr()" is 2.2536706924438E-6
the average float microtime using "array{}" is 1.821768283844E-6

$ php 1.php 
the average float microtime using "array[]" is 1.7251944541931E-6
the average float microtime using "substr()" is 2.0931363105774E-6
the average float microtime using "array{}" is 1.7225742340088E-6

$ php 1.php 
the average float microtime using "array[]" is 1.7293763160706E-6
the average float microtime using "substr()" is 2.1037721633911E-6
the average float microtime using "array{}" is 1.7249774932861E-6

Кажется, что использование операторов [] или {} более или менее одинаково.

  • 2
    Хороший тест! Некоторые числа из 3-летнего Xeon: среднее микропространство с плавающей запятой с использованием «array []» равно 2.2427082061768E-7 среднее микропространство с плавающей запятой с использованием «substr ()» составляет 3.9647579193115E-7, среднее микропространство с плавающей запятой с использованием «array {}» равно 2.1522283554077E-7
  • 0
    для точных измерений вы должны сделать микротайм вне цикла и не смешивать разные подходы в одном цикле.
Показать ещё 5 комментариев
6

Говоря как простой смертный, я бы придерживался $str[0]. Насколько мне известно, он быстрее понимает значение $str[0] с первого взгляда, чем substr($str, 0, 1). Вероятно, это зависит от предпочтения.

Что касается производительности, то профиль профиля профиля.:) Или вы могли бы заглянуть в исходный код PHP...

5
$str = 'abcdef';
echo $str[0];                 // a
  • 10
    Похоже, что ОП уже знает это.
  • 5
    -1; вопрос ОП заключался в том, был ли этот синтаксис плохой практикой, и вы ответили ... повторив синтаксис без каких-либо комментариев? Это не ответ.
2

В случае многобайтовых (unicode) строк с использованием str[0] может возникнуть проблема. mb_substr() - лучшее решение. Например:

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

Некоторые подробности здесь: Получить первый символ строки UTF-8

  • 0
    Спасибо за это решение! если первый символ Unicode, [] не будет работать
1

Я также использовал эту нотацию, без каких-либо побочных эффектов и недоразумений. Это имеет смысл - строка - это всего лишь массив символов.

  • 0
    Нет, строка не является массивом символов (по крайней мере, так как PHP использует эти два термина). -1.
Показать ещё 2 комментария
-3

Легко получить первый символ строки. Просто обрабатывайте строку как массив.

Пример:

$first = $string{0};
$fifth = $string{5};

Что это!

-3

Вот как я решил проблему:

<?php

    $string = 'Hello The World';
    $stringExp = explode(' ', $string);
    $shortCode = '';
    for($i = 0; $i < count($stringExp); $i++):

        $shortCode .= substr($stringExp[$i], 0, 1);

    endfor;

    echo $shortCode; // result : HTW

?>
-4

Рассмотрим следующее:

<?php
var_dump($_POST);

// Post var is a string:
echo '1'; var_dump( strtoupper( $_POST['flag1'][0] ) === 'T' );            // boolean true
echo '2'; var_dump( strtoupper( substr( $_POST['flag1'],0,1 ) ) === 'T' ); // boolean true

// Post var is an array of strings
echo '5'; var_dump( strtoupper( $_POST['flag2'][0] ) === 'T' );            // boolean false
echo '6'; var_dump( strtoupper( substr( $_POST['flag2'],0,1 ) ) === 'T' ); // generates a PHP warning
?>
<hr />
<form method="POST">
 <input type="text" name="name" value="bob" /><br />
 <input type="text" name="flag1" value="true" /><br />
 <select name="flag2[]" multiple>
  <option value="true" selected>true</option>
  <option value="false" selected>false</option>
  <option value="0" selected>0</option>
 </select><br />
 <input type="submit" value="Submit" /><br />
</form>

Цель состоит в том, чтобы обнаружить булевский флаг. Хотя можно путать проблему, превратив var в тип массива, использование нотации с индексом массива создает безопасный ложный результат, тогда как функция substr() создает ошибку. Учитывая выбор здесь, я бы пошел с нотной записью.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню