TIL PHP 7/3/2023

엽토군·2023년 7월 3일
0

TIL

목록 보기
9/13

(제한적인) 문자열 증감 허용

다음과 같은 코딩테스트 문제가 주어진다고 해 보자.

문자열 a를 받아서, 그 문자열의 '사전 수록 순서상 바로 뒤'에 나오는 문자열 b를 반환하는 함수를 작성하시오. 두 문자열의 길이는 일치할 필요가 없으나, 둘 다 정규표현식 \w+ 조건을 충족해야 한다.

대부분의 언어에서는 이 문제를 풀려면 고생 깨나 해야 한다. 예컨대 자바스크립트라면:

const getNextString = function (a) {
  let lastCharacter = a.charCodeAt(a.length - 1);
  let nextCharacter = String.fromCharCode(lastCharacter + 1);
  return a.substring(0, a.length - 1) + nextCharacter;
}

그런데 이게 PHP라면, 운이 좋을 경우, 다음 한 줄로 해결된다.

function getNextString(string $a): string {
	return ++$a;
}

상세

물론 한계는 있다. 아래 샘플 코드를 보며 확인해 보자.

# 기본적으로, 1바이트를 더한 결과를 가져온다.
$str0 = 'php'; 
echo ++$str0; // phq

# z에 1바이트 더한 것은 aa로 자릿수가 올라간다.
$str1 = 'plz'; 
echo ++$str1; // pma
$str2 = 'zzzzz'; 
echo ++$str2; // aaaaaa

# 숫자도 올라간다.
$ip1 = '192.168.0.254'; 
echo ++$ip1; // 192.168.0.255

# 그렇다고 방심하고 IP 주소 생성 같은 데 쓰면 그건 곤란하다.
$ip2 = '192.168.0.255'; 
echo ++$ip2; // 192.168.0.256

# 띄어쓰기가 있으면 안된다.
$str4 = '#MAKEPHPGREATAGAIN'; 
echo ++$str4; // #MAKEPHPGREATAGAIO
$str5 = '!!! MAKE PHP GREAT AGAIN !!!'; 
echo ++$str5; // !!! MAKE PHP GREAT AGAIN !!!

# 잘 안 될 경우 그냥 원본 문자열을 반환한다.
$str6 = '...'; 
echo ++$str6; // ...
$str7 = '???'; 
echo ++$str7; // ???
$str8 = '#PHP의영광을되찾자'; 
echo ++$str8; // #PHP의영광을되찾자

이상의 내용을 PHP 공식문서는 한 단락으로 소개하고 있다.

PHP는 문자 변수에 대한 산술 연산을 처리할 때 C의 규칙 대신 Perl의 규칙을 따릅니다. 예를 들어, PHP와 Perl에서는 $a = 'Z'; $a++; 실행 시 $a === 'AA'가 됩니다만, C에서는 (ASCII 값이 90에서 91로 바뀜에 따라) [가 되죠. 문자를 증가시킬 수는 있지만 감소시킬 수는 없으며, 일반 ASCII 문자와 숫자(a-z, A-Z 및 0-9)만 지원됩니다. 다른 문자 변수는 증가/감소해 보아야 소용이 없으며, 원래 문자열은 변경되지 않습니다.

소견

PHP는 왜 이런 게 될까? (안 되는 것도 한무더기 있는 주제에.)
이 기능을 십분 활용하고 있는 서비스/라이브러리/의존성도 꽤 되겠지?
정말 웃기는 짬뽕이 아닐 수 없다.

  • 제한적 용도로는 활용할 만한 것 같다.
    • 테스트, DB seeding 등에 활용할 fake data
    • (모종의 이유로) 스프레드시트 컬럼 번호 자동 부여 같은 걸 구현해야 할 때 등등
  • 그밖의 경우에는 그냥 프로그램을 제대로 짜는 편이 좋을 것이다.
// 예컨대 "다음 IP"를 얻어내는 방법은 다음과 같이 명확하다.
function getNextIP(string $ip): string {
	return $ip === '255.255.255.255'
    	         ? '0.0.0.0'
         : long2ip(ip2long($ip) + 1);
}
profile
4년차 PHP 개발자입니다.

0개의 댓글