# Участие в проекте ## Компиляция PHP ### С помощью Docker (Linux) Создайте образ Docker для разработки: ```console 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-dev ``` Образ содержит стандартные инструменты для разработки (Go, GDB, Valgrind, Neovim и др.). Если версия Docker ниже 23.0, сборка может завершиться ошибкой из-за [проблемы с шаблонами dockerignore](https://github.com/moby/moby/pull/42676). Добавьте в `.dockerignore` следующие директории: ```patch !testdata/*.php !testdata/*.txt +!caddy +!internal ``` ### Без Docker (Linux и macOS) [Следуйте инструкциям по компиляции из исходников](https://frankenphp.dev/docs/compile/) и укажите флаг конфигурации `--debug`. ## Запуск тестов ```console go test -tags watcher -race -v ./... ``` ## Модуль Caddy Соберите Caddy с модулем FrankenPHP: ```console cd caddy/frankenphp/ go build -tags watcher,brotli,nobadger,nomysql,nopgx cd ../../ ``` Запустите Caddy с модулем FrankenPHP: ```console cd testdata/ ../caddy/frankenphp/frankenphp run ``` Сервер будет доступен по адресу `127.0.0.1:8080`: ```console curl -vk https://localhost/phpinfo.php ``` ## Минимальный тестовый сервер Соберите минимальный тестовый сервер: ```console cd internal/testserver/ go build cd ../../ ``` Запустите тестовый сервер: ```console cd testdata/ ../internal/testserver/testserver ``` Сервер будет доступен по адресу `127.0.0.1:8080`: ```console curl -v http://127.0.0.1:8080/phpinfo.php ``` ## Локальная сборка Docker-образов Выведите план bake: ```console docker buildx bake -f docker-bake.hcl --print ``` Соберите образы FrankenPHP для amd64 локально: ```console docker buildx bake -f docker-bake.hcl --pull --load --set "*.platform=linux/amd64" ``` Соберите образы FrankenPHP для arm64 локально: ```console docker buildx bake -f docker-bake.hcl --pull --load --set "*.platform=linux/arm64" ``` Соберите образы FrankenPHP с нуля для arm64 и amd64 и отправьте их в Docker Hub: ```console docker buildx bake -f docker-bake.hcl --pull --no-cache --push ``` ## Отладка ошибок сегментации с использованием статических сборок 1. Скачайте отладочную версию бинарного файла FrankenPHP с GitHub или создайте собственную статическую сборку с включённым отладочным режимом: ```console 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 dunglas/frankenphp:static-builder):/go/src/app/dist/frankenphp-linux-$(uname -m) frankenphp ``` 2. Замените текущую версию `frankenphp` на бинарный файл с включенным отладочным режимом. 3. Запустите FrankenPHP как обычно (или сразу запустите FrankenPHP с GDB: `gdb --args frankenphp run`). 4. Подключитесь к процессу через GDB: ```console gdb -p `pidof frankenphp` ``` 5. При необходимости введите `continue` в консоли GDB. 6. Вызовите сбой FrankenPHP. 7. Введите `bt` в консоли GDB. 8. Скопируйте вывод. ## Отладка ошибок сегментации в GitHub Actions 1. Откройте файл `.github/workflows/tests.yml`. 2. Включите режим отладки PHP: ```patch - uses: shivammathur/setup-php@v2 # ... env: phpts: ts + debug: true ``` 3. Настройте `tmate` для удалённого подключения к контейнеру: ```patch - name: Set CGO flags run: echo "CGO_CFLAGS=$(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 ``` 4. Подключитесь к контейнеру. 5. Откройте файл `frankenphp.go`. 6. Включите `cgosymbolizer`: ```patch - //_ "github.com/ianlancetaylor/cgosymbolizer" + _ "github.com/ianlancetaylor/cgosymbolizer" ``` 7. Загрузите модуль: `go get`. 8. В контейнере используйте GDB и другие инструменты: ```console go test -tags watcher -c -ldflags=-w gdb --args frankenphp.test -test.run ^MyTest$ ``` 9. После исправления ошибки откатите все внесенные изменения. ## Дополнительные ресурсы для разработки * [Встраивание PHP в uWSGI](https://github.com/unbit/uwsgi/blob/master/plugins/php/php_plugin.c) * [Встраивание PHP в NGINX Unit](https://github.com/nginx/unit/blob/master/src/nxt_php_sapi.c) * [Встраивание PHP в Go (go-php)](https://github.com/deuill/go-php) * [Встраивание PHP в Go (GoEmPHP)](https://github.com/mikespook/goemphp) * [Встраивание PHP в C++](https://gist.github.com/paresy/3cbd4c6a469511ac7479aa0e7c42fea7) * [Книга "Extending and Embedding PHP" Сары Големан](https://books.google.fr/books?id=zMbGvK17_tYC&pg=PA254&lpg=PA254#v=onepage&q&f=false) * [Статья: Что такое TSRMLS_CC?](http://blog.golemon.com/2006/06/what-heck-is-tsrmlscc-anyway.html) * [SDL bindings](https://pkg.go.dev/github.com/veandco/go-sdl2@v0.4.21/sdl#Main) ## Docker-ресурсы * [Определение файлов bake](https://docs.docker.com/build/customize/bake/file-definition/) * [Документация по команде `docker buildx build`](https://docs.docker.com/engine/reference/commandline/buildx_build/) ## Полезные команды ```console apk add strace util-linux gdb strace -e 'trace=!futex,epoll_ctl,epoll_pwait,tgkill,rt_sigreturn' -p 1 ``` ## Перевод документации Чтобы перевести документацию и сайт на новый язык, выполните следующие шаги: 1. Создайте новую директорию с 2-буквенным ISO-кодом языка в папке `docs/`. 2. Скопируйте все `.md` файлы из корня папки `docs/` в новую директорию (используйте английскую версию как основу для перевода). 3. Скопируйте файлы `README.md` и `CONTRIBUTING.md` из корневой директории в новую папку. 4. Переведите содержимое файлов, но не изменяйте имена файлов. Не переводите строки, начинающиеся с `> [!`, это специальная разметка GitHub. 5. Создайте Pull Request с переводом. 6. В [репозитории сайта](https://github.com/dunglas/frankenphp-website/tree/main) скопируйте и переведите файлы в папках `content/`, `data/` и `i18n/`. 7. Переведите значения в созданных YAML-файлах. 8. Откройте Pull Request в репозитории сайта.