Hatred for PHP
ëë¶ë¶ì ì¬ëë¤ì PHPê° íë°©íë PHPì ì² íì ëìíë¤. ê·¸ë ë¤ë©´ 무ìì´ ì«ë¨ ë§ì¸ê°? ì¹ ê²ìì íµí´ì ë¤ìê³¼ ê°ì ê¸ë¤ì ë°ê²¬í ì ììë¤.
- I hate PHP
- Why PHP sucks (for large systems)
- PHP in contrast to Perl
- Experiences of Using PHP in Large Websites
- PHP annoyances
- PHP: A love and hate relationship
- PHP 5 Enterprise Edition?"
ì´ ì¬ëë¤ì 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ì ê°ë³´ë¼.
마지막 People 항목은 옳은 지적이 아닙니다. 그런 질답이 많이 올라오는 이유는 PHP를 처음 시작한 초보분들이 많기 때문이죠. 그걸 가지고 다른 분들을 가르쳐주지는 못할 망정 수준이 낮다, 한심하다 하는 것은 많이 아는 사람으로서 해야 할 자세가 아닙니다. 누구나 처음 아무것도 모르던 시절은 존재하기 마련이고, 그런 초보 시절을 망각한다면 개발자는 발전할 수 없다고 생각합니다.
와.. 잘 정리하셨네요! 제가 PHP를 싫어하는 이유가 모두 들어있네요. ;-) namespace, array, html embedding, undefined literal lookup 등등.
shortcut behavior는 무슨 뜻인지 잘 모르겠고, anonymous function은 php에도 create_function이라는 이름으로 있습니다. closure처럼 동작할 겁니다.
마지막 항목은, 물론 결과적으로는 그렇게 보인다는 데 동의하지만, 꼭 php라서라기보다는 php 자체가 워낙 웹에 특화되어 있고, 웹프로그래밍 노동이란 것의 영향이 크다고 생각합니다. 물론 jsp와는 또다른 무언가가 있긴 하지만, 한국 IT 산업의 특수성도 고려해야 할 것 같고, 쉽게 얘기하기는 힘들 것 같네요.
Reidin: 오해입니다. 저는 물론 그러한 점을 잘 알고 있습니다. 절대로 비난을 위해서 그러한 말을 쓴 것이 아닙니다. PHP 개발자 개개인은 당연히 그렇지 않을 수 있습니다.
당연히 어느 개발자 커뮤너티를 가더라도 기초적인 문제에 대한 질답이 많은 것이 당연합니다. 문제는 그것을 벗어나지 못한다는 것이죠. 예를 들어, PHPSCHOOL에서 MVC를 검색해보십시오. 글 2개밖에 없더군요. (전엔 하나밖에 없었는데 요 며칠전에 어느 분이 올리셨더군요) 그리고, PHP에서 자주 사용되는 Web framework가 무엇인지 회사 개발자 분들에게 물어본 적이 있습니다. 아무도 답변이 없더군요. 매우 이상하다고 생각했습니다.
nohmad님이 말씀하신대로, 닷컴 붐 이후에 웹 개발자들에 대한 대량 수요가 발생했고, PHP 개발자들의 수준이 낮아졌죠. 누구에게 물어보더라도 PHP 개발자들을 포함한 업계 사람들은 PHP 개발자들이 하는 일을 매우 가치가 낮은 일로 여깁니다. 저는 그러한 생각이 또다시 전체적인 PHP 개발자들의 질을 낮추는 positive feedback을 가져온다고 생각합니다.
이 내용을 Part 2에 적으려다가, 결론이 되는 Part 3에 적으려고 빼두었는데, 다 얘기해버렸군요. 일단, 오해가 될만한 부분을 수정했습니다.
굉장한 뒷북 덧글이라 이걸 누가 읽을지 모르겠습니다만…….
nohmad 님이 말씀하시길 create_function()이 익명 함수이며 클로져로 작동한다고 하셨는데, 하나는 반쯤 맞고 하나는 아닙니다. 익명 함수라고 볼 수도 있겠지만, 실제로는 lambda_n 형식의 이름을 가진 함수가 만들어집니다. (정확히는 이름 맨 마지막에 널 문자가 들어갑니다.)
개인적으로는 저 이유들보다, PHP의 이상한 객체 모델이 더 마음에 들지 않습니다. 메서드와 멤버(속성)가 다른 네임스페이스를 가지고 있죠. 게다가 함수 이름으로 콜백을 지원하는 것도 불편합니다. create_function()이 이름을 가질 수밖에 없는 이유죠. 이름이 있어야 호출할 수 있거든요.
PHP 사용할 일이 많아서 불만이 상당히 쌓였는데, 최근에 느끼는 것은…… 불만이 있다면, 일단 그것을 고쳐보려는 시도를 해보는 게 더 생산적이라는 점입니다. 저도 그래서 나름대로 프레임워크를 만들어서 람다, 클로져 등을 구현해서 쓰고 있습니다.