ENbext.dev
DocumentationIntégrations de frameworks

Traduction automatique depuis l’anglais. Consulter l’original.

Sur cette page

Intégration Laravel

bext exécute Laravel à l'intérieur du processus Edge. Contrairement à l'intégration Rails - qui inverse le proxy vers un Puma externe - bext intègre libphp via un SAPI personnalisé ( crates/bext-php ) et envoie chaque requête à un noyau Laravel conservé dans la mémoire du thread de travail. Il n'y a pas de php-fpm, pas de socket FastCGI, pas de sous-processus. Un binaire sert TLS, HTTP/2/3, WAF, cache et PHP.

Le mode Worker va plus loin : le noyau Laravel démarre une fois par thread de travail au démarrage, et chaque requête ultérieure réutilise ce noyau via une boucle bext_handle_request(...). La surcharge par requête passe du classique 1 à 5 ms (chargement automatique du Composer + reconstruction de la configuration + câblage du conteneur) à environ 34 us (réutilisation du noyau + cycle GC).

Quand l’utiliser. Si vous avez déjà un projet Laravel et vous voulez un serveur Edge + application mono-binaire sans opérations empreinte, cette intégration est faite pour vous. Si tu veux du classique FastCGI avec php-fpm, le proxy inverse de bext peut lui transmettre les requêtes, mais le mode intégré est strictement plus rapide et plus simple.

Architecture#

code
    ┌─────────┐          ┌───────────────────────────────────────┐
    │         │  HTTPS   │                bext                   │
    │ client  │ ───────► │  TLS • WAF • cache • obs • PHP kernel │
    │         │  :443    │                :8080                  │
    └─────────┘          └───────────────────────────────────────┘
                                        │
                                        ▼ (in-process, 34 us)
                               ┌──────────────────┐
                               │  Laravel kernel  │
                               │   (per worker)   │
                               └──────────────────┘

Parcours d’une requête :

  1. Le client ouvre une connexion TLS vers bext sur :443, ou :8080 en développement.
  2. bext termine TLS, exécute le WAF, vérifie le cache ISR et achemine la requête. Les ressources statiques sous /build/*, /storage/*, /favicon.ico et /robots.txt sont servies directement depuis le disque, sans faire appel à PHP.
  3. Les requêtes dynamiques sont réparties entre les threads de travail PHP, au nombre de workers. Le rappel bext_handle_request(...) du thread de travail s’active, le noyau de Laravel traite la requête, la réponse revient en streaming vers bext, puis bext l’envoie au client en HTTP/2 ou HTTP/3.

bext.config.toml#

La configuration du projet de démarrage, réduite à l’essentiel :

toml
[server]
port = 8080

[php]
enabled = true
document_root = "./public"
worker_script = "./bootstrap/worker.php"
workers = 4
max_requests = 10000
max_execution_time = 30

[php.ini]
memory_limit = "256M"
post_max_size = "16M"
upload_max_filesize = "16M"

[waf]
enabled = true

[[route_rules]]
pattern = "/build/*"
render = "static"

[[route_rules]]
pattern = "/storage/*"
render = "static"

Champs principaux :

  • worker_script — chemin du fichier PHP qui initialise le noyau une fois par travailleur. Lorsqu'il n'est pas défini, bext revient en mode classique (démarre public/index.php par requête).
  • workers — nombre de noyaux parallèles contenus dans la RAM. Chaque travailleur est un contexte TSRM distinct ; sur NTS PHP, cela est limité à 1.
  • max_requests — le travailleur est recyclé après autant de demandes de contenir des fuites de mémoire dans des packages tiers. bext le redémarre automatiquement sans aucune demande abandonnée.
  • [php.ini] — n'importe quelle clé PHP INI ; bext définit une production raisonnable valeurs par défaut (OPcache activé, opcache.validate_timestamps=0, durcissement des fonctions désactivées, sandboxing open_basedir, JIT désactivé par défaut).

Voir référence [php] pour la liste complète des champs.

bootstrap/worker.php#

Le cœur du mode travailleur. S'exécute une fois par thread au démarrage, puis boucle :

php
<?php
require __DIR__ . '/../vendor/autoload.php';

$app = require __DIR__ . '/app.php';
$kernel = $app->make(\Illuminate\Contracts\Http\Kernel::class);

while (bext_handle_request(function () use ($kernel) {
    $response = $kernel->handle(
        $request = \Illuminate\Http\Request::capture()
    );
    $response->send();
    $kernel->terminate($request, $response);
})) {
    gc_collect_cycles();
}

bext_handle_request est une fonction hôte exposée par bext -php. Il bloque jusqu'à ce qu'une requête arrive, appelle le rappel et renvoie true — à moins que le travailleur ait atteint max_requests, auquel cas il renvoie false et la boucle while se termine proprement afin que bext puisse générer un travailleur de remplacement.

Ce que bext ajoute#

Préoccupation Qui s'en occupe
TLS / ACME bext
HTTP/2, HTTP/3 (QUIC) bext
WAF (bots, limite de débit) bext
Cache périphérique (ISR/SWR) bext
Compression (brotli) bext
Métriques Prometheus bext
Traces OpenTelemetry bext
Service d'actifs statiques bext (voir les règles d'itinéraire ci-dessus)
Exécution PHP bext (libphp SAPI intégré)
Logique métier Laravel
Éloquent / DB Laravel
Files d'attente / tâches Laravel (Horizon, synchronisation, base de données)
Artisan / migrations Laravel

Invalidation du cache à partir de Laravel#

Le package compagnon bext/laravel Composer enregistre les aides pour invalider le cache ISR de bext depuis l'intérieur d'un contrôleur :

php
class ProductController extends Controller
{
    public function update(Request $request, string $id)
    {
        $product = Product::findOrFail($id)->update($request->all());

        // Invalidate ISR cache entries tagged "products"
        bext_invalidate("products");

        return response()->json($product);
    }
}

Voir la référence complète de l'assistant bext/laravel ci-dessous.

Aides et services#

Installez le package Composer compagnon pour déverrouiller les assistants de cache, en temps réel et de tâches :

bash
composer require bext/laravel

Trois globaux sont alors disponibles partout :

php
bext_invalidate("products");
bext_publish("orders", ["id" => 123, "status" => "shipped"]);
bext_task("cleanup", "0 2 * * *", "cache::gc");

Ou injecter à partir du récipient :

php
app('bext.cache')->invalidate("products");
app('bext.realtime')->publish("orders", [...]);
app('bext.tasks')->register("daily-report", "0 9 * * 1-5", $url);

Détection#

Le scanner importation infrarouge de bext reconnaît un projet Laravel à partir de :

  • un composer.json qui déclare laravel/framework, et
  • un fichier CLI artisan

Lorsque les deux sont présents, bext infra import suggère le modèle d'intégration Laravel et propose un échafaudage à partir de @bext/starter-laravel.

L'entrée de catalogue réside dans crates/bext-import/catalog/frameworks.yaml :

yaml
- match:
    any_of_files:
      - "composer.json"
      - "artisan"
    composer:
      any_of_packages:
        - "laravel/framework"
  extract:
    framework: laravel
    starter: "@bext/starter-laravel"
  confidence: high

Le démarreur#

bash
bext new my-laravel-app --template @bext/starter-laravel
cd my-laravel-app
composer install
bext serve

Visitez http://localhost:8080.

Le démarreur est un échafaudage , et non une application Laravel fonctionnelle. Il est livré avec la forme minimale dont bext a besoin : un composer.json, un contrôleur frontal, un bootstrap/worker.php, un minuscule HomeController et Itinéraire web.php et un bext.config.toml avec le bloc [php] câblé. Utilisez composer create-project laravel/laravel pour générer un véritable projet Laravel et supprimez le démarreur bext.config.toml + bootstrap/worker.php – c'est le flux de travail canonique.

Comment cela se compare à Rails#

Dimension bext + Rails bext + Laravel
Modèle de processus bext + Puma séparé bext uniquement (PHP intégré)
Inter -saut de processus Bouclage HTTP/1.1 aucun — appel en cours
Frais généraux par requête ~100 à 300 us (proxy) ~34 nous (mode travailleur)
Langue d'exécution Ruby (interprète externe) PHP (libphp intégré)
Section de configuration [upstreams.*] + proxy = [php]
unités système 2 ( bext + rails-app.service) 1 (bext)
Déployer l'artefact Gemfile + arborescence d'applications + bext compositeur + arborescence d'applications + bext

L'asymétrie existe parce que les écosystèmes PHP et Ruby proposent des histoires d'intégration très différentes. libphp expose un SAPI stable intégré à des dizaines de serveurs Web ; Ruby ne le fait pas. Rails sous Puma est rapide et ergonomique, le chemin du proxy inverse HTTP est donc le bon compromis pour Rails. PHP intégré dans le processus est strictement plus rapide et plus simple pour Laravel.

Attention

Le mode Worker nécessite une version PHP ZTS (thread-safe). PHP non thread-safe (NTS) revient au démarrage classique par requête : pas de noyau persistant, pas de surcharge d'environ 34 µs. Utilisez la distribution PHP prédéfinie de bext (livrée ZTS par défaut) pour éviter une compilation PHP personnalisée.

Limites#

  • Le mode Worker nécessite ZTS PHP. Constructions non thread-safe (NTS) de PHP revient en mode classique (pas de noyau persistant). Créez PHP avec --enable-zts pour débloquer le mode travailleur – ou utilisez la distribution PHP prédéfinie de bext qui fournit ZTS par défaut.
  • Aucune isolation de processus entre les demandes. Parce que les demandes partagez le noyau du travailleur, un crash dans une requête fait planter l'ensemble du travailleur. bext redémarre automatiquement le travailleur et relit les requêtes en cours, mais ce n'est pas aussi infaillible que le modèle de processus par requête de php-fpm. max_requests aide à contenir les fuites lentes.
  • Le premier démarrage est lent. Le démarrage du noyau Laravel prend 100 à 300 ms. opération. bext démarre tous les travailleurs simultanément au démarrage, de sorte que la première requête après bext serve peut toucher les travailleurs froids jusqu'à ce qu'ils apparaissent tous.
  • Les extensions doivent être regroupées au moment de la génération. bext -liens php par rapport à un ensemble d'extensions organisé (pdo_mysql, pdo_pgsql, redis, gd, mbstring, intl, opcache). Les extensions personnalisées nécessitent une reconstruction de bext : elles ne peuvent pas être chargées au moment de l'exécution.

En rapport#

  • Laravel — documentation officielle Laravel
Modifier cette page ↗Besoin d’aide ? ↗
Rechercher dans la documentation

Saisissez un sujet, une commande ou une question.