Build the dev Docker image:
docker build -t frankenphp-dev -f dev.Dockerfile .
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -p 8080:8080 -p 443:443 -p 443:443/udp -v $PWD:/go/src/app -it frankenphp-devThe image contains the usual development tools (Go, GDB, Valgrind, Neovim...) and uses the following php setting locations
- php.ini:
/etc/frankenphp/php.iniA php.ini file with development presets is provided by default. - additional configuration files:
/etc/frankenphp/php.d/*.ini - php extensions:
/usr/lib/frankenphp/modules/
If your Docker version is lower than 23.0, the build will fail due to dockerignore pattern issue. Add directories to .dockerignore:
!testdata/*.php
!testdata/*.txt
+!caddy
+!internalFollow the instructions to compile from sources and pass the --debug configuration flag.
export CGO_CFLAGS=-O0 -g $(php-config --includes) CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)"
go test -race -v ./...Build Caddy with the FrankenPHP Caddy module:
cd caddy/frankenphp/
go build -tags nobadger,nomysql,nopgx
cd ../../Run the Caddy with the FrankenPHP Caddy module:
cd testdata/
../caddy/frankenphp/frankenphp runThe server is listening on 127.0.0.1:80:
Note
If you are using Docker, you will have to either bind container port 80 or execute from inside the container
curl -vk http://127.0.0.1/phpinfo.phpBuild the minimal test server:
cd internal/testserver/
go build
cd ../../Run the test server:
cd testdata/
../internal/testserver/testserverThe server is listening on 127.0.0.1:8080:
curl -v http://127.0.0.1:8080/phpinfo.php-
Configure Git to always use
lfline endingsgit config --global core.autocrlf false git config --global core.eol lf
-
Install Visual Studio, Git, and Go:
winget install -e --id Microsoft.VisualStudio.2022.Community --override "--passive --wait --add Microsoft.VisualStudio.Workload.NativeDesktop --add Microsoft.VisualStudio.Component.VC.Llvm.Clang --includeRecommended" winget install -e --id GoLang.Go winget install -e --id Git.Git
-
Install vcpkg:
cd C:\ git clone https://github.com/microsoft/vcpkg .\vcpkg\bootstrap-vcpkg.bat
-
Download the latest version of the watcher library for Windows and extract it to a directory named
C:\watcher -
Download the latest Thread Safe version of PHP and of the PHP SDK for Windows, extract them in directories named
C:\phpandC:\php-devel -
Clone the FrankenPHP Git repository:
git clone https://github.com/php/frankenphp C:\frankenphp cd C:\frankenphp
-
Install the dependencies:
C:\vcpkg\vcpkg.exe install -
Configure the needed environment variables (PowerShell):
$env:PATH += ';C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\bin' $env:CC = 'clang' $env:CXX = 'clang++' $env:CGO_CFLAGS = "-O0 -g -IC:\frankenphp\vcpkg_installed\x64-windows\include -IC:\watcher -IC:\php-devel\include -IC:\php-devel\include\main -IC:\php-devel\include\TSRM -IC:\php-devel\include\Zend -IC:\php-devel\include\ext" $env:CGO_LDFLAGS = '-LC:\frankenphp\vcpkg_installed\x64-windows\lib -lbrotlienc -LC:\watcher -llibwatcher-c -LC:\php -LC:\php-devel\lib -lphp8ts -lphp8embed'
-
Run the tests:
go test -race -ldflags '-extldflags="-fuse-ld=lld"' ./... cd caddy go test -race -ldflags '-extldflags="-fuse-ld=lld"' -tags nobadger,nomysql,nopgx ./... cd ..
-
Build the binary:
cd caddy/frankenphp go build -ldflags '-extldflags="-fuse-ld=lld"' -tags nobadger,nomysql,nopgx cd ../..
Print Bake plan:
docker buildx bake -f docker-bake.hcl --printBuild FrankenPHP images for amd64 locally:
docker buildx bake -f docker-bake.hcl --pull --load --set "*.platform=linux/amd64"Build FrankenPHP images for arm64 locally:
docker buildx bake -f docker-bake.hcl --pull --load --set "*.platform=linux/arm64"Build FrankenPHP images from scratch for arm64 & amd64 and push to Docker Hub:
docker buildx bake -f docker-bake.hcl --pull --no-cache --push-
Download the debug version of the FrankenPHP binary from GitHub or create your custom static build including debug symbols:
docker buildx bake \ --load \ --set static-builder.args.DEBUG_SYMBOLS=1 \ --set "static-builder.platform=linux/amd64" \ static-builder docker cp $(docker create --name static-builder-musl dunglas/frankenphp:static-builder-musl):/go/src/app/dist/frankenphp-linux-$(uname -m) frankenphp
-
Replace your current version of
frankenphpwith the debug FrankenPHP executable -
Start FrankenPHP as usual (alternatively, you can directly start FrankenPHP with GDB:
gdb --args frankenphp run) -
Attach to the process with GDB:
gdb -p `pidof frankenphp` -
If necessary, type
continuein the GDB shell -
Make FrankenPHP crash
-
Type
btin the GDB shell -
Copy the output
-
Open
.github/workflows/tests.yml -
Enable PHP debug symbols
- uses: shivammathur/setup-php@v2 # ... env: phpts: ts + debug: true -
Enable
tmateto connect to the container- name: Set CGO flags run: echo "CGO_CFLAGS=-O0 -g $(php-config --includes)" >> "$GITHUB_ENV" + - run: | + sudo apt install gdb + mkdir -p /home/runner/.config/gdb/ + printf "set auto-load safe-path /\nhandle SIG34 nostop noprint pass" > /home/runner/.config/gdb/gdbinit + - uses: mxschmitt/action-tmate@v3 -
Connect to the container
-
Open
frankenphp.go -
Enable
cgosymbolizer- //_ "github.com/ianlancetaylor/cgosymbolizer" + _ "github.com/ianlancetaylor/cgosymbolizer"
-
Download the module:
go get -
In the container, you can use GDB and the like:
go test -tags -c -ldflags=-w gdb --args frankenphp.test -test.run ^MyTest$
-
When the bug is fixed, revert all these changes
Follow the instructions in compiling from sources. The steps assume the following environment:
- Go installed at
/usr/local/go - PHP source cloned to
~/php-src - PHP built at:
/usr/local/bin/php - FrankenPHP source cloned to
~/frankenphp
-
Install CLion (on your host OS)
-
Download from JetBrains
-
Launch (if on Windows, in WSL):
clion &>/dev/null
-
-
Open Project in CLion
- Open CLion β Open β Select the
~/frankenphpdirectory - Add a build chain: Settings β Build, Execution, Deployment β Custom Build Targets
- Select any Build Target, under
Buildset up an External Tool (call it e.g. go build) - Set up a wrapper script that builds frankenphp for you, called
go_compile_frankenphp.sh
CGO_CFLAGS="-O0 -g" ./go.sh- Under Program, select
go_compile_frankenphp.sh - Leave Arguments blank
- Working Directory:
~/frankenphp/caddy/frankenphp
- Open CLion β Open β Select the
-
Configure Run Targets
- Go to Run β Edit Configurations
- Create:
- frankenphp:
- Type: Native Application
- Target: select the
go buildtarget you created - Executable:
~/frankenphp/caddy/frankenphp/frankenphp - Arguments: the arguments you want to start frankenphp with, e.g.
php-cli test.php
- frankenphp:
-
Debug Go files from CLion
- Right click on a *.go file in the Project view on the left
- Override file type β C/C++
Now you can place breakpoints in C, C++ and Go files. To get syntax highlighting for imports from php-src, you may need to tell CLion about the include paths. Create a
compile_flags.txtfile in~/frankenphpwith the following contents:-I/usr/local/include/php -I/usr/local/include/php/Zend -I/usr/local/include/php/main -I/usr/local/include/php/TSRM
Use GoLand for primary Go development, but the debugger cannot debug C code.
-
Install GoLand (on your host OS)
-
Download from JetBrains
goland &>/dev/null
-
-
Open in GoLand
- Launch GoLand β Open β Select the
~/frankenphpdirectory
- Launch GoLand β Open β Select the
- Select Go Build
- Name
frankenphp - Run kind: Directory
- Name
- Directory:
~/frankenphp/caddy/frankenphp - Output directory:
~/frankenphp/caddy/frankenphp - Working directory:
~/frankenphp/caddy/frankenphp - Environment (adjust for your $(php-config ...) output):
CGO_CFLAGS=-O0 -g -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib;CGO_LDFLAGS=-lm -lpthread -lsqlite3 -lxml2 -lbrotlienc -lbrotlidec -lbrotlicommon -lwatcher - Go tool arguments:
-tags=nobadger,nomysql,nopgx - Program arguments: e.g.
php-cli -i
To debug C files from GoLand
- Right click on a *.c file in the Project view on the left
- Override file type β Go
Now you can place breakpoints in C, C++ and Go files.
-
Follow the Windows Development section
-
Install GoLand
- Download from JetBrains
- Launch GoLand
-
Open in GoLand
- Select Open β Choose the directory where you cloned
frankenphp
- Select Open β Choose the directory where you cloned
-
Configure Go Build
- Go to Run β Edit Configurations
- Click + and select Go Build
- Name:
frankenphp - Run kind: Directory
- Directory:
.\caddy\frankenphp - Output directory:
.\caddy\frankenphp - Working directory:
.\caddy\frankenphp - Go tool arguments:
-tags=nobadger,nomysql,nopgx - Environment variables: see the Windows Development section
- Program arguments: e.g.
php-server
- Use CLion for debugging PHP internals and
cgoglue code - Use GoLand for primary Go development and debugging
- FrankenPHP can be added as a run configuration in CLion for unified C/Go debugging if needed, but syntax highlighting won't work in Go files
- PHP embedding in uWSGI
- PHP embedding in NGINX Unit
- PHP embedding in Go (go-php)
- PHP embedding in Go (GoEmPHP)
- PHP embedding in C++
- Extending and Embedding PHP by Sara Golemon
- What the heck is TSRMLS_CC, anyway?
- SDL bindings
apk add strace util-linux gdb
strace -e 'trace=!futex,epoll_ctl,epoll_pwait,tgkill,rt_sigreturn' -p 1To translate the documentation and the site into a new language, follow these steps:
- Create a new directory named with the language's 2-character ISO code in this repository's
docs/directory - Copy all the
.mdfiles in the root of thedocs/directory into the new directory (always use the English version as source for translation, as it's always up to date) - Copy the
README.mdandCONTRIBUTING.mdfiles from the root directory to the new directory - Translate the content of the files, but don't change the filenames, also don't translate strings starting with
> [!(it's special markup for GitHub) - Create a Pull Request with the translations
- In the site repository, copy and translate the translation files in the
content/,data/, andi18n/directories - Translate the values in the created YAML file
- Open a Pull Request on the site repository