'=='와 'strcmp ()'를 사용한 문자열 비교


334

PHP ===연산자는 대소 문자를 구분 하는 것 같습니다 . 사용할 이유가 strcmp()있습니까?

다음과 같은 일을하는 것이 안전합니까?

if ($password === $password2) { ... }

10
대소 문자 구분은 무엇과 관련이 strcmp있습니까?
— kennytm

1
@KennyTM : strcmp대소 문자를 구분합니다. VB와 같은 일부 언어에서는 문자열 비교가 이루어지지 않을 수 있으므로 다른 결과를 반환합니다. 그러나 PHP에서는 그렇지 않습니다.
— cHao

13
@ jie : 당신 은 사실 이기 때문에 ===대신에 사용하고 싶을 수도 있습니다 . =='0XAB' == '0xab'
— kennytm

17
==와 0으로 임의의 문자열을 비교하는 true를 반환하기 때문에 대신 ==를 사용 ===에 ... 분명 거짓 인 것이 중요하다
— 칼 애들러

4
또한 @Kenny '확인 0xAB'== '171'
— 안티몬

답변:


329

그것을 사용하는 이유는 strcmp

str1이 str2보다 작 으면 <0을 리턴합니다. str1이 str2보다 크면 0이고, 같으면 0입니다.

===true또는 만 반환 false하며 "더 큰"문자열을 알려주지 않습니다.


9
현재의 경우 icic tho, 나는 어떤 문자열이 더 큰지 알 필요가 없습니다 :)
— Jiew Meng

154
일치하는 문자열이있는 strcmp는 0.207852 초 걸렸습니다. 일치하지 않는 문자열이있는 strcmp는 0.215276 초 걸렸습니다 === 일치하는 문자열이 0.067122 초 걸렸습니다 === 일치하지 않는 문자열이 0.057305 초 걸렸습니다 snipplr.com/view/758

3
strcmp의 다른 사용법은 정렬을 보여줍니다. 정렬에 대해 더 명확하게하기 위해. string1이 string2보다 먼저 정렬되면 strcmp ()는 <0을 리턴하고, string2가 string1보다 먼저 정렬되면> 0을 리턴하고 동일한 경우 0을 리턴합니다. 예를 들어 $ string_first = "aabo"; $ string_second = "aaao"; 에코 $ n = strcmp ($ string_first, $ string_second); aaao가 aabo보다 먼저 정렬되므로 0보다 큰 값을 반환합니다.
— HTML Man

20
왜이 답변이 가장 많이지지됩니까? 이 질문에 대한 답은 아니지만 '올바른'답은 아니기 때문에 다운 투표를하고 있습니다. 다른 답변에서 이미 많은 사람들이 말했듯이 정답은 'Use ==='이어야합니다.
— onur güngör

2
@onur güngör 사실,이 수행 답변입니다 연산의 질문, So is there any reason to use strcmp() ?Postfuturist의 대답은하지 않는 동안을. 아, 지옥 ... 아무도 대답을 한 번에 컴파일 것 같았다 사용 의 strcmp()1, 성능 의 ===, 그리고 나쁜 신뢰성 의 ==I 목록에 광산을 추가 ... 그래서 문자열 비교합니다.
— Balmipour

222

==문자열 비교에 사용해서는 안됩니다 . ===괜찮습니다.

$something = 0;
echo ('password123' == $something) ? 'true' : 'false';

위의 코드를 실행하면 이유를 알 수 있습니다.

$something = 0;
echo ('password123' === $something) ? 'true' : 'false';

이제는 조금 나아졌습니다.


19
== 다른 유형에 대한 문제가 아닙니다. 양쪽이 모두 문자열 인 경우에도 때때로 예기치 않은 결과가 발생합니다. '1e3'== '1000'시도
— 안티몬

3
0 == 'password123'은 어떻게됩니까?
— Andy Lobel

24
@AndyLobel PHP는 다른 피연산자가 숫자, 그 문자열은 대부분 0과 같이 숫자이고, PHP는 비교를 위해 true를 반환하기 때문에 홀수 느슨한 비교 규칙을 사용하여 'password123'을 숫자로 강제 변환합니다.
— postfuturist

8
빠른 var_dump ((int) 'password123'); 왜 이런 일이 발생했는지 완전히 이해하도록 도와주었습니다 ... ** 당황 ** ... === 연산자가 정말 마음에 듭니다
— Carlton

3
두 피연산자 중 하나를 숫자로 캐스트 할 수있는 경우 '=='를 사용하고 php는 두 피연산자를 모두 숫자로 캐스트하며, 숫자가 아닌 문자열을 숫자로 캐스트하는 경우 값 0을 가져 오므로 결과는 0과 같습니다. 원치 않는 캔 뭔가 '=='단순과의 비교 결과 때문에
— 루카 C.

98

==PHP 에서는 사용하지 마십시오 . 그것은 당신이 기대하는 것을하지 않을 것입니다. 문자열을 문자열과 비교하더라도 PHP는 암시 적으로 부동 소수점으로 캐스트하고 숫자로 표시되면 숫자를 비교합니다.

예를 들어 '1e3' == '1000'true 를 반환합니다. ===대신 사용해야 합니다.


16
그러나 당신은 단지 === 할 수 있습니다.
— Roman Newaza

11
@Roman은 그렇다. 그러나 많은 PHP 프로그래머들은 그렇게해야한다는 것을 모른다. 따라서 경고.
— 안티몬

5
@Antimony 그래서 그들이 당신의 대답에서 무엇을 해야하는지 말해 주지 않겠습니까?
— Tim

43

이 PHP 버그 리포트에 따르면 0wn을 얻을 수도 있습니다.

<?php 
    $pass = isset($_GET['pass']) ? $_GET['pass'] : '';
    // Query /?pass[]= will authorize user
    //strcmp and strcasecmp both are prone to this hack
    if ( strcasecmp( $pass, '123456' ) == 0 ){
      echo 'You successfully logged in.';
    }
 ?>

경고가 표시되지만 여전히 비교를 무시하십시오. @postfuturist가 제안한대로
해야합니다 ===.


5
와우 +1. 링크에서 인용 : "잘못된 유형의 인수를 수신하는 함수가 널을 리턴하도록 설정된 동작입니다." 매뉴얼에서 "str1이 str2보다 작 으면 <0을 반환하고, str1이 str2보다 크면> 0을 반환하고 같으면 0을 반환한다"고 생각하면 놀랍습니다. Null은 가능성으로 언급되지 않았지만 substr 매뉴얼 페이지와 같은 페이지에서는 언급됩니다. 한숨
— Gerry

그러나 양식 메소드가 게시 될 때도 마찬가지입니까?
— 3lokh

@NikhilGeorge 그것은 문제가되는 함수는 strcmp입니다. 어떤 입력을 비교하는지는 중요하지 않습니다.
— Ajith

버그 보고서에 null을 반환하는 것이 좋다고 표시되어 있지만 이는 잘못된 것입니다. PHP 4.3에서 PHP 7.3까지의 모든 공식 PHP 릴리스는 이러한 함수에서 null을 반환하지 않습니다. 알파 또는 베타 릴리스 일 가능성이있는 것으로 의심되며 닫히는 버그에 관계없이 유효하지 않습니다. 자세한 내용은 3v4l.org/Zq8tM 을 참조하십시오. 이는 HHVM 3.11-3.19 에 영향을 미친다는 것을 보여줍니다.
— Timo Tijhof

33

문자열을 비교할 때는 항상 ===연산자가 아닌 == 연산자 ( 엄격한 비교) 를 사용해야합니다 (느슨한 비교).


8
실제로, 나는 당신이 무엇을=== 비교할 때 사용해야한다고 말하는 것이 안전하다고 생각합니다 .
— rink.attendant.6

22

모든 답변을 요약 :

  • ==문자열 비교 에는 나쁜 생각 입니다.
    그것은 많은 경우에 "놀라운"결과를 줄 것입니다. 그것을 믿지 마십시오.

  • === 괜찮아 최고의 성능을 제공합니다.

  • strcmp() 일반적으로 정렬 작업에 "더 큰"문자열을 결정해야하는 경우 사용해야합니다.


20

사용하면 ==위험 할 수 있습니다.

변수가 다른 경우 변수를 다른 데이터 유형으로 캐스트합니다.

예 :

  • echo (1 == '1') ? 'true' : 'false';
  • echo (1 == true) ? 'true' : 'false';

보시다시피,이 두 가지 유형은 다르지만 결과는 true입니다. 코드가 기대하지 않을 수도 있습니다.

사용 ===하지만, 그것은 조금보다 더 빨리하다고 테스트 쇼로 추천 strcmp()하고 대소 문자를 구별 대안 strcasecmp().

빠른 인터넷 검색으로이 속도 비교를합니다. http://snipplr.com/view/758/


1
때로는 이미 같은 유형을 가지고 있어도 다른 유형으로 캐스트합니다.
— 안티몬

"012" == "12"php 와 같은 정수를 나타내는 두 문자열을 비교할 때도 두 문자열 의 유형을 모두 정수로 변경 12 == 12한 다음 반환했습니다 true.
— GoTo


6

strcmp는 실행중인 환경 (Linux / Windows)에 따라 다른 값을 반환합니다!

그 이유는 버그 보고서에 https://bugs.php.net/bug.php?id=53999 라는 버그가 있기 때문입니다.

조심해서 다루십시오 !! 감사합니다.


그러나 문자열이 같으면 항상 0을 반환합니다. 0이 아닌 다른 값에주의를 기울이면 +1입니다.
— Falken 교수 계약

4

사전 식으로strcmp() 문자열을 주문 / 비교하려는 경우 사용할 수 있습니다 . 평등을 확인하고 싶다면 괜찮습니다.==


1
usort 에서처럼 . 실제로 정렬하기 위해 만들어졌습니다.
— 찰스

@Charles 감사합니다. Wikipedia는 눈을 즐겁게했습니다.
— cbednarski

1
정렬에 대해 더 명확하게하기 위해. string1이 string2보다 먼저 정렬되면 strcmp ()는 <0을 리턴하고, string2가 string1보다 먼저 정렬되면> 0을 리턴하고 동일한 경우 0을 리턴합니다. 예를 들어 $ string_first = "aabo"; $ string_second = "aaao"; 에코 $ n = strcmp ($ string_first, $ string_second); aaao가 aabo보다 먼저 정렬되므로 0보다 큰 값을 반환합니다.
— HTML Man

@postfuturist 오타라고 확신합니다 ===.
— ash

4

또한이 기능은 정렬에 도움이 될 수 있습니다. 정렬에 대해 더 명확하게하기 위해. strcmp ()는 string1이 string2보다 먼저 정렬되면 0보다 작고 string2가 string1보다 먼저 정렬되면 0보다 크거나 같으면 0보다 큰 값을 반환합니다. 예를 들어

$first_string = "aabo";
$second_string = "aaao";
echo $n = strcmp($first_string,$second_string);

aaao가 aabo 전에 정렬되므로 함수는 0보다 큰 값을 반환합니다.


0

PHP 알파벳순 정렬을 사용하는 대신 문자의 ASCII 값을 사용하여 비교하십시오. 소문자는 대문자보다 ASCII 값이 높습니다 . 이러한 종류의 비교를하려면 identity 연산자 === 를 사용하는 것이 좋습니다 . strcmp () 는 이진 안전 문자열 비교를 수행하는 함수입니다. str1이 str2보다 작 으면 두 개의 문자열을 인수로 사용하고 <0을 리턴합니다. str1이 str2보다 크면 0이고, 같으면 0입니다. 거기에 또한 대소 문자를 구별하지 버전 이름 strcasecmp () 첫번째 변환 문자열을 소문자로 그게 한 다음를 비교합니다.


0

if ($password === $password2) { ... }입력 중 하나가 사용자가 제어하는 ​​비밀번호 또는 비밀번호 해시를 비교할 때 안전한 작업이 아닙니다.
이 경우 공격자가 실행 시간 차이에서 실제 비밀번호 해시를 도출 할 수 있도록 타이밍 오라클을 생성합니다. hash_equals는 "타이밍 공격 안전 문자열 비교"를 수행 하므로 대신
사용하십시오 .if (hash_equals($password, $password2)) { ... }

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.