JetBrains PHPverse 2025을 보면서 짧게 적었다. PHP 30주년을 맞아 즐겁고 축하 분위기 속에 진행되었다. 다년간 서로 영향을 주고 받으면서 성장한 라라벨과 심포니, 새로운 방향성을 제시하고 있는 FrankenPHP와 발족 이후 풍성한 활동을 하고 있는 PHP 재단까지 PHP의 현재를 폭넓게 살펴볼 수 있었던 시간이었다.

Table of Contents

FrankenPHP: Reinventing PHP for the Modern Web - Kévin Dunglas

FrankenPHP 에 대한 간략한 소개와 함께 현재 개발 상황을 공유했다. FrankenPHP는 go로 작성된 현대적 PHP 앱서버로 요즘 뜨거운 프로젝트 중 하나로 최근엔 PHP 재단의 지원도 받기 시작했다.

Go로 작성된 만큼 go의 가볍고 강력한 동시성, 성능의 혜택을 그대로 누릴 수 있게 됐다. 또한 go의 Caddy 웹서버를 기반으로 하고 있어서 Caddy의 모든 기능과 모듈을 사용할 수 있게 되었다. 거인의 어깨에 서서 고성능 달성!

$ docker run -v $PWD:/app \
    -p 80:80 -p 443:443 -p 443:443/udp \
    duglas/frankenphp

정적 바이너리로도 사용 가능해서 php 코드와 함께 번들해서 배포도 가능하게 되었다. homebrew나 리눅스 패키지로도 이미 다 배포되어 있어 손쉽게 사용할 수 있다.

$ curl https://frankenphp.dev/install.sh | sh
$ mv frankenphp /usr/local/bin/
$ frankenphp php-server -r public/
$ composer install --no-dev -a
$ git clone https://github.com/dunglas/frankenphp && cd frankenphp
$ EMBED=/path/to/my/app ./build-static.sh
$ ./dist/frankenphp-<os>-<arch> php-server
$ ./dist/frankenphp-<os>-<arch> php-cli my-command

다른 특징은 워커 모드의 지원인데 goroutines과 채널을 활용해서 더 빠르게 요청을 처리할 수 있다고 한다. 근래 대부분의 프레임워크와 라이브러리, 서비스(Symfony, Laravel Octane, Platform.sh, Laravel Cloud, Clever Cloud 등)에서 이미 잘 지원하고 있다고 한다.

frankenphp {
  worker {
    file ./public/worker.php
  }
}

103 Early Hints도 지원한다. 웹서버의 응답이 완전히 처리되기 전에는 브라우저에서 html을 받을 때까지 기다리게 되는데 정보성 응답으로 에셋을 미리 받을 수 있도록 돕는다.

// 바닐라
header('Link: </styles.css>; rel=preload; as=style');
header_send(103);
echo << 'HTML'
<!doctype html>
<title>Hello FrankenPHP</title>
<link rel="stylesheet" href="style.css">
HTML;

// symfony, 또는 laravel
$r = new Response();
$r->headers->set('Link', '</style.css>; rel=preload; as=style');
$r->sendHeaders(103);
// ...

go로 확장을 작성하고 php에서 쉽게 접근이 가능한 것도 재미있는 부분이었다. 물론 확장을 사용하기 위해서는 정적 컴파일이 필요하다. Zend 엔진 타입을 Go 타입으로 변환하는 등의 헬퍼를 제공해서 사용성을 높였다. 지원하는 타입은 계속 추가하는 과정에 있다고 한다.

//export_php:function background_hello(string $name): void
func BackgroundHello(*C.zend_string foo) {
  go func() {
    time.Sleep(10*time.Second)
    slog.Info("Hello", "name", franken.GoString(unsafe.Pointer(foo))
  }
}

위 함수를 다음처럼 간편하게 확장으로 빌드할 수 있다.

$ go mod init example.com/myextension
$ cd myextension
$ frankenphp extension-init myextension.go
 ...
$ xcaddy build \
    --output frankenphp \
    --with github.com/dunglas/frankenphp/caddy \
    --with example.com/myextension
<?php
background_hello("Alexandre Daubois"); // 직접 사용 가능

Symfony: Current State and Future Plans - Nicolas Grekas

Symfony도 라라벨과 함께 PHP 생태계에 큰 역할을 하는 프로젝트로 강력한 PHP 프레임워크이기도 하면서 작고 강력하면서도 다양한 라이브러리를 만들고 있다.

이외에도 최신 PHP 기능에도 잘 동작하고 PHP에 기여를 많이 한다, 문서화도 많이 신경 쓴다, 큰 규모의 건강한 커뮤니티가 잘 운영되고 있다는 등 이야기로 정리했다.

행사 디스코드에서 누가 Symfony 직장 잡기 힘들지 않냐고 푸념했는데 자기네는 Symfony만 엄청 뽑는다며 온갖 유럽 국가 이름이 쏟아졌다.

Building MCP Servers With PHP - Marcel Pociot

LLM이 어떻게 MCP 서버를 활용해서 서비스에 접근하는지 설명하고 php-mcp/server를 사용해서 MCP 서버를 작성하는 예제를 선보였다.

How AI Is Changing the Tech Industry - Cheuck Ting Ho

Laravel: Q&A With Its Creator - Taylor Otwell

The Future of PHP Education - Jeffrey Way, Povilas Korop, Kevin Bond

Laracasts의 Jeffery Way, LaravelDaily의 Povilas Korop, SymfonyCasts의 Kevin Bond가 PHP 교육에 관한 패널 토의를 진행했다.

PHP Foundation: Growing PHP for the Future - Roman Pronskiy, Gina Banyard

PHP 재단에 대한 개괄적인 이야기와 현재 무엇이 진행되고 있는지를 설명했다.

색상을 바꿔요

눈에 편한 색상을 골라보세요 :)

Darkreader 플러그인으로 선택한 색상이 제대로 표시되지 않을 수 있습니다.