다음과 같은 코딩테스트 문제가 주어진다고 해 보자.
문자열
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는 왜 이런 게 될까? (안 되는 것도 한무더기 있는 주제에.)
이 기능을 십분 활용하고 있는 서비스/라이브러리/의존성도 꽤 되겠지?
정말 웃기는 짬뽕이 아닐 수 없다.
// 예컨대 "다음 IP"를 얻어내는 방법은 다음과 같이 명확하다.
function getNextIP(string $ip): string {
return $ip === '255.255.255.255'
? '0.0.0.0'
: long2ip(ip2long($ip) + 1);
}