Soms werk ik tegelijkertijd aan drie of vier Laravel-projecten waarvan de PHP-versievereisten compleet van elkaar afwijken. Eén project draait op PHP 8.0 omdat een third-party pakket de sprong naar 8.2 nog niet heeft gemaakt, terwijl een ander project al PHP 8.3 vereist voor de readonly properties in constructors. Voor Herd had ik Valet met wat handmatige config-trucjes, maar Herd's site isolation maakt dat de versie per directory volledig geïsoleerd wordt, zonder dat je daar zelf iets voor hoeft om te schakelen.
Wat site isolation precies doet
Standaard heeft Herd één actieve PHP-versie die voor alle sites geldt. Dat werkt prima als je maar één project draait, maar zodra die mix van versies erbij komt, loop je snel tegen problemen aan. Site isolation legt vast aan welke PHP-versie een specifieke directory gekoppeld is, ongeacht welke versie globaal actief is. Herd regelt dit via de herd isolate opdracht op de commandoregel, waarbij het intern de nginx-configuratie voor die specifieke site aanpast zodat PHP-FPM op de juiste socket draait.
cd ~/Herd/mijn-project
herd isolate [email protected]
Na dit commando draait mijn-project.test op PHP 8.0, ook al heb je globaal PHP 8.3 actief. Controleer je de status via herd which-php, dan zie je per directory welke versie er actief is. Dat is het soort transparantie dat ik prettig vind: geen magie op de achtergrond waar je later achter moet komen.
Het mooie zit hem ook in hoe Herd dit beheert bij het opstarten. Elke geïsoleerde site krijgt zijn eigen PHP-FPM proces met de bijbehorende configuratie. Je hoeft dus niet handmatig processen te herstarten na een reboot of na het wisselen tussen projecten. Dat scheelt een hoop frustratie als je wisselt van werkplek of een nieuwe collega het project voor het eerst opstart.
PHP-versies installeren en beheren
Voordat je een specifieke versie aan een site koppelt, moet die versie wel beschikbaar zijn in Herd. Vanuit de GUI doe je dat via het Herd-icoon in de menubalk, maar ik werk liever via de terminal omdat het sneller gaat.
herd install [email protected]
herd install [email protected]
herd install [email protected]
herd install [email protected]
Herd downloadt dan de juiste PHP-binaries en configureert alles. Elke versie heeft zijn eigen php.ini die je apart kunt aanpassen per versie. Dat is relevant als je voor een specifiek project extensies nodig hebt die je globaal liever niet aanzet, zoals xdebug bij een project waarbij je actief aan het debuggen bent zonder dat alle andere projecten de overhead meesleuren.
herd php-config [email protected]
Dit opent de php.ini voor versie 8.2 direct in je standaard editor. Wil je per geïsoleerde site een aangepaste configuratie? Dat doe je door een .herd/php.ini bestand aan te maken in de root van je project. Herd pikt dat bestand automatisch op en samenvoegt de instellingen met de globale configuratie voor die PHP-versie.
; .herd/php.ini
memory_limit = 512M
upload_max_filesize = 64M
post_max_size = 64M
Dit gebruik ik bijvoorbeeld bij projecten die grote imports verwerken via een CLI-commando. De globale memory limit staat op 256M, maar voor dat ene project heb ik 512M nodig zonder dat ik de globale instelling opschroef.
Artisan en Composer uitvoeren op de juiste PHP-versie
Hier zit een valkuil waar ik in ben getrapt: ook als je site isolation correct hebt ingesteld, gebruikt Artisan of Composer op de commandoregel standaard de globale PHP-versie als je gewoon php artisan typt. De site in de browser draait wel op de juiste versie, maar jouw CLI-commando's niet.
# Fout: gebruikt globale PHP-versie
php artisan migrate
# Goed: gebruikt de geïsoleerde versie van die directory
herd php artisan migrate
Met herd php roep je de PHP-binary aan die voor de huidige directory geconfigureerd is. Dat geldt ook voor Composer-installaties.
herd composer install
herd composer require laravel/telescope
Ik heb een tijdje php artisan in mijn vingers gehad en me afgevraagd waarom bepaalde syntaxfouten opdoken die eigenlijk niet bestonden in de PHP-versie waarvoor ik de code had geschreven. Bleek dat mijn globale versie lager was dan de geïsoleerde versie van het project. Sindsdien gebruik ik consequent herd php voor alles in geïsoleerde projecten, ook in mijn IDE-configuratie voor run-targets.
PHPStorm en VS Code kun je zo instellen dat ze de PHP-binary van Herd als interpreter aanwijzen. Bij PHPStorm doe je dat via de project-interpreter instellingen, waarbij je als pad de Herd-binary meegeeft.
/Users/pim/.config/herd/bin/php
Dat is de generieke symlink die Herd aanmaakt en die altijd wijst naar de versie die voor de huidige directory geconfigureerd is. Zo profiteer je ook in je IDE van de juiste versie voor zaken als code completion en real-time syntax-controle.
Isolatie verwijderen en problemen oplossen
Soms wil je een project terug naar de globale versie brengen, of je merkt dat een site niet op de verwachte versie draait. Isolatie verwijder je met één commando.
cd ~/Herd/mijn-project
herd unisolate
Daarna valt de site terug op de globale PHP-versie. Een overzicht van alle geïsoleerde sites krijg je via herd isolated, zodat je direct ziet welk project welke versie heeft zonder door directories te klikken.
herd isolated
# Toont iets als:
# mijn-project [email protected]
# nieuwe-api [email protected]
# legacy-klantproject [email protected]
Loopt er iets mis en reageert een site onverwacht, dan is het eerste wat ik doe de Herd-services herstarten. Dat lost verrassend veel op, zeker na het installeren van een nieuwe PHP-versie of het aanpassen van een configuratiebestand.
herd restart
Een specifiek PHP-FPM-proces herstart je met herd restart [email protected] als je niet alle services wilt raken. Dat is handig als je midden in een actieve sessie zit op een ander project en dat niet wilt onderbreken. Loopt er dan nog steeds iets mis, dan kijk ik naar de Herd-logbestanden die per PHP-versie worden bijgehouden. Die vind je via herd log [email protected] rechtstreeks in de terminal, of via het Herd-dashboard als je de GUI verkiest.
Soms zie ik bij een nieuw opgezet project dat de site nog steeds de globale versie oppikt terwijl ik isolatie heb ingesteld. Dat gebeurt als Herd de nginx-configuratie nog niet heeft herladen na het herd isolate commando. Een snelle herd restart nginx lost dat dan op. Het is geen groot probleem, maar wel iets om in het achterhoofd te houden als je de tool net leert kennen.
Na een paar maanden werken met site isolation merk ik dat ik veel minder nadenk over versieconfiguratie dan vroeger. Het is nu een eenmalige handeling per project die ik doe zodra ik een repository cloon, samen met het kopiëren van het .env-bestand en het draaien van herd composer install. Die consistentie is waardevol, zeker als je zoals ik regelmatig wisselt tussen oudere klantprojecten en nieuwe builds waar je de nieuwste PHP-features wil inzetten.