12: Geavanceerd

Phlo blijft opzettelijk modulair. Je kunt een app klein houden en alleen de resources activeren die het nodig heeft, of meerdere bronpaden en resourcegroepen combineren.

12.1: App-code en runtime-resources

App-specifieke code behoort in de app zelf. Plaats het niet in /srv/phlo/resources/.

/srv/phlo/resources/ is de Phlo runtime catalogus: framework-brede bronnen die mogelijk gedeeld worden tussen meerdere apps en opzettelijk naast de runtime worden onderhouden. Alleen generieke, stabiele code behoort daar.

Als je code tussen apps wilt delen, maak dan eerst een expliciete gedeelde module of app-bibliotheekpad met een duidelijke eigenaar. Promoot code alleen naar de Phlo runtime catalogus wanneer het echt frameworkfunctionaliteit is.

Een runtime-resource kan een object, functie, stijl of script bieden. Metadata aan de bovenkant van het bestand helpt het Phlo Control Center en de handleiding:

@ summary: Stuur app-notificaties
@ package: notifications
@ frontend: false
@ backend: true

method send($message){
    return HTTP(%creds->notify->url, POST: ['message' => $message])
}

12.2: Meerdere brondirectory's

Houd de standaard eenvoudig: app-bron in het app-pad. Voeg alleen extra paden toe wanneer een codebase echt gedeeld moet worden.

Padkeuzes moeten voorspelbaar blijven:

12.3: Integreren met bestaande PHP

Gebruik Phlo naast bestaande PHP door de runtime te laden en de Phlo entrypoint alleen verantwoordelijk te maken voor de routes die de app afhandelt. Bestaande statische bestanden blijven rechtstreeks door de webserver worden bediend.

<?php
require('/srv/phlo/phlo.php');
phlo_app (
    id: 'Legacy',
    host: 'dev.legacy.test',
    build: true,
    debug: true,
    app: '/srv/legacy/',
);

12.4: Beveiliging en bezoekers

Voor openbare sites is de gebruikelijke basislijn:

{
    "resources": [
        "cookies",
        "security/security",
        "security/token",
        "session",
        "useragent",
        "visitors",
        "phlo.async",
        "DOM/form"
    ]
}

Voor lokale ontwikkeling kun je tracking uitsluiten:

{
    "exclude": [
        "visitors",
        "useragent",
        "wsCast"
    ]
}

12.5: Cookiewall: GDPR-toestemming

DOM/cookiewall is een ingebouwde, subtiele toestemmingsbanner. Activeer het in 3 stappen:

1. Resource in data/app.json:

{ "resources": [..., "DOM/cookiewall"] }

2. Banner in je lay-out:

view layout:
<body>
    {{ %cookiewall->banner }}
    <main>...</main>
</body>

De banner verschijnt alleen wanneer de bezoeker nog geen keuze heeft gemaakt. Twee knoppen: "Alleen essentieel" en "Accepteren". De keuze wordt opgeslagen in een cookie cookieChoice ('essential' of 'all'), geldig voor 1 jaar.

3. Beveiliging rond tracking:

<if %cookiewall->canTrack>
    <script src="https://analytics.example.com/script.js"></script>
</if>
Methode Retourneert
%cookiewall->hasChosen() true zodra de bezoeker iets heeft gekozen
%cookiewall->canTrack true alleen voor de 'all' keuze
%cookiewall->canAnalytics Alias van canTrack, semantisch nuttig voor een analytics brug
%cookiewall->choice 'essential' / 'all' / null

Meertalige variant: DOM/cookiewall.translated (maakt gebruik van de {nl: ...} shorthand voor de banner teksten).

12.6: Worker modus

Standaard draait Phlo per aanvraag: het PHP-proces start, verwerkt de aanvraag, het proces eindigt. Met thread: true in phlo_app(...) blijft de runtime in het geheugen tussen aanvragen, bedoeld voor FrankenPHP, ReactPHP of RoadRunner.

De prestatiewinst is groot (geen opstart per aanvraag), maar er gelden drie regels:

1. Geen die() of exit() in het HTTP-pad. Beide beëindigen de hele worker, niet alleen de huidige aanvraag. Gebruik return of laat een beëindigende oproep (view(), apply(), location()) de respons verzenden.

2. Geen aanvraagstatus in statische eigenschappen. Statics overleven tussen aanvragen. Gegevens van aanvraag A lekken in aanvraag B. Statics zijn alleen veilig voor klassenstructuur of berekende metadata die identiek is voor alle aanvragen, niet voor sessie, gebruiker, payload, tijd of DB-status.

3. Markeer langlevende objecten met $objPers = true. Standaard wist Phlo zijn instantiekaart tussen aanvragen. Voor objecten die je expliciet wilt hergebruiken (DB-verbinding, voorbereide statements), stel $this->objPers = true in zodat de opruiming ze met rust laat.

Combineren met build: true is niet toegestaan: build schrijft bestanden tussen aanvragen, en in een worker is dat een raceconditie. Phlo gooit een runtime-fout als je beide inschakelt.

12.7: Hulpmiddelen aanpassen zonder te forkeren

Soms wil je dat een gedeelde resource zich net iets anders gedraagt in één app, zonder die resource te kopiëren of te veranderen. Vanuit elk .phlo-bestand kun je een node in een andere klasse injecteren of overschrijven door de node te benoemen als %<class>.<node>:

static %visitors.table = 'control.visitors'
prop %visitors.db = 'control'
method %model.greet => 'hi'

De eerste regel overschrijft de static $table van het visitors-model; de tweede voegt een db prop toe aan visitors; de derde voegt een greet method toe aan model. Tijdens de build verwijdert de compiler het %<class>.-voorvoegsel en schrijft de node in <class>: een bestaande node met die naam wordt overschreven, een nieuwe wordt toegevoegd. De doelklasse moet deel uitmaken van de build (de resource moet geladen zijn), anders wordt de modifier stilletjes genegeerd. Houd het node-type identiek aan wat je vervangt (static met static, prop met prop): de hele node wordt verwisseld.

Een praktisch voorbeeld: laat het gedeelde visitors-model schrijven naar een centrale analytics-database, terwijl alle andere queries in de app op de eigen verbinding van de app blijven:

static %visitors.table = 'control.visitors'

Dit houdt de gedeelde resource agnostisch terwijl elke app haar eigen interpretatie geeft.

12.8: Bestand metadata: de complete @ referentie

Elke .phlo-bestand kan worden geopend met @ key: value-regels. Elke sleutel wordt opgeslagen als bestandsmetadata; deze hebben een engine- of tooling-betekenis:

Sleutel Effect
@ class: Overschrijf de PHP-klassenaam
@ extends: PHP-erfelijkheid (standaard: obj)
@ implements: PHP-interfaces, gescheiden door komma's
@ use: PHP use-verklaring (Full\Name as Alias)
@ namespace: PHP-namespace
@ type: class (standaard), abstract class, interface of trait
@ summary: Een-regelige beschrijving, weergegeven in de handleiding, reflectie en het Phlo Control Center
@ package: Groepsnaam voor tooling
@ frontend: / @ backend: Markeert een resource als alleen frontend- of backend
@ requires: Afhankelijkheden, opgelost wanneer de resource is ingeschakeld; name? is optioneel, php-ext: en creds: vermeldingen zijn informatief
@ provides: / @ binds: Frontend-API's aangeboden / selectors gekoppeld; voedt reflect::selectorGraph
@ tags: Vrije labels, weergegeven in reflectie-indexen
@ advice: Ontwikkelaarsrichtlijnen, weergegeven in reflect::objectIndex

12.9: Best practices

We gebruiken essentiële cookies om deze site te laten werken. Met uw toestemming gebruiken we ook analytics om de site te verbeteren.