mirror of
https://github.com/dunglas/frankenphp.git
synced 2025-12-24 13:38:11 +08:00
improvements
This commit is contained in:
@@ -128,6 +128,7 @@ Go to `https://localhost`, and enjoy!
|
||||
- [Worker mode](https://frankenphp.dev/docs/worker/)
|
||||
- [Early Hints support (103 HTTP status code)](https://frankenphp.dev/docs/early-hints/)
|
||||
- [Real-time](https://frankenphp.dev/docs/mercure/)
|
||||
- [Hot reloading](https://frankenphp.dev/docs/hot-reload/)
|
||||
- [Efficiently Serving Large Static Files](https://frankenphp.dev/docs/x-sendfile/)
|
||||
- [Configuration](https://frankenphp.dev/docs/config/)
|
||||
- [Writing PHP Extensions in Go](https://frankenphp.dev/docs/extensions/)
|
||||
|
||||
@@ -213,7 +213,9 @@ This is useful for development environments.
|
||||
}
|
||||
```
|
||||
|
||||
If the `watch` directory is not specified, it will fall back to `./**/*.{php,yaml,yml,twig,env}`,
|
||||
This feature is often used in combination with [hot reload](hot-reload.md)
|
||||
|
||||
If the `watch` directory is not specified, it will fall back to `./**/*.{env,php,twig,yaml,yml}`,
|
||||
which watches all `.php`, `.yaml`, `.yml`, `.twig` and `.env` files in the directory and subdirectories
|
||||
where the FrankenPHP process was started. You can instead also specify one or more directories via a
|
||||
[shell filename pattern](https://pkg.go.dev/path/filepath#Match):
|
||||
@@ -239,7 +241,7 @@ where the FrankenPHP process was started. You can instead also specify one or mo
|
||||
|
||||
The file watcher is based on [e-dant/watcher](https://github.com/e-dant/watcher).
|
||||
|
||||
## Matching the worker to a path
|
||||
## Matching the Worker To a Path
|
||||
|
||||
In traditional PHP applications, scripts are always placed in the public directory.
|
||||
This is also true for worker scripts, which are treated like any other PHP script.
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
FrankenPHP includes a built-in **hot reload** feature designed to vastly improve the developer experience.
|
||||
|
||||

|
||||
|
||||
This feature provides a workflow similar to **Hot Module Replacement (HMR)** found in modern JavaScript tooling (like Vite or Webpack).
|
||||
Instead of manually refreshing the browser after every file change (PHP code, templates, JavaScript and CSS files...),
|
||||
FrankenPHP updates the content in real-time.
|
||||
@@ -18,7 +20,7 @@ Depending on your setup, the browser will either:
|
||||
|
||||
## Configuration
|
||||
|
||||
To enable hot reloading, enable Mercure, then add the `hot_reload` option to the `php_server` directive in your `Caddyfile`.
|
||||
To enable hot reloading, enable Mercure, then add the `hot_reload` sub-directive to the `php_server` directive in your `Caddyfile`.
|
||||
|
||||
> [!WARNING]
|
||||
> This feature is intended for **development environments only**.
|
||||
@@ -37,7 +39,24 @@ php_server {
|
||||
}
|
||||
```
|
||||
|
||||
You can also explicitly specify the Mercure topic to use as well as which directories or files to watch by providing paths to the `hot_reload` option:
|
||||
By default, FrankenPHP will watch all files in the current working directory matching this glob pattern: `./**/*.{css,env,gif,htm,html,jpg,jpeg,js,mjs,php,png,svg,twig,webp,xml,yaml,yml}`
|
||||
|
||||
It's possible to explicitly set the files to watch using the glob syntax:
|
||||
|
||||
```caddyfile
|
||||
localhost
|
||||
|
||||
mercure {
|
||||
anonymous
|
||||
}
|
||||
|
||||
root public/
|
||||
php_server {
|
||||
hot_reload src/**/*{.php,.js} config/**/*.yaml
|
||||
}
|
||||
```
|
||||
|
||||
Use the long form to specify the Mercure topic to use as well as which directories or files to watch by providing paths to the `hot_reload` option:
|
||||
|
||||
```caddyfile
|
||||
localhost
|
||||
@@ -50,23 +69,46 @@ root public/
|
||||
php_server {
|
||||
hot_reload {
|
||||
topic hot-reload-topic
|
||||
watch src/
|
||||
watch src/**/*.php
|
||||
watch assets/**/*.{ts,json}
|
||||
watch templates/
|
||||
watch public/js/
|
||||
watch public/css/
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Client-Side Integration
|
||||
|
||||
While the server detects changes, the browser needs to subscribe to these events to update the page.
|
||||
FrankenPHP exposes the Mercure Hub URL to use for the subscribing to file changes via the `$_SERVER['FRANKENPHP_HOT_RELOAD']` environment variable.
|
||||
|
||||
A convenience JavaScript library, [frankenphp-hot-reload](https://www.npmjs.com/package/frankenphp-hot-reload), is also available to handle the client-side logic.
|
||||
To use it, add the following to your main layout:
|
||||
|
||||
```php
|
||||
<!DOCTYPE html>
|
||||
<title>FrankenPHP Hot Reload</title>
|
||||
<?php if (isset($_SERVER['FRANKENPHP_HOT_RELOAD']): ?>
|
||||
<meta name="frankenphp-hot-reload:url" content="<?=$_SERVER['FRANKENPHP_HOT_RELOAD']?>">
|
||||
<script src="https://cdn.jsdelivr.net/npm/idiomorph"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/frankenphp-hot-reload/+esm" type="module"></script>
|
||||
<?php endif ?>
|
||||
```
|
||||
|
||||
The library will automatically subscribe to the Mercure hub, fetch current URL in the background when a file change is detected and morph the DOM.
|
||||
It is available as a [npm](https://www.npmjs.com/package/frankenphp-hot-reload) package and on [GitHub](https://github.com/dunglas/frankenphp-hot-reload).
|
||||
|
||||
Alternatively, you can implement your own client-side logic by subscribing directly to the Mercure hub using the `EventSource` native JavaScript class.
|
||||
|
||||
### Worker Mode
|
||||
|
||||
If you are running your application in [Worker Mode](https://frankenphp.dev/docs/worker/), your application script remains in memory.
|
||||
This means changes to your PHP code will not be reflected immediately, even if the browser reloads.
|
||||
|
||||
For the best developer experience, you should combine `hot_reload` with the `watch` option in the `worker` directive.
|
||||
For the best developer experience, you should combine `hot_reload` with [the `watch` sub-directive in the `worker` directive](config.md#watching-for-file-changes).
|
||||
|
||||
* `hot_reload`: Refreshes the **browser** when files change.
|
||||
* `watch`: Refreshes the **application kernel** (restarts the worker) when files change.
|
||||
* `hot_reload`: refreshes the **browser** when files change
|
||||
* `worker.watch`: restarts the worker when files change
|
||||
|
||||
```caddy
|
||||
localhost
|
||||
@@ -79,36 +121,18 @@ root public/
|
||||
php_server {
|
||||
hot_reload
|
||||
worker {
|
||||
file my_worker.php
|
||||
file /path/to/my_worker.php
|
||||
watch
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Client-Side Integration
|
||||
|
||||
While the server detects changes, the browser needs to subscribe to these events to update the page. FrankenPHP exposes the Mercure Hub URL required for the subscription via the `$_SERVER['FRANKENPHP_HOT_RELOAD']` environment variable.
|
||||
|
||||
You must include the URL in a meta tag and load the FrankenPHP Hot Reload library.
|
||||
|
||||
Add the following to your main layout or HTML template:
|
||||
|
||||
```php
|
||||
<!DOCTYPE html>
|
||||
<title>FrankenPHP Hot Reload</title>
|
||||
<?php if (isset($_SERVER['FRANKENPHP_HOT_RELOAD']): ?>
|
||||
<meta name="frankenphp-hot-reload:url" content="<?=$_SERVER['FRANKENPHP_HOT_RELOAD']?>">
|
||||
<script src="https://cdn.jsdelivr.net/npm/idiomorph"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/frankenphp-hot-reload/+esm" type="module"></script>
|
||||
<?php endif ?>
|
||||
```
|
||||
|
||||
### How it works
|
||||
|
||||
1. **Watch**: FrankenPHP monitors the filesystem for modifications.
|
||||
2. **Restart (Worker Mode)**: If `watch` is enabled in the worker config, the PHP worker is restarted to load the new code.
|
||||
3. **Push**: A payload containing the list of changed files is sent to the built-in Mercure Hub.
|
||||
4. **Receive**: The browser, listening via the JS library, receives the event.
|
||||
1. **Watch**: FrankenPHP monitors the filesystem for modifications using [the `e-dant/watcher` library](https://github.com/e-dant/watcher) under the hood (we contributed the Go binding).
|
||||
2. **Restart (Worker Mode)**: if `watch` is enabled in the worker config, the PHP worker is restarted to load the new code.
|
||||
3. **Push**: a JSON payload containing the list of changed files is sent to the built-in [Mercure hub](https://mercure.rocks).
|
||||
4. **Receive**: The browser, listening via the JavaScript library, receives the Mercure event.
|
||||
5. **Update**:
|
||||
* If **Idiomorph** is detected, it fetches the updated content and morphs the current HTML to match the new state, applying changes instantly without losing state.
|
||||
* Otherwise, `window.location.reload()` is called to refresh the page.
|
||||
|
||||
BIN
docs/hot-reload.png
Normal file
BIN
docs/hot-reload.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 386 KiB |
@@ -35,6 +35,8 @@ The following command will trigger a restart if any file ending in `.php` in the
|
||||
frankenphp php-server --worker /path/to/your/worker/script.php --watch="/path/to/your/app/**/*.php"
|
||||
```
|
||||
|
||||
This feature is often used in combination with [hot reloading](hot-reload.md).
|
||||
|
||||
## Symfony Runtime
|
||||
|
||||
> [!TIP]
|
||||
|
||||
Reference in New Issue
Block a user