diff --git a/docs/cn/known-issues.md b/docs/cn/known-issues.md index 99a01b2d59..92bc07f89c 100644 --- a/docs/cn/known-issues.md +++ b/docs/cn/known-issues.md @@ -1,29 +1,47 @@ +--- +title: FrankenPHP 已知问题、不兼容的扩展和解决方案 +description: FrankenPHP 限制的参考,包括不支持的 PHP 扩展、musl libc 注意事项、使用 127.0.0.1 的 Docker TLS 设置以及 Composer @php 脚本。 +--- + # 已知问题 ## 不支持的 PHP 扩展 已知以下扩展与 FrankenPHP 不兼容: -| 名称 | 原因 | 替代方案 | -| ----------------------------------------------------------------------------------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------- | -| [imap](https://www.php.net/manual/imap.installation.php) | 不安全的线程 | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap) | -| [newrelic](https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/introduction-new-relic-php/) | 不安全的线程 | - | +| 名称 | 原因 | 替代方案 | +| ----------------------------------------------------------------------------------------------------------- | ------------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [imap](https://www.php.net/manual/imap.installation.php) | 非线程安全 | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap), [ImapEngine](https://github.com/DirectoryTree/ImapEngine) | +| [newrelic](https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/introduction-new-relic-php/) | 非线程安全 | - | +| [pcov](https://github.com/krakjoe/pcov) | 非线程安全 ([经典模式下的 SIGSEGV](https://github.com/krakjoe/pcov/issues/132)) | 使用 CLI SAPI 收集覆盖率(在 FrankenPHP 外部运行 PHPUnit/Pest) | ## 有缺陷的 PHP 扩展 以下扩展在与 FrankenPHP 一起使用时已知存在错误和意外行为: -| 名称 | 问题 | -| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [ext-openssl](https://www.php.net/manual/book.openssl.php) | 在使用静态构建的 FrankenPHP(使用 musl libc 构建)时,在重负载下 OpenSSL 扩展可能会崩溃。一个解决方法是使用动态链接的构建(如 Docker 镜像中使用的版本)。此错误正在由 PHP 跟踪。[查看问题](https://github.com/php/php-src/issues/13648)。 | +| 名称 | 问题 | +|---------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------| +| [datadog](https://github.com/DataDog) | 在分析 FrankenPHP 时存在不稳定性。此 bug [正由 DataDog 跟踪](https://github.com/DataDog/dd-trace-php/issues/3729)。 | +| [blackfire](https://blackfire.io/) | [FrankenPHP 支持处于 Beta 阶段,尚未功能完善](https://docs.blackfire.io/php/integrations/frankenphp)。 | +| [imagick](https://github.com/Imagick/imagick) | ImageMagick 的 OpenMP 线程与 FrankenPHP 的线程冲突,导致不稳定和崩溃。可以通过 `\Imagick::setResourceLimit(\Imagick::RESOURCETYPE_THREAD, 1)` 禁用 ImageMagick 线程,或通过使用 `--disable-openmp` 编译 ImageMagick 来缓解。OpenMP 在静态二进制文件和官方 `apt`/`apk`/`rpm` 包中已禁用,因此仅 Docker 镜像和 Homebrew 安装受影响。 | + +## 超出 PHP 硬内存限制会停止整个服务器 + +自 PHP 8.2.35、8.3.36、8.4.27 和 8.5.12 起,超出 `memory_limit` 不再立即停止脚本:在下一次函数调用或循环迭代时会引发“允许的内存大小耗尽”的致命错误。如果脚本在此之前分配超过硬内存限制,PHP 将退出进程。硬限制默认为 `memory_limit` 的两倍(或超过 1 GiB 时为 `memory_limit` 加 1 GiB),并且可以通过 `memory_hard_limit_percent` INI 设置进行更改。 + +超出 `memory_limit` 后仍在运行的代码可能会达到此限制,例如单个分配大于 `memory_limit`(如在大型数组上使用 `array_merge()`)或连续的字符串连接。 + +PHP-FPM 只会丢失一个子进程。FrankenPHP 从单个进程的线程处理所有请求,因此每个正在进行的请求都会丢失,并且服务器会停止,直到重新启动。请在能重启 FrankenPHP 的监督器下运行它,例如 Docker 重启策略或 systemd 的 `Restart=`(已在 `deb` 和 `rpm` 包中设置)。 ## get_browser -[get_browser()](https://www.php.net/manual/function.get-browser.php) 函数在一段时间后似乎表现不佳。解决方法是缓存(例如使用 [APCu](https://www.php.net/manual/book.apcu.php))每个 User-Agent,因为它们是不变的。 +[get_browser()](https://www.php.net/manual/function.get-browser.php) 函数在一段时间后似乎表现不佳。解决方法是缓存(例如使用 [APCu](https://www.php.net/manual/book.apcu.php))每个 User-Agent 的结果,因为它们是静态的。 ## 独立的二进制和基于 Alpine 的 Docker 镜像 -独立的二进制文件和基于 Alpine 的 Docker 镜像 (`dunglas/frankenphp:*-alpine`) 使用的是 [musl libc](https://musl.libc.org/) 而不是 [glibc and friends](https://www.etalabs.net/compare_libcs.html),为的是保持较小的二进制大小。这可能会导致一些兼容性问题。特别是,glob 标志 `GLOB_BRACE` [不可用](https://www.php.net/manual/function.glob.php)。 +完全静态的二进制文件和基于 Alpine 的 Docker 镜像 (`dunglas/frankenphp:*-alpine`) 使用的是 [musl libc](https://musl.libc.org/) 而不是 [glibc and friends](https://www.etalabs.net/compare_libcs.html),为的是保持较小的二进制大小。这可能会导致一些兼容性问题。特别是,glob 标志 `GLOB_BRACE` [不可用](https://www.php.net/manual/function.glob.php)。 + +如果遇到问题,请优先使用静态二进制文件的 GNU 变体和基于 Debian 的 Docker 镜像。 ## 在 Docker 中使用 `https://127.0.0.1` @@ -32,10 +50,10 @@ 如果确实想使用 `127.0.0.1` 作为主机,可以通过将服务器名称设置为 `127.0.0.1` 来配置它以为其生成证书。 -如果你使用 Docker,因为 [Docker 网络](https://docs.docker.com/network/) 问题,只做这些是不够的。 +不幸的是,如果你使用 Docker,因为 [Docker 网络系统](https://docs.docker.com/network/) 问题,只做这些是不够的。 你将收到类似于以下内容的 TLS 错误 `curl: (35) LibreSSL/3.3.6: error:1404B438:SSL routines:ST_CONNECT:tlsv1 alert internal error`。 -如果你使用的是 Linux,解决方案是使用 [使用宿主机网络](https://docs.docker.com/network/network-tutorial-host/): +如果你使用的是 Linux,解决方案是使用 [宿主机网络驱动](https://docs.docker.com/network/network-tutorial-host/): ```console docker run \ @@ -45,9 +63,9 @@ docker run \ dunglas/frankenphp ``` -Mac 和 Windows 不支持 Docker 使用宿主机网络。在这些平台上,你必须猜测容器的 IP 地址并将其包含在服务器名称中。 +Mac 和 Windows 不支持宿主机网络驱动。在这些平台上,你必须猜测容器的 IP 地址并将其包含在服务器名称中。 -运行 `docker network inspect bridge` 并查看 `Containers`,找到 `IPv4Address` 当前分配的最后一个 IP 地址,并增加 1。如果没有容器正在运行,则第一个分配的 IP 地址通常为 `172.17.0.2`。 +运行 `docker network inspect bridge` 并查看 `Containers` 键,以识别 `IPv4Address` 键下当前分配的最后一个 IP 地址,并将其增加 1。如果没有容器正在运行,则第一个分配的 IP 地址通常为 `172.17.0.2`。 然后将其包含在 `SERVER_NAME` 环境变量中: @@ -87,6 +105,7 @@ docker run \ ```bash #!/usr/bin/env bash +# /usr/local/bin/php args=("$@") index=0 for i in "$@" @@ -127,10 +146,10 @@ error:0A000086:SSL routines::certificate verify failed > [!WARNING] > -> Web 和命令行界面可能有不同的设置。 +> Web 和 CLI 上下文可能有不同的设置。 > 确保在适当的上下文中运行 `openssl_get_cert_locations()`。 -[从Mozilla提取的CA证书可以在curl网站上下载](https://curl.se/docs/caextract.html)。 +[从 Mozilla 提取的 CA 证书可以在 cURL 网站上下载](https://curl.se/docs/caextract.html)。 或者,许多发行版,包括 Debian、Ubuntu 和 Alpine,提供名为 `ca-certificates` 的软件包,其中包含这些证书。 diff --git a/docs/fr/known-issues.md b/docs/fr/known-issues.md index c0c44d6089..ab0724b462 100644 --- a/docs/fr/known-issues.md +++ b/docs/fr/known-issues.md @@ -1,21 +1,41 @@ +--- +title: Problèmes connus, extensions incompatibles et solutions de contournement de FrankenPHP +description: Référence des limitations de FrankenPHP, y compris les extensions PHP non prises en charge, les mises en garde de musl libc, la configuration TLS de Docker avec 127.0.0.1, et les scripts Composer @php. +--- + # Problèmes connus ## Extensions PHP non prises en charge Les extensions suivantes sont connues pour ne pas être compatibles avec FrankenPHP : -| Nom | Raison | Alternatives | -| ----------------------------------------------------------------------------------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------- | -| [imap](https://www.php.net/manual/imap.installation.php) | Non thread-safe | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap) | -| [newrelic](https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/introduction-new-relic-php/) | Non thread-safe | - | +| Nom | Raison | Alternatives | +| :---------------------------------------------------------------------------------------------------------- | :-------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [imap](https://www.php.net/manual/imap.installation.php) | Non thread-safe | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap), [ImapEngine](https://github.com/DirectoryTree/ImapEngine) | +| [newrelic](https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/introduction-new-relic-php/) | Non thread-safe | - | +| [pcov](https://github.com/krakjoe/pcov) | Non thread-safe ([SIGSEGV en mode classique](https://github.com/krakjoe/pcov/issues/132)) | Collecter la couverture avec le SAPI CLI (exécuter PHPUnit/Pest en dehors de FrankenPHP) | ## Extensions PHP boguées -Les extensions suivantes ont des bugs connus ou des comportements inattendus lorsqu'elles sont utilisées avec FrankenPHP : +Les extensions suivantes ont des bugs connus et des comportements inattendus lorsqu'elles sont utilisées avec FrankenPHP : + +| Nom | Problème | +| :-------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [datadog](https://github.com/DataDog) | Instabilité lors du profilage de FrankenPHP. Ce bug est [suivi par DataDog](https://github.com/DataDog/dd-trace-php/issues/3729). | +| [blackfire](https://blackfire.io/) | [Le support de FrankenPHP est en bêta et n'est pas encore complet](https://docs.blackfire.io/php/integrations/frankenphp). | +| [imagick](https://github.com/Imagick/imagick) | Les threads OpenMP d'ImageMagick entrent en conflit avec les threads de FrankenPHP, causant instabilité et plantages. Atténuez cela en désactivant le threading d'ImageMagick via ``\Imagick::setResourceLimit(\Imagick::RESOURCETYPE_THREAD, 1)`` ou en compilant ImageMagick avec ``--disable-openmp``. OpenMP est déjà désactivé dans les binaires statiques et les paquets officiels ``apt``/``apk``/``rpm``, donc seules les images Docker et les installations Homebrew sont affectées. | + +## Dépasser la limite de mémoire dure de PHP arrête l'ensemble du serveur -| Nom | Problème | -| ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [ext-openssl](https://www.php.net/manual/book.openssl.php) | Lors de l'utilisation d'une version statique de FrankenPHP (construite avec la libc musl), l'extension OpenSSL peut planter sous de fortes charges. Une solution consiste à utiliser une version liée dynamiquement (comme celle utilisée dans les images Docker). Ce bogue est [suivi par PHP](https://github.com/php/php-src/issues/13648). | +Depuis PHP 8.2.35, 8.3.36, 8.4.27 et 8.5.12, dépasser `memory_limit` n'arrête plus le script immédiatement : l'erreur fatale "Allowed memory size exhausted" est déclenchée lors du prochain appel de fonction ou itération de boucle. +Si le script alloue au-delà de la limite de mémoire dure avant cela, PHP quitte le processus. +La limite dure est par défaut le double de `memory_limit` (ou `memory_limit` plus 1 GiB au-dessus de 1 GiB) et peut être modifiée avec le paramètre INI `memory_hard_limit_percent`. + +Le code qui continue de s'exécuter au-delà de `memory_limit` peut l'atteindre, par exemple une seule allocation plus grande que `memory_limit` (comme `array_merge()` sur de grands tableaux) ou des concaténations de chaînes consécutives. + +PHP-FPM ne perd qu'un seul processus enfant. +FrankenPHP sert toutes les requêtes à partir de threads d'un seul processus, de sorte que chaque requête en cours est perdue et le serveur s'arrête jusqu'à ce qu'il soit redémarré. +Exécutez FrankenPHP sous un superviseur qui le redémarre, comme une politique de redémarrage Docker ou `Restart=` de systemd (déjà configuré dans les paquets `deb` et `rpm`). ## get_browser @@ -23,7 +43,11 @@ La fonction [get_browser()](https://www.php.net/manual/function.get-browser.php) ## Binaire autonome et images Docker basées sur Alpine -Le binaire autonome et les images Docker basées sur Alpine (`dunglas/frankenphp:*-alpine`) utilisent [musl libc](https://musl.libc.org/) au lieu de [glibc et ses amis](https://www.etalabs.net/compare_libcs.html), pour garder une taille de binaire plus petite. Cela peut entraîner des problèmes de compatibilité. En particulier, le drapeau glob `GLOB_BRACE` n'est [pas disponible](https://www.php.net/manual/function.glob.php). +Le binaire entièrement statique et les images Docker basées sur Alpine (`dunglas/frankenphp:*-alpine`) utilisent [musl libc](https://musl.libc.org/) au lieu de [glibc et ses amis](https://www.etalabs.net/compare_libcs.html), pour garder une taille de binaire plus petite. +Cela peut entraîner des problèmes de compatibilité. +En particulier, le drapeau glob `GLOB_BRACE` n'est [pas disponible](https://www.php.net/manual/function.glob.php). + +Préférez utiliser la variante GNU du binaire statique et les images Docker basées sur Debian si vous rencontrez des problèmes. ## Utilisation de `https://127.0.0.1` avec Docker @@ -47,7 +71,7 @@ docker run \ Le pilote de réseau "hôte" n'est pas pris en charge sur Mac et Windows. Sur ces plateformes, vous devrez deviner l'adresse IP du conteneur et l'inclure dans les noms de serveur. -Exécutez la commande `docker network inspect bridge` et inspectez la clef `Containers` pour identifier la dernière adresse IP attribuée sous la clef `IPv4Address`, puis incrémentez-la d'un. Si aucun conteneur n'est en cours d'exécution, la première adresse IP attribuée est généralement `172.17.0.2`. +Exécutez la commande `docker network inspect bridge` et inspectez la clé `Containers` pour identifier la dernière adresse IP attribuée sous la clé `IPv4Address`, puis incrémentez-la d'un. Si aucun conteneur n'est en cours d'exécution, la première adresse IP attribuée est généralement `172.17.0.2`. Ensuite, incluez ceci dans la variable d'environnement `SERVER_NAME` : @@ -87,6 +111,7 @@ Comme solution de contournement, nous pouvons créer un script shell dans `/usr/ ```bash #!/usr/bin/env bash +# /usr/local/bin/php args=("$@") index=0 for i in "$@" @@ -101,7 +126,7 @@ done /usr/local/bin/frankenphp php-cli ${args[@]} ``` -Ensuite, mettez la variable d'environnement `PHP_BINARY` au chemin de notre script `php` et lancez Composer : +Ensuite, définissez la variable d'environnement `PHP_BINARY` au chemin de notre script `php` et lancez Composer : ```console export PHP_BINARY=/usr/local/bin/php diff --git a/docs/it/known-issues.md b/docs/it/known-issues.md index ac84569859..23d1218dd6 100644 --- a/docs/it/known-issues.md +++ b/docs/it/known-issues.md @@ -1,33 +1,53 @@ +--- +title: Problemi noti di FrankenPHP, estensioni incompatibili e soluzioni alternative +description: Riferimento alle limitazioni di FrankenPHP, incluse estensioni PHP non supportate, avvertenze su musl libc, configurazione TLS di Docker con 127.0.0.1 e script Composer @php. +--- + # Problemi noti ## Estensioni PHP non supportate Le seguenti estensioni non sono compatibili con FrankenPHP: -| Nome | Motivo | Alternative | -| ----------------------------------------------------------------------------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------- | -| [imap](https://www.php.net/manual/imap.installation.php) | Non thread-safe | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap) | -| [newrelic](https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/introduction-new-relic-php/) | Non thread-safe | - | +| Nome | Motivo | Alternative | +| ----------------------------------------------------------------------------------------------------------- | --------------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [imap](https://www.php.net/manual/imap.installation.php) | Non thread-safe | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap), [ImapEngine](https://github.com/DirectoryTree/ImapEngine) | +| [newrelic](https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/introduction-new-relic-php/) | Non thread-safe | - | +| [pcov](https://github.com/krakjoe/pcov) | Non thread-safe ([SIGSEGV in modalità classica](https://github.com/krakjoe/pcov/issues/132)) | Raccogliere la copertura con la SAPI CLI (eseguire PHPUnit/Pest al di fuori di FrankenPHP) | ## Estensioni PHP difettose Le seguenti estensioni presentano bug noti e comportamenti imprevisti se utilizzate con FrankenPHP: -| Nome | Problema | -| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [ext-openssl](https://www.php.net/manual/book.openssl.php) | Quando si utilizza musl libc, l'estensione OpenSSL potrebbe bloccarsi in caso di carichi pesanti. Il problema non si verifica quando si utilizza la più popolare libc GNU. Questo bug è [monitorato da PHP](https://github.com/php/php-src/issues/13648). | +| Nome | Problema | +|---------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------| +| [datadog](https://github.com/DataDog) | Sperimenta instabilità durante la profilazione di FrankenPHP. Questo bug è [monitorato da DataDog](https://github.com/DataDog/dd-trace-php/issues/3729). | +| [blackfire](https://blackfire.io/) | [Il supporto FrankenPHP è in beta e non ancora completo di funzionalità](https://docs.blackfire.io/php/integrations/frankenphp). | +| [imagick](https://github.com/Imagick/imagick) | I thread OpenMP di ImageMagick sono in conflitto con i thread di FrankenPHP, causando instabilità e crash. Mitigare disabilitando il threading di ImageMagick tramite `\Imagick::setResourceLimit(\Imagick::RESOURCETYPE_THREAD, 1)` o compilando ImageMagick con `--disable-openmp`. OpenMP è già disabilitato nei binari statici e nei pacchetti ufficiali `apt`/`apk`/`rpm`, quindi sono interessate solo le immagini Docker e le installazioni Homebrew. | + +## Il superamento del limite di memoria rigido di PHP arresta l'intero server + +A partire da PHP 8.2.35, 8.3.36, 8.4.27 e 8.5.12, il superamento di `memory_limit` non arresta più lo script immediatamente: l'errore fatale "Allowed memory size exhausted" viene sollevato alla successiva chiamata di funzione o iterazione del ciclo. +Se lo script alloca oltre il limite di memoria rigido prima di ciò, PHP esce dal processo. +Il limite rigido predefinito è il doppio di `memory_limit` (o `memory_limit` più 1 GiB al di sopra di 1 GiB) e può essere modificato con l'impostazione INI `memory_hard_limit_percent`. + +Il codice che continua a essere eseguito oltre `memory_limit` può raggiungerlo, ad esempio una singola allocazione maggiore di `memory_limit` (come `array_merge()` su array di grandi dimensioni) o concatenazioni di stringhe consecutive. + +PHP-FPM perde solo un processo figlio. +FrankenPHP serve tutte le richieste da thread di un singolo processo, quindi ogni richiesta in corso viene persa e il server si ferma fino al riavvio. +Eseguire FrankenPHP sotto un supervisore che lo riavvia, come una policy di riavvio di Docker o `Restart=` di systemd (già impostato nei pacchetti `deb` e `rpm`). ## get_browser La funzione [get_browser()](https://www.php.net/manual/function.get-browser.php) sembra funzionare male dopo un po'. Una soluzione alternativa consiste nel memorizzare nella cache (ad esempio con [APCu](https://www.php.net/manual/book.apcu.php)) i risultati per agente utente, poiché sono statici. -## Immagini Docker binarie autonome e basate su Alpine +## Binari autonomi e immagini Docker basate su Alpine Le immagini Docker binarie completamente statiche e basate su Alpine (`dunglas/frankenphp:*-alpine`) utilizzano [musl libc](https://musl.libc.org/) invece di [glibc e amici](https://www.etalabs.net/compare_libcs.html), per mantenere una dimensione binaria più piccola. Ciò potrebbe portare ad alcuni problemi di compatibilità. -In particolare, il flag glob `GLOB_BRACE` [non è disponibile](https://www.php.net/manual/function.glob.php) +In particolare, il flag glob `GLOB_BRACE` [non è disponibile](https://www.php.net/manual/function.glob.php). -Se si riscontrano problemi, utilizzare la variante GNU del binario statico e delle immagini Docker basate su Debian. +Preferire l'utilizzo della variante GNU del binario statico e delle immagini Docker basate su Debian se si riscontrano problemi. ## Uso di `https://127.0.0.1` con Docker @@ -51,7 +71,7 @@ docker run \ Il driver di rete host non è supportato su Mac e Windows. Su queste piattaforme si dovrà ricavare l'indirizzo IP del contenitore e includerlo nei nomi dei server. -Eseguire `docker network inspect bridge` e trovare la chiave `Containers` per identificare l'ultimo indirizzo IP attualmente assegnato sotto la chiave `IPv4Address` e incrementarlo di uno. Se non è in esecuzione alcun contenitore, il primo indirizzo IP assegnato è solitamente `172.17.0.2`. +Eseguire `docker network inspect bridge` e cercare la chiave `Containers` per identificare l'ultimo indirizzo IP attualmente assegnato sotto la chiave `IPv4Address` e incrementarlo di uno. Se non è in esecuzione alcun contenitore, il primo indirizzo IP assegnato è solitamente `172.17.0.2`. Quindi, includerlo nella variabile di ambiente `SERVER_NAME`: @@ -80,12 +100,12 @@ docker run \ dunglas/frankenphp ``` -## Script di composer che fanno riferimento a `@php` +## Script Composer che fanno riferimento a `@php` -[Gli script di composer](https://getcomposer.org/doc/articles/scripts.md) potrebbero voler eseguire un binario PHP per alcune attività, ad es. in [un progetto Laravel](laravel.md) per eseguire `@php artisan package:discover --ansi`. Questo [attualmente fallisce](https://github.com/php/frankenphp/issues/483#issuecomment-1899890915) per due motivi: +[Gli script di Composer](https://getcomposer.org/doc/articles/scripts.md) potrebbero voler eseguire un binario PHP per alcune attività, ad es. in [un progetto Laravel](laravel.md) per eseguire `@php artisan package:discover --ansi`. Questo [attualmente fallisce](https://github.com/php/frankenphp/issues/483#issuecomment-1899890915) per due motivi: -- composer non sa come chiamare il binario FrankenPHP; -- composer può aggiungere impostazioni PHP utilizzando il flag `-d` nel comando, che FrankenPHP non supporta ancora. +- Composer non sa come chiamare il binario FrankenPHP; +- Composer può aggiungere impostazioni PHP utilizzando il flag `-d` nel comando, che FrankenPHP non supporta ancora. Come soluzione alternativa, possiamo creare uno script di shell in `/usr/local/bin/php` che rimuove i parametri non supportati e quindi chiama FrankenPHP: @@ -106,16 +126,16 @@ done /usr/local/bin/frankenphp php-cli ${args[@]} ``` -Quindi impostare la variabile di ambiente `PHP_BINARY` sul percorso dello script `php` ed eseguire composer: +Quindi impostare la variabile di ambiente `PHP_BINARY` sul percorso dello script `php` ed eseguire Composer: ```console export PHP_BINARY=/usr/local/bin/php composer install ``` -## Risoluzione dei problemi TLS/SSL con file binari statici +## Risoluzione dei problemi TLS/SSL con binari statici -Quando si utilizzano i file binari statici, è possibile che si verifichino i seguenti errori relativi a TLS, ad esempio quando si inviano email utilizzando STARTTLS: +Quando si utilizzano i binari statici, è possibile che si verifichino i seguenti errori relativi a TLS, ad esempio quando si inviano email utilizzando STARTTLS: ```text Unable to connect with STARTTLS: stream_socket_enable_crypto(): SSL operation failed with code 5. OpenSSL Error messages: @@ -125,7 +145,7 @@ error:80000002:system library::No such file or directory error:0A000086:SSL routines::certificate verify failed ``` -Poiché il file binario statico non include i certificati TLS, è necessario indirizzare OpenSSL all'installazione dei certificati della CA locale. +Poiché il binario statico non include i certificati TLS, è necessario indirizzare OpenSSL all'installazione dei certificati CA locali. Esaminare l'output di [`openssl_get_cert_locations()`](https://www.php.net/manual/function.openssl-get-cert-locations.php), per trovare dove devono essere installati i certificati CA e archiviarli in questa posizione. diff --git a/docs/ja/known-issues.md b/docs/ja/known-issues.md index 884daa3ac2..e6c94ded47 100644 --- a/docs/ja/known-issues.md +++ b/docs/ja/known-issues.md @@ -1,21 +1,41 @@ +--- +title: FrankenPHPの既知の問題、非互換の拡張モジュール、および回避策 +description: サポートされていないPHP拡張モジュール、musl libcの注意点、127.0.0.1を使用したDocker TLSセットアップ、Composer @phpスクリプトなど、FrankenPHPの制限事項の参照。 +--- + # 既知の問題 ## 未対応のPHP拡張モジュール 以下の拡張モジュールはFrankenPHPと互換性がないことが確認されています: -| 名前 | 理由 | 代替手段 | -| ----------------------------------------------------------------------------------------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------- | -| [imap](https://www.php.net/manual/imap.installation.php) | スレッドセーフでない | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap) | -| [newrelic](https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/introduction-new-relic-php/) | スレッドセーフでない | - | +| 名前 | 理由 | 代替手段 | +| :---------------------------------------------------------------------------------------------------------- | :------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [imap](https://www.php.net/manual/imap.installation.php) | スレッドセーフでない | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap), [ImapEngine](https://github.com/DirectoryTree/ImapEngine) | +| [newrelic](https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/introduction-new-relic-php/) | スレッドセーフでない | - | +| [pcov](https://github.com/krakjoe/pcov) | スレッドセーフでない ([クラシックモードでのSIGSEGV](https://github.com/krakjoe/pcov/issues/132)) | CLI SAPIでカバレッジを収集する(FrankenPHPの外部でPHPUnit/Pestを実行する) | ## バグのあるPHP拡張モジュール 以下の拡張モジュールはFrankenPHPとの組み合わせで既知のバグや予期しない動作が確認されています: -| 名前 | 問題 | -| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| [ext-openssl](https://www.php.net/manual/book.openssl.php) | FrankenPHPの静的ビルド(musl libcでビルド)を使用した場合、高負荷時にOpenSSL拡張がクラッシュすることがあります。回避策として動的リンクのビルド(Dockerイメージで使用されているもの)を使用してください。このバグは[PHP側で追跡中](https://github.com/php/php-src/issues/13648)です。 | +| 名前 | 問題 | +| :------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------- | +| [datadog](https://github.com/DataDog) | FrankenPHPのプロファイリング時に不安定な動作が確認されています。このバグは[DataDogによって追跡中](https://github.com/DataDog/dd-trace-php/issues/3729)です。 | +| [blackfire](https://blackfire.io/) | [FrankenPHPのサポートはベータ版であり、まだ機能が完全ではありません](https://docs.blackfire.io/php/integrations/frankenphp)。 | +| [imagick](https://github.com/Imagick/imagick) | ImageMagickのOpenMPスレッドがFrankenPHPのスレッドと競合し、不安定性やクラッシュを引き起こします。\Imagick::setResourceLimit(\Imagick::RESOURCETYPE_THREAD, 1)でImageMagickのスレッドを無効にするか、`--disable-openmp`でImageMagickをコンパイルすることで軽減できます。静的バイナリおよび公式の`apt`/`apk`/`rpm`パッケージではOpenMPはすでに無効になっているため、DockerイメージとHomebrewインストールのみが影響を受けます。 | + +## PHPのハードメモリ制限を超過するとサーバー全体が停止する + +PHP 8.2.35、8.3.36、8.4.27、および8.5.12以降、`memory_limit`を超過してもスクリプトがすぐに停止しなくなりました。「Allowed memory size exhausted」の致命的なエラーは、次の関数呼び出しまたはループイテレーションで発生します。 +それ以前にスクリプトがハードメモリ制限を超えて割り当てを行うと、PHPはプロセスを終了します。 +ハード制限はデフォルトで`memory_limit`の2倍(または1 GiBを超える場合は`memory_limit`プラス1 GiB)であり、`memory_hard_limit_percent` INI設定で変更できます。 + +`memory_limit`を超えて実行され続けるコードは、例えば`memory_limit`より大きい単一の割り当て(大規模な配列に対する`array_merge()`など)や、連続する文字列連結によって、この制限に達する可能性があります。 + +PHP-FPMは1つの子プロセスしか失いません。 +FrankenPHPはすべてのリクエストを単一プロセスのスレッドから処理するため、処理中のすべてのリクエストが失われ、サーバーは再起動されるまで停止します。 +Dockerの再起動ポリシーやsystemdの`Restart=`(`deb`および`rpm`パッケージではすでに設定済み)など、FrankenPHPを再起動する監視プログラムの下で実行してください。 ## get_browser @@ -25,6 +45,8 @@ スタンドアロンバイナリおよびAlpineベースのDockerイメージ(`dunglas/frankenphp:*-alpine`)は、バイナリサイズを小さく保つために[glibc and friends](https://www.etalabs.net/compare_libcs.html)ではなく[musl libc](https://musl.libc.org/)を使用しています。これによりいくつかの互換性問題が発生する可能性があります。特に、globフラグ`GLOB_BRACE`は [サポートされていません](https://www.php.net/manual/function.glob.php) 。 +問題が発生した場合は、静的バイナリのGNU版およびDebianベースのDockerイメージを使用することをお勧めします。 + ## Dockerで`https://127.0.0.1`を使用する デフォルトでは、FrankenPHPは`localhost`用のTLS証明書を生成します。 @@ -78,7 +100,7 @@ docker run \ ## `@php` を参照するComposerスクリプト -[Composerスクリプト](https://getcomposer.org/doc/articles/scripts.md)では、いくつかのタスクでPHPバイナリを実行したい場合があります。例えば、[Laravelプロジェクト](laravel.md)で`@php artisan package:discover --ansi`を実行する場合です。しかし現在これは以下の2つの理由で[失敗します](https://github.com/dunglas/frankenphp/issues/483#issuecomment-1899890915): +[Composerスクリプト](https://getcomposer.org/doc/articles/scripts.md)では、いくつかのタスクでPHPバイナリを実行したい場合があります。例えば、[Laravelプロジェクト](laravel.md)で`@php artisan package:discover --ansi`を実行する場合です。しかし現在これは以下の2つの理由で[失敗します](https://github.com/php/frankenphp/issues/483#issuecomment-1899890915): - ComposerはFrankenPHPバイナリを呼び出す方法を知りません - Composerはコマンドで`-d`フラグを使用してPHP設定を追加する場合があり、FrankenPHPはまだサポートしていません @@ -87,6 +109,7 @@ docker run \ ```bash #!/usr/bin/env bash +# /usr/local/bin/php args=("$@") index=0 for i in "$@" diff --git a/docs/pt-br/known-issues.md b/docs/pt-br/known-issues.md index cc2e93587a..7e617bfb61 100644 --- a/docs/pt-br/known-issues.md +++ b/docs/pt-br/known-issues.md @@ -1,58 +1,66 @@ +--- +title: Problemas conhecidos, extensões incompatíveis e soluções alternativas do FrankenPHP +description: Referência das limitações do FrankenPHP, incluindo extensões PHP não suportadas, ressalvas da musl libc, configuração TLS do Docker com 127.0.0.1 e scripts @php do Composer. +--- + # Problemas conhecidos ## Extensões PHP não suportadas -As seguintes extensões são conhecidas por não serem compatíveis com o -FrankenPHP: +As seguintes extensões são conhecidas por não serem compatíveis com o FrankenPHP: -| Nome | Motivo | Alternativas | -| ----------------------------------------------------------------------------------------------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------- | -| [imap](https://www.php.net/manual/imap.installation.php) | Não é thread-safe | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap) | -| [newrelic](https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/introduction-new-relic-php/) | Não é thread-safe | - | +| Nome | Motivo | Alternativas | +| :---------------------------------------------------------------------------------------------------------- | :-------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [imap](https://www.php.net/manual/imap.installation.php) | Não é thread-safe | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap), [ImapEngine](https://github.com/DirectoryTree/ImapEngine) | +| [newrelic](https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/introduction-new-relic-php/) | Não é thread-safe | - | +| [pcov](https://github.com/krakjoe/pcov) | Não é thread-safe ([SIGSEGV no modo clássico](https://github.com/krakjoe/pcov/issues/132)) | Coletar cobertura com a SAPI CLI (execute PHPUnit/Pest fora do FrankenPHP) | ## Extensões PHP com falhas -As seguintes extensões apresentam falhas conhecidas e comportamentos inesperados -quando usadas com o FrankenPHP: +As seguintes extensões apresentam falhas conhecidas e comportamentos inesperados quando usadas com o FrankenPHP: + +| Nome | Problema | +| :-------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------- | +| [datadog](https://github.com/DataDog) | Apresenta instabilidade ao perfilar o FrankenPHP. Este bug está [sendo rastreado pela DataDog](https://github.com/DataDog/dd-trace-php/issues/3729). | +| [blackfire](https://blackfire.io/) | [O suporte ao FrankenPHP está em fase beta e ainda não está completo em recursos](https://docs.blackfire.io/php/integrations/frankenphp). | +| [imagick](https://github.com/Imagick/imagick) | Os threads OpenMP do ImageMagick entram em conflito com os threads do FrankenPHP, causando instabilidade e travamentos. Mitigue desativando o threading do ImageMagick via `\Imagick::setResourceLimit(\Imagick::RESOURCETYPE_THREAD, 1)` ou compilando o ImageMagick com `--disable-openmp`. O OpenMP já está desativado nos binários estáticos e nos pacotes oficiais `apt`/`apk`/`rpm`, então apenas as imagens Docker e instalações Homebrew são afetadas. | + +## Exceder o limite de memória "hard" do PHP paralisa o servidor inteiro + +Desde o PHP 8.2.35, 8.3.36, 8.4.27 e 8.5.12, exceder o `memory_limit` não para mais o script imediatamente: o erro fatal "Allowed memory size exhausted" é lançado na próxima chamada de função ou iteração de loop. +Se o script alocar além do limite de memória "hard" antes disso, o PHP encerra o processo. +O limite "hard" padrão é o dobro do `memory_limit` (ou `memory_limit` mais 1 GiB acima de 1 GiB) e pode ser alterado com a configuração INI `memory_hard_limit_percent`. -| Nome | Problema | -| ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [ext-openssl](https://www.php.net/manual/book.openssl.php) | Ao usar uma versão estática do FrankenPHP (compilada com a `libc` `musl`), a extensão OpenSSL pode quebrar sob cargas pesadas. Uma solução alternativa é usar uma versão vinculada dinamicamente (como a usada em imagens Docker). Esta falha está [sendo monitorada pelo PHP](https://github.com/php/php-src/issues/13648) | +O código que continua executando além do `memory_limit` pode atingir esse limite, por exemplo, uma única alocação maior que `memory_limit` (como `array_merge()` em grandes arrays) ou concatenações de strings consecutivas. -## `get_browser` +O PHP-FPM perde apenas um processo filho. +O FrankenPHP atende a todas as requisições a partir de threads de um único processo, então cada requisição em andamento é perdida e o servidor para até ser reiniciado. +Execute o FrankenPHP sob um supervisor que o reinicie, como uma política de reinício do Docker ou o `Restart=` do systemd (já configurado nos pacotes `deb` e `rpm`). -A função -[`get_browser()`](https://www.php.net/manual/function.get-browser.php) -parece apresentar mau desempenho após algum tempo. -Uma solução alternativa é armazenar em cache (por exemplo, com -[APCu](https://www.php.net/manual/book.apcu.php)) os resultados por Agente -de Usuário, pois são estáticos. +## get_browser -## Imagens Docker binárias independentes e baseadas em Alpine +A função [`get_browser()`](https://www.php.net/manual/function.get-browser.php) parece apresentar mau desempenho após algum tempo. +Uma solução alternativa é armazenar em cache (por exemplo, com [APCu](https://www.php.net/manual/book.apcu.php)) os resultados por Agente de Usuário, pois são estáticos. -As imagens Docker binárias independentes e baseadas em Alpine -(`dunglas/frankenphp:*-alpine`) usam a [`libc` `musl`](https://musl.libc.org/) -em vez de [`glibc` e similares](https://www.etalabs.net/compare_libcs.html) para -manter um tamanho binário menor. +## Binário standalone e imagens Docker baseadas em Alpine + +O binário totalmente estático e as imagens Docker baseadas em Alpine (`dunglas/frankenphp:*-alpine`) usam a [musl libc](https://musl.libc.org/) em vez de [glibc e similares](https://www.etalabs.net/compare_libcs.html), para manter um tamanho de binário menor. Isso pode levar a alguns problemas de compatibilidade. -Em particular, o sinalizador glob `GLOB_BRACE` -[não está disponível](https://www.php.net/manual/function.glob.php). +Em particular, o sinalizador glob `GLOB_BRACE` [não está disponível](https://www.php.net/manual/function.glob.php). + +Prefira usar a variante GNU do binário estático e imagens Docker baseadas em Debian se encontrar problemas. -## Usando `https://127.0.0.1` com o Docker +## Usando `https://127.0.0.1` com Docker Por padrão, o FrankenPHP gera um certificado TLS para `localhost`. É a opção mais fácil e recomendada para desenvolvimento local. -Se você realmente deseja usar `127.0.0.1` como host, é possível configurá-lo -para gerar um certificado definindo o nome do servidor como `127.0.0.1`. +Se você realmente deseja usar `127.0.0.1` como host, é possível configurá-lo para gerar um certificado para ele definindo o nome do servidor como `127.0.0.1`. -Infelizmente, isso não é suficiente ao usar o Docker devido ao -[seu sistema de rede](https://docs.docker.com/network/). -Você receberá um erro TLS semelhante a -`curl: (35) LibreSSL/3.3.6: erro:1404B438:SSL routines:ST_CONNECT:tlsv1 alert internal error`. +Infelizmente, isso não é suficiente ao usar o Docker devido ao [seu sistema de rede](https://docs.docker.com/network/). +Você receberá um erro TLS semelhante a `curl: (35) LibreSSL/3.3.6: error:1404B438:SSL routines:ST_CONNECT:tlsv1 alert internal error`. -Se você estiver usando Linux, uma solução é usar -[o driver de rede do host](https://docs.docker.com/network/network-tutorial-host/): +Se você estiver usando Linux, uma solução é usar [o driver de rede do host](https://docs.docker.com/network/network-tutorial-host/): ```console docker run \ @@ -62,15 +70,9 @@ docker run \ dunglas/frankenphp ``` -O driver de rede do host não é compatível com Mac e Windows. -Nessas plataformas, você terá que descobrir o endereço IP do contêiner e -incluí-lo nos nomes dos servidores. +O driver de rede do host não é compatível com Mac e Windows. Nessas plataformas, você terá que adivinhar o endereço IP do contêiner e incluí-lo nos nomes dos servidores. -Execute o comando `docker network inspect bridge` e verifique a chave -`Containers` para identificar o último endereço IP atribuído atualmente sob a -chave `IPv4Address` e incremente-o em um. -Se nenhum contêiner estiver em execução, o primeiro endereço IP atribuído -geralmente é `172.17.0.2`. +Execute o comando `docker network inspect bridge` e verifique a chave `Containers` para identificar o último endereço IP atribuído atualmente sob a chave `IPv4Address`, e incremente-o em um. Se nenhum contêiner estiver em execução, o primeiro endereço IP atribuído geralmente é `172.17.0.2`. Em seguida, inclua isso na variável de ambiente `SERVER_NAME`: @@ -84,13 +86,11 @@ docker run \ > [!CAUTION] > -> Certifique-se de substituir `172.17.0.3` pelo IP que será atribuído ao seu -> contêiner. +> Certifique-se de substituir `172.17.0.3` pelo IP que será atribuído ao seu contêiner. Agora você deve conseguir acessar `https://127.0.0.1` a partir da máquina host. -Se este não for o caso, inicie o FrankenPHP em modo de depuração para tentar -descobrir o problema: +Se este não for o caso, inicie o FrankenPHP em modo de depuração para tentar descobrir o problema: ```console docker run \ @@ -103,24 +103,16 @@ docker run \ ## Scripts do Composer que referenciam `@php` -[Scripts do Composer](https://getcomposer.org/doc/articles/scripts.md) podem -querer executar um binário PHP para algumas tarefas, por exemplo, em -[um projeto Laravel](laravel.md) para executar -`@php artisan package:discover --ansi`. -Isso -[atualmente falha](https://github.com/php/frankenphp/issues/483#issuecomment-1899890915) -por dois motivos: +[Scripts do Composer](https://getcomposer.org/doc/articles/scripts.md) podem querer executar um binário PHP para algumas tarefas, por exemplo, em [um projeto Laravel](laravel.md) para executar `@php artisan package:discover --ansi`. Isso [atualmente falha](https://github.com/php/frankenphp/issues/483#issuecomment-1899890915) por dois motivos: - O Composer não sabe como chamar o binário do FrankenPHP; -- O Composer pode adicionar configurações do PHP usando a flag `-d` no comando, - que o FrankenPHP ainda não suporta. +- O Composer pode adicionar configurações do PHP usando a flag `-d` no comando, que o FrankenPHP ainda não suporta. -Como solução alternativa, podemos criar um script de shell em -`/usr/local/bin/php` que remove os parâmetros não suportados e, em seguida, -chama o FrankenPHP: +Como solução alternativa, podemos criar um script de shell em `/usr/local/bin/php` que remove os parâmetros não suportados e, em seguida, chama o FrankenPHP: ```bash #!/usr/bin/env bash +# /usr/local/bin/php args=("$@") index=0 for i in "$@" @@ -135,8 +127,7 @@ done /usr/local/bin/frankenphp php-cli ${args[@]} ``` -Em seguida, defina a variável de ambiente `PHP_BINARY` para o caminho do nosso -script `php` e execute o Composer: +Em seguida, defina a variável de ambiente `PHP_BINARY` para o caminho do nosso script `php` e execute o Composer: ```console export PHP_BINARY=/usr/local/bin/php @@ -145,8 +136,7 @@ composer install ## Solução de problemas de TLS/SSL com binários estáticos -Ao usar binários estáticos, você pode encontrar os seguintes erros relacionados -a TLS, por exemplo, ao enviar emails usando STARTTLS: +Ao usar binários estáticos, você pode encontrar os seguintes erros relacionados a TLS, por exemplo, ao enviar emails usando STARTTLS: ```text Unable to connect with STARTTLS: stream_socket_enable_crypto(): SSL operation failed with code 5. OpenSSL Error messages: @@ -156,30 +146,22 @@ error:80000002:system library::No such file or directory error:0A000086:SSL routines::certificate verify failed ``` -Como o binário estático não empacota certificados TLS, você precisa apontar o -OpenSSL para a instalação local de certificados de CA. +Como o binário estático não empacota certificados TLS, você precisa apontar o OpenSSL para a instalação local de certificados de CA. -Inspecione a saída de -[`openssl_get_cert_locations()`](https://www.php.net/manual/function.openssl-get-cert-locations.php), -para descobrir onde os certificados de CA devem ser instalados e armazene-os -neste local. +Inspecione a saída de [`openssl_get_cert_locations()`](https://www.php.net/manual/function.openssl-get-cert-locations.php), para descobrir onde os certificados de CA devem ser instalados e armazene-os neste local. > [!WARNING] > > Contextos web e CLI podem ter configurações diferentes. -> Certifique-se de executar `openssl_get_cert_locations()` no contexto -> apropriado. +> Certifique-se de executar `openssl_get_cert_locations()` no contexto apropriado. [Certificados CA extraídos do Mozilla podem ser baixados no site do cURL](https://curl.se/docs/caextract.html). -Como alternativa, muitas distribuições, incluindo Debian, Ubuntu e Alpine, -fornecem pacotes chamados `ca-certificates` que contêm esses certificados. +Como alternativa, muitas distribuições, incluindo Debian, Ubuntu e Alpine, fornecem pacotes chamados `ca-certificates` que contêm esses certificados. -Também é possível usar `SSL_CERT_FILE` e `SSL_CERT_DIR` para indicar à OpenSSL -onde procurar certificados CA: +Também é possível usar `SSL_CERT_FILE` e `SSL_CERT_DIR` para indicar à OpenSSL onde procurar certificados CA: ```console # Define variáveis de ambiente para certificados TLS export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt export SSL_CERT_DIR=/etc/ssl/certs -``` diff --git a/docs/ru/known-issues.md b/docs/ru/known-issues.md index 14de020de1..f21477814e 100644 --- a/docs/ru/known-issues.md +++ b/docs/ru/known-issues.md @@ -1,40 +1,65 @@ +--- +title: Известные проблемы FrankenPHP, несовместимые расширения и обходные пути +description: Справочник по ограничениям FrankenPHP, включая неподдерживаемые расширения PHP, особенности musl libc, настройку Docker TLS с 127.0.0.1 и скрипты Composer @php. +--- + # Известные проблемы ## Неподдерживаемые расширения PHP Следующие расширения не совместимы с FrankenPHP: -| Название | Причина | Альтернативы | -| ----------------------------------------------------------------------------------------------------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -| [imap](https://www.php.net/manual/imap.installation.php) | Не поддерживает потокобезопасность | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap) | -| [newrelic](https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/introduction-new-relic-php/) | Не поддерживает потокобезопасность | - | +| Название | Причина | Альтернативы | +| :---------------------------------------------------------------------------------------------------------- | :---------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [imap](https://www.php.net/manual/imap.installation.php) | Не является потокобезопасным | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap), [ImapEngine](https://github.com/DirectoryTree/ImapEngine) | +| [newrelic](https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/introduction-new-relic-php/) | Не является потокобезопасным | - | +| [pcov](https://github.com/krakjoe/pcov) | Не является потокобезопасным ([SIGSEGV в классическом режиме](https://github.com/krakjoe/pcov/issues/132)) | Собирайте покрытие с помощью SAPI CLI (запускайте PHPUnit/Pest вне FrankenPHP) | ## Проблемные расширения PHP Следующие расширения имеют известные ошибки или могут вести себя непредсказуемо при использовании с FrankenPHP: -| Название | Проблема | -| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [ext-openssl](https://www.php.net/manual/book.openssl.php) | При использовании статической сборки FrankenPHP (на базе musl libc) расширение OpenSSL может аварийно завершаться при высокой нагрузке. Решение — использовать динамически связанную сборку (например, ту, что используется в Docker-образах). Ошибка [отслеживается сообществом PHP](https://github.com/php/php-src/issues/13648). | +| Название | Проблема | +| :---------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------- | +| [datadog](https://github.com/DataDog) | Испытывает нестабильность при профилировании FrankenPHP. Эта ошибка [отслеживается DataDog](https://github.com/DataDog/dd-trace-php/issues/3729). | +| [blackfire](https://blackfire.io/) | [Поддержка FrankenPHP находится в бета-версии и ещё не полностью функциональна](https://docs.blackfire.io/php/integrations/frankenphp). | +| [imagick](https://github.com/Imagick/imagick) | Потоки OpenMP ImageMagick конфликтуют с потоками FrankenPHP, вызывая нестабильность и сбои. Смягчить проблему можно, отключив потоки ImageMagick с помощью `\Imagick::setResourceLimit(\Imagick::RESOURCETYPE_THREAD, 1)` или скомпилировав ImageMagick с `--disable-openmp`. OpenMP уже отключен в статических бинарных файлах и официальных пакетах `apt`/`apk`/`rpm`, поэтому затронуты только образы Docker и установки Homebrew. | + +## Превышение жёсткого лимита памяти PHP останавливает весь сервер + +Начиная с PHP 8.2.35, 8.3.36, 8.4.27 и 8.5.12, превышение `memory_limit` больше не останавливает скрипт немедленно: фатальная ошибка "Allowed memory size exhausted" возникает при следующем вызове функции или итерации цикла. +Если скрипт выделяет память за пределы жёсткого лимита памяти до этого, PHP завершает процесс. +Жёсткий лимит по умолчанию составляет двукратный `memory_limit` (или `memory_limit` плюс 1 ГиБ сверх 1 ГиБ) и может быть изменён с помощью настройки INI `memory_hard_limit_percent`. + +Код, продолжающий выполняться после `memory_limit`, может достичь жёсткого лимита, например, при одном выделении памяти, превышающем `memory_limit` (таком как `array_merge()` для больших массивов), или при последовательных конкатенациях строк. -## `get_browser` +PHP-FPM теряет только один дочерний процесс. +FrankenPHP обслуживает все запросы из потоков одного процесса, поэтому каждый обрабатываемый запрос будет потерян, а сервер остановится до перезапуска. +Запускайте FrankenPHP под управлением супервизора, который его перезапускает, например, с помощью политики перезапуска Docker или настройки `Restart=` в systemd (уже установлено в пакетах `deb` и `rpm`). -Функция [get_browser()](https://www.php.net/manual/function.get-browser.php) начинает работать медленно через некоторое время. Решение — кэшировать результаты для каждого User-Agent, например, с помощью [APCu](https://www.php.net/manual/book.apcu.php), так как они статичны. +## get_browser + +Функция [get_browser()](https://www.php.net/manual/function.get-browser.php) со временем начинает работать медленно. Решение — кэшировать результаты для каждого User-Agent (например, с помощью [APCu](https://www.php.net/manual/book.apcu.php)), так как они статичны. ## Автономные бинарные файлы и образы на базе Alpine -Автономные бинарные файлы и образы на базе Alpine (`dunglas/frankenphp:*-alpine`) используют [musl libc](https://musl.libc.org/) вместо [glibc](https://www.etalabs.net/compare_libcs.html) для уменьшения размера бинарных файлов. Это может вызвать проблемы совместимости. В частности, флаг `GLOB_BRACE` в функции glob [не поддерживается](https://www.php.net/manual/function.glob.php). +Полностью статический бинарный файл и образы Docker на базе Alpine (`dunglas/frankenphp:*-alpine`) используют [musl libc](https://musl.libc.org/) вместо [glibc и его друзей](https://www.etalabs.net/compare_libcs.html) для уменьшения размера бинарного файла. +Это может привести к некоторым проблемам совместимости. +В частности, флаг `GLOB_BRACE` [недоступен](https://www.php.net/manual/function.glob.php). + +Если вы столкнетесь с проблемами, предпочитайте использовать GNU-вариант статического бинарного файла и образы Docker на базе Debian. ## Использование `https://127.0.0.1` с Docker -По умолчанию FrankenPHP генерирует TLS-сертификат для `localhost`, что является самым простым и рекомендуемым вариантом для локальной разработки. +По умолчанию FrankenPHP генерирует TLS-сертификат для `localhost`. +Это самый простой и рекомендуемый вариант для локальной разработки. -Если вы всё же хотите использовать `127.0.0.1`, настройте генерацию сертификата, указав в переменной окружения `SERVER_NAME` значение `127.0.0.1`. +Если вы действительно хотите использовать `127.0.0.1` в качестве хоста, его можно настроить для генерации сертификата, установив имя сервера в `127.0.0.1`. -Однако этого может не хватить при использовании Docker из-за [особенностей его сетевой системы](https://docs.docker.com/network/). Возможна ошибка TLS вида: -`curl: (35) LibreSSL/3.3.6: error:1404B438:SSL routines:ST_CONNECT:tlsv1 alert internal error`. +К сожалению, этого недостаточно при использовании Docker из-за [его сетевой системы](https://docs.docker.com/network/). +Вы получите ошибку TLS, похожую на `curl: (35) LibreSSL/3.3.6: error:1404B438:SSL routines:ST_CONNECT:tlsv1 alert internal error`. -Если вы используете Linux, можно воспользоваться [host-драйвером](https://docs.docker.com/network/network-tutorial-host/): +Если вы используете Linux, решением является использование [драйвера хостовой сети](https://docs.docker.com/network/network-tutorial-host/): ```console docker run \ @@ -44,11 +69,11 @@ docker run \ dunglas/frankenphp ``` -Host-драйвер не поддерживается на Mac и Windows. На этих платформах нужно определить IP-адрес контейнера и включить его в `SERVER_NAME`. +Драйвер хостовой сети не поддерживается на Mac и Windows. На этих платформах вам придется угадать IP-адрес контейнера и включить его в имена серверов. -Выполните команду `docker network inspect bridge`, найдите ключ `Containers` и определите последний присвоенный IP из `IPv4Address`. Увеличьте его на единицу. Если контейнеров нет, первый IP обычно `172.17.0.2`. +Выполните `docker network inspect bridge` и найдите ключ `Containers`, чтобы определить последний текущий назначенный IP-адрес в ключе `IPv4Address`, и увеличьте его на единицу. Если контейнеры не запущены, первый назначенный IP-адрес обычно `172.17.0.2`. -Включите этот IP в переменную окружения `SERVER_NAME`: +Затем включите это в переменную окружения `SERVER_NAME`: ```console docker run \ @@ -59,11 +84,12 @@ docker run \ ``` > [!CAUTION] +> > Обязательно замените `172.17.0.3` на IP, который будет присвоен вашему контейнеру. -Теперь вы должны иметь доступ к `https://127.0.0.1`. +Теперь вы сможете получить доступ к `https://127.0.0.1` с хост-машины. -Если это не так, запустите FrankenPHP в режиме отладки: +Если это не так, запустите FrankenPHP в режиме отладки, чтобы попытаться выяснить проблему: ```console docker run \ @@ -76,16 +102,16 @@ docker run \ ## Скрипты Composer с использованием `@php` -[Скрипты Composer](https://getcomposer.org/doc/articles/scripts.md) могут вызывать PHP для выполнения задач, например, в [проекте Laravel](laravel.md) для команды `@php artisan package:discover --ansi`. -Это [на данный момент не поддерживается](https://github.com/php/frankenphp/issues/483#issuecomment-1899890915) по двум причинам: +[Скрипты Composer](https://getcomposer.org/doc/articles/scripts.md) могут вызывать бинарный файл PHP для выполнения некоторых задач, например, в [проекте Laravel](laravel.md) для запуска `@php artisan package:discover --ansi`. Это [в настоящее время не удается](https://github.com/php/frankenphp/issues/483#issuecomment-1899890915) по двум причинам: - Composer не знает, как вызывать бинарный файл FrankenPHP; -- Composer может добавлять настройки PHP через флаг `-d`, который FrankenPHP пока не поддерживает. +- Composer может добавлять настройки PHP с помощью флага `-d` в команде, который FrankenPHP пока не поддерживает. -Решение — создать shell-скрипт в `/usr/local/bin/php`, который удаляет неподдерживаемые параметры и вызывает FrankenPHP: +В качестве обходного пути мы можем создать shell-скрипт в `/usr/local/bin/php`, который удаляет неподдерживаемые параметры, а затем вызывает FrankenPHP: ```bash #!/usr/bin/env bash +# /usr/local/bin/php args=("$@") index=0 for i in "$@" @@ -107,9 +133,9 @@ export PHP_BINARY=/usr/local/bin/php composer install ``` -## TLS/SSL: проблемы со статическими бинарными файлами +## Устранение неполадок TLS/SSL со статическими бинарными файлами -При использовании статических бинарных файлов могут возникать следующие ошибки TLS, например, при отправке писем через STARTTLS: +При использовании статических бинарных файлов вы можете столкнуться со следующими ошибками, связанными с TLS, например, при отправке электронных писем с использованием STARTTLS: ```text Unable to connect with STARTTLS: stream_socket_enable_crypto(): SSL operation failed with code 5. OpenSSL Error messages: @@ -119,22 +145,23 @@ error:80000002:system library::No such file or directory error:0A000086:SSL routines::certificate verify failed ``` -Статический бинарный файл не включает TLS-сертификаты, поэтому необходимо указать OpenSSL местоположение локальных сертификатов CA. +Поскольку статический бинарный файл не включает TLS-сертификаты, вам необходимо указать OpenSSL путь к локальной установке CA-сертификатов. -Выполните [`openssl_get_cert_locations()`](https://www.php.net/manual/function.openssl-get-cert-locations.php), чтобы определить, где должны находиться сертификаты CA, и поместите их туда. +Проверьте вывод [`openssl_get_cert_locations()`](https://www.php.net/manual/function.openssl-get-cert-locations.php), +чтобы определить, куда должны быть установлены CA-сертификаты, и поместите их в это место. > [!WARNING] -> Веб и CLI контексты могут иметь разные настройки. -> Запустите `openssl_get_cert_locations()` в нужном контексте. +> +> Веб- и CLI-контексты могут иметь разные настройки. +> Убедитесь, что вы запускаете `openssl_get_cert_locations()` в соответствующем контексте. -[Сертификаты CA, извлечённые из Mozilla, можно скачать с сайта cURL](https://curl.se/docs/caextract.html). +[CA-сертификаты, извлечённые из Mozilla, можно скачать с сайта cURL](https://curl.se/docs/caextract.html). -Кроме того, многие дистрибутивы, такие как Debian, Ubuntu и Alpine, предоставляют пакеты `ca-certificates`, содержащие эти сертификаты. +Кроме того, многие дистрибутивы, включая Debian, Ubuntu и Alpine, предоставляют пакеты с именем `ca-certificates`, которые содержат эти сертификаты. -Также можно использовать переменные `SSL_CERT_FILE` и `SSL_CERT_DIR`, чтобы указать OpenSSL, где искать сертификаты CA: +Также можно использовать `SSL_CERT_FILE` и `SSL_CERT_DIR`, чтобы подсказать OpenSSL, где искать CA-сертификаты: ```console # Установите переменные окружения для TLS-сертификатов export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt export SSL_CERT_DIR=/etc/ssl/certs -``` diff --git a/docs/tr/known-issues.md b/docs/tr/known-issues.md index a0f851446e..bc2a1e6645 100644 --- a/docs/tr/known-issues.md +++ b/docs/tr/known-issues.md @@ -1,37 +1,63 @@ +--- +title: FrankenPHP bilinen sorunlar, uyumsuz eklentiler ve geçici çözümler +description: Desteklenmeyen PHP eklentileri, musl libc uyarıları, 127.0.0.1 ile Docker TLS kurulumu ve Composer @php betikleri dahil olmak üzere FrankenPHP sınırlamalarının referansı. +--- + # Bilinen sorunlar ## Desteklenmeyen PHP eklentileri Aşağıdaki eklentilerin FrankenPHP ile uyumlu olmadığı bilinmektedir: -| Adı | Nedeni | Alternatifleri | -| ----------------------------------------------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------- | -| [imap](https://www.php.net/manual/imap.installation.php) | İş parçacığı güvenli değil | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap) | +| Adı | Nedeni | Alternatifler | +|---|---|---| +| [imap](https://www.php.net/manual/imap.installation.php) | İş parçacığı güvenli değil | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap), [ImapEngine](https://github.com/DirectoryTree/ImapEngine) | +| [newrelic](https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/introduction-new-relic-php/) | İş parçacığı güvenli değil | - | +| [pcov](https://github.com/krakjoe/pcov) | İş parçacığı güvenli değil ([klasik modda SIGSEGV](https://github.com/krakjoe/pcov/issues/132)) | Kapsamı CLI SAPI ile toplayın (PHPUnit/Pest'i FrankenPHP dışında çalıştırın) | ## Sorunlu PHP eklentileri Aşağıdaki eklentiler FrankenPHP ile kullanıldığında bilinen hatalara ve beklenmeyen davranışlara sahiptir: -| Adı | Problem | -| --- | ------- | +| Adı | Sorun | +|---|---| +| [datadog](https://github.com/DataDog) | FrankenPHP'yi profilleyerken kararsızlık yaşıyor. Bu hata [DataDog tarafından takip ediliyor](https://github.com/DataDog/dd-trace-php/issues/3729). | +| [blackfire](https://blackfire.io/) | [FrankenPHP desteği beta aşamasındadır ve henüz özellikler tamamlanmamıştır](https://docs.blackfire.io/php/integrations/frankenphp). | +| [imagick](https://github.com/Imagick/imagick) | ImageMagick'in OpenMP iş parçacıkları FrankenPHP'nin iş parçacıklarıyla çakışarak kararsızlığa ve çökmelere neden olur. Bu durum, ImageMagick iş parçacıklarını `\Imagick::setResourceLimit(\Imagick::RESOURCETYPE_THREAD, 1)` aracılığıyla devre dışı bırakarak veya ImageMagick'i `--disable-openmp` ile derleyerek hafifletilebilir. OpenMP, statik ikili dosyalarda ve resmi `apt`/`apk`/`rpm` paketlerinde zaten devre dışıdır, bu nedenle yalnızca Docker imajları ve Homebrew kurulumları etkilenir. | + +## PHP'nin sabit bellek sınırını aşmak tüm sunucuyu durdurur + +PHP 8.2.35, 8.3.36, 8.4.27 ve 8.5.12'den beri, `memory_limit`'in aşılması betiği hemen durdurmaz: "Allowed memory size exhausted" (İzin verilen bellek boyutu tükendi) ölümcül hatası bir sonraki fonksiyon çağrısında veya döngü iterasyonunda yükseltilir. +Eğer betik, bundan önce sabit bellek sınırını aşacak şekilde bellek ayırırsa, PHP süreci sonlandırır. +Sabit sınır varsayılan olarak `memory_limit`'in iki katıdır (veya 1 GiB'ın üzerinde 1 GiB artı `memory_limit`'tir) ve `memory_hard_limit_percent` INI ayarı ile değiştirilebilir. + +`memory_limit`'i aşan kodlar, örneğin `memory_limit`'ten daha büyük tek bir tahsis (büyük dizilerde `array_merge()` gibi) veya ardışık dize birleştirmeleri gibi durumlarda bu sınıra ulaşabilir. + +PHP-FPM yalnızca bir çocuk sürecini kaybeder. +FrankenPHP, tüm istekleri tek bir sürecin iş parçacıklarından sunar, bu nedenle devam eden her istek kaybolur ve sunucu yeniden başlatılana kadar durur. +FrankenPHP'yi, Docker yeniden başlatma politikası veya systemd'nin `Restart=` (deb ve rpm paketlerinde zaten ayarlanmış olan) gibi onu yeniden başlatan bir denetleyici altında çalıştırın. ## get_browser [get_browser()](https://www.php.net/manual/function.get-browser.php) fonksiyonu bir süre sonra kötü performans gösteriyor gibi görünüyor. Geçici bir çözüm, statik oldukları için User-Agent başına sonuçları önbelleğe almaktır (örneğin [APCu](https://www.php.net/manual/book.apcu.php) ile). -## Binary çıktısı ve Alpine tabanlı Docker imajları +## Bağımsız ikili dosya ve Alpine tabanlı Docker imajları + +Tamamen statik ikili dosya ve Alpine tabanlı Docker imajları (`dunglas/frankenphp:*-alpine`), daha küçük bir ikili dosya boyutu korumak için [glibc ve benzerleri](https://www.etalabs.net/compare_libcs.html) yerine [musl libc](https://musl.libc.org/) kullanır. +Bu durum bazı uyumluluk sorunlarına yol açabilir. +Özellikle, glob bayrağı `GLOB_BRACE` [mevcut değildir](https://www.php.net/manual/function.glob.php). -Binary çıktısı ve Alpine tabanlı Docker imajları (dunglas/frankenphp:\*-alpine), daha küçük bir binary boyutu korumak için glibc ve arkadaşları yerine musl libc kullanır. Bu durum bazı uyumluluk sorunlarına yol açabilir. Özellikle, glob seçeneği GLOB_BRACE mevcut değildir. +Sorun yaşarsanız, statik ikili dosyanın GNU varyantını ve Debian tabanlı Docker imajlarını kullanmayı tercih edin. ## Docker ile `https://127.0.0.1` kullanımı FrankenPHP varsayılan olarak `localhost` için bir TLS sertifikası oluşturur. Bu, yerel geliştirme için en kolay ve önerilen seçenektir. -Bunun yerine ana bilgisayar olarak `127.0.0.1` kullanmak istiyorsanız, sunucu adını `127.0.0.1` şeklinde ayarlayarak bunun için bir sertifika oluşturacak yapılandırma yapmak mümkündür. +Bunun yerine ana bilgisayar olarak `127.0.0.1` kullanmak istiyorsanız, sunucu adını `127.0.0.1` olarak ayarlayarak bunun için bir sertifika oluşturacak şekilde yapılandırmak mümkündür. Ne yazık ki, [ağ sistemi](https://docs.docker.com/network/) nedeniyle Docker kullanırken bu yeterli değildir. -`Curl: (35) LibreSSL/3.3.6: error:1404B438:SSL routines:ST_CONNECT:tlsv1 alert internal error`'a benzer bir TLS hatası alırsınız. +`curl: (35) LibreSSL/3.3.6: error:1404B438:SSL routines:ST_CONNECT:tlsv1 alert internal error` benzeri bir TLS hatası alırsınız. Linux kullanıyorsanız, [ana bilgisayar ağ sürücüsünü](https://docs.docker.com/network/network-tutorial-host/) kullanmak bir çözümdür: @@ -45,7 +71,7 @@ docker run \ Ana bilgisayar ağ sürücüsü Mac ve Windows'ta desteklenmez. Bu platformlarda, konteynerin IP adresini tahmin etmeniz ve bunu sunucu adlarına dahil etmeniz gerekecektir. -`docker network inspect bridge`'i çalıştırın ve `IPv4Address` anahtarının altındaki son atanmış IP adresini belirlemek için `Containers` anahtarına bakın ve bir artırın. Eğer hiçbir konteyner çalışmıyorsa, ilk atanan IP adresi genellikle `172.17.0.2`dir. +`docker network inspect bridge` komutunu çalıştırın ve `Containers` anahtarının altındaki `IPv4Address` anahtarındaki son atanmış IP adresini belirlemek için bakın, ardından bu IP'yi bir artırın. Eğer hiçbir konteyner çalışmıyorsa, ilk atanan IP adresi genellikle `172.17.0.2`dir. Ardından, bunu `SERVER_NAME` ortam değişkenine ekleyin: @@ -59,7 +85,7 @@ docker run \ > [!CAUTION] > -> 172.17.0.3`ü konteynerinize atanacak IP ile değiştirdiğinizden emin olun. +> `172.17.0.3`'ü konteynerinize atanacak IP ile değiştirdiğinizden emin olun. Artık ana makineden `https://127.0.0.1` adresine erişebilmeniz gerekir. @@ -74,21 +100,25 @@ docker run \ dunglas/frankenphp ``` -## `@php` referanslı Composer betikler +## `@php` referanslı Composer betikleri -[Composer betikleri](https://getcomposer.org/doc/articles/scripts.md) bazı görevler için bir PHP binary çalıştırmak isteyebilir, örneğin [bir Laravel projesinde](laravel.md) `@php artisan package:discover --ansi` çalıştırmak. Bu [şu anda mümkün değil](https://github.com/php/frankenphp/issues/483#issuecomment-1899890915) ve 2 nedeni var: +[Composer betikleri](https://getcomposer.org/doc/articles/scripts.md) bazı görevler için bir PHP ikili dosyası çalıştırmak isteyebilir, örneğin [bir Laravel projesinde](laravel.md) `@php artisan package:discover --ansi` çalıştırmak. Bu durum [şu anda başarısız oluyor](https://github.com/php/frankenphp/issues/483#issuecomment-1899890915) ve iki nedeni vardır: -- Composer FrankenPHP binary dosyasını nasıl çağıracağını bilmiyor; +- Composer, FrankenPHP ikili dosyasını nasıl çağıracağını bilmiyor; - Composer, FrankenPHP'nin henüz desteklemediği `-d` bayrağını kullanarak PHP ayarlarını komuta ekleyebilir. Geçici bir çözüm olarak, `/usr/local/bin/php` içinde desteklenmeyen parametreleri silen ve ardından FrankenPHP'yi çağıran bir kabuk betiği oluşturabiliriz: ```bash -#!/bin/bash +#!/usr/bin/env bash +# /usr/local/bin/php +# Parametreleri bir diziye kopyala args=("$@") index=0 +# Parametreleri döngüye al for i in "$@" do + # "-d" bayrağını ve sonraki parametreyi kaldır if [ "$i" == "-d" ]; then unset 'args[$index]' unset 'args[$index+1]' @@ -96,12 +126,44 @@ do index=$((index+1)) done -/usr/local/bin/frankenphp php-cli ${args[@]} +/usr/local/bin/frankenphp php-cli "${args[@]}" ``` -Ardından `PHP_BINARY` ortam değişkenini PHP betiğimizin yoluna ayarlayın ve Composer bu yolla çalışacaktır: +Ardından `PHP_BINARY` ortam değişkenini PHP betiğimizin yoluna ayarlayın ve Composer'ı çalıştırın: -```bash +```console export PHP_BINARY=/usr/local/bin/php composer install ``` + +## Statik ikili dosyalarla TLS/SSL sorunlarını giderme + +Statik ikili dosyaları kullanırken, örneğin STARTTLS kullanarak e-posta gönderirken aşağıdaki TLS ile ilgili hatalarla karşılaşabilirsiniz: + +```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 +``` + +Statik ikili dosya TLS sertifikalarını içermediği için, OpenSSL'i yerel CA sertifikaları kurulumunuza yönlendirmeniz gerekir. + +CA sertifikalarının nereye yüklenmesi gerektiğini bulmak ve bunları bu konuma kaydetmek için [`openssl_get_cert_locations()`](https://www.php.net/manual/function.openssl-get-cert-locations.php) çıktısını inceleyin. + +> [!WARNING] +> +> Web ve CLI bağlamlarının farklı ayarları olabilir. +> `openssl_get_cert_locations()` fonksiyonunu doğru bağlamda çalıştırdığınızdan emin olun. + +Mozilla'dan çıkarılan CA sertifikaları [cURL sitesinden indirilebilir](https://curl.se/docs/caextract.html). + +Alternatif olarak, Debian, Ubuntu ve Alpine dahil olmak üzere birçok dağıtım, bu sertifikaları içeren `ca-certificates` adlı paketler sunar. + +OpenSSL'e CA sertifikalarını nerede arayacağını belirtmek için `SSL_CERT_FILE` ve `SSL_CERT_DIR` ortam değişkenlerini kullanmak da mümkündür: + +```console +# TLS sertifikaları ortam değişkenlerini ayarla +export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt +export SSL_CERT_DIR=/etc/ssl/certs