mirror of
https://github.com/dunglas/frankenphp.git
synced 2025-12-24 13:38:11 +08:00
docs: improve Mercure documentation and various other parts
This commit is contained in:
1
.gitleaksignore
Normal file
1
.gitleaksignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/github/workspace/docs/mercure.md:jwt:65
|
||||||
@@ -17,7 +17,7 @@ func init() {
|
|||||||
caddycmd.RegisterCommand(caddycmd.Command{
|
caddycmd.RegisterCommand(caddycmd.Command{
|
||||||
Name: "extension-init",
|
Name: "extension-init",
|
||||||
Usage: "go_extension.go [--verbose]",
|
Usage: "go_extension.go [--verbose]",
|
||||||
Short: "(Experimental) Initializes a PHP extension from a Go file",
|
Short: "Initializes a PHP extension from a Go file (EXPERIMENTAL)",
|
||||||
Long: `
|
Long: `
|
||||||
Initializes a PHP extension from a Go file. This command generates the necessary C files for the extension, including the header and source files, as well as the arginfo file.`,
|
Initializes a PHP extension from a Go file. This command generates the necessary C files for the extension, including the header and source files, as well as the arginfo file.`,
|
||||||
CobraFunc: func(cmd *cobra.Command) {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
|
|||||||
107
docs/config.md
107
docs/config.md
@@ -1,17 +1,38 @@
|
|||||||
# Configuration
|
# Configuration
|
||||||
|
|
||||||
FrankenPHP, Caddy as well as the Mercure and Vulcain modules can be configured using [the formats supported by Caddy](https://caddyserver.com/docs/getting-started#your-first-config).
|
FrankenPHP, Caddy as well as the [Mercure](mercure.md) and [Vulcain](https://vulcain.rocks) modules can be configured using [the formats supported by Caddy](https://caddyserver.com/docs/getting-started#your-first-config).
|
||||||
|
|
||||||
In [the Docker images](docker.md), the `Caddyfile` is located at `/etc/frankenphp/Caddyfile`.
|
The most common format is the `Caddyfile`, which is a simple, human-readable text format.
|
||||||
The static binary will also look for the `Caddyfile` in the directory where the `frankenphp run` command is executed.
|
By default, FrankenPHP will look for a `Caddyfile` in the current directory.
|
||||||
You can specify a custom path with the `-c` or `--config` option.
|
You can specify a custom path with the `-c` or `--config` option.
|
||||||
|
|
||||||
|
A minimal `Caddyfile` to serve a PHP application is shown below:
|
||||||
|
|
||||||
|
```caddyfile
|
||||||
|
# The hostname to respond to
|
||||||
|
localhost
|
||||||
|
|
||||||
|
# Optionaly, the directory to serve files from, otherwise defaults to the current directory
|
||||||
|
#root public/
|
||||||
|
php_server
|
||||||
|
```
|
||||||
|
|
||||||
|
A more advanced `Caddyfile` enabling more features and providing convenient environment variables is provided [in the FrankenPHP repository](https://github.com/php/frankenphp/blob/main/caddy/frankenphp/Caddyfile),
|
||||||
|
and with Docker images.
|
||||||
|
|
||||||
PHP itself can be configured [using a `php.ini` file](https://www.php.net/manual/en/configuration.file.php).
|
PHP itself can be configured [using a `php.ini` file](https://www.php.net/manual/en/configuration.file.php).
|
||||||
|
|
||||||
Depending on your installation method, the PHP interpreter will look for configuration files in locations described below.
|
Depending on your installation method, FrankenPHP and the PHP interpreter will look for configuration files in locations described below.
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
|
FrankenPHP:
|
||||||
|
|
||||||
|
- `/etc/frankenphp/Caddyfile`: the main configuration file
|
||||||
|
- `/etc/frankenphp/caddy.d/*.caddy`: additional configuration files that are loaded automatically
|
||||||
|
|
||||||
|
PHP:
|
||||||
|
|
||||||
- `php.ini`: `/usr/local/etc/php/php.ini` (no `php.ini` is provided by default)
|
- `php.ini`: `/usr/local/etc/php/php.ini` (no `php.ini` is provided by default)
|
||||||
- additional configuration files: `/usr/local/etc/php/conf.d/*.ini`
|
- additional configuration files: `/usr/local/etc/php/conf.d/*.ini`
|
||||||
- PHP extensions: `/usr/local/lib/php/extensions/no-debug-zts-<YYYYMMDD>/`
|
- PHP extensions: `/usr/local/lib/php/extensions/no-debug-zts-<YYYYMMDD>/`
|
||||||
@@ -29,12 +50,25 @@ RUN cp $PHP_INI_DIR/php.ini-development $PHP_INI_DIR/php.ini
|
|||||||
|
|
||||||
## RPM and Debian packages
|
## RPM and Debian packages
|
||||||
|
|
||||||
|
FrankenPHP:
|
||||||
|
|
||||||
|
- `/etc/frankenphp/Caddyfile`: the main configuration file
|
||||||
|
- `/etc/frankenphp/caddy.d/*.caddy`: additional configuration files that are loaded automatically
|
||||||
|
|
||||||
|
PHP:
|
||||||
|
|
||||||
- `php.ini`: `/etc/frankenphp/php.ini` (a `php.ini` file with production presets is provided by default)
|
- `php.ini`: `/etc/frankenphp/php.ini` (a `php.ini` file with production presets is provided by default)
|
||||||
- additional configuration files: `/etc/frankenphp/php.d/*.ini`
|
- additional configuration files: `/etc/frankenphp/php.d/*.ini`
|
||||||
- PHP extensions: `/usr/lib/frankenphp/modules/`
|
- PHP extensions: `/usr/lib/frankenphp/modules/`
|
||||||
|
|
||||||
## Static binary
|
## Static binary
|
||||||
|
|
||||||
|
FrankenPHP:
|
||||||
|
|
||||||
|
- In the current working directory: `Caddyfile`
|
||||||
|
|
||||||
|
PHP:
|
||||||
|
|
||||||
- `php.ini`: The directory in which `frankenphp run` or `frankenphp php-server` is executed, then `/etc/frankenphp/php.ini`
|
- `php.ini`: The directory in which `frankenphp run` or `frankenphp php-server` is executed, then `/etc/frankenphp/php.ini`
|
||||||
- additional configuration files: `/etc/frankenphp/php.d/*.ini`
|
- additional configuration files: `/etc/frankenphp/php.d/*.ini`
|
||||||
- PHP extensions: cannot be loaded, bundle them in the binary itself
|
- PHP extensions: cannot be loaded, bundle them in the binary itself
|
||||||
@@ -229,34 +263,6 @@ and otherwise forward the request to the worker matching the path pattern.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Full Duplex (HTTP/1)
|
|
||||||
|
|
||||||
When using HTTP/1.x, it may be desirable to enable full-duplex mode to allow writing a response before the entire body
|
|
||||||
has been read. (for example: WebSocket, Server-Sent Events, etc.)
|
|
||||||
|
|
||||||
This is an opt-in configuration that needs to be added to the global options in the `Caddyfile`:
|
|
||||||
|
|
||||||
```caddyfile
|
|
||||||
{
|
|
||||||
servers {
|
|
||||||
enable_full_duplex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
> [!CAUTION]
|
|
||||||
>
|
|
||||||
> Enabling this option may cause old HTTP/1.x clients that don't support full-duplex to deadlock.
|
|
||||||
> This can also be configured using the `CADDY_GLOBAL_OPTIONS` environment config:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
CADDY_GLOBAL_OPTIONS="servers {
|
|
||||||
enable_full_duplex
|
|
||||||
}"
|
|
||||||
```
|
|
||||||
|
|
||||||
You can find more information about this setting in the [Caddy documentation](https://caddyserver.com/docs/caddyfile/options#enable-full-duplex).
|
|
||||||
|
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
|
|
||||||
The following environment variables can be used to inject Caddy directives in the `Caddyfile` without modifying it:
|
The following environment variables can be used to inject Caddy directives in the `Caddyfile` without modifying it:
|
||||||
@@ -293,6 +299,43 @@ You can also change the PHP configuration using the `php_ini` directive in the `
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Disabling HTTPS
|
||||||
|
|
||||||
|
By default, FrankenPHP will automatically enable HTTPS using for all the hostnames, including `localhost`.
|
||||||
|
If you want to disable HTTPS (for example in a development environment), you can set the `SERVER_NAME` environment variable to `http://` or `:80`:
|
||||||
|
|
||||||
|
Alternatively, you can use all other methods described in the [Caddy documentation](https://caddyserver.com/docs/automatic-https#activation).
|
||||||
|
|
||||||
|
If you want to use HTTPS with the `127.0.0.1` IP address instead of the `localhost` hostname, please read the [known issues](known-issues.md#using-https127001-with-docker) section.
|
||||||
|
|
||||||
|
### Full Duplex (HTTP/1)
|
||||||
|
|
||||||
|
When using HTTP/1.x, it may be desirable to enable full-duplex mode to allow writing a response before the entire body
|
||||||
|
has been read. (for example: [Mercure](mercure.md), WebSocket, Server-Sent Events, etc.)
|
||||||
|
|
||||||
|
This is an opt-in configuration that needs to be added to the global options in the `Caddyfile`:
|
||||||
|
|
||||||
|
```caddyfile
|
||||||
|
{
|
||||||
|
servers {
|
||||||
|
enable_full_duplex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
>
|
||||||
|
> Enabling this option may cause old HTTP/1.x clients that don't support full-duplex to deadlock.
|
||||||
|
> This can also be configured using the `CADDY_GLOBAL_OPTIONS` environment config:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
CADDY_GLOBAL_OPTIONS="servers {
|
||||||
|
enable_full_duplex
|
||||||
|
}"
|
||||||
|
```
|
||||||
|
|
||||||
|
You can find more information about this setting in the [Caddy documentation](https://caddyserver.com/docs/caddyfile/options#enable-full-duplex).
|
||||||
|
|
||||||
## Enable the Debug Mode
|
## Enable the Debug Mode
|
||||||
|
|
||||||
When using the Docker image, set the `CADDY_GLOBAL_OPTIONS` environment variable to `debug` to enable the debug mode:
|
When using the Docker image, set the `CADDY_GLOBAL_OPTIONS` environment variable to `debug` to enable the debug mode:
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Building Custom Docker Image
|
# Building Custom Docker Image
|
||||||
|
|
||||||
[FrankenPHP Docker images](https://hub.docker.com/r/dunglas/frankenphp) are based on [official PHP images](https://hub.docker.com/_/php/). Debian and Alpine Linux variants are provided for popular architectures. Debian variants are recommended.
|
[FrankenPHP Docker images](https://hub.docker.com/r/dunglas/frankenphp) are based on [official PHP images](https://hub.docker.com/_/php/).
|
||||||
|
Debian and Alpine Linux variants are provided for popular architectures.
|
||||||
|
Debian variants are recommended.
|
||||||
|
|
||||||
Variants for PHP 8.2, 8.3 and 8.4 are provided.
|
Variants for PHP 8.2, 8.3 and 8.4 are provided.
|
||||||
|
|
||||||
@@ -28,6 +30,11 @@ docker build -t my-php-app .
|
|||||||
docker run -it --rm --name my-running-app my-php-app
|
docker run -it --rm --name my-running-app my-php-app
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## How to Tweak the Configuration
|
||||||
|
|
||||||
|
For convenience, [a default `Caddyfile`](https://github.com/php/frankenphp/blob/main/caddy/frankenphp/Caddyfile) containing
|
||||||
|
useful environment variables is provided in the image.
|
||||||
|
|
||||||
## How to Install More PHP Extensions
|
## How to Install More PHP Extensions
|
||||||
|
|
||||||
The [`docker-php-extension-installer`](https://github.com/mlocati/docker-php-extension-installer) script is provided in the base image.
|
The [`docker-php-extension-installer`](https://github.com/mlocati/docker-php-extension-installer) script is provided in the base image.
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ The following extensions are known not to be compatible with FrankenPHP:
|
|||||||
|
|
||||||
The following extensions have known bugs and unexpected behaviors when used with FrankenPHP:
|
The following extensions have known bugs and unexpected behaviors when used with FrankenPHP:
|
||||||
|
|
||||||
| Name | Problem |
|
| Name | Problem |
|
||||||
| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| [ext-openssl](https://www.php.net/manual/en/book.openssl.php) | When using a static build of FrankenPHP (built with the musl libc), the OpenSSL extension may crash under heavy loads. A workaround is to use a dynamically linked build (like the one used in Docker images). This bug is [being tracked by PHP](https://github.com/php/php-src/issues/13648). |
|
| [ext-openssl](https://www.php.net/manual/en/book.openssl.php) | When using musl libc, the OpenSSL extension may crash under heavy loads. The problem doesn't occur when using the more popular GNU libc. This bug is [being tracked by PHP](https://github.com/php/php-src/issues/13648). |
|
||||||
|
|
||||||
## get_browser
|
## get_browser
|
||||||
|
|
||||||
@@ -23,7 +23,11 @@ The [get_browser()](https://www.php.net/manual/en/function.get-browser.php) func
|
|||||||
|
|
||||||
## Standalone Binary and Alpine-based Docker Images
|
## Standalone Binary and Alpine-based Docker Images
|
||||||
|
|
||||||
The standalone binary and Alpine-based Docker images (`dunglas/frankenphp:*-alpine`) use [musl libc](https://musl.libc.org/) instead of [glibc and friends](https://www.etalabs.net/compare_libcs.html), to keep a smaller binary size. This may lead to some compatibility issues. In particular, the glob flag `GLOB_BRACE` is [not available](https://www.php.net/manual/en/function.glob.php)
|
The fully binary and Alpine-based Docker images (`dunglas/frankenphp:*-alpine`) use [musl libc](https://musl.libc.org/) instead of [glibc and friends](https://www.etalabs.net/compare_libcs.html), to keep a smaller binary size.
|
||||||
|
This may lead to some compatibility issues.
|
||||||
|
In particular, the glob flag `GLOB_BRACE` is [not available](https://www.php.net/manual/en/function.glob.php)
|
||||||
|
|
||||||
|
Prefer using the GNU variant of the static binary and Debian-based Docker images if you encounter issues.
|
||||||
|
|
||||||
## Using `https://127.0.0.1` with Docker
|
## Using `https://127.0.0.1` with Docker
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ The `octane:frankenphp` command can take the following options:
|
|||||||
> [!TIP]
|
> [!TIP]
|
||||||
> To get structured JSON logs (useful when using log analytics solutions), explicitly the pass `--log-level` option.
|
> To get structured JSON logs (useful when using log analytics solutions), explicitly the pass `--log-level` option.
|
||||||
|
|
||||||
|
See also [how to use Mercure with Octane](#mercure-support).
|
||||||
|
|
||||||
Learn more about [Laravel Octane in its official documentation](https://laravel.com/docs/octane).
|
Learn more about [Laravel Octane in its official documentation](https://laravel.com/docs/octane).
|
||||||
|
|
||||||
## Laravel Apps As Standalone Binaries
|
## Laravel Apps As Standalone Binaries
|
||||||
@@ -166,6 +168,34 @@ This is not suitable for embedded applications, as each new version will be extr
|
|||||||
|
|
||||||
Set the `LARAVEL_STORAGE_PATH` environment variable (for example, in your `.env` file) or call the `Illuminate\Foundation\Application::useStoragePath()` method to use a directory outside the temporary directory.
|
Set the `LARAVEL_STORAGE_PATH` environment variable (for example, in your `.env` file) or call the `Illuminate\Foundation\Application::useStoragePath()` method to use a directory outside the temporary directory.
|
||||||
|
|
||||||
|
### Mercure Support
|
||||||
|
|
||||||
|
[Mercure](https://mercure.rocks) is a great way to add real-time capabilities to your Laravel apps.
|
||||||
|
FrankenPHP includes [Mercure support out of the box](mercure.md).
|
||||||
|
|
||||||
|
If you are not using [Octane](#laravel-octane), see [the Mercure documentation entry](mercure.md).
|
||||||
|
|
||||||
|
If you are using Octane, you can use enable Mercure support by adding the following lines to your `config/octane.php` file:
|
||||||
|
|
||||||
|
```php
|
||||||
|
// ...
|
||||||
|
|
||||||
|
return [
|
||||||
|
// ...
|
||||||
|
|
||||||
|
'mercure' => [
|
||||||
|
'anonymous' => true,
|
||||||
|
'publisher_jwt' => '!ChangeThisMercureHubJWTSecretKey!',
|
||||||
|
'subscriber_jwt' => '!ChangeThisMercureHubJWTSecretKey!',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use [all directives supported by Mercure](https://mercure.rocks/docs/hub/config#directives) in this array.
|
||||||
|
|
||||||
|
To publish and subscribe to updates, we recommend using the [Laravel Mercure Broadcaster](https://github.com/mvanduijker/laravel-mercure-broadcaster) library.
|
||||||
|
Alternatively, see [the Mercure documentation](mercure.md) to do it in pure PHP and JavaScript.
|
||||||
|
|
||||||
### Running Octane With Standalone Binaries
|
### Running Octane With Standalone Binaries
|
||||||
|
|
||||||
It's even possible to package Laravel Octane apps as standalone binaries!
|
It's even possible to package Laravel Octane apps as standalone binaries!
|
||||||
|
|||||||
121
docs/mercure.md
121
docs/mercure.md
@@ -3,13 +3,124 @@
|
|||||||
FrankenPHP comes with a built-in [Mercure](https://mercure.rocks) hub!
|
FrankenPHP comes with a built-in [Mercure](https://mercure.rocks) hub!
|
||||||
Mercure allows you to push real-time events to all the connected devices: they will receive a JavaScript event instantly.
|
Mercure allows you to push real-time events to all the connected devices: they will receive a JavaScript event instantly.
|
||||||
|
|
||||||
No JS library or SDK is required!
|
It's a convenient alternative to WebSockets that is simple to use and is natively supported by all modern web browsers!
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
To enable the Mercure hub, update the `Caddyfile` as described [on Mercure's site](https://mercure.rocks/docs/hub/config).
|
## Enabling Mercure
|
||||||
|
|
||||||
The path of the Mercure hub is `/.well-known/mercure`.
|
Mercure support is disabled by default.
|
||||||
When running FrankenPHP inside Docker, the full send URL would look like `http://php/.well-known/mercure` (with `php` being the container's name running FrankenPHP).
|
Here is a minimal example of a `Caddyfile` enabling both FrankenPHP and the Mercure hub:
|
||||||
|
|
||||||
To push Mercure updates from your code, we recommend the [Symfony Mercure Component](https://symfony.com/components/Mercure) (you don't need the Symfony full-stack framework to use it).
|
```caddyfile
|
||||||
|
# The hostname to respond to
|
||||||
|
localhost
|
||||||
|
|
||||||
|
mercure {
|
||||||
|
# The secret key used to sign the JWT tokens for publishers
|
||||||
|
publisher_jwt !ChangeThisMercureHubJWTSecretKey!
|
||||||
|
# Allows anonymous subscribers (without JWT)
|
||||||
|
anonymous
|
||||||
|
}
|
||||||
|
|
||||||
|
root public/
|
||||||
|
php_server
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
>
|
||||||
|
> The [sample `Caddyfile`](https://github.com/php/frankenphp/blob/main/caddy/frankenphp/Caddyfile)
|
||||||
|
> provided by [the Docker images](docker.md) already includes a commented Mercure configuration
|
||||||
|
> with convenient environment variables to configure it.
|
||||||
|
>
|
||||||
|
> Uncomment the Mercure section in `/etc/frankenphp/Caddyfile` to enable it.
|
||||||
|
|
||||||
|
## Subscribing to Updates
|
||||||
|
|
||||||
|
By default, the Mercure hub is available on the `/.well-known/mercure` path of your FrankenPHP server.
|
||||||
|
To subscribe to updates, use the native [`EventSource`](https://developer.mozilla.org/docs/Web/API/EventSource) JavaScript class:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- public/index.html -->
|
||||||
|
<!doctype html>
|
||||||
|
<title>Mercure Example</title>
|
||||||
|
<script>
|
||||||
|
const eventSource = new EventSource("/.well-known/mercure?topic=my-topic");
|
||||||
|
eventSource.onmessage = function (event) {
|
||||||
|
console.log("New message:", event.data);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Publishing Updates
|
||||||
|
|
||||||
|
### Using `file_put_contents()`
|
||||||
|
|
||||||
|
To dispatch an update to connected subscribers, send an authenticated POST request to the Mercure hub with the `topic` and `data` parameters:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
// public/publish.php
|
||||||
|
|
||||||
|
const JWT = 'eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdfX0.PXwpfIGng6KObfZlcOXvcnWCJOWTFLtswGI5DZuWSK4';
|
||||||
|
|
||||||
|
$updateID = file_get_contents('https://localhost/.well-known/mercure', context: stream_context_create(['http' => [
|
||||||
|
'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);
|
||||||
|
```
|
||||||
|
|
||||||
|
The key passed as parameter of the `mercure.publisher_jwt` option in the `Caddyfile` must used to sign the JWT token used in the `Authorization` header.
|
||||||
|
|
||||||
|
The JWT must include a `mercure` claim with a `publish` permission for the topics you want to publish to.
|
||||||
|
See [the Mercure documentation](https://mercure.rocks/spec#publishers) about authorization.
|
||||||
|
|
||||||
|
To generate your own tokens, you can use [this jwt.io link](https://www.jwt.io/#token=eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdfX0.PXwpfIGng6KObfZlcOXvcnWCJOWTFLtswGI5DZuWSK4),
|
||||||
|
but for production apps, it's recommended to use short-lived tokens generated aerodynamically using with a trusted [JWT library](https://www.jwt.io/libraries?programming_language=php).
|
||||||
|
|
||||||
|
### Using Symfony Mercure
|
||||||
|
|
||||||
|
Alternatively, you can use the [Symfony Mercure Component](https://symfony.com/components/Mercure), a standalone PHP library.
|
||||||
|
|
||||||
|
This library handled the JWT generation, update publishing as well as cookie-based authorization for subscribers.
|
||||||
|
|
||||||
|
First, install the library using Composer:
|
||||||
|
|
||||||
|
```console
|
||||||
|
composer require symfony/mercure lcobucci/jwt
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, you can use it like this:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
// public/publish.php
|
||||||
|
|
||||||
|
require __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
|
const JWT_SECRET = '!ChangeThisMercureHubJWTSecretKey!'; // Must be the same as mercure.publisher_jwt in Caddyfile
|
||||||
|
|
||||||
|
// Set up the JWT token provider
|
||||||
|
$jwFactory = new \Symfony\Component\Mercure\Jwt\LcobucciFactory(JWT_SECRET);
|
||||||
|
$provider = new \Symfony\Component\Mercure\Jwt\FactoryTokenProvider($jwFactory, publish: ['*']);
|
||||||
|
|
||||||
|
$hub = new \Symfony\Component\Mercure\Hub('https://localhost/.well-known/mercure', $provider);
|
||||||
|
// Serialize the update, and dispatch it to the hub, that will broadcast it to the clients
|
||||||
|
$updateID = $hub->publish(new \Symfony\Component\Mercure\Update('my-topic', json_encode(['key' => 'value'])));
|
||||||
|
|
||||||
|
// Write to FrankenPHP's logs
|
||||||
|
error_log("update $updateID published", 4);
|
||||||
|
```
|
||||||
|
|
||||||
|
Mercure is also natively supported by:
|
||||||
|
|
||||||
|
- [Laravel](laravel.md#mercure-support)
|
||||||
|
- [Symfony](https://symfony.com/doc/current/mercure.html)
|
||||||
|
- [API Platform](https://api-platform.com/docs/core/mercure/)
|
||||||
|
|||||||
Reference in New Issue
Block a user