From 935c7e5a999d756066fef8cf127880553b4eee20 Mon Sep 17 00:00:00 2001 From: dunglas <57224+dunglas@users.noreply.github.com> Date: Mon, 26 Oct 2026 11:13:43 +0000 Subject: [PATCH] docs: update translations --- docs/cn/security.md | 26 ++++++++++++------------ docs/cn/worker.md | 1 + docs/fr/worker.md | 3 ++- docs/it/worker.md | 37 +++++++++++++++++----------------- docs/ja/security.md | 30 ++++++++++++++-------------- docs/ja/worker.md | 1 + docs/pt-br/worker.md | 32 ++++++++++++++++-------------- docs/ru/security.md | 30 ++++++++++++++-------------- docs/ru/worker.md | 47 ++++++++++++++++++++++++++------------------ docs/tr/worker.md | 11 ++++++----- 10 files changed, 117 insertions(+), 101 deletions(-) diff --git a/docs/cn/security.md b/docs/cn/security.md index 46c0739f93..f38e285c64 100644 --- a/docs/cn/security.md +++ b/docs/cn/security.md @@ -33,27 +33,27 @@ FrankenPHP 在一个包含四个不同参与者的栈中运行: 可信计算基有三项职责。FrankenPHP 中的安全缺陷存在于其中之一: -1. **忠实传输**:将请求映射到 PHP 超全局变量和 php://input 中,并将 PHP 的输出和请求头传回客户端,而不引入注入(请求头/CRLF 注入、请求走私、执行错误文件)。 -2. **隔离**:防止请求范围的状态在不同请求之间、PHP 线程之间以及工作进程迭代之间交叉。 -3. **内存安全**:管理 CGO 边界(Go ↔ C/PHP),不损坏内存。 +1. **忠实传输**:将请求映射到 PHP 超全局变量和 php://input 中,并将 PHP 的输出和请求头传回客户端,而不引入注入(请求头/CRLF 注入、请求走私、执行错误文件)。 +2. **隔离**:防止请求范围的状态在不同请求之间、PHP 线程之间以及工作进程迭代之间交叉。 +3. **内存安全**:管理 CGO 边界(Go ↔ C/PHP),不损坏内存。 ## 范围:FrankenPHP 自身的攻击面 以下是 FrankenPHP 拥有的攻击面。这里的漏洞是 FrankenPHP 的漏洞: -- **请求到超全局变量映射**(`cgi.go`、`frankenphp_register_server_vars`):从请求构建 `$_SERVER`、`REMOTE_ADDR`、`SCRIPT_NAME`、`PATH_INFO` 和其他 CGI 变量。 -- **PHP 脚本路径解析**:请求路径在 `split_path`(默认为 `.php`)处被分割为 `SCRIPT_NAME` / `PATH_INFO`,然后通过 `sanitizedPathJoin`(`filepath.Join(root, filepath.Clean("/"+reqPath))`)与文档根目录连接,这可以防止 `SCRIPT_FILENAME` 逃逸文档根目录(路径遍历)。`php_server` 指令还会额外设置一个默认的 `try_files` 重写规则,将请求路由到现有文件或前端控制器,从而缓解了 PHP-FPM 经典陷阱——执行错误文件的问题。 -- **工作模式状态隔离**:FrankenPHP 在请求之间重置 `$_GET`、`$_POST`、`$_COOKIE`、`$_FILES`、`$_SERVER` 和 `$_REQUEST`,显式清除 `$_SESSION`(否则会在请求之间泄露),以及 `error_get_last()` 和 `libxml_get_errors()` 返回的错误,`http_get_last_response_headers()` 返回的请求头,`strtok()` 状态,以及 `output_add_rewrite_var()` 添加的变量,但 **`$_ENV` 不会被重置**,并且 `putenv()` 写入、`static` 变量、类静态属性、全局变量和运行时引擎设置(`ini_set()`、默认流上下文、默认时区、工作目录等)会在同一线程的请求之间持久存在。留在该状态中的请求或用户特定数据可能会泄露到后续请求中(参见 [工作模式](worker.md#state-persistence))。 -- **每线程环境沙盒**:`frankenphp_putenv()` / `frankenphp_getenv()` 操作的是线程本地的 `sandboxed_env`。`putenv()` 写入保留在该沙盒内,绝不会到达进程全局的操作系统环境,因此一个请求设置的秘密不会泄露给子进程(`proc_open`、`exec` 等)、Go/Caddy 端或其他请求。必须看到此类变量的子进程必须通过 `proc_open()` 或 `exec()` 的环境参数明确地提供给它(参见 [内部原理](internals.md#per-thread-environment-sandboxing))。 -- **CGO 内存边界**:Go 字符串固定以及 `C.CString()` / `free()` 在 Go ↔ C 边界上的生命周期。 -- **Caddy 管理 API**:`/frankenphp/workers/restart` 和 `/frankenphp/threads` 端点,通过 Caddy 的管理 API(默认监听 `localhost:2019`)暴露。将该端点暴露到 localhost 之外是操作员的决定。 -- **受信任代理处理**:传入的 `X-Forwarded-*` 请求头总是作为不可信的 `$_SERVER['HTTP_X_FORWARDED_*']` 值到达 PHP;只有当配置了 [`trusted_proxies`](production.md#running-behind-a-reverse-proxy) 时,它们才被信任用于推导真实的客户端 IP 和协议。 -- **慢速请求体**:客户端宣布请求体后,如果缓慢发送或停滞,会长时间占用处理线程。在一个有界线程池中,足够多的此类连接会耗尽线程池(慢速 POST DoS)。FrankenPHP 默认对请求体读取应用 60 秒的空闲超时([`request_body_timeout`](config.md#caddyfile-config)),并在每次读取前重置截止时间,这样任何大小的稳定上传都能成功,而停滞的上传会被切断并释放线程。 +- **请求到超全局变量映射**(`cgi.go`、`frankenphp_register_server_vars`):从请求构建 `$_SERVER`、`REMOTE_ADDR`、`SCRIPT_NAME`、`PATH_INFO` 和其他 CGI 变量。 +- **PHP 脚本路径解析**:请求路径在 `split_path`(默认为 `.php`)处被分割为 `SCRIPT_NAME` / `PATH_INFO`,然后通过 `sanitizedPathJoin`(`filepath.Join(root, filepath.Clean("/"+reqPath))`)与文档根目录连接,这可以防止 `SCRIPT_FILENAME` 逃逸文档根目录(路径遍历)。`php_server` 指令还会额外设置一个默认的 `try_files` 重写规则,将请求路由到现有文件或前端控制器,从而缓解了 PHP-FPM 经典陷阱——执行错误文件的问题。 +- **工作模式状态隔离**:FrankenPHP 在请求之间重置 `$_GET`、`$_POST`、`$_COOKIE`、`$_FILES`、`$_SERVER` 和 `$_REQUEST`,显式清除 `$_SESSION`(否则会在请求之间泄露),以及 `error_get_last()` 和 `libxml_get_errors()` 返回的错误,`http_get_last_response_headers()` 返回的请求头,`strtok()` 状态,以及 `output_add_rewrite_var()` 添加的变量,但 **`$_ENV` 不会被重置**,并且 `putenv()` 写入、`static` 变量、类静态属性、全局变量和运行时引擎设置(`ini_set()`、默认流上下文、默认时区、工作目录等)会在同一线程的请求之间持久存在。留在该状态中的请求或用户特定数据可能会泄露到后续请求中(参见 [工作模式](worker.md#state-persistence))。 +- **每线程环境沙盒**:`frankenphp_putenv()` / `frankenphp_getenv()` 操作的是线程本地的 `sandboxed_env`。`putenv()` 写入保留在该沙盒内,绝不会到达进程全局的操作系统环境,因此一个请求设置的秘密不会泄露给子进程(`proc_open`、`exec` 等)、Go/Caddy 端或其他请求。必须看到此类变量的子进程必须通过 `proc_open()` 或 `exec()` 的环境参数明确地提供给它(参见 [内部原理](internals.md#per-thread-environment-sandboxing))。 +- **CGO 内存边界**:Go 字符串固定以及 `C.CString()` / `free()` 在 Go ↔ C 边界上的生命周期。 +- **Caddy 管理 API**:`/frankenphp/workers/restart` 和 `/frankenphp/threads` 端点,通过 Caddy 的管理 API(默认监听 `localhost:2019`)暴露。将该端点暴露到 localhost 之外是操作员的决定。 +- **受信任代理处理**:传入的 `X-Forwarded-*` 请求头总是作为不可信的 `$_SERVER['HTTP_X_FORWARDED_*']` 值到达 PHP;只有当配置了 [`trusted_proxies`](production.md#running-behind-a-reverse-proxy) 时,它们才被信任用于推导真实的客户端 IP 和协议。 +- **慢速请求体**:客户端宣布请求体后,如果缓慢发送或停滞,会长时间占用处理线程。在一个有界线程池中,足够多的此类连接会耗尽线程池(慢速 POST DoS)。FrankenPHP 默认对请求体读取应用 60 秒的空闲超时([`request_body_timeout`](config.md#caddyfile-config)),并在每次读取前重置截止时间,这样任何大小的稳定上传都能成功,而停滞的上传会被切断并释放线程。 ## 范围之外 -- **应用程序 PHP 代码中的漏洞**(SQL 注入、XSS、不安全的反序列化等)。FrankenPHP 将不可信的请求数据原封不动地传递给应用程序;防御这些漏洞是应用程序的职责,就像任何 SAPI 一样。 -- **FrankenPHP 使用的上游组件(PHP、Caddy、Go)或在其之上构建的项目(Laravel Octane、Symfony Runtime)中的缺陷。** 请将这些报告给相关项目。 +- **应用程序 PHP 代码中的漏洞**(SQL 注入、XSS、不安全的反序列化等)。FrankenPHP 将不可信的请求数据原封不动地传递给应用程序;防御这些漏洞是应用程序的职责,就像任何 SAPI 一样。 +- **FrankenPHP 使用的上游组件(PHP、Caddy、Go)或在其之上构建的项目(Laravel Octane、Symfony Runtime)中的缺陷。** 请将这些报告给相关项目。 ## 报告漏洞 diff --git a/docs/cn/worker.md b/docs/cn/worker.md index 1de9ab52ce..6c4f864455 100644 --- a/docs/cn/worker.md +++ b/docs/cn/worker.md @@ -241,6 +241,7 @@ $handler = static function () use ($workerServer) { - **全局变量**:worker 脚本全局范围内的变量在请求之间持久化。 - **内存缓存**:在请求处理器之外存储在内存中的任何数据(数组、对象)都将持久化。 - **运行时引擎设置**:使用 `ini_set()`、`stream_context_set_default()`、`date_default_timezone_set()`、`chdir()`、`stream_wrapper_register()`、`set_error_handler()` 或 `set_exception_handler()` 进行的更改对后续请求仍然有效。切勿在此处存储与请求或用户相关的特定值,例如默认流上下文中的凭据:请为每个调用传递一个显式上下文。 +- **进程范围设置**:`umask()` 和 `setlocale()` 会更改整个 FrankenPHP 进程,而不仅仅是当前线程。Worker 模式不会在请求之间恢复它们,并且在任何模式下它们也会影响同时运行的请求。请在启动时设置一次,或者对创建的文件调用 `chmod()` 而不是更改 umask。 这是设计使然,也是 worker 模式快速的原因。然而,它需要注意避免意外的副作用: diff --git a/docs/fr/worker.md b/docs/fr/worker.md index 8e3c167485..3d177a8782 100644 --- a/docs/fr/worker.md +++ b/docs/fr/worker.md @@ -119,7 +119,7 @@ docker run \ Si votre application utilise [PSR-15](https://www.php-fig.org/psr/psr-15/) au lieu des superglobales, convertissez la requête/réponse aux limites du handler avec [`nyholm/psr7`](https://github.com/Nyholm/psr7) et [`nyholm/psr7-server`](https://github.com/Nyholm/psr7-server) : -```bash +```console composer require nyholm/psr7 nyholm/psr7-server psr/http-server-handler ``` @@ -244,6 +244,7 @@ Parce que le mode worker maintient le processus PHP en vie entre les requêtes, - **Variables globales** : Les variables dans la portée globale du script worker persistent entre les requêtes. - **Caches en mémoire** : Toute donnée stockée en mémoire (tableaux, objets) en dehors du gestionnaire de requêtes persiste. - **Paramètres du moteur d'exécution** : Les modifications effectuées avec `ini_set()`, `stream_context_set_default()`, `date_default_timezone_set()`, `chdir()`, `stream_wrapper_register()`, `set_error_handler()` ou `set_exception_handler()` restent en vigueur pour les requêtes ultérieures. Ne stockez jamais de valeurs spécifiques à la requête ou à l'utilisateur, telles que des identifiants dans le contexte de flux par défaut : passez plutôt un contexte explicite à chaque appel. +- **Paramètres à l'échelle du processus** : `umask()` et `setlocale()` modifient l'ensemble du processus FrankenPHP, pas seulement le thread actuel. Le mode worker ne les restaure pas entre les requêtes, et dans tous les modes, ils affectent également les requêtes exécutées simultanément. Définissez-les une fois au démarrage, ou appelez `chmod()` sur les fichiers créés au lieu de modifier l'umask. C'est un comportement intentionnel et c'est ce qui rend le mode worker rapide. Cependant, cela demande de l'attention pour éviter les effets secondaires involontaires : diff --git a/docs/it/worker.md b/docs/it/worker.md index ad9b625256..c8dd4d97cd 100644 --- a/docs/it/worker.md +++ b/docs/it/worker.md @@ -5,14 +5,14 @@ description: Esegui FrankenPHP in modalità worker per mantenere la tua applicaz # Utilizzare i worker di FrankenPHP -Avviare l'applicazione una volta e mantenerla in memoria. +Avvia la tua applicazione una volta e mantienila in memoria. FrankenPHP gestirà le richieste in arrivo in pochi millisecondi. ## Avvio degli script worker di FrankenPHP ### Esecuzione di un worker FrankenPHP con Docker -Impostare il valore della variabile di ambiente `FRANKENPHP_CONFIG` su `worker /path/to/your/worker/script.php`: +Imposta il valore della variabile di ambiente `FRANKENPHP_CONFIG` su `worker /path/to/your/worker/script.php`: ```bash docker run \ @@ -24,27 +24,27 @@ docker run \ ### Esecuzione di un worker FrankenPHP con il binario autonomo -Utilizzare l'opzione `--worker` del comando `php-server` per servire il contenuto della cartella corrente utilizzando un worker: +Usa l'opzione `--worker` del comando `php-server` per servire il contenuto della directory corrente utilizzando un worker: ```bash frankenphp php-server --worker /path/to/your/worker/script.php ``` -Se l'app PHP è [incorporata nel binario](embed.md), si può aggiungere un `Caddyfile` personalizzato nella cartella principale dell'app. +Se la tua app PHP è [incorporata nel binario](embed.md), puoi aggiungere un `Caddyfile` personalizzato nella directory radice dell'app. Verrà utilizzato automaticamente. -È anche possibile [riavviare il worker in caso di modifiche al file](config.md#watching-for-file-changes) con l'opzione `--watch`. -Il seguente comando attiverà un riavvio se qualsiasi file che termina con `.php` nella cartella o nelle sottocartelle `/path/to/your/app/` viene modificato: +È anche possibile [riavviare il worker in caso di modifiche ai file](config.md#monitorare-le-modifiche-ai-file) con l'opzione `--watch`. +Il seguente comando attiverà un riavvio se qualsiasi file che termina con `.php` nella directory `/path/to/your/app/` o nelle sue sottodirectory viene modificato: ```bash frankenphp php-server --worker /path/to/your/worker/script.php --watch="/path/to/your/app/**/*.php" ``` -Questa funzione viene spesso utilizzata in combinazione con [ricaricamento a caldo](hot-reload.md). +Questa funzione viene spesso utilizzata in combinazione con il [ricaricamento a caldo](hot-reload.md). ## Modalità worker per Symfony -Vedi [la documentazione sulla modalità worker di FrankenPHP con Symfony](symfony.md#symfony-worker-mode-with-frankenphp). +Vedi [la documentazione sulla modalità worker di FrankenPHP con Symfony](symfony.md#symfony-worker-mode-con-frankenphp). ## Modalità worker per Laravel Octane @@ -52,7 +52,7 @@ Vedi [la documentazione di FrankenPHP Laravel Octane](laravel.md#laravel-octane) ## Scrittura di uno script worker FrankenPHP personalizzato -L'esempio seguente mostra come creare il proprio script worker senza fare affidamento su una libreria di terze parti: +L'esempio seguente mostra come creare il tuo script worker senza fare affidamento su una libreria di terze parti: ```php boot(); -// Gestore fuori dal ciclo per migliori prestazioni (meno lavoro per richiesta) +// Gestore fuori dal ciclo per migliori prestazioni (meno lavoro) $handler = static function () use ($myApp) { try { - // Chiamato quando arriva una richiesta, + // Chiamato quando viene ricevuta una richiesta, // i superglobali, php://input e simili vengono reimpostati echo $myApp->handle($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER); } catch (\Throwable $exception) { @@ -84,7 +84,7 @@ for ($nbRequests = 0; !$maxRequests || $nbRequests < $maxRequests; ++$nbRequests // Esegui qualcosa dopo aver inviato la risposta HTTP $myApp->terminate(); - // Richiama il garbage collector per ridurre la probabilità che parta durante la generazione di una pagina + // Richiama il garbage collector per ridurre la probabilità che venga attivato durante la generazione di una pagina gc_collect_cycles(); if (!$keepRunning) break; @@ -94,7 +94,7 @@ for ($nbRequests = 0; !$maxRequests || $nbRequests < $maxRequests; ++$nbRequests $myApp->shutdown(); ``` -Quindi, avviare l'app e utilizzare la variabile di ambiente `FRANKENPHP_CONFIG` per configurare il worker: +Quindi, avvia la tua app e utilizza la variabile di ambiente `FRANKENPHP_CONFIG` per configurare il tuo worker: ```bash docker run \ @@ -165,16 +165,16 @@ for ($nbRequests = 0; !$maxRequests || $nbRequests < $maxRequests; ++$nbRequests ### Riavvia il worker dopo un certo numero di richieste -Poiché PHP non è stato originariamente progettato per processi di lunga durata, molte librerie e codici legacy perdono ancora memoria. +Poiché PHP non è stato originariamente progettato per processi di lunga durata, molte librerie e codice legacy perdono ancora memoria. Una soluzione alternativa all'utilizzo di questo tipo di codice in modalità worker consiste nel riavviare lo script worker dopo aver elaborato un certo numero di richieste: Il precedente script worker consente di configurare un numero massimo di richieste da gestire impostando una variabile di ambiente denominata `MAX_REQUESTS`. ### Riavvia i worker manualmente -Sebbene sia possibile riavviare i worker [in seguito alle modifiche dei file](config.md#watching-for-file-changes), è anche possibile riavviare tutti i worker +Sebbene sia possibile riavviare i worker [in seguito alle modifiche dei file](config.md#monitorare-le-modifiche-ai-file), è anche possibile riavviare tutti i worker in modo elegante tramite l'[API di amministrazione Caddy](https://caddyserver.com/docs/api). Se l'amministratore è abilitato nel tuo -[Caddyfile](config.md#caddyfile-config), si può eseguire il ping dell'endpoint di riavvio con una semplice richiesta POST: +[Caddyfile](config.md#configurazione-caddyfile), puoi eseguire il ping dell'endpoint di riavvio con una semplice richiesta POST: ```bash curl -X POST http://localhost:2019/frankenphp/workers/restart @@ -183,12 +183,12 @@ curl -X POST http://localhost:2019/frankenphp/workers/restart ### Fallimenti dei worker Se uno script worker si blocca con un codice di uscita diverso da zero, FrankenPHP lo riavvierà con una strategia di backoff esponenziale. -Se lo script worker rimane attivo più a lungo dell'ultimo backoff moltiplicato per due, +Se lo script worker rimane attivo più a lungo dell'ultimo backoff × 2, non penalizzerà lo script worker e lo riavvierà di nuovo. Tuttavia, se lo script worker continua a fallire con un codice di uscita diverso da zero in un breve periodo di tempo (ad esempio, avendo un errore di battitura in uno script), FrankenPHP si bloccherà con l'errore: `too many consecutive failures`. -Il numero di errori consecutivi può essere configurato nel tuo [Caddyfile](config.md#caddyfile-config) con l'opzione `max_consecutive_failures`: +Il numero di errori consecutivi può essere configurato nel tuo [Caddyfile](config.md#configurazione-caddyfile) con l'opzione `max_consecutive_failures`: ```caddyfile frankenphp { @@ -243,6 +243,7 @@ Poiché la modalità worker mantiene attivo il processo PHP tra le richieste, il - **Variabili globali**: le variabili nell'ambito globale dello script worker persistono tra le richieste. - **Cache in memoria**: tutti i dati archiviati in memoria (array, oggetti) all'esterno del gestore delle richieste persistono. - **Impostazioni del motore di runtime**: le modifiche apportate con `ini_set()`, `stream_context_set_default()`, `date_default_timezone_set()`, `chdir()`, `stream_wrapper_register()`, `set_error_handler()` o `set_exception_handler()` rimangono in vigore per le richieste successive. Non archiviare mai valori specifici della richiesta o dell'utente in queste impostazioni, come le credenziali nel contesto del flusso predefinito: passa invece un contesto esplicito ad ogni chiamata. +- **Impostazioni a livello di processo**: `umask()` e `setlocale()` modificano l'intero processo FrankenPHP, non solo il thread corrente. La modalità worker non li ripristina tra le richieste, e in ogni modalità influenzano anche le richieste in esecuzione contemporaneamente. Impostali una volta all'avvio, o chiama `chmod()` sui file creati invece di modificare la umask. Questo è previsto dalla progettazione ed è ciò che rende veloce la modalità worker. Tuttavia, richiede attenzione per evitare effetti collaterali indesiderati: diff --git a/docs/ja/security.md b/docs/ja/security.md index 590e668fa3..0ebde38ccf 100644 --- a/docs/ja/security.md +++ b/docs/ja/security.md @@ -26,8 +26,8 @@ FrankenPHP は、4 つの異なるアクターを持つスタックで動作し これは最も重要な区別であり、「PHP を信頼すべきか否か?」という混乱のほとんどを解消するものです。 -- **コードの出所は信頼されています。** FrankenPHP は、オペレーターによってデプロイされた PHP ファイル(ドキュメントルート下で解決されるスクリプト、または設定されたワーカー スクリプト)のみを実行します。リクエスト自体に含まれるコード(ボディ、クエリ文字列、ヘッダー)は決して評価しません。SAPI 境界は信頼されていない*コード*ではなく、*データ*を伝達します。 -- **リクエストデータは汚染されています。** PHP コードがリクエストから読み取るすべてのもの(`$_GET`、`$_POST`、`$_COOKIE`、`$_FILES`、`$_SERVER`、`php://input`)は、他の PHP SAPI と同様に信頼されていません。これをサニタイズするのはアプリケーションの仕事です。 +- **コードの出所は信頼されています。** FrankenPHP は、オペレーターによってデプロイされた PHP ファイル(ドキュメントルート下で解決されるスクリプト、または設定されたワーカー スクリプト)のみを実行します。リクエスト自体に含まれるコード(ボディ、クエリ文字列、ヘッダー)は決して評価しません。SAPI 境界は信頼されていない*コード*ではなく、*データ*を伝達します。 +- **リクエストデータは汚染されています。** PHP コードがリクエストから読み取るすべてのもの(`$_GET`、`$_POST`、`$_COOKIE`、`$_FILES`、`$_SERVER`、`php://input`)は、他の PHP SAPI と同様に信頼されていません。これをサニタイズするのはアプリケーションの仕事です。 したがって、「PHP から来るものは信頼できる」というは*コード*については真であり、「SAPI は信頼されていない入力を運ぶ」というのは*データ*については真です。この 2 つは矛盾しません。 FrankenPHP の役割は、その汚染されたデータを忠実に運び、あるリクエストのデータが別のリクエストに漏洩するのを防ぐことです。 @@ -36,27 +36,27 @@ FrankenPHP の役割は、その汚染されたデータを忠実に運び、あ 信頼できるコンピューティングベースには 3 つの役割があります。FrankenPHP のセキュリティ上の欠陥は、そのいずれかに存在します。 -1. **忠実な転送**: リクエストを PHP のスーパーグローバル変数と `php://input` にマッピングし、PHP の出力とヘッダーをクライアントに返送します。その際、インジェクション(ヘッダー/CRLF インジェクション、リクエスト密輸、誤ったファイルの実行)を引き起こさないようにします。 -2. **分離**: リクエストスコープの状態が、リクエスト間、PHP スレッド間、およびワーカーのイテレーション間で交差するのを防ぎます。 -3. **メモリ安全性**: CGO 境界(Go ↔ C/PHP)をメモリを破損することなく管理します。 +1. **忠実な転送**: リクエストを PHP のスーパーグローバル変数と `php://input` にマッピングし、PHP の出力とヘッダーをクライアントに返送します。その際、インジェクション(ヘッダー/CRLF インジェクション、リクエスト密輸、誤ったファイルの実行)を引き起こさないようにします。 +2. **分離**: リクエストスコープの状態が、リクエスト間、PHP スレッド間、およびワーカーのイテレーション間で交差するのを防ぎます。 +3. **メモリ安全性**: CGO 境界(Go ↔ C/PHP)をメモリを破損することなく管理します。 ## 適用範囲: FrankenPHP 自身の攻撃対象領域 これらは FrankenPHP が所有する領域です。ここでの脆弱性は FrankenPHP の脆弱性となります。 -- **リクエストからスーパーグローバルへのマッピング** (`cgi.go`、`frankenphp_register_server_vars`):`$_SERVER`、`REMOTE_ADDR`、`SCRIPT_NAME`、`PATH_INFO`、およびその他の CGI 変数をリクエストから構築します。 -- **PHP スクリプトパスの解決**:リクエストパスは `split_path` (デフォルトでは `.php`) で `SCRIPT_NAME` / `PATH_INFO` に分割され、その後 `sanitizedPathJoin` (`filepath.Join(root, filepath.Clean("/"+reqPath))`) を使用してドキュメントルートに結合されます。これにより、`SCRIPT_FILENAME` がドキュメントルートから逸脱するのを防ぎます(パストラバーサル)。また、`php_server` ディレクティブは、既存のファイルまたはフロントコントローラーにリクエストをルーティングするデフォルトの `try_files` リライトを設定し、誤ったファイルを実行するという従来の PHP-FPM の落とし穴を軽減します。 -- **ワーカーモードの状態分離**:FrankenPHP は、リクエスト間で `$_GET`、`$_POST`、`$_COOKIE`、`$_FILES`、`$_SERVER`、`$_REQUEST` をリセットし、`$_SESSION`(さもなければリクエスト間で漏洩する)および `error_get_last()` と `libxml_get_errors()` によって返されるエラー、`http_get_last_response_headers()` によって返されるヘッダー、`strtok()` の状態、`output_add_rewrite_var()` によって追加された変数を明示的にクリアします。しかし、**`$_ENV` はリセットされず**、`putenv()` による書き込み、`static` 変数、クラスの静的プロパティ、グローバル変数、およびランタイムエンジン設定(`ini_set()`、デフォルトのストリームコンテキスト、デフォルトのタイムゾーン、作業ディレクトリなど)は、同じスレッド上のリクエスト間で永続化します。その状態に残されたリクエストまたはユーザー固有のデータは、その後のリクエストに漏洩する可能性があります([ワーカーモード](worker.md#state-persistence)を参照)。 -- **スレッドごとの環境サンドボックス**:`frankenphp_putenv()` / `frankenphp_getenv()` はスレッドローカルな `sandboxed_env` 上で動作します。`putenv()` による書き込みはそのサンドボックス内に留まり、プロセスグローバルな OS 環境には決して到達しません。そのため、あるリクエストによって設定された秘密が子プロセス(`proc_open`、`exec` など)、Go/Caddy 側、または他のリクエストに漏洩することはありません。そのような変数を見る必要がある子プロセスには、`proc_open()` または `exec()` の環境引数を通じて明示的に与える必要があります([内部構造](internals.md#per-thread-environment-sandboxing)を参照)。 -- **CGO メモリ境界**:Go ↔ C 境界における Go 文字列のピン留めと `C.CString()` / `free()` のライフタイム。 -- **Caddy 管理 API**:Caddy の管理 API(デフォルトでは `localhost:2019` でリッスン)を通じて公開される `/frankenphp/workers/restart` および `/frankenphp/threads` エンドポイント。このエンドポイントを localhost 以外に公開するかどうかはオペレーターの判断です。 -- **信頼されたプロキシ処理**:受信する `X-Forwarded-*` ヘッダーは常に汚染された `$_SERVER['HTTP_X_FORWARDED_*']` 値として PHP に到達します。これらは、[`trusted_proxies`](production.md#running-behind-a-reverse-proxy) が設定されている場合にのみ、実際のクライアント IP とスキームを導出するために信頼されます。 -- **遅いリクエストボディ**:ボディをアナウンスした後にデータを少量ずつ送ったり停止させたりするクライアントは、処理スレッドをその間ずっと保持します。制限されたスレッドプールでは、このような接続が十分に多くなるとプールを使い果たしてしまいます(Slow-POST DoS)。FrankenPHP は、デフォルトでボディの読み取りに 60 秒のアイドルタイムアウト([`request_body_timeout`](config.md#caddyfile-config))を適用します。これにより、各読み取り前にデッドラインがリセットされるため、任意のサイズの安定したアップロードは成功し、停止したものは切断されてスレッドが解放されます。 +- **リクエストからスーパーグローバルへのマッピング** (`cgi.go`、`frankenphp_register_server_vars`):`$_SERVER`、`REMOTE_ADDR`、`SCRIPT_NAME`、`PATH_INFO`、およびその他の CGI 変数をリクエストから構築します。 +- **PHP スクリプトパスの解決**:リクエストパスは `split_path` (デフォルトでは `.php`) で `SCRIPT_NAME` / `PATH_INFO` に分割され、その後 `sanitizedPathJoin` (`filepath.Join(root, filepath.Clean("/"+reqPath))`) を使用してドキュメントルートに結合されます。これにより、`SCRIPT_FILENAME` がドキュメントルートから逸脱するのを防ぎます(パストラバーサル)。また、`php_server` ディレクティブは、既存のファイルまたはフロントコントローラーにリクエストをルーティングするデフォルトの `try_files` リライトを設定し、誤ったファイルを実行するという従来の PHP-FPM の落とし穴を軽減します。 +- **ワーカーモードの状態分離**:FrankenPHP は、リクエスト間で `$_GET`、`$_POST`、`$_COOKIE`、`$_FILES`、`$_SERVER`、`$_REQUEST` をリセットし、`$_SESSION`(さもなければリクエスト間で漏洩する)および `error_get_last()` と `libxml_get_errors()` によって返されるエラー、`http_get_last_response_headers()` によって返されるヘッダー、`strtok()` の状態、`output_add_rewrite_var()` によって追加された変数を明示的にクリアします。しかし、**`$_ENV` はリセットされず**、`putenv()` による書き込み、`static` 変数、クラスの静的プロパティ、グローバル変数、およびランタイムエンジン設定(`ini_set()`、デフォルトのストリームコンテキスト、デフォルトのタイムゾーン、作業ディレクトリなど)は、同じスレッド上のリクエスト間で永続化します。その状態に残されたリクエストまたはユーザー固有のデータは、その後のリクエストに漏洩する可能性があります([ワーカーモード](worker.md#state-persistence)を参照)。 +- **スレッドごとの環境サンドボックス**:`frankenphp_putenv()` / `frankenphp_getenv()` はスレッドローカルな `sandboxed_env` 上で動作します。`putenv()` による書き込みはそのサンドボックス内に留まり、プロセスグローバルな OS 環境には決して到達しません。そのため、あるリクエストによって設定された秘密が子プロセス(`proc_open`、`exec` など)、Go/Caddy 側、または他のリクエストに漏洩することはありません。そのような変数を見る必要がある子プロセスには、`proc_open()` または `exec()` の環境引数を通じて明示的に与える必要があります([内部構造](internals.md#per-thread-environment-sandboxing)を参照)。 +- **CGO メモリ境界**:Go ↔ C 境界における Go 文字列のピン留めと `C.CString()` / `free()` のライフタイム。 +- **Caddy 管理 API**:Caddy の管理 API(デフォルトでは `localhost:2019` でリッスン)を通じて公開される `/frankenphp/workers/restart` および `/frankenphp/threads` エンドポイント。このエンドポイントを localhost 以外に公開するかどうかはオペレーターの判断です。 +- **信頼されたプロキシ処理**:受信する `X-Forwarded-*` ヘッダーは常に汚染された `$_SERVER['HTTP_X_FORWARDED_*']` 値として PHP に到達します。これらは、[`trusted_proxies`](production.md#running-behind-a-reverse-proxy) が設定されている場合にのみ、実際のクライアント IP とスキームを導出するために信頼されます。 +- **遅いリクエストボディ**:ボディをアナウンスした後にデータを少量ずつ送ったり停止させたりするクライアントは、処理スレッドをその間ずっと保持します。制限されたスレッドプールでは、このような接続が十分に多くなるとプールを使い果たしてしまいます(Slow-POST DoS)。FrankenPHP は、デフォルトでボディの読み取りに 60 秒のアイドルタイムアウト([`request_body_timeout`](config.md#caddyfile-config))を適用します。これにより、各読み取り前にデッドラインがリセットされるため、任意のサイズの安定したアップロードは成功し、停止したものは切断されてスレッドが解放されます。 ## 適用範囲外 -- **アプリケーションの PHP コードの脆弱性**(SQLインジェクション、XSS、安全でないデシリアライゼーションなど)。FrankenPHP は、信頼されていないリクエストデータをアプリケーションにそのまま渡します。これに対する防御は、他の SAPI と同様に、アプリケーションの責任です。 -- FrankenPHP が使用する**アップストリームコンポーネントの欠陥**(PHP、Caddy、Go)、またはその上に構築されたプロジェクト(Laravel Octane、Symfony Runtime)の欠陥。これらは関連するプロジェクトに報告してください。 +- **アプリケーションの PHP コードの脆弱性**(SQLインジェクション、XSS、安全でないデシリアライゼーションなど)。FrankenPHP は、信頼されていないリクエストデータをアプリケーションにそのまま渡します。これに対する防御は、他の SAPI と同様に、アプリケーションの責任です。 +- FrankenPHP が使用する**アップストリームコンポーネントの欠陥**(PHP、Caddy、Go)、またはその上に構築されたプロジェクト(Laravel Octane、Symfony Runtime)の欠陥。これらは関連するプロジェクトに報告してください。 ## 脆弱性の報告 diff --git a/docs/ja/worker.md b/docs/ja/worker.md index aae5cf4c04..784d78e953 100644 --- a/docs/ja/worker.md +++ b/docs/ja/worker.md @@ -243,6 +243,7 @@ $handler = static function () use ($workerServer) { - **グローバル変数**: ワーカー スクリプトのグローバルスコープ内の変数はリクエスト間で永続します。 - **インメモリキャッシュ**: リクエストハンドラーの外部にメモリ(配列、オブジェクト)に保存されたデータは永続します。 - **ランタイムエンジン設定**: `ini_set()`、`stream_context_set_default()`、`date_default_timezone_set()`、`chdir()`、`stream_wrapper_register()`、`set_error_handler()`、または`set_exception_handler()`で行われた変更は、それ以降のリクエストでも有効なままになります。デフォルトのストリームコンテキストに資格情報などのリクエスト固有またはユーザー固有の値を保存しないでください。代わりに、各呼び出しに明示的なコンテキストを渡してください。 +- **プロセス全体の設定**: `umask()`と`setlocale()`は、現在のスレッドだけでなくFrankenPHPプロセス全体を変更します。ワーカーモードではこれらの設定がリクエスト間で復元されることはなく、どのモードにおいても同時に実行されているリクエストに影響を与えます。起動時に一度設定するか、umaskを変更する代わりに作成されたファイルに対して`chmod()`を呼び出してください。 これは意図された設計であり、ワーカーモードを高速にする要因です。ただし、意図しない副作用を避けるためには注意が必要です: diff --git a/docs/pt-br/worker.md b/docs/pt-br/worker.md index f8d834816f..6fd86e78e6 100644 --- a/docs/pt-br/worker.md +++ b/docs/pt-br/worker.md @@ -58,21 +58,21 @@ O exemplo a seguir mostra como criar seu próprio script de worker sem depender boot(); -// Handler outside the loop for better performance (doing less work) +// Manipulador fora do loop para melhor desempenho (fazendo menos trabalho) $handler = static function () use ($myApp) { try { - // Called when a request is received, - // superglobals, php://input and the like are reset + // Chamado quando uma requisição é recebida, + // superglobais, php://input e similares são redefinidos echo $myApp->handle($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER); } catch (\Throwable $exception) { - // `set_exception_handler` is called only when the worker script ends, - // which may not be what you expect, so catch and handle exceptions here + // `set_exception_handler` é chamado apenas quando o script do worker termina, + // o que pode não ser o que você espera, então capture e trate as exceções aqui (new \MyCustomExceptionHandler)->handleException($exception); } }; @@ -81,16 +81,16 @@ $maxRequests = (int)($_SERVER['MAX_REQUESTS'] ?? 0); for ($nbRequests = 0; !$maxRequests || $nbRequests < $maxRequests; ++$nbRequests) { $keepRunning = \frankenphp_handle_request($handler); - // Do something after sending the HTTP response + // Faça algo depois de enviar a resposta HTTP $myApp->terminate(); - // Call the garbage collector to reduce the chances of it being triggered in the middle of a page generation + // Chame o coletor de lixo para reduzir as chances de ele ser acionado no meio de uma geração de página gc_collect_cycles(); if (!$keepRunning) break; } -// Cleanup +// Limpeza $myApp->shutdown(); ``` @@ -132,7 +132,7 @@ require __DIR__.'/vendor/autoload.php'; use Nyholm\Psr7\Factory\Psr17Factory; use Nyholm\Psr7Server\ServerRequestCreator; -$myApp = new \App\Kernel(); // implements Psr\Http\Server\RequestHandlerInterface +$myApp = new \App\Kernel(); // implementa Psr\Http\Server\RequestHandlerInterface $myApp->boot(); $psr17Factory = new Psr17Factory(); @@ -203,6 +203,7 @@ frankenphp { Quando o modo worker está habilitado, um thread adicional é necessário para lidar com as requisições recebidas, portanto, o valor padrão de `num_threads` é `1 + 2x(número de CPUs disponíveis)`. + Assim, nesse modo, se `num_threads` e `num` forem definidos explicitamente, `num_threads` deve ser estritamente maior que `num`. ## Comportamento das superglobais @@ -217,12 +218,12 @@ Para acessar as superglobais do script de worker dentro do retorno de chamada, v ```php boot(); -// Обработчик запросов за пределами цикла для повышения производительности (выполняет меньше работы) +// Обработчик за пределами цикла для лучшей производительности (выполняет меньше работы) $handler = static function () use ($myApp) { try { - // Выполняется при получении запроса, - // суперглобальные переменные, php://input и прочие сбрасываются + // Вызывается при получении запроса, + // суперглобальные переменные, php://input и подобные сбрасываются echo $myApp->handle($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER); } catch (\Throwable $exception) { // `set_exception_handler` вызывается только когда worker-скрипт завершается, @@ -81,10 +81,10 @@ $maxRequests = (int)($_SERVER['MAX_REQUESTS'] ?? 0); for ($nbRequests = 0; !$maxRequests || $nbRequests < $maxRequests; ++$nbRequests) { $keepRunning = \frankenphp_handle_request($handler); - // Действия после отправки HTTP-ответа + // Сделайте что-либо после отправки HTTP-ответа $myApp->terminate(); - // Вызов сборщика мусора, чтобы снизить вероятность его запуска в процессе генерации страницы + // Вызовите сборщик мусора, чтобы уменьшить вероятность его запуска в середине генерации страницы gc_collect_cycles(); if (!$keepRunning) break; @@ -104,7 +104,8 @@ docker run \ dunglas/frankenphp ``` -По умолчанию запускается 2 воркера на каждый CPU. Вы также можете настроить количество запускаемых воркеров: +По умолчанию запускается 2 воркера на каждый CPU. +Вы также можете настроить количество запускаемых воркеров: ```bash docker run \ @@ -131,7 +132,7 @@ require __DIR__.'/vendor/autoload.php'; use Nyholm\Psr7\Factory\Psr17Factory; use Nyholm\Psr7Server\ServerRequestCreator; -$myApp = new \App\Kernel(); // implements Psr\Http\Server\RequestHandlerInterface +$myApp = new \App\Kernel(); // реализует Psr\Http\Server\RequestHandlerInterface $myApp->boot(); $psr17Factory = new Psr17Factory(); @@ -164,14 +165,14 @@ for ($nbRequests = 0; !$maxRequests || $nbRequests < $maxRequests; ++$nbRequests ### Перезапуск worker-скрипта после определённого количества запросов -PHP изначально не предназначался для долгоживущих процессов, поэтому есть ещё много библиотек и устаревшего кода, которые вызывают утечки памяти. +Поскольку PHP изначально не предназначался для долгоживущих процессов, многие библиотеки и устаревший код всё ещё вызывают утечки памяти. Обходной путь для использования такого кода в режиме воркера состоит в перезапуске скрипта воркера после обработки определённого количества запросов: Предыдущий сниппет воркера позволяет настроить максимальное количество запросов для обработки, установив переменную окружения с именем `MAX_REQUESTS`. ### Перезапуск воркеров вручную -Хотя можно перезапускать воркеры [при изменении файлов](config.md#watching-for-file-changes), также можно корректно перезапустить все воркеры через [API администрирования Caddy](https://caddyserver.com/docs/api). Если администрирование включено в вашем [Caddyfile](config.md#caddyfile-config), вы можете отправить запрос POST на конечную точку перезапуска следующим образом: +Хотя можно перезапускать воркеры [при изменении файлов](config.md#отслеживание-изменений-файлов), также можно корректно перезапустить все воркеры через [API администрирования Caddy](https://caddyserver.com/docs/api). Если администрирование включено в вашем [Caddyfile](config.md#настройка-caddyfile), вы можете отправить запрос POST на конечную точку перезапуска следующим образом: ```bash curl -X POST http://localhost:2019/frankenphp/workers/restart @@ -180,11 +181,12 @@ curl -X POST http://localhost:2019/frankenphp/workers/restart ### Сбои worker-скрипта Если worker-скрипт завершится с ненулевым кодом выхода, FrankenPHP перезапустит его со стратегией экспоненциальной задержки. -Если скрипт воркера остается активным дольше, чем время последней задержки × 2, FrankenPHP не будет применять штраф к worker-скрипту и перезапустит его снова. +Если скрипт воркера остаётся активным дольше, чем время последней задержки × 2, +FrankenPHP не будет применять штраф к worker-скрипту и перезапустит его снова. Однако, если worker-скрипт продолжает завершаться с ненулевым кодом выхода в течение короткого промежутка времени (например, из-за опечатки в скрипте), FrankenPHP завершит работу с ошибкой: `too many consecutive failures`. -Количество последовательных сбоев можно настроить в вашем [Caddyfile](config.md#caddyfile-config) с помощью опции `max_consecutive_failures`: +Количество последовательных сбоев можно настроить в вашем [Caddyfile](config.md#настройка-caddyfile) с помощью опции `max_consecutive_failures`: ```caddyfile frankenphp { @@ -197,13 +199,15 @@ frankenphp { ### Количество потоков -Когда включен режим воркера, требуется дополнительный поток для обработки входящих запросов, поэтому значение по умолчанию для `num_threads` составляет `1 + 2x(количество доступных CPU)`. +Когда включен режим воркера, требуется дополнительный поток для обработки входящих запросов, +поэтому значение по умолчанию для `num_threads` составляет `1 + 2x(количество доступных CPU)`. Таким образом, в этом режиме, если `num_threads` и `num` заданы явно, `num_threads` должно быть строго больше, чем `num`. ## Поведение суперглобальных переменных -[PHP суперглобальные переменные](https://www.php.net/manual/language.variables.superglobals.php) (`$_SERVER`, `$_ENV`, `$_GET`...) ведут себя следующим образом: +[PHP суперглобальные переменные](https://www.php.net/manual/language.variables.superglobals.php) (`$_SERVER`, `$_ENV`, `$_GET`...) +ведут себя следующим образом: - до первого вызова `frankenphp_handle_request()`, суперглобальные переменные содержат значения, связанные с самим worker-скриптом - во время и после вызова `frankenphp_handle_request()`, суперглобальные переменные содержат значения, сгенерированные на основе обработанного HTTP-запроса, каждый вызов `frankenphp_handle_request()` изменяет значения суперглобальных переменных @@ -223,7 +227,10 @@ $handler = static function () use ($workerServer) { // ... ``` -Большинство суперглобальных переменных (`$_GET`, `$_POST`, `$_COOKIE`, `$_FILES`, `$_SERVER`, `$_REQUEST`) автоматически сбрасываются между запросами. Однако, **`$_ENV` в настоящее время не сбрасывается между запросами**. Это означает, что любые изменения, внесённые в `$_ENV` во время запроса, будут сохраняться и быть видны последующим запросам, обрабатываемым тем же потоком воркера. Избегайте хранения данных, специфичных для запроса или конфиденциальных, в `$_ENV`. +Большинство суперглобальных переменных (`$_GET`, `$_POST`, `$_COOKIE`, `$_FILES`, `$_SERVER`, `$_REQUEST`) автоматически сбрасываются между запросами. +Однако, **`$_ENV` в настоящее время не сбрасывается между запросами**. +Это означает, что любые изменения, внесённые в `$_ENV` во время запроса, будут сохраняться и быть видны последующим запросам, обрабатываемым тем же потоком воркера. +Избегайте хранения данных, специфичных для запроса или конфиденциальных, в `$_ENV`. ## Сохранение состояния @@ -233,7 +240,8 @@ $handler = static function () use ($workerServer) { - **Статические свойства классов**: Статические свойства классов сохраняются между запросами. - **Глобальные переменные**: Переменные в глобальной области видимости worker-скрипта сохраняются между запросами. - **Кэши в памяти**: Любые данные, хранящиеся в памяти (массивы, объекты) за пределами обработчика запросов, сохраняются. -- **Настройки среды выполнения**: Изменения, сделанные с помощью `ini_set()`, `stream_context_set_default()`, `date_default_timezone_set()`, `chdir()`, `stream_wrapper_register()`, `set_error_handler()` или `set_exception_handler()`, остаются в силе для последующих запросов. Никогда не храните там значения, специфичные для запроса или пользователя, например, учетные данные в контексте потока по умолчанию: вместо этого передавайте явный контекст при каждом вызове. +- **Настройки среды выполнения**: Изменения, сделанные с помощью `ini_set()`, `stream_context_set_default()`, `date_default_timezone_set()`, `chdir()`, `stream_wrapper_register()`, `set_error_handler()` или `set_exception_handler()` остаются в силе для последующих запросов. Никогда не храните там значения, специфичные для запроса или пользователя, например, учётные данные в контексте потока по умолчанию: вместо этого передавайте явный контекст при каждом вызове. +- **Настройки процесса**: `umask()` и `setlocale()` изменяют весь процесс FrankenPHP, а не только текущий поток. Режим воркера не восстанавливает их между запросами, и в любом режиме они также влияют на запросы, выполняющиеся одновременно. Установите их один раз при запуске или вызывайте `chmod()` для созданных файлов вместо изменения umask. Это сделано намеренно и является тем, что делает режим воркера быстрым. Однако это требует внимания, чтобы избежать непредвиденных побочных эффектов: @@ -253,4 +261,5 @@ while (\frankenphp_handle_request($handler)) { } ``` -При написании worker-скриптов убедитесь, что вы сбрасываете любое состояние, специфичное для запроса, между запросами. Фреймворки, такие как [Symfony](symfony.md) и [Laravel Octane](laravel.md), позаботятся о сбросе большинства состояний за вас, но вам всё равно может потребоваться сбросить свои собственные сервисы. В Symfony сервисы, которые содержат состояние, специфичное для запроса, должны реализовывать [`Symfony\Contracts\Service\ResetInterface`](https://github.com/symfony/contracts/blob/main/Service/ResetInterface.php), чтобы они сбрасывались ядром между запросами. +При написании worker-скриптов убедитесь, что вы сбрасываете любое состояние, специфичное для запроса, между запросами. +Фреймворки, такие как [Symfony](symfony.md) и [Laravel Octane](laravel.md), позаботятся о сбросе большинства состояний за вас, но вам всё равно может потребоваться сбросить свои собственные сервисы. В Symfony сервисы, которые содержат состояние, специфичное для запроса, должны реализовывать [`Symfony\Contracts\Service\ResetInterface`](https://github.com/symfony/contracts/blob/main/Service/ResetInterface.php), чтобы они сбрасывались ядром между запросами. diff --git a/docs/tr/worker.md b/docs/tr/worker.md index 72092bae91..58158d31d0 100644 --- a/docs/tr/worker.md +++ b/docs/tr/worker.md @@ -33,7 +33,7 @@ frankenphp php-server --worker /path/to/your/worker/script.php PHP uygulamanız [ikili dosyaya gömülü](embed.md) ise, uygulamanın kök dizinine özel bir `Caddyfile` ekleyebilirsiniz. Otomatik olarak kullanılacaktır. -Dosya değişikliklerinde worker'ı yeniden başlatmak ([dosya değişikliklerini izleme](config.md#watching-for-file-changes)) `--watch` seçeneğiyle de mümkündür. +Dosya değişikliklerinde worker'ı yeniden başlatmak ([dosya değişikliklerini izleme](config.md#dosya-değişikliklerini-izleme)) `--watch` seçeneğiyle de mümkündür. Aşağıdaki komut, `/path/to/your/app/` dizininde veya alt dizinlerde `.php` ile biten herhangi bir dosya değiştirilirse yeniden başlatmayı tetikleyecektir: ```bash @@ -172,9 +172,9 @@ Bu tür kodları worker modunda kullanmak için geçici bir çözüm, belirli sa ### Worker'ları manuel olarak yeniden başlatma -Worker'ları [dosya değişikliklerinde](config.md#watching-for-file-changes) yeniden başlatmak mümkünken, tüm worker'ları -[Caddy admin API](https://caddyserver.com/docs/api) aracılığıyla sorunsuz bir şekilde yeniden başlatmak da mümkündür. Yönetici -[Caddyfile](config.md#caddyfile-config)'ınızda etkinleştirilmişse, yeniden başlatma uç noktasına aşağıdaki gibi basit bir POST isteği gönderebilirsiniz: +Worker'ları [dosya değişikliklerinde](config.md#dosya-değişikliklerini-izleme) yeniden başlatmak mümkünken, tüm worker'ları +[Caddy yönetici API'si](https://caddyserver.com/docs/api) aracılığıyla sorunsuz bir şekilde yeniden başlatmak da mümkündür. Yönetici +[Caddyfile](config.md#caddyfile-yapılandırması)'ınızda etkinleştirilmişse, yeniden başlatma uç noktasına aşağıdaki gibi basit bir POST isteği gönderebilirsiniz: ```bash curl -X POST http://localhost:2019/frankenphp/workers/restart @@ -188,7 +188,7 @@ worker betiğini cezalandırmayacak ve tekrar yeniden başlatacaktır. Ancak, worker betiği kısa bir süre içinde sıfır olmayan bir çıkış koduyla başarısız olmaya devam ederse (örneğin, bir betikte yazım hatası olması durumunda), FrankenPHP `too many consecutive failures` hatasıyla çökecektir. -Ardışık hata sayısı, [Caddyfile](config.md#caddyfile-config)'ınızda `max_consecutive_failures` seçeneği ile yapılandırılabilir: +Ardışık hata sayısı, [Caddyfile](config.md#caddyfile-yapılandırması)'ınızda `max_consecutive_failures` seçeneği ile yapılandırılabilir: ```caddyfile frankenphp { @@ -242,6 +242,7 @@ Worker modu, PHP sürecini istekler arasında canlı tuttuğu için, aşağıdak - **Küresel değişkenler**: Worker betiğinin küresel kapsamındaki değişkenler, istekler arasında kalıcı olur. - **Bellek içi önbellekler**: İstek işleyicisi dışında bellekte depolanan herhangi bir veri (diziler, nesneler) kalıcı olur. - **Çalışma zamanı motoru ayarları**: `ini_set()`, `stream_context_set_default()`, `date_default_timezone_set()`, `chdir()`, `stream_wrapper_register()`, `set_error_handler()` veya `set_exception_handler()` ile yapılan değişiklikler sonraki istekler için geçerliliğini korur. Varsayılan akış bağlamında kimlik bilgileri gibi isteğe veya kullanıcıya özgü değerleri asla orada saklamayın: bunun yerine her çağrıya açık bir bağlam geçirin. +- **Süreç genelindeki ayarlar**: `umask()` ve `setlocale()` tüm FrankenPHP sürecini değiştirir, yalnızca mevcut iş parçacığını değil. Worker modu bunları istekler arasında geri yüklemez ve her modda aynı anda çalışan istekleri de etkiler. Bunları başlangıçta bir kez ayarlayın veya umask'ı değiştirmek yerine oluşturulan dosyalarda `chmod()` çağırın. Bu, tasarım gereğidir ve worker modunu hızlı yapan şey budur. Ancak, istenmeyen yan etkilerden kaçınmak için dikkat gerektirir: