Is PHP A Bad Programming Langauge? (Part 2)

Hatred for PHP

대부분의 사람들은 PHP가 표방하는 PHP의 철학에 동의한다. 그렇다면 무엇이 싫단 말인가? 웹 검색을 통해서 다음과 같은 글들을 발견할 수 있었다.

이 사람들은 PHP를 미워하고 있다. 그 이유는? 어느 정도 유효하고 중요한 내용들만 내 생각들과 함께 정리해보았다.

Language Syntax

  • No namespaces: 어느 정도 복잡한 product를 만들 때, 불편한 점 중의 하나는 함수 이름이나 변수 이름이 중복되는 것이다. 이 문제에 대한 해결책으로, 모든 함수나 변수들의 이름에 prefix를 붙여서 namespace를 구분하거나, 클래스를 namespace의 대용으로 사용하는 방법이 있다. C와 같은 다른 언어들을 생각해보면, 분명히 namespace가 없이도 커다란 프로덕트를 만드는 것은 가능하다. 하지만, 최근에 나온 대부분의 언어가 namespace를 가지고 있음에도 불구하고 PHP 5에 namespace가 들어가지 않은 것은 상당히 아쉬운 부분이다.
  • Arrays are ordered maps: PHP의 array는 기본적으로는 key, value pair의 집합인 ordered map이다. PHP의 array는 이러한 map의 용도 뿐만 아니라 여러 용도로 전용된다. integer를 key로 하는 전통적인 array를 비롯하여, list, queue, stack 등으로 사용될 수 있다. 이러한 사실은 array function들을 ë³´ë©´ 알 수 있다. 언어가 단순해지고, 여러가지 데이터형으로 활용함으로써 얻는 편리한 점도 있겠으나, 프로그래머가 array라는 데이터형에 대한 명확한 모델을 머리속에 그리지 못하게 하고, 또한 프로그래머가 실수를 할 가능성을 높힌다는 측면에서 그리 좋지 못하다고 생각된다. 많은 언어들이 array와 map을한다. 하지만, 그렇다고 string 만으로 array를 지원하는 언어들을 무시할 수는 없다. 어떤 데이터형을 지원하는가 하는 문제는 언어의 단순성과 프로그래머의 편이성 사이의 trade-off 문제라고 생각한다. 어떤 언어가 어떤 데이터형을 지원하느냐는 ê·¸ 언어의 철학에 달린 일이고, 정답이 있는 것은 아니다.
  • Does not enforce the declaration of variables: PHP는 선언 또는 정의되지 않은 변수이더라도 참조가 가능하다. (물론 warning은 발생한다.) "<? print $undeclared_variable; ?>"라는 PHP 코드와 "print undeclared_variable"이라는 Ruby 코드를 실행해보라. PHP에서는 아무렇지 않은 듯이 조용히 실행되지만 Ruby에서는 "undefined local variable or method"라는 에러가 발생한다. 비교적 작은 프로그램, 모듈, 또는 함수에서는 큰 문제가 되지 않지만, 코드가 길어지고 복잡해질 수록 버그를 발생시킬 가능성이 높아지고, 이 버그를 발견하는 것도 힘들어진다. PHP에서는 옵션을 통해 정의되지 않은 변수 접근에 대한 경고를 켤 수 있다.
  • No real references: reference가 아니라 name alias일 뿐이기 때문에 여러가지 문제가 발생한다. http://www.php.net/manual/en/language.references.php
  • No chained method call: $foo->bar()->op() 같은 문법이 불가능했었다. PHP 5에서 가능해졌다.
  • No closure, not even anonymous functions
  • shortcut behavior: 다른 언어들과는 달리 shortcut의 결과값이 boolean 값이다.
  • call-time pass-by-reference deprecation: PHP에서 reference를 사용하는 문법은 매우 이상했다. function을 정의할 때 파라미터에 reference임을 나타낼 수도 있고, 실제로 호출을 수행할 때도 reference임을 나타낼 수 있었다. 이 점은 기존 PHP 문법이 상당히 불완전함을 나타내는 증거라고 ë³¼ 수 있는 것 같다. (예를 들어, function 정의의 파라미터에도 reference라고 명시하고, 호출 시 아규먼트에도 reference라고 명시한다면 어떻게 될 것인가. reference의 reference? 답은, 그냥 reference다.) 결국은 호출 시 reference 명시는 deprecated 되었다. 문제는 이 deprecation으로 기존에 할 수 ì
    žˆì—ˆë˜ 일을 할 수 없게 되어버렸다는 것이다. PHP 5에서는 모든 variable을 reference semantic을 가지도록 바꾸었기 때문에 더이상 이런 문제는 없을 것이다.

Language Implementation

  • Template: 대부분의 언어들은 templating을 언어의 구현과 분리해놓지만, PHP의 구현에는 완전히 합쳐져있다. 웹 어플리케이션의 규모가 커지면서 프리젠테이션과 로직의 분리가 중요해진 지금 시점에는 그다지 좋지 않은 방법이다.
  • Register Globals: Register Globals는 CGI를 통해 들어오는 리퀘스트 변수들을 전역 변수로 만들어주는 기능이다. namespace를 가지지못한 PHP로서는 전역 namespace를 더럽히는 것은 엄청나게 해로운 일이다. 물론 여기에는 "웹 프로그래머의 편이"라는 언어가 만들어지던 당시의 고려가 담겨있다. 하지만, 웹 어플리케이션의 규모가 커지면서 이 기능은 PHP를 해치는 기능이 되어버렸다. 최근에는 이 기능을 켜고 끌 수있는 옵션의 기본 값이 "끄는 것"으로 바뀌었다.
  • Bad recursion support: 스피드를 위해서 stack에 저장하는 데이터가 많기 때문에 recursion에 좋지 않다.
  • Not thread-safe: 구현을 ë³´ë©´ thread safety를 위한 노력을 하고 있으나, 실제로 thread-safe 하지는 않다.
  • Magic quotes: Magic quotes는 PHP가 사용하는 데이터에서 특정 문자들을 자동으로 escaping 해주는 기능이다. 프로그래머가 직접 하더라도 크게 불편하지 않은 작업을 굳이 자동으로 해주어서 복잡도를 증가시키는 것은 좋지 않은 기능인 것 같다.

Standard Library/3rd-party Library/Framework

  • Inconsistency: PHP에서 기본으로 제공되는 라이브러리에 들어있는 함수들의 이름이나 파라미터들은 상당히 일관성이 없다. 다음 링크 참조.
  • no crucial XXX library: html parser, MIME builder, WWW library, consistent database API, gd를 제외한 graphics library가 없다는 것을 불만스러워하고 있다. PEAR에서 어느 정도 해결되기를 기대해본다.
  • no CPAN: 현재는 PEAR가 공식적인 extension repository가 되었으나, CPAN 처럼 사용하기에 편리한 것은 아니다.

People

  • Knowledgeable people are in a serious minority: 외국의 PHP 커뮤너티조차도 수준이 낮다는 지적을 많이 받고 있는데, 내가 보기에는 국내의 PHP 커뮤너티ë
    „ 크게 다르지 않은 것 같다. 가장 유명하다는 PHPSCHOOL에 가보라.

“Is PHP A Bad Programming Langauge? (Part 2)”에 대한 4개의 생각

  1. 마지막 People 항목은 옳은 지적이 아닙니다. 그런 질답이 많이 올라오는 이유는 PHP를 처음 시작한 초보분들이 많기 때문이죠. 그걸 가지고 다른 분들을 가르쳐주지는 못할 망정 수준이 낮다, 한심하다 하는 것은 많이 아는 사람으로서 해야 할 자세가 아닙니다. 누구나 처음 아무것도 모르던 시절은 존재하기 마련이고, 그런 초보 시절을 망각한다면 개발자는 발전할 수 없다고 생각합니다.

  2. 와.. 잘 정리하셨네요! 제가 PHP를 싫어하는 이유가 모두 들어있네요. ;-) namespace, array, html embedding, undefined literal lookup 등등.
    shortcut behavior는 무슨 뜻인지 잘 모르겠고, anonymous function은 php에도 create_function이라는 이름으로 있습니다. closure처럼 동작할 겁니다.
    마지막 항목은, 물론 결과적으로는 그렇게 보인다는 데 동의하지만, 꼭 php라서라기보다는 php 자체가 워낙 웹에 특화되어 있고, 웹프로그래밍 노동이란 것의 영향이 크다고 생각합니다. 물론 jsp와는 또다른 무언가가 있긴 하지만, 한국 IT 산업의 특수성도 고려해야 할 것 같고, 쉽게 얘기하기는 힘들 것 같네요.

  3. Reidin: 오해입니다. 저는 물론 그러한 점을 잘 알고 있습니다. 절대로 비난을 위해서 그러한 말을 쓴 것이 아닙니다. PHP 개발자 개개인은 당연히 그렇지 않을 수 있습니다.
    당연히 어느 개발자 커뮤너티를 가더라도 기초적인 문제에 대한 질답이 많은 것이 당연합니다. 문제는 그것을 벗어나지 못한다는 것이죠. 예를 들어, PHPSCHOOL에서 MVC를 검색해보십시오. 글 2개밖에 없더군요. (전엔 하나밖에 없었는데 요 며칠전에 어느 분이 올리셨더군요) 그리고, PHP에서 자주 사용되는 Web framework가 무엇인지 회사 개발자 분들에게 물어본 적이 있습니다. 아무도 답변이 없더군요. 매우 이상하다고 생각했습니다.
    nohmad님이 말씀하신대로, 닷컴 붐 이후에 웹 개발자들에 대한 대량 수요가 발생했고, PHP 개발자들의 수준이 낮아졌죠. 누구에게 물어보더라도 PHP 개발자들을 포함한 업계 사람들은 PHP 개발자들이 하는 일을 매우 가치가 낮은 일로 여깁니다. 저는 그러한 생각이 또다시 전체적인 PHP 개발자들의 질을 낮추는 positive feedback을 가져온다고 생각합니다.
    이 내용을 Part 2에 적으려다가, 결론이 되는 Part 3에 적으려고 빼두었는데, 다 얘기해버렸군요. 일단, 오해가 될만한 부분을 수정했습니다.

  4. 굉장한 뒷북 덧글이라 이걸 누가 읽을지 모르겠습니다만…….
    nohmad 님이 말씀하시길 create_function()이 익명 함수이며 클로져로 작동한다고 하셨는데, 하나는 반쯤 맞고 하나는 아닙니다. 익명 함수라고 볼 수도 있겠지만, 실제로는 lambda_n 형식의 이름을 가진 함수가 만들어집니다. (정확히는 이름 맨 마지막에 널 문자가 들어갑니다.)
    개인적으로는 저 이유들보다, PHP의 이상한 객체 모델이 더 마음에 들지 않습니다. 메서드와 멤버(속성)가 다른 네임스페이스를 가지고 있죠. 게다가 함수 이름으로 콜백을 지원하는 것도 불편합니다. create_function()이 이름을 가질 수밖에 없는 이유죠. 이름이 있어야 호출할 수 있거든요.
    PHP 사용할 일이 많아서 불만이 상당히 쌓였는데, 최근에 느끼는 것은…… 불만이 있다면, 일단 그것을 고쳐보려는 시도를 해보는 게 더 생산적이라는 점입니다. 저도 그래서 나름대로 프레임워크를 만들어서 람다, 클로져 등을 구현해서 쓰고 있습니다.

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.