Libraries (PHP - DVB)

Uit De Vliegende Brigade
Ga naar: navigatie, zoeken

Rond 1987 of 1988, leerde ik via GW-BASIC het concept van programmeerbibliotheken, bibliotheken, programming libraries of libraries kennen. Ik vond het gelijk een geweldig idee: De mogelijkheid om voort te bouwen op eerder gemaakte programmeercode en de mogelijkheid om oplossingen voor bepaalde problemen te abstraheren (dus dat je niet meer hoeft te weten hoe een bepaald probleem wordt opgelost, want dat doet zo'n hergebruikte functie, script of whatever voor je).

Met een bibliotheek bedoel ik trouwens hetzelfde als een script. Het kan gaan om slechts één functie die ik hergebruik, maar ook om een verzameling functies. Tot op heden (april 2021) betreft dit voor mij functies en scripts. Omgevingen:

  • MySQL-Sprocs en -scripts (=gewone sql-bestanden)
  • Bash-scripts
  • PHP-functies & -scripts

De praktijk is weerbarstiger

Het idee achter bibliotheken vind ik geweldig. De praktijk bleek weerbarstiger:

  • Herbruikbaarheid werkt eigenlijk alleen als je langere tijd werkt aan projecten die heel sterk op elkaar lijken
  • Het vervaardigen van robuuste en betrouwbare routines vergt veel tijd en herhaling. Misschien vergelijkbaar met wat de Mythical Man-Month bedoelt met de uitspraak dat van concept-code naar productie-code, een factor 9 aan werk betekent. Of wat Joel on Software bedoelt met hoe lastig het is om code te beheren Things You Should Never Do, Part I. Of program today for today and tomorrow for tomorrow, wat ik in een XP-boek tegenwam
  • Documentatie: Het is naderhand vaak lastig om te weten wat een functie precies doet.

Succesverhaal: MySQL

Desalniettemin is er minimaal één situatie waarin het concept van herbruikbaarheid en abstractie heel goed werkt voor mij: M'n bibliotheek aan sprocs in MySQL rondom datawarehousing.

Een goed voorbeeld is m'n Explode-functie:

  • Zo'n functie had ik écht nodig. Ontwikkeling is geleidelijk gegaan (program today for today and tomorrow for tomorrow)
  • Dat ding werkt verbazend goed
  • De code ziet er niet uit, maar dat boeit niet (abstractie).

Waarom dit werkt - Een paar ideeën:

Unit-tests

Helaas is mijn unit-test-bibliotheek momenteel een rommeltje, maar dit speelt wel een belangrijke rol waarom dit werkt: Als ik het niet meer weet, pak ik er een unit-test bij, en ik weet weer snel hoe de vork in de steel zit

Beperkte context

Ik heb de indruk dat mijn datawarehouse-werkzaamheden een beperkte context hebben - oftewel een sterke focus. Er is dus veel herhaling qua werkzaamheden

Overzichtelijk

Ik kan in m'n basis-datawarehouse (bal_dwh_org) in één oogopslag alle sprocs zien.

Projectdatabase

Per project werk ik meestal met een projectdatabase. Daarin importeer ik de benodigde sprocs. Vanaf dat moment worden ze niet meer gesynchroniseerd, en dat hoeft ook niet. Het is belangrijk dat zulke projectdatabases autonoom zijn

Synchronisatie

  • Heb ik in een projectdatabase een verder-ontwikkelde versie van zo'n sproc, dan exporteer ik 'm weer naar bal_dwh_org
  • Het is altijd duidelijk wat de "hoofd-database" is (bal_dwh_org). In- & uitchecken gebeurt alleen daar.

Eénduidige interface

Op een bepaalde manier is SQL en sprocs heel simpel:

  • Een sproc kan alleen werken op data in dezelfde database als waar de sproc zich bevindt (toch?)
  • Er is maar één manier om een script aan te roepen: In SQL - Da's anders in PHP
  • Het is altijd duidelijk waar de sprocs zich bevinden: In de betreffende database.

Context

  • Dit artikel gaat verder over m'n PHP-bibliotheek. Daar valt nog wat werk te verzetten
  • Ik gebruik PHP uitsluitend voor interactie met WordPress en de PHP-API. Daaruit voortvloeiend ook voor interactie met MySQL-databases.

Locatie van bibliotheek-bestanden

Dit hoofdstuk gaat over de master-varianten van code. Mocht ik per project eigen kopieën van functies/bestanden hebben, dan geldt dit niet (komt nog)

functions.php

Tot ca. 2018 plaatste ik functies die ik wilde hergebruiken, in het standaard WordPress-bestand functions.php.

Laptop

Rond 2019 ben ik gestopt om functies in WordPress' functions.php te plaatsen. De diverse functies heb ik ondergebracht in twee bestanden:

  • /Dropbox/Overhead/Scripts/php/dvb_db_functions.php
  • /Dropbox/Overhead/Scripts/php/dvb_wordpress_functions.php.

In april 2021 heb ik die paden licht gewijzigd:

  • /Dropbox/Overhead/Scripts/php-library-dvb/dvb_db_functions.php
  • /Dropbox/Overhead/Scripts/php-library-dvb/dvb_wordpress_functions.php.

Op m'n laptop wordt er niets opgeslagen in mappen buiten Dropbox, zoals </code>/opt</code> or whatever.

Later in april 2021 heb ik besloten om functies (en varianten daarop) in eigen bestanden onder te brengen. Die staan hiero:

Dropbox/Overhead/Scripts/php-library-dvb

Servers

Ik heb op zo'n beetje al m'n servers een handjevol met eigen routines (bv. voor het updaten van sites). Deze commando's en bibliotheken bevinden zich hier:

/use/local/bin

Wordt tijd voor een versioning-systeem: Synchronisatie is altijd gedoe.

Samenvoegen of per functie?

Tot april 2021 werkte ik met twee bibliotheken. Dus twee bestanden met daarin een handjevol functies:

dvb_db_functions.php:

  • dvb_fetch_table
  • dvb_create_pdo_object

dvb_wordpress_functions.php:

  • dvb_add_attribute_taxonomy
  • dvb_check_attribute_name
  • dvb_delete_all_products
  • dvb_delete_all_thumbnails
  • dvb_delete_all_woocommerce_taxonomical_data

Dilemma

Blijf ik bij deze aanpak, of plaats ik voortaan functies (met eventuele varianten) in aparte bestanden?

De aanleindg - April 2021

Ik vind het gebruik van deze bibliotheekbestanden onhandig:

  • Onoverzichtelijke bestanden (drie niveaus van documentatie ipv. twee)
  • Geen overzicht van de functies
  • Synchronisatie is lastig: Moeilijk om te achterhalen welke versie de juiste is en, en om bestanden op verschillende locaties gesynchroniseerd te houden
  • Werkwijze is rigide. Vermoedelijk, omdat ik niet goed weet of bepaalde functies door andere projecten gebruikt worden. Daardoor ben ik terughoudend om code aan te passen.

Nadelen aparte functies

  • Onhandig om te synchroniseren
  • Onhandig omdat ik in een script vermoedelijk naar meerdere functies tegelijkertijd moet verwijzen (of gaat dat in één keer door $PATH?)

Voordelen aparte functies

  • Je ziet in één oogopslag welke functies er zijn
  • De eigenlijke bestanden met code zijn overzichtelijker
  • Ik denk dat ik al snel variaties op functies ga krijgen (bv. dezelfde functie maar met verschillende default-waardes of context), en het is waarschijnlijk intuïtief om die varianten wel allemaal in één bestand te plaatsen

Nadelen samengevoegde functies

  • Geen overzicht van functies
  • Code is groot en onoverzichtelijk - Ik heb daardoor drie niveaus van hiërarchie in code ipv. de gebruikelijke twee. Daar ben ik niet blij mee
  • Foutgevoelig
  • Het gaat nooit lukken om functies op een intuïtieve manier samen te voegen. Tot april 2021 had ik bibliotheken dvb_db_functies en dvb_wordpress_functies en er is belist overlap tussen die twee. Er is zelfs een goede kans dat ik bepaalde functies per ongeluk in beide bibliotheken heb staan zonder het door te hebben
  • Waarschijnlijk lastig om bestanden gesynchroniseerd te houden: Zo snel één functie verandert, heb ik al een synchronisatie-probleem

Voordelen samengevoegde functies

  • Gemakkelijk te kopiëren en te synchroniseren?

Conclusies - 2021.04.26

Voortaan gebruik ik aparte bestanden per functie:

  • Alleen als ik dingen ga aanpassen. Bestaande functies waar ik momenteel niets mee doe, ga ik ook niet aanpassen
  • Misschien gemakkelijk om per project aparte versies van een functie in zo'n bestand onder te brengen (bv. een versie met input-argumenten voor algemeen gebruik, en eentje zonder zulke argumenten, voor een specifiek project, of voor aanroep door een ander php-script waarin de context al is geïnitialiseerd)
  • Ze staan op m'n laptop hiero: Dropbox/Overhead/Script/php-library

Zie ook