코딩짜는 일상

[PHP] strpos() 사용시 주의사항! - PHP 버전 7.3 미만인 경우 본문

IT/PHP

[PHP] strpos() 사용시 주의사항! - PHP 버전 7.3 미만인 경우

Remily 2024. 1. 23. 00:44
반응형

함께 읽어보면 좋은 글

https://weavingcoding.tistory.com/30

 

[PHP] 문자열에 특수문자 또는 일부 문자열이 포함되어 있는지 확인 - strpos(), preg_match()

함께 읽어보면 좋은 글 https://weavingcoding.tistory.com/32 [PHP] strpos() 사용시 주의사항! - PHP 버전 7.3 미만인 경우 서론 사용자가 선택한 값에 부분 문자열이 포함되어 있는가 아닌가의 여부로 서버 종

weavingcoding.tistory.com

 

 

 


서론

사용자가 선택한 값에 부분 문자열이 포함되어 있는가 아닌가의 여부로

서버 종류를 판별하고 각자에 맞는 저장 쿼리를 실행하는 코드를 작성하였습니다.

// $type = 'user_board' - 사용자 게시판
// $type = 'admin_board' - 관리자 게시판
if(strpos($type, 'admin_')){
    // 관리자 서버 저장 쿼리
} else{
    // 사용자 서버 저장 쿼리
}

 

 

 


오류

이 경우 기대하는 동작값은 $type = 'admin_board'일 때만 관리자 서버에 저장되고

그 외 모든 게시글은 사용자 서버에 저장되는 것이었습니다.

 

하지만 실제로는 모든 게시글이 사용자 서버에만 저장되었죠...

 

 

 


원인

php manual의 strpos 첫 설명글을 보면 답이 있습니다.

strpos — Find the position of the first occurrence of a substring in a string

https://www.php.net/manual/en/function.strpos.php

 

그리고 코딩에서 처음 시작은 1이 아니라 0부터 시작하기 때문에

 

전체 문자열 admin_board에서 부분 문자열인 admin_이 처음 시작되는 위치는

전체 문자열의 가장 첫 부분이고 이 경우 결과값은 0이 됩니다.

 

 

if($변수)에서 변수가 0이어도 false와 마찬가지로 틀리다로 인식하기 때문에 오류가 발생하였습니다.

 

 

PHP 7.1 버전부터는 offset에 음수를 쓸 수 있어 if(strpos($type, 'admin_', -1))로 쓸 수 있고

PHP 7.3 버전 이상부터는 true / false로만 반환하기 때문에 위와 같은 문제는 생기지 않습니다.

 

 

 


해결

strpos()는 부분 문자열이 존재할 경우 int를.

부분 문자열이 존재하지 않을 경우 false를 반환하기 때문에

 

if(strpos($type, 'admin_') == 0)으로 고쳐줄 수도 있을 것입니다.

 

 

하지만 0false가 같은 취급을 받는다는 것이 뭔가 찜찜해서

제 경우는 임의의 텍스트를 하나 덧붙여주어 해결하였습니다.

 

// $type = 'user_board' - 사용자 게시판
// $type = 'admin_board' - 관리자 게시판
if(strpos('check_' . $type, 'admin_')){
    // 관리자 서버 저장 쿼리
} else{
    // 사용자 서버 저장 쿼리
}

 

 

 

 


덧붙이는 말

위 케이스에 strpos()를 활용한 판별도 좋지만 서버종류_작업명같은 규칙성이 있다면

$str_arr = explode('_', 'admin_board')을 사용하여

 

if($str_arr[0] == 'admin_') 같은 방법으로도 분류해 줄 수도 있습니다.

 

반응형