### Compile and install PHP Source: https://frankenphp.dev/docs/compile Compile and install PHP. ```bash make -j"$(getconf _NPROCESSORS_ONLN)" sudo make install ``` -------------------------------- ### Start the server Source: https://frankenphp.dev/docs/laravel Starts the FrankenPHP server. ```shell frankenphp php-server ``` -------------------------------- ### Install vcpkg on Windows Source: https://frankenphp.dev/docs/contributing Clones the vcpkg repository and runs the bootstrap script to install it. ```bash cd C:\ git clone https://github.com/microsoft/vcpkg .\vcpkg\bootstrap-vcpkg.bat ``` -------------------------------- ### Starting App in Production Mode Source: https://frankenphp.dev/docs/production Command to start the application in production mode using Docker Compose. ```bash docker compose up --wait ``` -------------------------------- ### Install development tools on Windows using winget Source: https://frankenphp.dev/docs/contributing Installs Visual Studio Community, Go, and Git using the Windows Package Manager (winget). ```bash 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 ``` -------------------------------- ### Start the FrankenPHP server Source: https://frankenphp.dev/docs/symfony Command to run the extracted static binary as a PHP server. ```bash ./my-app php-server ``` -------------------------------- ### Go Configuration Example Source: https://frankenphp.dev/docs/contributing Configuration details for setting up Go build in GoLand for FrankenPHP development. ```bash Name `frankenphp` Run kind: Directory 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` ``` -------------------------------- ### Cloning Project with Git Source: https://frankenphp.dev/docs/production Example command to clone the project repository using Git. ```bash git clone git@github.com:/.git ``` -------------------------------- ### Install Symfony Mercure Source: https://frankenphp.dev/docs/mercure Installs the Symfony Mercure library and lcobucci/jwt using Composer. ```bash composer require symfony/mercure lcobucci/jwt ``` -------------------------------- ### GoLand Setup on Windows - Configure Go Build Source: https://frankenphp.dev/docs/contributing Specific configuration steps for Go Build in GoLand on Windows. ```bash 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` ``` -------------------------------- ### Get PHP sources Source: https://frankenphp.dev/docs/compile Get the PHP sources and extract them. ```bash tar xf php-* cd php-* ``` -------------------------------- ### CLion Setup for CGO glue/PHP Source Development Source: https://frankenphp.dev/docs/contributing Commands for launching CLion and setting up a build wrapper script. ```bash clion &>/dev/null ``` ```bash CGO_CFLAGS="-O0 -g" ./go.sh ``` -------------------------------- ### Install dependencies using vcpkg on Windows Source: https://frankenphp.dev/docs/contributing Installs necessary dependencies using the vcpkg package manager. ```bash C:\vcpkg\vcpkg.exe install ``` -------------------------------- ### Production-ready Caddyfile for WordPress Source: https://frankenphp.dev/docs/wordpress Example Caddyfile configuration for a production WordPress setup with FrankenPHP, enabling Zstandard and Brotli compression. ```caddy example.com php_server encode zstd br gzip log ``` -------------------------------- ### Docker PHP Configuration Source: https://frankenphp.dev/docs/config Example Dockerfile commands for setting up PHP configuration files. ```dockerfile FROM dunglas/frankenphp # Production: RUN cp $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini # Or development: RUN cp $PHP_INI_DIR/php.ini-development $PHP_INI_DIR/php.ini ``` -------------------------------- ### Starting the Octane server Source: https://frankenphp.dev/docs/laravel The Octane server can be started via the octane:frankenphp Artisan command. ```bash php artisan octane:frankenphp ``` -------------------------------- ### Install PHP with Homebrew Source: https://frankenphp.dev/docs/compile Install the ZTS variant of PHP, Brotli (optional, for compression support) and watcher (optional, for file change detection) using Homebrew. ```bash brew install shivammathur/php/php-zts brotli watcher brew link --overwrite --force shivammathur/php/php-zts ``` -------------------------------- ### Testing the extension Source: https://frankenphp.dev/docs/extensions Example `index.php` file to test the implemented Go functions. ```php > ~/.zshrc ``` -------------------------------- ### GoLand Setup for FrankenPHP Development Source: https://frankenphp.dev/docs/contributing Command for launching GoLand. ```bash goland &>/dev/null ``` -------------------------------- ### Run the self-contained app Source: https://frankenphp.dev/docs/embed Command to start the web application from the generated self-contained binary. ```bash ./my-app php-server ``` -------------------------------- ### Installing Additional PHP Extensions Source: https://frankenphp.dev/docs/docker Dockerfile snippet showing how to install extra PHP extensions using the provided installer script. ```docker FROM dunglas/frankenphp # add additional extensions here: RUN install-php-extensions \ pdo_mysql \ gd \ intl \ zip \ opcache ``` -------------------------------- ### Install Script (Windows) Source: https://frankenphp.dev/docs Installs FrankenPHP on Windows using PowerShell. ```powershell irm https://frankenphp.dev/install.ps1 | iex ``` -------------------------------- ### Installing Bash shell completions for Linux Source: https://frankenphp.dev/docs/config This command installs FrankenPHP shell completions for Bash system-wide on Linux. ```bash frankenphp completion bash > \/usr\/share\/bash-completion\/completions\/frankenphp ``` -------------------------------- ### Test your generated extension Source: https://frankenphp.dev/docs/extensions Example PHP code to test the functionality of a generated extension. ```php process('Hello World', StringProcessor::MODE_LOWERCASE); // "hello world" echo $processor->process('Hello World', StringProcessor::MODE_UPPERCASE); // "HELLO WORLD" ``` -------------------------------- ### Example of Early Hints implementation Source: https://frankenphp.dev/docs/early-hints This PHP code demonstrates how to send Early Hints by preloading a CSS file and then sending the main HTML content. ```php ; rel=preload; as=style'); headers_send(103); // your slow algorithms and SQL queries 🤪 echo <<<'HTML' Hello FrankenPHP HTML; ``` -------------------------------- ### Example usage of my_array_map Source: https://frankenphp.dev/docs/extensions These PHP code examples show how to use the `my_array_map` function with a closure and a built-in function. ```PHP memory_get_usage(), 'peak_usage' => memory_get_peak_usage(), ], ); ``` -------------------------------- ### Configuring full duplex mode via environment variable Source: https://frankenphp.dev/docs/config This example shows how to enable full-duplex mode using the `CADDY_GLOBAL_OPTIONS` environment variable. ```bash CADDY_GLOBAL_OPTIONS="servers { enable_full_duplex }" ``` -------------------------------- ### Install PIE Extensions (rpm) Source: https://frankenphp.dev/docs Installs extensions not available by default using PIE with rpm. ```bash sudo dnf install pie-zts sudo pie-zts install asgrim/example-pie-extension ``` -------------------------------- ### Run the app with HTTPS enabled Source: https://frankenphp.dev/docs/embed Command to start the web application with HTTPS, HTTP/2, and HTTP/3 enabled, specifying a domain name. ```bash ./my-app php-server --domain localhost ``` -------------------------------- ### Install PIE Extensions (deb) Source: https://frankenphp.dev/docs Installs extensions not available by default using PIE with deb. ```bash sudo apt install pie-zts sudo pie-zts install asgrim/example-pie-extension ``` -------------------------------- ### FrankenPHP Docker setup (After) Source: https://frankenphp.dev/docs/migrate A single Docker Compose configuration using FrankenPHP. ```yaml # compose.yaml services: php: image: dunglas/frankenphp:1-php8.5 volumes: - .:/var/www/app # mount the Caddyfile into the container - ./config:/etc/frankenphp - caddy_data:/data - caddy_config:/config ports: - "80:80" - "443:443" - "443:443/udp" volumes: caddy_data: caddy_config: ``` -------------------------------- ### Prepare a Symfony app for embedding Source: https://frankenphp.dev/docs/embed Commands to prepare a Symfony application by exporting the project, setting environment variables, removing unneeded files, and installing production dependencies. ```bash # Export the project to get rid of .git/, etc mkdir $TMPDIR/my-prepared-app git archive HEAD | tar -x -C $TMPDIR/my-prepared-app cd $TMPDIR/my-prepared-app # Set proper environment variables echo APP_ENV=prod > .env.local echo APP_DEBUG=0 >> .env.local # Remove the tests and other unneeded files to save space # Alternatively, add these files with the export-ignore attribute in your .gitattributes file rm -Rf tests/ # Install the dependencies composer install --ignore-platform-reqs --no-dev -a # Optimize .env composer dump-env prod ``` -------------------------------- ### Example TLS/SSL error message Source: https://frankenphp.dev/docs/known-issues An example of a TLS/SSL error encountered when using static binaries with STARTTLS, indicating certificate verification failure. ```text Unable to connect with STARTTLS: stream_socket_enable_crypto(): SSL operation failed with code 5. OpenSSL Error messages: error:80000002:system library::No such file or directory error:80000002:system library::No such file or directory error:80000002:system library::No such file or directory error:0A000086:SSL routines::certificate verify failed ``` -------------------------------- ### Basic Dockerfile Source: https://frankenphp.dev/docs/docker A simple Dockerfile to start using FrankenPHP images. ```docker FROM dunglas/frankenphp COPY . /app/public ``` -------------------------------- ### Installing Custom Caddy Modules Source: https://frankenphp.dev/docs/docker Dockerfile demonstrating how to build a custom FrankenPHP binary with additional Caddy modules using xcaddy. ```docker FROM dunglas/frankenphp:builder AS builder # Copy xcaddy in the builder image COPY --from=caddy:builder /usr/bin/xcaddy /usr/bin/xcaddy # CGO must be enabled to build FrankenPHP RUN CGO_ENABLED=1 \ XCADDY_SETCAP=1 \ XCADDY_GO_BUILD_FLAGS="-ldflags='-w -s' -tags=nobadger,nomysql,nopgx" \ CGO_CFLAGS=$(php-config --includes) \ CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \ xcaddy build \ --output /usr/local/bin/frankenphp \ --with github.com/dunglas/frankenphp=./ \ --with github.com/dunglas/frankenphp/caddy=./caddy/ \ --with github.com/dunglas/caddy-cbrotli \ # Mercure and Vulcain are included in the official build, but feel free to remove them --with github.com/dunglas/mercure/caddy \ --with github.com/dunglas/vulcain/caddy # Add extra Caddy modules here FROM dunglas/frankenphp AS runner # Replace the official binary with the one containing your custom modules COPY --from=builder /usr/local/bin/frankenphp /usr/local/bin/frankenphp ``` -------------------------------- ### Fish Shell Completion Setup Source: https://frankenphp.dev/docs/config Commands to enable Fish shell completion for FrankenPHP. ```shell frankenphp completion fish | source ``` ```shell frankenphp completion fish > ~/.config/fish/completions/frankenphp.fish ``` -------------------------------- ### Run the worker script Source: https://frankenphp.dev/docs/embed Command to start a worker script from the self-contained binary. ```bash ./my-app php-server --worker public/index.php ``` -------------------------------- ### DNS A Record Source: https://frankenphp.dev/docs/production Example of a DNS A record configuration for a domain name pointing to a server IP address. ```dns your-domain-name.example.com. IN A 207.154.233.113 ``` -------------------------------- ### Zsh Shell Completion Setup Source: https://frankenphp.dev/docs/config Commands to enable Zsh shell completion for FrankenPHP. ```shell echo "autoload -U compinit; compinit" >> ~/.zshrc ``` ```shell frankenphp completion zsh > "${fpath[1]}/_frankenphp" ``` -------------------------------- ### Loading additional PHP configuration files Source: https://frankenphp.dev/docs/config This example demonstrates how to load additional PHP configuration files using the `php_ini` directive within the `frankenphp` block, allowing for multiple settings to be configured. ```caddyfile { frankenphp { php_ini memory_limit 256M # or php_ini { memory_limit 256M max_execution_time 15 } } } ``` -------------------------------- ### Installing Laravel Octane Source: https://frankenphp.dev/docs/laravel After installing Octane, you may execute the octane:install Artisan command, which will install Octane’s configuration file into your application: ```bash php artisan octane:install --server=frankenphp ``` -------------------------------- ### PHP-FPM Docker setup (Before) Source: https://frankenphp.dev/docs/migrate A typical Docker Compose configuration using Nginx and PHP-FPM. ```yaml # compose.yaml services: nginx: image: nginx:1 volumes: # mount Nginx config into the container - ./config:/etc/nginx/conf.d - .:/var/www/app ports: - "80:80" - "443:443" php: image: php:8.5-fpm volumes: - .:/var/www/app ``` -------------------------------- ### Advanced Caddyfile Configuration with FrankenPHP Global Options Source: https://frankenphp.dev/docs/config An example of configuring FrankenPHP using global options within the Caddyfile. ```caddyfile { frankenphp { num_threads # Sets the number of PHP threads to start. Default: 2x the number of available CPUs. max_threads # Limits the number of additional PHP threads that can be started at runtime. Default: num_threads. Can be set to 'auto'. max_wait_time # Sets the maximum time a request may wait for a free PHP thread before timing out. Default: disabled. max_idle_time # Sets the maximum time an autoscaled thread may be idle before being deactivated. Default: 5s. max_requests # (experimental) Sets the maximum number of requests a PHP thread will handle before being restarted, useful for mitigating memory leaks. Applies to both regular and worker threads. Default: 0 (unlimited). php_ini # Set a php.ini directive. Can be used several times to set multiple directives. worker { file # Sets the path to the worker script. num # Sets the number of PHP threads to start, defaults to 2x the number of available CPUs. env # Sets an extra environment variable to the given value. Can be specified more than once for multiple environment variables. watch # Sets the path to watch for file changes. Can be specified more than once for multiple paths. name # Sets the name of the worker, used in logs and metrics. Default: absolute path of worker file max_consecutive_failures # Sets the maximum number of consecutive failures before the worker is considered unhealthy, -1 means the worker will always restart. Default: 6. } } } # ... ``` -------------------------------- ### Converting PHP arrays to Go maps/slices Source: https://frankenphp.dev/docs/extensions Examples demonstrating how to convert PHP associative and packed arrays to their Go equivalents, maintaining order where necessary or optimizing for performance. ```Go // Converting between PHP arrays and Go maps/slices package example // #include import "C" import ( "unsafe" "github.com/dunglas/frankenphp" ) // export_php:function process_data_ordered(array $input): array func process_data_ordered_map(arr *C.zend_array) unsafe.Pointer { // Convert PHP associative array to Go while keeping the order associativeArray, err := frankenphp.GoAssociativeArray[any](/docs/unsafe.Pointer(arr)) if err != nil { // handle error } // loop over the entries in order for _, key := range associativeArray.Order { value, _ = associativeArray.Map[key] // do something with key and value } // return an ordered array // if 'Order' is not empty, only the key-value pairs in 'Order' will be respected return frankenphp.PHPAssociativeArray[string](/docs/frankenphp.AssociativeArray[string]{ Map: map[string]string{ "key1": "value1", "key2": "value2", }, Order: []string{"key1", "key2"}, }) } // export_php:function process_data_unordered(array $input): array func process_data_unordered_map(arr *C.zend_array) unsafe.Pointer { // Convert PHP associative array to a Go map without keeping the order // ignoring the order will be more performant goMap, err := frankenphp.GoMap[any](/docs/unsafe.Pointer(arr)) if err != nil { // handle error } // loop over the entries in no specific order for key, value := range goMap { // do something with key and value } // return an unordered array return frankenphp.PHPMap(map[string]string { "key1": "value1", "key2": "value2", }) } // export_php:function process_data_packed(array $input): array func process_data_packed(arr *C.zend_array) unsafe.Pointer { // Convert PHP packed array to Go goSlice, err := frankenphp.GoPackedArray(unsafe.Pointer(arr)) if err != nil { // handle error } // loop over the slice in order for index, value := range goSlice { // do something with index and value } // return a packed array return frankenphp.PHPPackedArray([]string{"value1", "value2", "value3"}) } ``` -------------------------------- ### Caddyfile Configuration for Mercure Source: https://frankenphp.dev/docs/mercure Minimal Caddyfile example to enable FrankenPHP and the Mercure hub, including publisher and subscriber JWT secrets and anonymous access. ```caddyfile # The hostname to respond to localhost mercure { # The secret key used to sign the JWT tokens for publishers publisher_jwt !ChangeThisMercureHubJWTSecretKey! # When publisher_jwt is set, you must set subscriber_jwt too! subscriber_jwt !ChangeThisMercureHubJWTSecretKey! # Allows anonymous subscribers (without JWT) anonymous } root public/ php_server ``` -------------------------------- ### Configure the number of workers to start Source: https://frankenphp.dev/docs/worker By default, 2 workers per CPU are started. You can also configure the number of workers to start. ```bash docker run \ -e FRANKENPHP_CONFIG="worker ./public/index.php 42" \ -v $PWD:/app \ -p 80:80 -p 443:443 -p 443:443/udp \ dunglas/frankenphp ``` -------------------------------- ### Setting PHP_BINARY environment variable and running Composer Source: https://frankenphp.dev/docs/known-issues These commands set the PHP_BINARY environment variable to the custom script and then execute Composer install. ```bash export PHP_BINARY=/usr/local/bin/php composer install ``` -------------------------------- ### Plain PHP Example for X-Accel-Redirect Source: https://frankenphp.dev/docs/x-sendfile A simple PHP code snippet demonstrating how to set the X-Accel-Redirect header to specify the file to be served by the web server. ```php header('X-Accel-Redirect: file.txt'); ``` -------------------------------- ### Initialize a Go module Source: https://frankenphp.dev/docs/extensions Command to initialize a new Go module for writing PHP extensions. ```bash go mod init example.com/example ``` -------------------------------- ### Installing Laravel Octane Source: https://frankenphp.dev/docs/laravel Octane may be installed via the Composer package manager: ```bash composer require laravel/octane ``` -------------------------------- ### Install FrankenPHP Symfony Package Source: https://frankenphp.dev/docs/symfony Command to install the FrankenPHP package for older Symfony versions. ```bash composer require runtime/frankenphp-symfony ``` -------------------------------- ### Publishing Updates using file_get_contents() Source: https://frankenphp.dev/docs/mercure PHP example showing how to dispatch an update by sending an authenticated POST request to the Mercure hub using file_get_contents(). ```php [ 'method' => 'POST', 'header' => "Content-type: application/x-www-form-urlencoded\r\nAuthorization: Bearer " . JWT, 'content' => http_build_query([ 'topic' => 'my-topic', 'data' => json_encode(['key' => 'value']), ]), ]])); // Write to FrankenPHP's logs error_log("update $updateID published", 4); ``` -------------------------------- ### Install Homebrew Source: https://frankenphp.dev/docs Installs FrankenPHP using Homebrew on macOS and Linux. ```bash brew install dunglas/frankenphp/frankenphp ``` -------------------------------- ### Configure PHP for Mac Source: https://frankenphp.dev/docs/compile Run the configure script for Mac. ```bash ./configure \ --enable-embed \ --enable-zts \ --disable-zend-signals \ --with-iconv=/opt/homebrew/opt/libiconv/ ``` -------------------------------- ### Remove tests and install dependencies Source: https://frankenphp.dev/docs/symfony Commands to clean up the project by removing the tests directory and installing production dependencies for the application. ```bash rm -Rf tests/ composer install --ignore-platform-reqs --no-dev -a composer dump-env prod ``` -------------------------------- ### Installing Bash shell completions for macOS Source: https://frankenphp.dev/docs/config This command installs FrankenPHP shell completions for Bash on macOS using Homebrew. ```bash frankenphp completion bash > $(brew --prefix)\/share\/bash-completion\/completions\/frankenphp ``` -------------------------------- ### Prepare Symfony App for Standalone Binary Source: https://frankenphp.dev/docs/symfony Steps to prepare a Symfony app for distribution as a standalone binary using FrankenPHP. ```bash # Export the project to get rid of .git/, etc mkdir $TMPDIR/my-prepared-app git archive HEAD | tar -x -C $TMPDIR/my-prepared-app cd $TMPDIR/my-prepared-app # Set proper environment variables echo APP_ENV=prod > .env.local echo APP_DEBUG=0 >> .env.local ``` -------------------------------- ### Build the static binary using Docker Source: https://frankenphp.dev/docs/embed Command to build the Docker image for the static application. ```bash docker build -t static-app -f static-build.Dockerfile . ``` -------------------------------- ### Install deb Packages Source: https://frankenphp.dev/docs Installs FrankenPHP using deb packages on systems with apt. ```bash VERSION=85 # 82-85 available sudo curl https://pkg.henderkes.com/api/packages/${VERSION}/debian/repository.key -o /etc/apt/keyrings/static-php${VERSION}.asc echo "deb [signed-by=/etc/apt/keyrings/static-php${VERSION}.asc] https://pkg.henderkes.com/api/packages/${VERSION}/debian php-zts main" | sudo tee -a /etc/apt/sources.list.d/static-php${VERSION}.list sudo apt update sudo apt install frankenphp ``` -------------------------------- ### Install rpm Packages Source: https://frankenphp.dev/docs Installs FrankenPHP using rpm packages on systems with dnf. ```bash sudo dnf install https://rpm.henderkes.com/static-php-1-0.noarch.rpm sudo dnf module enable php-zts:static-8.5 # 8.2-8.5 available sudo dnf install frankenphp ``` -------------------------------- ### Equivalent configuration for php_server Source: https://frankenphp.dev/docs/config This configuration demonstrates the underlying directives that the `php_server` directive is equivalent to. ```caddy route { # Add trailing slash for directory requests @canonicalPath { file {path}/index.php not path */ } redir @canonicalPath {path}/ 308 # If the requested file does not exist, try index files @indexFiles file { try_files {path} {path}/index.php index.php split_path .php } rewrite @indexFiles {http.matchers.file.relative} # FrankenPHP! @phpFiles path *.php php @phpFiles file_server } ``` -------------------------------- ### Build a binary for other OSes using shell script Source: https://frankenphp.dev/docs/embed Instructions to clone the FrankenPHP repository and use the build-static.sh script to create a binary for other operating systems. ```bash git clone https://github.com/php/frankenphp cd frankenphp EMBED=/path/to/your/app ./build-static.sh ``` -------------------------------- ### Install Script (Linux/macOS) Source: https://frankenphp.dev/docs Automatically installs an appropriate version of FrankenPHP for Linux and macOS. ```bash curl https://frankenphp.dev/install.sh | sh ``` -------------------------------- ### Build the minimal test server Source: https://frankenphp.dev/docs/contributing Navigates to the internal testserver directory and builds the minimal test server binary. ```bash cd internal/testserver/ go build cd ../.. ``` -------------------------------- ### Build static binary with extra Caddy modules Source: https://frankenphp.dev/docs/static Docker command to build a static binary with additional Caddy modules, including Souin, cbrotli, Mercure, and Vulcain. ```bash docker buildx bake \ --load \ --set static-builder-musl.args.XCADDY_ARGS="--with github.com/darkweak/souin/plugins/caddy --with github.com/dunglas/caddy-cbrotli --with github.com/dunglas/mercure/caddy --with github.com/dunglas/vulcain/caddy" \ static-builder-musl ``` -------------------------------- ### Configure PHP for Linux and FreeBSD Source: https://frankenphp.dev/docs/compile Run the configure script with the options needed for Linux and FreeBSD. ```bash ./configure \ --enable-embed \ --enable-zts \ --disable-zend-signals \ --enable-zend-max-execution-timers ``` -------------------------------- ### Build static binary with custom PHP extensions and libraries Source: https://frankenphp.dev/docs/static Docker command to build a static binary with specified PHP extensions and enabling additional functionality through extension libraries. ```bash docker buildx bake \ --load \ --set static-builder-musl.args.PHP_EXTENSIONS=gd \ --set static-builder-musl.args.PHP_EXTENSION_LIBS=libjpeg,libwebp \ static-builder-musl ``` -------------------------------- ### Integrate the generated extension into FrankenPHP Source: https://frankenphp.dev/docs/extensions Command to build FrankenPHP with a custom extension, using xcaddy. ```bash CGO_ENABLED=1 \ XCADDY_GO_BUILD_FLAGS="-ldflags='-w -s' -tags=nobadger,nomysql,nopgx" \ CGO_CFLAGS=$(php-config --includes) \ CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \ xcaddy build \ --output frankenphp \ --with github.com/my-account/my-module/build ``` -------------------------------- ### Start your app and use the FRANKENPHP_CONFIG environment variable to configure your worker Source: https://frankenphp.dev/docs/worker Start your app and use the `FRANKENPHP_CONFIG` environment variable to configure your worker. ```bash docker run \ -e FRANKENPHP_CONFIG="worker ./public/index.php" \ -v $PWD:/app \ -p 80:80 -p 443:443 -p 443:443/udp \ dunglas/frankenphp ``` -------------------------------- ### Useful Command for Debugging Source: https://frankenphp.dev/docs/contributing A command to install debugging tools and trace processes. ```bash apk add strace util-linux gdb strace -e 'trace=!futex,epoll_ctl,epoll_pwait,tgkill,rt_sigreturn' -p 1 ``` -------------------------------- ### Build musl-based, fully static binary with mimalloc allocator Source: https://frankenphp.dev/docs/static Docker command to build a fully static binary with the mimalloc allocator for better performance in concurrent scenarios. ```bash docker buildx bake --load --set static-builder-musl.args.MIMALLOC=1 static-builder-musl ``` -------------------------------- ### Build static binary with GitHub token Source: https://frankenphp.dev/docs/static Docker command to build a static binary while setting a GitHub Personal Access Token to avoid API rate limits. ```bash GITHUB_TOKEN="xxx" docker --load buildx bake static-builder-musl # ... ``` -------------------------------- ### Build static binary with custom PHP extensions Source: https://frankenphp.dev/docs/static Docker command to build a static binary with only the specified PHP extensions to reduce binary size and attack surface. ```bash docker buildx bake --load --set static-builder-musl.args.PHP_EXTENSIONS=opcache,pdo_sqlite static-builder-musl # ... ``` -------------------------------- ### PowerShell Shell Completion Setup Source: https://frankenphp.dev/docs/config Commands to enable PowerShell shell completion for FrankenPHP. ```powershell frankenphp completion powershell | Out-String | Invoke-Expression ``` ```powershell frankenphp completion powershell | Out-File -FilePath (Join-Path (Split-Path $PROFILE) "frankenphp.ps1") Add-Content -Path $PROFILE -Value '. (Join-Path (Split-Path $PROFILE) "frankenphp.ps1")' ``` -------------------------------- ### Combining functions, classes, methods, and constants in one extension Source: https://frankenphp.dev/docs/extensions An example demonstrating the integration of global constants, class constants, functions, and methods within a single Go extension file. ```Go // Combining functions, classes, methods, and constants in one extension package example // #include import "C" import ( "strings" "unsafe" "github.com/dunglas/frankenphp" ) //export_php:const const STR_REVERSE = iota //export_php:const const STR_NORMAL = iota //export_php:classconst StringProcessor const MODE_LOWERCASE = 1 //export_php:classconst StringProcessor const MODE_UPPERCASE = 2 //export_php:function repeat_this(string $str, int $count, int $mode): string func repeat_this(s *C.zend_string, count int64, mode int) unsafe.Pointer { str := frankenphp.GoString(unsafe.Pointer(s)) result := strings.Repeat(str, int(count)) if mode == STR_REVERSE { // reverse the string } if mode == STR_NORMAL { // no-op, just to showcase the constant } return frankenphp.PHPString(result, false) } //export_php:class StringProcessor type StringProcessorStruct struct { // internal fields } //export_php:method StringProcessor::process(string $input, int $mode): string func (sp *StringProcessorStruct) Process(input *C.zend_string, mode int64) unsafe.Pointer { str := frankenphp.GoString(unsafe.Pointer(input)) switch mode { case MODE_LOWERCASE: str = strings.ToLower(str) case MODE_UPPERCASE: str = strings.ToUpper(str) } return frankenphp.PHPString(str, false) } ``` -------------------------------- ### Multiple worker configuration Source: https://frankenphp.dev/docs/config Example of defining multiple worker configurations for different applications on the same server. ```caddy app.example.com { root /path/to/app/public php_server { root /path/to/app/public # allows for better caching worker index.php } } other.example.com { root /path/to/other/public php_server { root /path/to/other/public worker index.php } } ``` -------------------------------- ### Build the binary on Windows Source: https://frankenphp.dev/docs/contributing Navigates to the caddy/frankenphp directory and builds the binary with specific linker flags for Windows. ```bash cd caddy/frankenphp go build -ldflags '-extldflags "-fuse-ld=lld"' -tags nobadger,nomysql,nopgx cd ../.. ``` -------------------------------- ### Worker configuration for PHP server Source: https://frankenphp.dev/docs/performance A worker equivalent configuration for the previous try_files example. ```caddy route { php_server { # use "php" instead of "php_server" if you don't need the file server at all root /root/to/your/app worker /path/to/worker.php { match * # send all requests directly to the worker } } } ``` -------------------------------- ### Build static binary for macOS Source: https://frankenphp.dev/docs/static Script to clone the FrankenPHP repository and build a static binary for macOS. This script also works on Linux. ```bash git clone https://github.com/php/frankenphp cd frankenphp ./build-static.sh ```