$ str [0]으로 문자열의 첫 문자 얻기


276

문자열의 첫 글자를 얻고 싶습니다 $str[0]. 표기법이 일반적으로 배열과 함께 사용되기 때문에 이것이 '좋은 습관'인지 확실하지 않습니다. 이 기능은 문서화가 잘되어 있지 않은 것 같습니다. 그래서이 표기법을 사용하는 것이 모든면에서 괜찮은지 말해 주실 것입니다.

아니면 그냥 좋은 ol '에 충실해야 substr($str, 0, 1)합니까?

또한 중괄호 ( $str{0})도 작동합니다. 무슨 일이야?


5
"good ol 'substr ($ str, 0, 1)"에 1을 더한 값.
산티아고 종료 SO

답변:


390

예. 문자열은 문자형 배열로 볼 수 있으며 배열의 위치에 액세스하는 방법은 []연산자 를 사용하는 것 입니다. 일반적으로 사용하는 데 전혀 문제가 없습니다 $str[0](그리고 substr()방법 보다 훨씬 빠릅니다 ).

두 가지 방법 모두 한 가지주의 사항이 있습니다 . 첫 번째 문자가 아닌 첫 번째 바이트 를 얻습니다 . 멀티 바이트 인코딩 (예 : UTF-8)을 사용하는 경우 중요합니다. 이를 지원하려면을 사용하십시오 . 요즘에는 항상 멀티 바이트 입력을 가정해야하므로 이것이 최선의 선택이지만 약간 느려질 것입니다.mb_substr()


7
PHP $ str [0]은 2 바이트 길이의 문자가있을 수 있다는 것을 고려합니까? UTF 등? (substr ()도 도움이되지 않더라도!)
Tomer W

77
추가 안전을 원한다면 mb_substr($str, 0, 1, 'utf-8')멀티 바이트 문자열을 자르지 않도록 해야 합니다.
Vic

18
이 것보다 짧고 기억하기는 쉽지만 substr($str, 0, 1)코드를 읽는 사람을 혼란스럽게합니다.
trante

10
대괄호와 substr () 사이의 선택은 주로 선호의 문제이지만 빈 문자열에 적용하면 결과가 다릅니다. $ s = ""이면 $ s [] === ""이지만 substr ($ s, 0, 1) === false입니다.
xtempore

9
$ s = ""이면 $ s [0]은 "알림 : 초기화되지 않은 문자열 오프셋 : 0"을 생성하지만 substr ($ s, 0, 1)은 생성하지 않습니다.
chris

46

{} 구문은 PHP 5.3.0부터 더 이상 사용되지 않습니다. 대괄호가 권장됩니다.


14
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].
VolkerK

4
@VolkerK은 : 링크에 당신은 내가 그들이 단지 왼쪽 PHP 매뉴얼에 메모를 제거 눈치 제공 Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose.그들이 사용하는 결정 만약 내가 궁금하네요 그래서 {}PHP 6으로 더 이상 사용되지되지 않습니다
마르코 Demaio을

1
@MarcoDemaio 이제 링크가 MichaelMorton의 말을 알려줍니다.
Tino

1
"사용 중단 표시가 없음"-실제로 사용 중단 메시지가 개정판 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

오늘 (10 일 May'18)로, 마음에서 인용 한 PHP 워드 프로세서 : Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose. 이 구문은 잠시 동안 머물 것처럼 보인다.
Fr0zenFyr

25

$ _POST의 일부에서 첫 번째 문자를 원한다고 가정하고 'type'이라고 부를 수 있습니다. 그리고 그 $ _POST [ 'type']은 현재 'Control'입니다. 당신은 사용이 경우 경우 경우 $_POST['type'][0], 또는 substr($_POST['type'], 0, 1)당신은 얻을 것이다 C다시.

클라이언트 측 그들은에서 보내 데이터 수정했다 그러나, typetype[], 예를 들어를, 다음이 배열의 데이터로 '제어'와 '테스트'를 보내, $_POST['type'][0]지금 돌아갑니다 Control보다는 C반면 substr($_POST['type'], 0, 1)단순히 실패합니다.

따라서을 사용하는 데 문제가있을 수 $str[0]있지만 주변 환경에 따라 다릅니다.


2
이 특정 문제를 피하기위한 부가적인 참고 사항으로, 어느 경우 든 항상 데이터 유효성 검사를 수행해야합니다. if (true === is_string($_POST['type']))
fyrye

13

내 유일한 의심은이 기술이 멀티 바이트 문자열에 어떻게 적용되는지에 대한 것입니다. (의심 mb_substr()스러운 경우 분명히 안전한 선택 인 것 같습니다.)

그러나 큰 그림의 관점에서 볼 때, 이것이 문자열에서 'n'번째 문자에 얼마나 자주 액세스해야하는지 궁금합니다.


9

리소스에 따라 다를 수 있지만 스크립트를 실행하여 직접 볼 수 있습니다.)

<?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
Ellert van Koperen

정확한 측정을 위해서는 루프에서 마이크로 타임을 더 잘 수행하고 동일한 루프 내에서 서로 다른 접근 방식을 혼합하지 않아야합니다.
PypeBros

1
실행 혼합하지 testA그리고 testB당신은 사실 예 검출 할 수있는 것과 동일한 루프 수단 내에서 testB하는 동안 캐시 살인자 testA캐시 친화적이다. 둘 다 동일한 루프에 있으면 testB오염 된 testA캐싱 때문에 타이밍이 매우 동일한 것으로 측정됩니다 .
PypeBros

1
마찬가지로 테스트 루프 내에서 문자열 또는 임의의 생성을 피하고 근처 배열에서 준비하십시오.
PypeBros

1
-1; 의심스러운 타이밍 메커니즘을 제쳐두고 (한 번에 하나씩 시간을 계산하는 것보다 많은 작업을 시간을 정하는 것이 더 좋을 것입니다.) microtime()전화를하는 데 걸리는 시간이 대부분의 시간 차이를 차지할 것이라고 걱정했습니다. 사실이 아닙니다), 여기서 작은 속도 차이에 신경 쓸 이유가 없습니다. 그것은 백만 분의 1 초의 일부입니다. 이것이 언제 문제가 될까요?
Mark Amery

6

단순한 필사자로 말하면, 나는 고수 할 것이다 $str[0]. 내가 아는 한,의 의미 $str[0]를 한 눈 에 파악하는 것이 더 빠릅니다 substr($str, 0, 1). 이것은 아마도 선호의 문제로 귀결됩니다.

성능에 관한 한, 프로파일 프로파일 프로파일. :) 또는 PHP 소스 코드를 들여다 볼 수 있습니다 ...


6
$str = 'abcdef';
echo $str[0];                 // a

6
-1; OP의 질문은이 구문이 나쁜 습관인지 아닌지에 대한 것입니다. 이것은 답이 아닙니다.
Mark Amery

5

멀티 바이트 (유니 코드) 문자열을 사용 str[0]하는 경우 문제가 발생할 수 있습니다. mb_substr()더 나은 솔루션입니다. 예를 들면 다음과 같습니다.

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

여기에 몇 가지 세부 사항이 있습니다 : UTF-8 문자열의 첫 문자를 얻으십시오


이 솔루션에 감사드립니다! 첫 문자가 유니 코드 인 경우 []가 작동하지
않음

1

나는 부작용이없고 오해 없이이 표기법을 사용했습니다. 문자열은 문자의 배열 일뿐입니다.


아니요, 문자열은 문자 배열이 아닙니다 (적어도 PHP는이 두 용어를 사용하므로). -1.
Mark Amery


@gattsbr 내부적으로는 있지만 PHP가 노출하는 모델은 근본적으로 다릅니다. 대괄호 표기법을 사용하여 오프셋에 액세스하는 것은 배열과 공통되는 유일한 작업입니다. 문자열 함수는 배열에서 작동하지 않으며 그 반대도 마찬가지이며 배열 추가 구문 ( $arr[] = $new_element)은 문자열에서 작동하지 않습니다. 따라서 문자열을 문자 배열로 생각하는 것이 유용하다고 생각하지 않습니다.
Mark Amery

@markamery는 php.net 매뉴얼을 다시 작성하여 그런 작은 기술을 포함시키는 것이 좋습니다.
gattsbr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.