모던php가 더이상 모던하지 않고 php의 표준 개발방법으로 정립될때, 그리고 워드프레스를 포함한 CMS들이 모던php를 채택했을때 php가 안전한 범용언어로 사람들에게 인식될 거라 생각합니다. 신뢰를 복구하는 것은 일반적으로 신뢰를 깨는 것보다 노력이 많이 듭니다
하위호환성 유지라는 명목으로 입문자들이 PHP의 기본기능만 가지고 안전하지 못한 웹서비스를 만들수 있도록 허용하기 때문입니다. PHP tutorial로 검색한 사이트 상위 5개중 XSS를 방어하기 위해 초전역변수(superglobal)의 내용을 출력할때 HTML 이스케이프를 적용해야 한다는 내용을 포함시킨 사례는 PHP 공식 사이트 이외에는 없습니다. 그들이 공식적으로 제공하는 가이드가 웹개발의 내용을 담고 있으니 PHP는 언어와 프레임워크 두 가지의 역할을 하고 있는 것 아닐까요?
초전역변수의 이름으로 HTTP의 여러 요소들이 기본 제공되고 있는 점에 대해서는 어떻게 생각하시나요? 저는 언어가 표현하고 있는 내용에 따라 범용성의 범위와 사용처가 결정된다고 생각합니다.
예로 들어주신 $_GET, $_POST 같은 초전역변수는 PHP를 CGI, SAPI 모드로 사용했을 때 노출되는 값입니다. PHP를 CLI로 사용할 경우 해당 값은 노출되지 않습니다.
그러한 초전역변수는 PHP를 실행시키는 런타임인 PHP-CGI, PHP-FPM 등이 노출시키는 API의 일종이지, 언어로서의 PHP 스펙이 아닙니다.
이전에 언급된 "템플릿 언어를 표방하는 PHP" 도 엄밀히 이야기하면 PHP가 아닌 PHP의 런타임 중 하나인 CGI가 그렇게 활용되기를 원하는 것이지요.
마찬가지로, 취약점이라 이야기되었던 수 많은 PHP 내장 함수들도 PHP의 익스텐션이 노출시키는 함수들이지, PHP라는 "언어"가 가진 기능이 아닙니다.
말씀하신대로라면,
자바스크립트는 브라우저와 통신하기 위해 브라우저가 노출하는 API를 사용하는, 또 애초에 그럴 목적으로 설계된 언어이자 프레임워크가 되는 것이고,
자바는 언어이지만 사실상 JDK의 수 많은 API들을 활용하기 위해 사용되는 프레임워크가 되는 것이고,
여타 다른 모든 언어들도 언어 그 자체의 스펙과는 관계 없이, 표준 라이브러리, API를 제공한다면 전부 프레임워크라고 보아야 할테니까요.
물론 뗄레야 뗄 수 없는 관계임은 맞으나, 이러한 부분을 가지고 PHP가 프레임워크라고 주장하기엔 설득력이 많이 떨어집니다.
그리고 2024년 5월 현재까지도 워드프레스 코어 프로젝트에서 XSS가 패치되고 있는 것을 보면 온전히 PHP 문법 차원의 개선으로는 XSS를 막을 수 없는 것으로 보입니다.
프론트엔드 프레임워크, 서버사이드 템플릿 엔진 등은 데이터로 렌더링할 수 있는 모든 내용에 일괄적으로 HTML 이스케이프를 적용하며, 명시적으로 이스케이프를 해제할 때에만 안전하지 않은 방식으로 출력을 생성합니다. PHP에는 그런 처리를 일괄적으로 적용할 수 있는 합의된 방법이 없습니다. echo나 print 문이 이스케이프를 기본 지원했다면 당장에는 동작하지 않는 코드가 속출했겠지만, 장기적으로는 많은 사람들이 이스케이프를 누락시키는 실수를 줄일 수 있었을 것입니다.
네, 저는 언어와 실행환경을 분리해서 보는 시각에 동의하지 않고 어떤 식으로든 실행환경이 언어에 영향을 준다고 생각합니다. 자바스크립트의 경우 nodejs와 브라우저 두개의 실행환경이 있고, 파이썬에는 많은 구현체들이 있지만 cpython이 우세한 것으로 이해하시면 되겠습니다
원글의 주제가 문법적인 개선에 한정되어 있는데 저는 이런 프레임보다 조금 더 넓은 범위의 이야기를 하고 싶었습니다
또한 라라벨은 오픈소스 기여자들이 아니라 라스무스나 zend같은 회사에 의해서, 2011년이 아니라 2007년쯤에 개별 프로젝트가 아니라 공식 언어 기능으로 나왔어야 할 물건이라 생각합니다. 파이썬3가 하위호환성을 일부 포기한 것때문에 도입에 차질이 있었지만 PHP도 5버전 즈음에 대규모의 하위호환성 정리를 했어야 한다고 생각합니다. PHP의 변화는 시대의 흐름보다 항상 시차가 있는 것 같기도 합니다
위 댓글에 대한 답도 겸합니다.
말씀하신 관점에서 봤을 때 PHP를 일종의 웹 프레임워크로 취급할 수 있겠다는 생각은 드네요.
그렇지만 예시로 든 XSS 필터, 이스케이프 등등을 포함한 여러 기능들을 PHP가 기본적으로 제공해야 한다고는 생각하지 않습니다.
제일 보편적인 PHP-FPM과 Django, RoR는 동일한 포지션이 아닙니다. Flask, Sinatra, Express에 가깝지요.
PHP-FPM은 라우팅(디렉토리 기반), 요청 해석($_GET, $_POST, $_FILE, $_COOKIE), 응답 전송(echo, print), 세션관리($_SESSION) 이상의 기능을 담당하지 않습니다.
Flask는 다른가요?
플라스크에서 HTML 이스케이프된 응답을 반환하려면 단순히 return 만으로 해결되지 않습니다.
https://flask.palletsprojects.com/en/3.0.x/quickstart/#html-escaping
Sinatra는 다른가요?
마찬가지로 별도의 이스케이프 라이브러리를 사용해야 합니다.
https://sinatrarb.com/faq.html#escape_html
Express는 다른가요?
이것도 마찬가지로 별도의 이스케이프 라이브러리를 사용해야 합니다.
https://expressjs.com/en/resources/middleware.html
예시로 든 라이브러리 모두 그 프레임워크에서 공식적으로 제공하는 라이브러리가 아닙니다.
그런데 왜 PHP는 꼭 PHP에서 공식적으로 그러한 기능을 제공해야 하나요?
"어떤 미친 프레임워크가 요청 데이터를 초전역변수로 노출시키냐, 설령 보안 상 문제가 없더라도 이건 유저에 대한 예의가 아니다!" 같은
이미 많은 사람들이 이야기하는 이유로 PHP가 쓰레기다 주장한다면 모르겠는데,
말씀하신 "PHP의 기본 기능이 풀스택 프레임워크가 제공하는 것만큼 충분하지 못하다" 라는 이유는... 최소한 저는 동의하기 힘듭니다.
Express를 좀 더 모던하게 체계적으로 사용하기 위해 Nestjs 라는 친구가 만들어진 것처럼, PHP를 좀 더 모던하게 체계적으로 사용하기 위해 Laravel 이라는 친구가 만들어졌다 생각하면...
다른 프레임워크(언어)와 비교되는 단점보다 제 원 댓글의 주장처럼 PHP(-FPM) 특유의 장점이 더 와닿지 않을까요?
옛 기억을 더듬어보니 최소한 slim twig 조합만 보편화되어 있었어도 프로젝트에서 했던 PHP 실수들을 줄일 수 있었을 것 같습니다. 물론 다른 PHP 개발자들이 PHP 날코딩에 익숙해 있었기 때문에 그 당시에는 도입할 수 없었구요. 다행히 PDO는 표준 라이브러리에 있어서 SQL 인젝션에 대한 대비는 할 수 있었습니다
원 댓글에서 언급하신 버그 영향도 제한이나 처리성능에 대해서는 딱히 부정이나 긍정 의견이 없습니다. 있으면 좋은 기능이라고는 생각합니다만, 처리량 폭증이나 메모리 사용량 문제는 성장단계에서 최소 한번은 고민해야할 문제이기 때문에 그런 문제가 명시적인 형태로 가능한 빨리 나오면 좋다고 생각합니다
물론 다른 PHP 개발자들이 PHP 날코딩에 익숙해 있었기 때문에 그 당시에는 도입할 수 없었구요.
PHP로 개발을 할 줄 아는 사람들이 바뀌는게 제일 시간이 걸리고 어렵기 때문에
개인적으로 PHP 자체는 문제가 없거나, 충분히 대응할 수단이 있거나, 또는 다른 언어에서와 같이 납득할 수 있는 이유로 생겨난 차이 정도만 있다고 보는데, 말씀하신 인력 문제... 이게 사실상 제일 큰 문제가 아닐까 싶네요.
PHP를 진지하게 사용할 수 있는 개발자들은 이미 오래전의 PHP에 학을 떼고 PHP에서 탈출한 지 오래고,
남아있는 대부분의 사용자들은 PHP가 아무리 발전해도 제대로 봐 주지 않는, 또는 제대로 봐 줄 여력이 되지 않는 사람들...
PHP가 적합하다 생각하는 MVP+a 의 프로젝트엔 전자의 경력자들이 참여할 이유가 없고,
설령 참여한다고 해도, PHP를 선택하지 않거나, PHP를 선택하더라도 후자의 유저가 한두명 끼는 순간 엉망진창이 될거라...ㅋㅋ
적어도 국내에선 만족스러운 PHP 개발 가능 인력을 구하는 것 자체가 쉽지 않네요.
그렇게 또 PHP는 선택지에서 제외되고, 더더욱 평균적인 인력 수준이 낮아지고, 그게 무한 반복되며 악순환을 만들어 나가는 것 같습니다.
이렇게라도 계속 약을 팔아 소규모 1~3인 프로젝트에서만이라도 제대로 된 PHP 프로젝트를 시도하는 케이스가 늘어나야 악순환이 끊기지 않을까 생각합니다.
그러는 저도 사실 PHP가 만들어주는 수익이 그리 크지는 않네요. 만족스러운 인력 수급이 너무 힘드니까 PHP를 메인 스택으로 가져갈래야 가져갈 수 없는 현실...
범용 언어와 PHP 사이에는 HTML 페이지를 만들어내는 방식의 차이가 있기 때문입니다. Flask는 최소한 1.0 버전을 출시할 때 부터 사람들이 템플릿 엔진을 사용하도록 장려하였고 템플릿 엔진에 의존하도록 설계되었습니다. HTML 페이지와 서버사이드 데이터 사이를 의도적으로 격리하고 템플릿 단위의 작업을 지원해오고 있습니다. 해결하고자 하는 문제의 특징과 사람들의 사용 습관이 고려되어 있다고 생각합니다.
반면에 PHP는 표준 출력이 곧 페이지의 일부가 되며 서버사이드 데이터와 HTML 페이지 사이의 경계가 모호합니다. print하는 것이 결과 페이지에 그대로 들어가며 이스케이프를 명시적으로 개발자가 수행해야 합니다. htmlcharacterescapes 함수를 모든 외부 데이터에 붙여야한다는 설계는 사람들에게 잘 받아들여지지 않았습니다. 사람들은 무의식적으로 템플릿을 원했지만 PHP에는 HTML 페이지를 만들어낸다는 사용자의 목적이 고려되지 않은 것으로 보입니다.
표준 라이브러리 내지는 언어 자체로 그 기능이 들어가야 하는 이유는 PHP의 환경 구성과 코드 배포방식을 고려했을때 가장 효과적인 방법이기 때문입니다. LAMP 스택으로 개발환경이, 웹호스팅 방식으로 운영환경이 정형화 되어 있고 FTP 파일을 던져넣는 방식에 익숙해져 있으니 추가 패키지를 제공할 수 있는 가능성은 범용언어에 비해 낮습니다. 모듈 설치를 입문자에게 요구할 수도 없습니다. 남는 선택지는 표준 라이브러리와 표준 문서밖에 없습니다.
사람들은 무의식적으로 템플릿을 원했지만 PHP에는 HTML 페이지를 만들어낸다는 사용자의 목적이 고려되지 않은 것으로 보입니다.
크게 공감되는 내용은 아닌 것 같습니다.
단순히 C API를 CGI로 쉽게 노출시켜주는 수준이었던 PHP3 시절은 말씀하신 것과 같이 템플릿 용도로 사용되었다 말할 수 있겠지만...
PHP4.2 부터 이미 범용적인 활용이 충분히 가능한 수준으로 환경이 만들어졌습니다.
코드가 CLI를 통해 실행되기를 기대할 수 있는 환경이 되었고, 이전 댓글에서 언급하셨던 것 처럼 "라라벨은 2007년쯤에 개별 프로젝트가 아니라 공식 언어 기능으로 나왔어야 할 물건" 이라는 내용은 당시 PHP의 방향성에 전혀 맞지 않는 이야기입니다.
2004년 공개된 Smarty 라는 PHP용 템플릿 엔진, 2006년 공개된 CodeIgniter 라는 PHP용 MVC 프레임워크 등의 존재는 PHP 그 자체로는 템플릿 언어가 아님을 반증하고, 또 그렇게 사용하지 않겠다는 PHP 사회적 공감대가 이미 형성되었다고 판단할 수 있겠지요.
프론트엔드 프레임워크, 서버사이드 템플릿 엔진 등은 데이터로 렌더링할 수 있는 모든 내용에 일괄적으로 HTML 이스케이프를 적용하며, 명시적으로 이스케이프를 해제할 때에만 안전하지 않은 방식으로 출력을 생성합니다.
이전 댓글의 위 내용도 PHP의 시간대와 비교해 보았을 때 딱히 올바른 이야기는 아니라고 생각됩니다.
django가 처음 공개된 05년부터, 그 이후 몇년간 HTML 이스케이핑은 기본 세팅이 아니었습니다. 개발자가 의도적으로 이스케이프 필터를 설정해 주어야했지요. 지금도 파이썬에서 사용되고 있는 jinja의 경우 아직까지도 HTML 이스케이핑을 자동으로 처리하지 않습니다.
자동으로 이스케이핑 해 주는 것이 일반적인 것으로 취급되던 시기엔 이미 PHP는 템플릿 언어라는 정체성을 벗어 던진지 오래입니다. (당시 PHP를 무지성적으로 사용하던 사용자들이 그걸 원하지는 않았겠지만, 다르게 보면 이미 PHP는 그러한 사용자들을 천천히 배제해 나가겠다고 결정내렸다 볼 수도 있겠지요.)
PHP는 더 이상 그러한 용도의 언어가 아니기 때문에 PHP에서 표준 라이브러리와 언어에 그러한 기능을 디폴트 값으로 적용할 이유는 하등 없는 것이고, 범용 언어로써 동작하기를 원하는 PHP 입장에선 언급하신 htmlcharacterescapes 함수로 이미 충분히 제 역할을 다 했다고 봅니다.
웹호스팅 방식으로 운영환경이 정형화 되어 있고 FTP 파일을 던져넣는 방식에 익숙해져 있으니 추가 패키지를 제공할 수 있는 가능성은 범용언어에 비해 낮습니다.
위 내용에도 크게 공감하기 힘듭니다. 십수년도 더 넘은 이전부터 git 등을 아주 잘 활용했습니다. 심지어 도커가 공개된 직후부터 도커를 사용한 배포도 충분히 많이 시도되었고, 지금도 그렇게 사용하고 있습니다.
언급하신 내용들 대부분 PHP 보다는 PHP로 개발된 CMS 위에서 놀 때나 의미가 있는 이야기가 아닐까 싶습니다.
이런 표현을 좋아하지는 않지만, PHP 개발자들도 개발자 취급 안해주는 그런 케이스...
jinja의 자동 이스케이핑 기능은 제 주장이 틀렸고 언급하신 내용이 맞습니다.
위 내용에도 크게 공감하기 힘듭니다. 십수년도 더 넘은 이전부터 git 등을 아주 잘 활용했습니다. 심지어 도커가 공개된 직후부터 도커를 사용한 배포도 충분히 많이 시도되었고, 지금도 그렇게 사용하고 있습니다.
제 PHP 경험은 2014년에 머물러있고 그 당시에는 도커가 없었습니다. git도 일하는 방식을 바꿔야 했기에 도입할 수 없었구요. 실제 일하는 환경에서 그런 걸 도입해야 하면 공감대가 있어야 하는데 제 상황에서는 불가능했었습니다
이런 표현을 좋아하지는 않지만, PHP 개발자들도 개발자 취급 안해주는 그런 케이스...
돌아보면 개발자 취급 못받는 사람들 사이에서 제가 일을 했었나 봅니다
예로 드신 장고의 인증, 접근제어, 양식 검증, DB 마이그레이션 툴, 테스트 도구는 PHP의 라라벨에서도 모두 제공하고 있습니다.
인증: https://laravel.com/docs/11.x/authentication
접근제어: https://laravel.com/docs/11.x/authorization
양식 검증: https://laravel.com/docs/11.x/validation
DB 마이그레이션: https://laravel.com/docs/11.x/migrations
테스트: https://laravel.com/docs/11.x/testing
또, 외부 라이브러리거나 유료 라이브러리지만,
기존의 DB 스키마를 모델과 마이그레이션 코드로 내보내거나, 반대로도 작동하는 친구도 존재하고,
CRUD UI를 포함한 깔끔한 백오피스를 제공하는 https://nova.laravel.com/ 도 존재합니다.
장고가 가진 기능들 거의 모두가 라라벨에도 존재합니다.
(애초에 둘 다 RoR의 컨셉을 이어 받은만큼, 제공되는 기능 자체는 비슷할 수 밖에 없다고 봅니다.)
그럼에도 장고-파이썬과 다르게 라라벨-PHP에는 제가 원 댓글에서 언급한 장점이 추가로 존재하지요.
PHP가 웹앱용 템플릿 언어를 표방하며 설계된 언어임은 부정할 수 없는 사실이지만,
모던 PHP 스타일이 정착한지 십년이 다 되어가는 이 시기까지 단순히 템플릿 언어로만 보는건 가혹하지 않나 싶습니다.
Nova를 링크해주셔서 봤는데 이것도 유료 라이센스네요 프로젝트 튜토리얼에서 명시되고 바로 사용할 수 있는 장고 어드민과 기능은 유사할지 몰라도 접근성 면에서 차이가 있어 보입니다.
또한 라라벨은 오픈소스 기여자들이 아니라 라스무스나 zend같은 회사에 의해서, 2011년이 아니라 2007년쯤에 개별 프로젝트가 아니라 공식 언어 기능으로 나왔어야 할 물건이라 생각합니다. 파이썬3가 하위호환성을 일부 포기한 것때문에 도입에 차질이 있었지만 PHP도 5버전 즈음에 대규모의 하위호환성 정리를 했어야 한다고 생각합니다. PHP의 변화는 시대의 흐름보다 항상 시차가 있는 것 같기도 합니다
이제는 개인적으로 웹개발에 입문하는 입장이 아니기 때문에 PHP를 선택할 일은 없을 것입니다
저는 좀 생각이 다른게 혼자 MVP를 만들어내려면 DB 스키마, WAS, UI 세가지를 최소한의 코딩으로 구현하는 도구가 필요하다고 생각합니다. 그리고 PHP의 대안으로 루비온레일즈와 장고라는 훌륭한 선택지가 있다고 생각합니다
장고의 경우 액티브 레코드 패턴(참 낡은 단어네요)으로 모델 클래스만 정의하면 DB 스키마랑 그럭저럭 쓸만한 백오피스용 CRUD UI가 나옵니다. 인증, 접근제어, 양식 검증, DB 마이그레이션 툴, 테스트 도구 등 최소한의 웹서비스 개발을 위한 도구가 제공됩니다. 개인적으로는 2000년대 후반에 웹 프로그래밍을 시작하고 나서 장고만한 생산성을 경험해본 적이 없습니다. SPA 방식이 유행하고 프론트엔드와 백엔드 직군이 나눠진 이후로는 오히려 생산성이 줄어든 느낌마저 듭니다. 최소한 두명의 작업자가 사용자 플로우를 이해해야하고 프로토콜을 맞춘 상태에서 작업해야 작업을 병렬적으로 수행할 수 있기 때문입니다
PHP가 웹앱용 템플릿 언어를 표방하고 싶었다면 언어 수준에서 웹 취약점을 방어하는 수단을 제공했어야 한다고 생각합니다. 모던 PHP 스타일이 프레임워크 개발방식을 채택한게 그 증거라고 볼 수 있을 것 같습니다.