PHP의 당황스런 특징들

PHP는 나름 태생이 특이한 언어다. 현재 웹에서 널리 쓰이고 있는 많은 서버사이드 언어들(Java, PHP, Python, Ruby 등등 ((등등 취급해서 미안하다. perl 그리고 c)) ) – 중에서 거의 유일하게 ‘진짜로 웹개발에 특화된’ 언어다.

그래서 그런건지 PHP는 다른 언어를 쓰다 온 사람들을 희한한 방식으로 깜짝 놀래키곤 한다. 지난 3년간 나를 당황시킨 PHP의 독특한 동작 몇가지를 소개해 보겠다.

0 == ‘string’

<?php
print 0=='hello';

위 코드를 실행하면 놀랍게도 1이 출력된다.

PHP는 어째서 숫자 0과 ‘hello’을 같다(equal)고 판단한 것인가? 그것은 숫자와 문자열을 equal operator로 비교를 시도하는 경우, PHP는 문자열을 숫자로 변환하기 때문이다. ‘hello’를 숫자로 변환하면 0이 되므로 PHP는 0과 ‘hello’를 같다고 판단한다.

PHP 개발자들은 ’42’ == 42 와 같은 평가식이 아무 에러 없이 참을 반환하는 편리함을 누리는 동시에, 위와 같은 PHP 고유의 독특한 해석도 받아들여야만 한다.

이렇게 동작하게 된 배경에는 PHP가 태생적으로 HTML에 embeded해서 사용하기 위한 언어라는 사실이 자리하고 있을 것이다. 그런 형태로 사용하려면 가급적 코드가 짧은 것이 바람직할 것이며, 잦을 수 밖에 없는 문자열 변환 함수 호출도 생략할 수 있게 하고 싶었던 것이 아닐런지.
이런 특성은 PHP가 perl의 weak typing을 그대로 물려받은 것이 아닐까 싶다.

함수 이름에 대소문자를 구분하지 않는다.

<?php
function foo() {
    print 'hello';
}
FoO();

C 개발자가 보면 기절초풍할 코드지만 문제없이 잘 동작한다. 더 신기하게도, 함수 이름에선 대소문자를 전혀 구분하지 않지만 변수 이름에선 정확하게 구분한다.

이것 역시 PHP가 웹개발용 언어이기 때문일 것이다. 내 추측으로는 과거 HTML 태그를 소문자로 써야 하는건지 대문자로 써야하는 건지 명확하지 않던 시절의 잔재가 아닐까 싶다. HTML element를 만들어주는 함수를 PHP로 작성했을 때(예: a(), table(), …) 대문자로 호출하든 소문자로 호출하든 잘 동작하게 하고 싶었던 게 아닐까?

foo()[0] 불가능

<?php
function foo() {
    return array('first', 'second');
}

$result = foo();
print $result[0]; # print 'first'
print foo()[0]; # ?

두 print 문 모두 문제없이 ‘first’ 가 출력될 것으로 기대하게 되지만,  사실 두번째 print 문은 parse 에러를 일으킨다.

PHP Parse error:  syntax error, unexpected '[' in - on line 8

함수 호출문 뒤에 첨자 연산자를 붙여 사용할 수 없다. 이유는 나도 모르겠다. 파서를 단순하게 유지하기 위함일 것이라고 짐작할 뿐이다.

PHP 6에서도 안될 예정이다: http://bugs.php.net/bug.php?id=43577

PHP의 당황스런 특징들”에 대한 3개의 생각

  1. 말씀하신대로 첫번째 항목은 펄과 유사하다고 생각합니다. weak typing 때문이라고 말하기는 조금 애매할 수 있는데 일단 perl의 예를 들면 perl의 경우 context를 굉장히 중요하게 여깁니다. 이것이 스칼라 문맥인지 아니면 목록 문맥인지, 스칼라 문맥 안에서는 문자열 문맥인지 숫자 문맥인지… 스칼라 문맥 안에서 문자열 문맥인지 숫자 문맥인지를 판단하는 것은 대부분의 경우 연산자를 통해 피연산자의 상태를 판단합니다. == 의 경우 숫자(numeric) 이항 연산자기 때문에 좌우측 값을 스칼라 값, 그 중에서도 숫자로 인식한답니다.

    래리월이 언어학자인 만큼 자연어의 특성을 많이 계승 받은 펄에서는 문맥(context)을 무척 중요하게 여기는데, 익숙해지면 너무 당연하게 편하게 받아들이지만, 익숙해져있지 않은 상황에서는 충분히 복잡하고 어려울 수 있는 부분이라고 생각됩니다. 문법의 일부로 받아들이는게 맞지 않나 생각합니다. 🙂

    좋아요

  2. @keedi
    자세한 설명 정말 고맙습니다. perl 이 context 를 다루는 방법에 대해 관심이 생기네요. 그것만으로도 perl 을 깊이있게 공부할 이유가 될 것 같습니다.

    좋아요

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중