### FSEventStreamContext Setup Example Source: https://github.com/php/frankenphp/blob/main/watcher/devel/include/detail/wtr/watcher/adapter/darwin/notes.md An example demonstrating how to initialize an FSEventStreamContext with default values. This is useful for setting up the context for event stream operations on Darwin. ```cpp std::unique_ptr context(new FSEventStreamContext()); context->version = 0; context->info = nullptr; context->retain = nullptr; context->release = nullptr; context->copyDescription = nullptr; ``` -------------------------------- ### Install Development Tools on Windows Source: https://github.com/php/frankenphp/blob/main/CONTRIBUTING.md Install Visual Studio Community, Go, and Git using winget. ```powershell 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 PHP with Homebrew Source: https://github.com/php/frankenphp/blob/main/docs/compile.md Installs ZTS PHP, Brotli, and watcher using Homebrew. Ensure Homebrew is installed first. The `brew link` command overwrites existing links. ```bash brew install shivammathur/php/php-zts brotli watcher brew link --overwrite --force shivammathur/php/php-zts ``` -------------------------------- ### Install Dependencies with vcpkg Source: https://github.com/php/frankenphp/blob/main/CONTRIBUTING.md Install project dependencies using the bootstrapped vcpkg instance. ```powershell C:\vcpkg\vcpkg.exe install ``` -------------------------------- ### Go Watcher Example Source: https://github.com/php/frankenphp/blob/main/watcher/readme.md Demonstrates watching a directory and processing file system events in Go. ```go package main import ( "fmt" "log/slog" "github.com/e-dant/watcher/watcher-go" ) func main() { w := watcher.NewWatcher("/path/to/dir", func(e *watcher.Event) { slog.Info("filesystem event", "event", e) }) defer w.Close() // Wait for a new line to exit _, _ = fmt.Scanln() } ``` -------------------------------- ### Install PIE Extension with APK Source: https://github.com/php/frankenphp/blob/main/README.md Install the PIE (PHP In Extension) package manager and use it to install extensions not available by default on Alpine systems. ```bash sudo apk add pie-zts sudo pie-zts install asgrim/example-pie-extension ``` -------------------------------- ### C++ Build and Run Instructions Source: https://github.com/php/frankenphp/blob/main/watcher/readme.md Instructions for building and running the C++ watcher example. ```sh # Sigh PLATFORM_EXTRAS=$(test "$(uname)" = Darwin && echo '-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -framework CoreFoundation -framework CoreServices') # Build eval c++ -std=c++17 -Iinclude src/wtr/tiny_watcher/main.cpp -o watcher $PLATFORM_EXTRAS # Run ./watcher ``` -------------------------------- ### Install vcpkg on Windows Source: https://github.com/php/frankenphp/blob/main/CONTRIBUTING.md Clone the vcpkg repository and bootstrap the package manager. ```powershell cd C:\ git clone https://github.com/microsoft/vcpkg .\vcpkg\bootstrap-vcpkg.bat ``` -------------------------------- ### Install PIE Extension with RPM Source: https://github.com/php/frankenphp/blob/main/README.md Install the PIE (PHP In Extension) package manager and use it to install extensions not available by default on RPM systems. ```bash sudo dnf install pie-zts sudo pie-zts install asgrim/example-pie-extension ``` -------------------------------- ### Install PIE Extension with DEB Source: https://github.com/php/frankenphp/blob/main/README.md Install the PIE (PHP In Extension) package manager and use it to install extensions not available by default on Debian systems. ```bash sudo apt install pie-zts sudo pie-zts install asgrim/example-pie-extension ``` -------------------------------- ### C Watcher Example Source: https://github.com/php/frankenphp/blob/main/watcher/readme.md Demonstrates watching the current directory and processing file system events in C. ```c #include "wtr/watcher-c.h" #include void callback(struct wtr_watcher_event event, void* _ctx) { printf( "path name: %s, effect type: %d path type: %d, effect time: %lld, associated path name: %s\n", event.path_name, event.effect_type, event.path_type, event.effect_time, event.associated_path_name ? event.associated_path_name : "" ); } int main() { void* watcher = wtr_watcher_open(".", callback, NULL); getchar(); return ! wtr_watcher_close(watcher); } ``` -------------------------------- ### Compile and Install PHP Source: https://github.com/php/frankenphp/blob/main/docs/compile.md Compiles PHP using all available CPU cores for faster build times and then installs it. This step should be run after configuring the PHP build. ```bash make -j"$(getconf _NPROCESSORS_ONLN)" sudo make install ``` -------------------------------- ### Node.js Watcher Example Source: https://github.com/php/frankenphp/blob/main/watcher/readme.md Demonstrates watching the current directory and processing file system events in Node.js. ```javascript import * as watcher from 'watcher'; var w = watcher.watch('.', (event) => { console.log(event); }); process.stdin.on('data', () => { w.close(); process.exit(); }); ``` -------------------------------- ### Python Watcher Example Source: https://github.com/php/frankenphp/blob/main/watcher/readme.md Demonstrates watching the current directory and processing file system events in Python. ```python from watcher import Watch with Watch(".", print): input() ``` -------------------------------- ### Python Watcher Installation Source: https://github.com/php/frankenphp/blob/main/watcher/readme.md Install the watcher library for Python using pip. ```sh pip install wtr-watcher ``` -------------------------------- ### GoLand Configuration Program Arguments (Windows) Source: https://github.com/php/frankenphp/blob/main/CONTRIBUTING.md Program arguments for GoLand's Go Build configuration on Windows, used to start the FrankenPHP server. ```bash php-server ``` -------------------------------- ### C++ Watcher Example Source: https://github.com/php/frankenphp/blob/main/watcher/readme.md Demonstrates watching the current directory and processing file system events in C++. ```cpp #include "wtr/watcher.hpp" #include #include using namespace std; using namespace wtr; // The event type, and every field within it, has // string conversions and stream operators. All // kinds of strings -- Narrow, wide and weird ones. // If we don't want particular formatting, we can // json-serialize and show the event like this: // some_stream << event // Here, we'll apply our own formatting. auto show(event e) { cout << to(e.effect_type) + ' ' + to(e.path_type) + ' ' + to(e.path_name) + (e.associated ? " -> " + to(e.associated->path_name) : "") << endl; } auto main() -> int { // Watch the current directory asynchronously, // calling the provided function on each event. auto watcher = watch(".", show); // Do some work. (We'll just wait for a newline.) getchar(); // The watcher would close itself around here, // though we can check and close it ourselves. return watcher.close() ? 0 : 1; } ``` -------------------------------- ### Start FrankenPHP Server Source: https://github.com/php/frankenphp/blob/main/docs/laravel.md Command to start the FrankenPHP web server for the standalone Laravel application. ```bash frankenphp php-server ``` -------------------------------- ### Start FrankenPHP with Custom Worker Source: https://github.com/php/frankenphp/blob/main/docs/worker.md Configure FrankenPHP to use a custom worker script by setting the FRANKENPHP_CONFIG environment variable. This example starts the worker using './public/index.php'. ```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 ``` -------------------------------- ### Launch GoLand Source: https://github.com/php/frankenphp/blob/main/CONTRIBUTING.md Launches GoLand from the command line. Ensure GoLand is installed and accessible in your PATH. ```bash goland &>/dev/null ``` -------------------------------- ### Rust Watcher Example Source: https://github.com/php/frankenphp/blob/main/watcher/readme.md Demonstrates watching the current directory and processing file system events asynchronously in Rust. ```rust use futures::StreamExt; use wtr_watcher::Watch; #[tokio::main(flavor = "current_thread")] async fn main() -> Result<(), Box> { let show = |e| async move { println!("{e:?}") }; let events = Watch::try_new(".")?; events.for_each(show).await; Ok(()) } ``` -------------------------------- ### Install Development Tools and Trace System Calls Source: https://github.com/php/frankenphp/blob/main/CONTRIBUTING.md Installs essential development tools like strace, util-linux, and gdb. It then uses strace to trace specific system calls for a running process, excluding futex, epoll_ctl, epoll_pwait, tgkill, and rt_sigreturn. ```bash apk add strace util-linux gdb strace -e 'trace=!futex,epoll_ctl,epoll_pwait,tgkill,rt_sigreturn' -p 1 ``` -------------------------------- ### Launch CLion Source: https://github.com/php/frankenphp/blob/main/CONTRIBUTING.md Launches CLion from the command line. Ensure CLion is installed and accessible in your PATH. ```bash clion &>/dev/null ``` -------------------------------- ### Install FrankenPHP with PowerShell Script Source: https://github.com/php/frankenphp/blob/main/README.md Run this command in PowerShell on Windows to install FrankenPHP. ```powershell irm https://frankenphp.dev/install.ps1 | iex ``` -------------------------------- ### Basic FrankenPHP Dockerfile Source: https://github.com/php/frankenphp/blob/main/docs/docker.md Use this Dockerfile to start a new project with FrankenPHP. It sets the base image and copies your application files. ```dockerfile FROM dunglas/frankenphp COPY . /app/public ``` -------------------------------- ### Run Caddy with FrankenPHP Module Source: https://github.com/php/frankenphp/blob/main/CONTRIBUTING.md Starts the Caddy server with the FrankenPHP module from the testdata directory. The server will listen on 127.0.0.1:80. ```console cd testdata/ ../caddy/frankenphp/frankenphp run ``` -------------------------------- ### Example Watcher Output Source: https://github.com/php/frankenphp/blob/main/watcher/readme.md A snapshot of the output from the watcher program, showing filesystem event details. ```json { "1666393024210001000": { "path_name": "/home/edant/dev/watcher/.git/logs/HEAD", "effect_type": "modify", "path_type": "file" }, "1666393024210026000": { "path_name": "/home/edant/dev/watcher/.git/logs/refs/heads/next", "effect_type": "modify", "path_type": "file" }, "1666393024210032000": { "path_name": "/home/edant/dev/watcher/.git/refs/heads/next.lock", "effect_type": "create", "path_type": "other" } } ``` -------------------------------- ### GoLand Configuration Program Arguments Source: https://github.com/php/frankenphp/blob/main/CONTRIBUTING.md Program arguments for GoLand's Go Build configuration, used to start the FrankenPHP executable with specific arguments. ```bash php-cli -i ``` -------------------------------- ### Zsh Shell Completion Setup Source: https://github.com/php/frankenphp/blob/main/docs/config.md Enable Zsh shell completion by ensuring compinit is loaded and then placing the completion script in the fpath. ```console echo "autoload -U compinit; compinit" >> ~/.zshrc ``` ```console frankenphp completion zsh > "${fpath[1]}/_frankenphp" ``` -------------------------------- ### Fish Shell Completion (New Sessions) Source: https://github.com/php/frankenphp/blob/main/docs/config.md Install Fish shell completions for all new sessions by redirecting the output to the user's config directory. ```console frankenphp completion fish > ~/.config/fish/completions/frankenphp.fish ``` -------------------------------- ### Install Custom Caddy Modules with xcaddy Source: https://github.com/php/frankenphp/blob/main/docs/docker.md Build a custom FrankenPHP binary with additional Caddy modules using xcaddy in a builder image. Ensure CGO is enabled for the build process. ```dockerfile 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 ``` -------------------------------- ### Run Embedded Web App Source: https://github.com/php/frankenphp/blob/main/docs/embed.md Command to start the embedded web application using the generated standalone binary. ```console ./my-app php-server ``` -------------------------------- ### Start FrankenPHP with Docker Compose Source: https://github.com/php/frankenphp/blob/main/docs/production.md Initiates the FrankenPHP application in production mode using Docker Compose. Ensure you are in the project directory before running. ```console docker compose up --wait ``` -------------------------------- ### Run Performance Tests with Bash Script Source: https://github.com/php/frankenphp/blob/main/testdata/performance/performance-testing.md Execute this script from the repository root to build the Docker image and start the load testing environment. ```bash bash testdata/performance/perf-test.sh ``` -------------------------------- ### Build Static FrankenPHP Binary on macOS Source: https://github.com/php/frankenphp/blob/main/docs/static.md Run this script to create a static binary for macOS. Ensure Homebrew is installed and navigate to the cloned repository directory before execution. ```bash git clone https://github.com/php/frankenphp cd frankenphp ./build-static.sh ``` -------------------------------- ### Compile Watcher Library from Source Source: https://github.com/php/frankenphp/blob/main/watcher/watcher-c/readme.md Compiles the watcher C library from source using C++ and meson. Ensure you have the necessary build tools installed. ```bash curl -L https://github.com/e-dant/watcher/archive/refs/heads/next.tar.gz | tar xz cd watcher-next/watcher-c c++ -o libwatcher-c.so ./src/watcher-c.cpp -I ./include -I ../include -std=c++17 -fPIC -shared ``` -------------------------------- ### Start FrankenPHP Worker with Standalone Binary Source: https://github.com/php/frankenphp/blob/main/docs/worker.md Serve the content of the current directory using a worker script with the standalone FrankenPHP binary. The --worker option specifies the entry point script. ```bash frankenphp php-server --worker /path/to/your/worker/script.php ``` -------------------------------- ### Start FrankenPHP Systemd Service Source: https://github.com/php/frankenphp/blob/main/README.md Start the FrankenPHP systemd service on systems where it has been installed via deb or rpm packages. ```bash sudo systemctl start frankenphp ``` -------------------------------- ### Run Embedded App with HTTPS Source: https://github.com/php/frankenphp/blob/main/docs/embed.md Command to start the embedded web application with HTTPS enabled, automatically handling Let's Encrypt certificates, HTTP/2, and HTTP/3. ```console ./my-app php-server --domain localhost ``` -------------------------------- ### Bash Shell Completion (New Sessions - Linux) Source: https://github.com/php/frankenphp/blob/main/docs/config.md Install Bash shell completions for all new sessions on Linux by redirecting the output to the appropriate directory. ```console frankenphp completion bash > /usr/share/bash-completion/completions/frankenphp ``` -------------------------------- ### PHP Server Directive Equivalent Configuration Source: https://github.com/php/frankenphp/blob/main/docs/config.md This configuration block shows the equivalent setup for the 'php_server' directive, including routing, file handling, and PHP execution. It demonstrates how FrankenPHP processes requests. ```caddyfile 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 Minimal Test Server Source: https://github.com/php/frankenphp/blob/main/CONTRIBUTING.md Navigate to the test server directory and build the executable. ```console cd internal/testserver/ go build cd ../.. ``` -------------------------------- ### Cachegrind Output Analysis Source: https://github.com/php/frankenphp/blob/main/watcher/readme.md This is an example output from a Cachegrind analysis, showing detailed statistics on instruction cache (I1, LLi) and data cache (D1, LLd) references and misses. ```txt I refs: 797,368,564 I1 misses: 6,807 LLi misses: 2,799 I1 miss rate: 0.00% LLi miss rate: 0.00% D refs: 338,544,669 (224,680,988 rd + 113,863,681 wr) D1 misses: 35,331 ( 24,823 rd + 10,508 wr) LLd misses: 11,884 ( 8,121 rd + 3,763 wr) D1 miss rate: 0.0% ( 0.0% + 0.0% ) LLd miss rate: 0.0% ( 0.0% + 0.0% ) LL refs: 42,138 ( 31,630 rd + 10,508 wr) LL misses: 14,683 ( 10,920 rd + 3,763 wr) LL miss rate: 0.0% ( 0.0% + 0.0% ) ``` -------------------------------- ### Start FrankenPHP with Custom Worker and Request Limit Source: https://github.com/php/frankenphp/blob/main/docs/worker.md Configure FrankenPHP to use a custom worker script and specify the maximum number of requests the worker should handle before restarting. This example sets the limit to 42 requests. ```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 ``` -------------------------------- ### Install Watcher Library in Container Source: https://github.com/php/frankenphp/blob/main/watcher/watcher-c/readme.md Copies the compiled watcher C library to the system's library path and updates the dynamic linker cache. This is typically used in containerized environments. ```bash cp libwatcher-c.so /usr/local/lib/libwatcher-c.so ldconfig ``` -------------------------------- ### Initialize Go Module Source: https://github.com/php/frankenphp/blob/main/docs/extensions.md Initializes a new Go module for your project. This command sets up the necessary Go module files. ```console go mod init example.com/example ``` -------------------------------- ### Install Laravel Octane with FrankenPHP Source: https://github.com/php/frankenphp/blob/main/docs/laravel.md Install the Laravel Octane package using Composer. This command prepares your application for use with FrankenPHP by installing its configuration file. ```bash composer require laravel/octane ``` ```bash php artisan octane:install --server=frankenphp ``` -------------------------------- ### Run Minimal Test Server Source: https://github.com/php/frankenphp/blob/main/CONTRIBUTING.md Navigate to the test data directory and execute the built test server. ```console cd testdata/ ../internal/testserver/testserver ``` -------------------------------- ### Install and Run Igor PHP for Worker Compatibility Audit Source: https://github.com/php/frankenphp/blob/main/docs/symfony.md Install Igor PHP as a development dependency to audit your Symfony project for potential state leaks in worker mode. After installation, run the Igor PHP linter against your project directory. ```console composer require --dev igor-php/igor-php vendor/bin/igor-php . ``` -------------------------------- ### Example structured JSON log output Source: https://github.com/php/frankenphp/blob/main/docs/logging.md This is an example of the structured JSON output generated by `frankenphp_log()` when viewed in logs. ```json {"level":"info","ts":1704067200,"logger":"frankenphp","msg":"Hello from FrankenPHP!"} {"level":"warn","ts":1704067200,"logger":"frankenphp","msg":"Memory usage high","current_usage":10485760,"peak_usage":12582912} ``` -------------------------------- ### Install FrankenPHP with Curl Script Source: https://github.com/php/frankenphp/blob/main/README.md Use this command on Linux and macOS to automatically install an appropriate version of FrankenPHP for your platform. ```bash curl https://frankenphp.dev/install.sh | sh ``` -------------------------------- ### Install FrankenPHP with Homebrew Source: https://github.com/php/frankenphp/blob/main/README.md Install FrankenPHP on macOS and Linux using the Homebrew package manager. Extensions are managed via PIE. ```bash brew install dunglas/frankenphp/frankenphp ``` -------------------------------- ### Build Static Binary with Extra Caddy Modules Source: https://github.com/php/frankenphp/blob/main/docs/static.md Add extra Caddy modules or pass arguments to xcaddy using the XCADDY_ARGS Docker ARG. This example includes Souin, cbrotli, Mercure, and Vulcain modules. ```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 ``` -------------------------------- ### Install FrankenPHP with APK Packages Source: https://github.com/php/frankenphp/blob/main/README.md Install FrankenPHP and manage extensions using apk on Alpine Linux. Supports PHP versions 8.2-8.5. ```bash VERSION=85 # 82-85 available echo "https://pkg.henderkes.com/api/packages/${VERSION}/alpine/main/php-zts" | sudo tee -a /etc/apk/repositories KEYFILE=$(curl -sJOw '%{filename_effective}' https://pkg.henderkes.com/api/packages/${VERSION}/alpine/key) sudo mv ${KEYFILE} /etc/apk/keys/ && sudo apk update && sudo apk add frankenphp ``` -------------------------------- ### Install FrankenPHP with DEB Packages Source: https://github.com/php/frankenphp/blob/main/README.md Install FrankenPHP and manage extensions using apt on Debian-based systems. Supports PHP versions 8.2-8.5. ```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 ``` -------------------------------- ### Basic php_server Configuration Source: https://github.com/php/frankenphp/blob/main/docs/config.md Configures a PHP server with root directory, path splitting, environment variables, and file server settings. ```caddyfile php_server [] { root # Sets the root folder to the site. Default: `root` directive. split_path # Sets the substrings for splitting the URI into two parts. The first matching substring will be used to split the "path info" from the path. The first piece is suffixed with the matching substring and will be assumed as the actual resource (CGI script) name. The second piece will be set to PATH_INFO for the script to use. Default: `.php` resolve_root_symlink false # Disables resolving the `root` directory to its actual value by evaluating a symbolic link, if one exists (enabled by default). env # Sets an extra environment variable to the given value. Can be specified more than once for multiple environment variables. file_server off # Disables the built-in file_server directive. worker { # Creates a worker specific to this server. Can be specified more than once for multiple workers. file # Sets the path to the worker script, can be relative to the php_server root num # Sets the number of PHP threads to start, defaults to 2x the number of available name # Sets the name for the worker, used in logs and metrics. Default: absolute path of worker file. Always starts with m# when defined in a php_server block. watch # Sets the path to watch for file changes. Can be specified more than once for multiple paths. env # Sets an extra environment variable to the given value. Can be specified more than once for multiple environment variables. Environment variables for this worker are also inherited from the php_server parent, but can be overwritten here. match # match the worker to a path pattern. Overrides try_files and can only be used in the php_server directive. } worker # Can also use the short form like in the global frankenphp block. } ``` -------------------------------- ### Install FrankenPHP with RPM Packages Source: https://github.com/php/frankenphp/blob/main/README.md Install FrankenPHP and manage extensions using dnf on RPM-based systems. Supports PHP versions 8.2-8.5. ```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 ``` -------------------------------- ### Add Pkg-Config Target Source: https://github.com/php/frankenphp/blob/main/watcher/CMakeLists.txt Manages the creation and installation of pkg-config files. It conditionally creates the file based on the `BUILD_PKG_CONFIG` flag and installs it if `WTR_WATCHER_MAIN_PROJECT` is true. ```cmake function(wtr_add_pkg_config_target NAME SRC) if(BUILD_PKG_CONFIG) message(STATUS "${NAME}: Added (BUILD_PKG_CONFIG=${BUILD_PKG_CONFIG})") configure_file("${SRC}" "${CMAKE_BINARY_DIR}/${NAME}" @ONLY) if(WTR_WATCHER_MAIN_PROJECT) install(FILES "${CMAKE_BINARY_DIR}/${NAME}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" COMPONENT pkgconfig) endif() else() message(STATUS "${NAME}: Skipped (BUILD_PKG_CONFIG=${BUILD_PKG_CONFIG})") endif() endfunction() ``` -------------------------------- ### Install Symfony Mercure Component Source: https://github.com/php/frankenphp/blob/main/docs/mercure.md Install the Symfony Mercure Component and lcobucci/jwt library using Composer to manage JWT generation and update publishing. ```console composer require symfony/mercure lcobucci/jwt ``` -------------------------------- ### Start Laravel Octane FrankenPHP Server Source: https://github.com/php/frankenphp/blob/main/docs/laravel.md Start the Laravel Octane server configured for FrankenPHP. This command can be customized with various options to control host, port, worker count, and more. ```bash php artisan octane:frankenphp ``` -------------------------------- ### Start FrankenPHP Worker with File Watching Source: https://github.com/php/frankenphp/blob/main/docs/worker.md This command starts FrankenPHP in worker mode and automatically restarts the worker when specified PHP files are modified. It's useful for development with hot reloading. ```bash frankenphp php-server --worker /path/to/your/worker/script.php --watch="/path/to/your/app/**/*.php" ``` -------------------------------- ### Install Dependencies for Mac Build Source: https://github.com/php/frankenphp/blob/main/docs/compile.md Installs necessary dependencies like libiconv, bison, and brotli using Homebrew for Mac users. Updates the Zsh configuration to include Homebrew's bison path. ```bash brew install libiconv bison brotli re2c pkg-config watcher echo 'export PATH="/opt/homebrew/opt/bison/bin:$PATH"' >> ~/.zshrc ``` -------------------------------- ### Rust Watcher Installation Source: https://github.com/php/frankenphp/blob/main/watcher/readme.md Add the watcher, tokio, and futures crates to your Rust project. ```sh cargo add wtr-watcher tokio futures ``` -------------------------------- ### Build and Compile Xdebug Extension for FrankenPHP Source: https://github.com/php/frankenphp/blob/main/docs/static.md This Docker command sequence builds a Docker image for compiling extensions, starts a container, compiles the Xdebug extension with ZTS support, and copies the compiled module and FrankenPHP binary to the host. Ensure you are in the directory containing the static-builder-gnu.Dockerfile. ```bash docker build -t gnu-ext -f static-builder-gnu.Dockerfile --build-arg FRANKENPHP_VERSION=1.0 . docker create --name static-builder-gnu -it gnu-ext /bin/sh docker start static-builder-gnu docker exec -it static-builder-gnu /bin/sh cd /go/src/app/dist/static-php-cli/buildroot/bin git clone https://github.com/xdebug/xdebug.git && cd xdebug source scl_source enable devtoolset-10 ../phpize ./configure --with-php-config=/go/src/app/dist/static-php-cli/buildroot/bin/php-config make exit docker cp static-builder-gnu:/go/src/app/dist/static-php-cli/buildroot/bin/xdebug/modules/xdebug.so xdebug-zts.so docker cp static-builder-gnu:/go/src/app/dist/frankenphp-linux-$(uname -m) ./frankenphp docker stop static-builder-gnu docker rm static-builder-gnu docker rmi gnu-ext ``` -------------------------------- ### Build Static Binary with Extension Libraries Source: https://github.com/php/frankenphp/blob/main/docs/static.md To enable additional functionality for PHP extensions, pass the PHP_EXTENSION_LIBS Docker ARG with the required 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 ``` -------------------------------- ### Build Static Binary with GitHub Token Source: https://github.com/php/frankenphp/blob/main/docs/static.md If you encounter GitHub API rate limits, set a GitHub Personal Access Token in the GITHUB_TOKEN environment variable before running the build command. ```bash GITHUB_TOKEN="xxx" docker --load buildx bake static-builder-musl # ... ``` -------------------------------- ### Build Musl-based Fully Static Binary Source: https://github.com/php/frankenphp/blob/main/docs/static.md Use this command to create a fully static binary for Linux that runs without dependencies but does not support dynamic PHP extensions. It's suitable for minimal environments like scratch Docker images. ```bash docker buildx bake --load static-builder-musl docker cp $(docker create --name static-builder-musl dunglas/frankenphp:static-builder-musl):/go/src/app/dist/frankenphp-linux-$(uname -m) frankenphp ; docker rm static-builder-musl ``` -------------------------------- ### TLS/SSL Error Example with STARTTLS Source: https://github.com/php/frankenphp/blob/main/docs/known-issues.md Illustrates a common TLS/SSL error encountered when using static FrankenPHP binaries, specifically related to STARTTLS and certificate verification failures. This indicates missing CA certificates. ```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 ``` -------------------------------- ### Install Additional PHP Extensions Source: https://github.com/php/frankenphp/blob/main/docs/docker.md Use the `install-php-extensions` script in your Dockerfile to add common PHP extensions. ```dockerfile FROM dunglas/frankenphp # add additional extensions here: RUN install-php-extensions \ pdo_mysql \ gd \ intl \ zip \ opcache ``` -------------------------------- ### Run Embedded Worker Source: https://github.com/php/frankenphp/blob/main/docs/embed.md Command to start the worker script of the embedded application using the standalone binary. ```console ./my-app php-server --worker public/index.php ``` -------------------------------- ### Build FrankenPHP with xcaddy Source: https://github.com/php/frankenphp/blob/main/docs/compile.md Compiles the FrankenPHP binary using xcaddy, including Caddy modules and FrankenPHP extensions. Environment variables and build tags are set for the Go build process. ```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/dunglas/frankenphp/caddy \ --with github.com/dunglas/mercure/caddy \ --with github.com/dunglas/vulcain/caddy \ --with github.com/dunglas/caddy-cbrotli # Add extra Caddy modules and FrankenPHP extensions here # optionally, if you would like to compile from your frankenphp sources: # --with github.com/dunglas/frankenphp=$(pwd) \ # --with github.com/dunglas/frankenphp/caddy=$(pwd)/caddy ``` -------------------------------- ### Nix Build and Run Commands Source: https://github.com/php/frankenphp/blob/main/watcher/readme.md Commands to build, run, and develop within a Nix environment. Useful for managing dependencies and ensuring reproducible builds. ```sh nix build # To just build ``` ```sh nix run # Build the default target, then run without arguments ``` ```sh nix run . -- / | jq # Build and run, watch the root directory, pipe it to jq ``` ```sh nix develop # Enter an isolated development shell with everything needed to explore this project ``` -------------------------------- ### Production Caddyfile for WordPress Source: https://github.com/php/frankenphp/blob/main/docs/wordpress.md A Caddyfile configuration for a production WordPress setup with FrankenPHP, enabling Zstandard compression and logging. ```caddyfile example.com php_server encode zstd br gzip log ``` -------------------------------- ### Enable Worker Mode in Dockerfile Source: https://github.com/php/frankenphp/blob/main/docs/docker.md Set the FRANKENPHP_CONFIG environment variable in your Dockerfile to start FrankenPHP with a worker script by default. ```dockerfile FROM dunglas/frankenphp # ... ENV FRANKENPHP_CONFIG="worker ./public/index.php" ``` -------------------------------- ### Go Worker with Lifecycle Hooks Source: https://github.com/php/frankenphp/blob/main/docs/extension-workers.md This Go code demonstrates how to register a FrankenPHP worker and utilize lifecycle hooks for server startup and thread readiness. It includes global setup and per-thread initialization logic. ```go // FrankenPHP extension worker with lifecycle hooks package myextension import ( "fmt" "github.com/dunglas/frankenphp" frankenphpCaddy "github.com/dunglas/frankenphp/caddy" ) func init() { workerHandle = frankenphpCaddy.RegisterWorkers( "my-worker", "worker.php", 2, // Server Startup (Global) frankenphp.WithWorkerOnServerStartup(func() { fmt.Println("Extension: Server starting up...") }), // Thread Ready (Per Thread) // Note: The function accepts an integer representing the Thread ID frankenphp.WithWorkerOnReady(func(id int) { fmt.Printf("Extension: Worker thread #%d is ready.\n", id) }), ) } ``` -------------------------------- ### Build and Run Watcher Programmatically Source: https://github.com/php/frankenphp/blob/main/watcher/readme.md Clone the Watcher repository, build the release version using the provided script, and then run the executable. The output can be piped to other commands for further processing. ```bash # The main branch is the (latest) release branch. git clone https://github.com/e-dant/watcher.git && cd watcher # Via Nix nix run | grep -oE 'cmake-is-tough' # With the build script tool/build --no-build-test --no-run && cd out/this/Release # Build the release version for the host platform. ./wtr.watcher | grep -oE 'needle-in-a-haystack/.+"' ```