Blog

Dokumentation som är bra

Jag anpassar för närvarande Bokarenan till att nyttja Symfonys olika komponenter. Det är åtminstone planen men det blir mycket läsande. Jag är ute på nya marker när jag nu utforskar ett framework utan en bok som grund. Men det gör ingenting! Jag tycker dokumentationen är utmärkt. Symfony har guider för att komma igång med grunderna, för att starta med Unit-tester och för att sätta upp ett inloggningssystem. Fler finns det, men detta är så många som jag har gjort just nu. För närvarande går jag igenom Security-guiden. Eller, jag höll på med det, tills den föreslog att jag skulle gå igenom guiden för att sätta upp en inloggningssida. Det blir lite som att hoppa ned i hål efter hål, och hoppas man kommer tillbaka någon gång.

Den här veckan har det gått långsamt att programmera. Det har kanske blivit att jag funnit en timme per dag att programmera eller läsa om programmering. Anledningen: bebisarna växer och behöver mer stimulans, och jag har känt ett ökat behov av att träna mer. Det blir därför fler promenader och ett antal timmar på gymmet under veckan. Men jag känner mig nöjd med programmeringen. Jag är i huvudsak pappa, och programmering är min hobby. Så länge som jag hittar någon tid att sitta ned och programmera så är jag nöjd.

Det jag kommer göra till nästa uppdatering här på bloggen är att sätta upp en enkel front-end och lägga till entiteter och kontroller för att hantera böcker.

Sen så är det ju självklart fredag igen, och med helgen så kommer mina enkla nöjestips. Jag är rätt så bevandrad nu, i och med alla barnvagnspromenader. Och sen en månad tillbaka så ser jag fram emot mina promenader, för då kan jag lyssna på podcasts. Och en av mina favoriter just nu är Linear Digressions. De består av en duo – en webbutvecklare och en datavetare som diskuterar olika tillämpningar av machine learning. Det jag älskar med denna podd är att jag som bara känner till ämnet hyfsat ytligt kan följa med. Och det är alltid trevligt att lyssna på denna duo som har sån bra dynamik sinsemellan.

Så slår jag också ännu en gång ett slag för Elite: Dangerous. Den gångna veckan har jag somnat ett par gånger framför det när jag försökt spela när bebisar varit lugna. Spelet kanske låter något tråkigt nu, men det är mest för att jag varit något utmattad vid slutet av dagen.

Trevlig helg, allihop!


Jag testar och experimenterar

Det råkade bli testning inkluderat, som jag beskrev i mitt förra inlägg. Jag har inte mycket erfarenhet av att testa, men jag hade några enklare JUnit-tester när jag höll på med Java, och efter att ha mixtrat lite med PHPUnit så skulle jag påstå att jag uppnått samma låga kompetensnivå i det.

Såsom jag jobbar nu blir det att jag lägger till ett test och sedan den metod som testet kollar. Jag började med att testa att repository gör det den ska, men det kändes något onödigt. Anledningen: jag vill testa min kod, inte någon annans. Och med tanke på att Symfony kommer med Doctrine så fanns det egentligen inget där att testa för mig förrän jag inkluderade mina egna funktioner. Så de första stegen var att se lite som uppvärmning.

Snart så inkluderade jag ändå egna metoder, och mycket riktigt så hade jag skrivit test för dem. En sådan metod var att repository skulle söka med så kallade wildcards. Enligt testet så funkar det galant.

Testen startar jag från konsolen med utgångspunkt från mitt projekts mapp med instruktionen ./bin/phpunit, och som svar får jag OK (5 tests, 5 assertions). Som ni kan se är jag fortfarande i startgroparna, men det känns bra i magen när man ser testen köras och kan ändra ett fel till ett rätt.

Något som är helt nytt för mig är att testa att Controller presenterar korrekt sida till klienter. Symfony Docs är mig behjälplig och med instruktioner där ifrån så har jag mitt första test klart:
public function testShowHome() {        
$client = static::createClient();
    $client->request('GET', '/');
    $this->assertEquals(200, 

$client->getResponse()->getStatusCode());    
}

Testet kollar att HTTP-statuskoden är 200, vilket vill säga att korrekt sida hittats och levererats till klienten. I detta exempel så kollar testen helt enkelt om index-sidan hittas.


Att hantera innehåll

Helgen är slut och en ny vecka är påbörjad. Denna helg kom jag en bit ut i rymden i Elite: Dangerous. Det är helt fantastiskt hur omfattande det spelet är. Jag gillar att sugas in i det, men det går rätt långsamt. Jag vet inte riktigt vad jag tycker om utforskandet. Där handlar det om att först skicka ut en energipuls för att säkerställa att det finns himlakroppar i ett solsystem att upptäcka. När det är gjort så öppnar man ett fönster där man justerar ”radiofrekvensen” för att ställa in rätt kanal och därefter zooma in mot en himlakroppindikation. Det är bara att kanalen verkar glida något så man måste vara alert för att bibehålla rätt kanal. Jag får fortsätta med detta till nästa helg så kanske det hela klickar för mig.

Denna vecka fortsätter jag med Bokarenan. Innehållet till Bokarenan tänker hanteras av en databas. Databasen innehåller data om bland annat böcker, författare, användare och användares listor och recensioner.

I en tidigare iteration av Bokarenan så hanterade jag interaktioner med databasen genom SQL-instruktioner. När en användare hade skrivit en recension så sparades den till databasen med följande SQL-instruktion:
$q="INSERT INTO review (review, rate, book_id, title, reviewer)
VALUES ('$review', $rate, $book_id, '$title', $reviewer)";

Variablerna lät jag sanera innan de tilläts sättas in i SQL-strängen men det var inte vackert. Jag var inte konsekvent med var i kedjan av funktionsrop som jag lät sanera innehållet.

Datahanteringen behöver göras om från grunden. Det jag vill uppnå är överblickbar kod som är säker och flexibel. Säker är den datahantering som stänger ute användare från att injicera SQL-instruktioner. Flexibel är den kod som gör det enkelt att expandera med fler databasentiteter och justera relationer mellan dem. Eftersom jag gått mot objektorienterat denna gång så kommer jag använda en ORM (Object Relational Mapping). Det innebär att jag inte skriver egna SQL-instruktioner (och det läggs ett ytterligare lager mellan användare och deras möjlighet att injicera SQL). Det innebär också snyggare kod.

Den ORM jag använder mig av här är Doctrine. Genom annotationer kan jag instruera Doctrine hur den ska hantera innehåll i entiteter (objekt som ska sparas i databasen) och hur entiteter relaterar till varandra.

Jag försöker modelera entiteterna så gott det går mot den databas som finns sedan tidigare. En utmaning är att den nya databasen inte kommer bli identisk, men ska ändå tillåta att innehåll från tidigare version ska kunna importeras till den nya.

Nog kan det vara svårt att behärska sig från att kasta sig över än mer saker. Jag har kommit fram till att jag vill köra tester. Det innebär att jag SAMTIDIGT lär mig ORM och PHPUnit. Jag är inte bekväm med mock-objekt som testerna körs på. Alternativet skulle vara att koppla tester till databasen med transaktioner som påbörjas men sedan ”rullas tillbaka”. När det kommer till Repositories rekommenderas att testa dem mot en riktigt databaskoppling ( https://symfony.com/doc/current/testing/doctrine.html ). Jag får testa enligt denna rekommendation.

Anledningen till att jag till slut beslöt mig för att köra PHPUnit var att det är enklare att lägga till tester i ett tidigt skede än att göra dem som en efterhandskonstruktion. Det innebär också att det kommer finnas tester som säkerställer korrekt funktion när jag vill modifiera applikationen.


Fredagsmys

Detta med Vagrant. Jag blev introducerad till Vagrant i boken Learning PHP 7 (2016) av Antonio Lopez. Konceptet är väldigt lovande: Man får en virtuell låda/maskin som kommer ha samma konfigurering oavsett var den körs, så länge man utgår från samma konfigurationsfil.

”Using Vagrant is quite easy.” (Lopez 2016)
Nja, detta var inte min upplevelse riktigt. Jag hade flera tillfällen där jag snubblade. Planen var att köra laravel/homestead i Vagrant men min upplevelse att upprätta denna box var lite svårartad.

Bild

Det började med att jag försökte få Vagrant att fungera med den virtuella maskinen som Windows 10 Pro kommer med, nämligen Hyper-V. Jag startar kommandotolken och kör vagrant init och up. Då stöter jag på mitt första problem med att vagrant inte hittar någon virtuell maskin. Jag specificerar att vagrant ska använda Hyper-V och får då det klart för mig att jag måste köra med administratörrättigheter. Så jag gör det, och får då klart för mig att jag har problem att fortsätta med Hyper-V. Då beslöt jag mig för att använda Virtual Box istället. Jag avställde Hyper-V-servicen i Windows och startade om. Så jag kör Vagrant med Virtual Box istället. TRODDE JAG! Det visade sig att Hyper-V stod gömd i kulisserna och la krokben för Virtual Box när den skulle fram i rampljuset. Lite googling och en träff på Stack Overflow gav mig en lösning. Omstart igen! Nu kunde vagrant starta och jag kunde koppla upp mig mot den.

Jag får se om jag återvänder till Vagrant. På lite omvägar har jag landat på Symfony som ett framework och den kommer med en server som är lätt att köra. Finns mycket jag gillar med Symfony, och jag återkommer framöver med mina upplevelser. Kan hända att jag illustrerar den lika vackert som jag illustrerat min upplevelse av Vagrant.

Så vill jag avsluta veckan med att konstatera att det är helg även denna gång! Något som jag tycker om är att spela TV-spel. Det gör jag när tid finns över och min hjärna är för trött för programmeringen. Nu när det är helg så låter jag hjärnan vila lite, och plockar upp handkontrollen när bebisarna sover. Liksom förra veckan så tittar jag mot Elite: Dangerous. Jag är fortfarande i startgroparna. Jag håller mig fortfarande till startområdet och har inte riktigt vågat bege mig utanför den trygga bubblan. Men med ett något mer slagkraftigt skepp än Sidewinder (startskeppet) och ett antal pirater tillintetgjorda så börjar jag känna mig redo för lite utforskande.

Trevlig helg, allihop!


Omtag

När jag började implementera MVC till Bokarenan så kom jag också att använda RewriteEngine som ger instruktioner till Apache-servern hur den ska hantera adresser. Filstrukturen är en projektmapp med de två mapparna public och app. App innehåller backend-logiken och public innehåller frontend-materialet. App är oåtkomligt för användare. Strukturen innebär att adresser behöver behandlas av servern för att inte avslöja den interna strukturen. Jag vill inte att användare ska behöva ange bokarenan.se/bokarenan/public/pages/ för att komma till startsidan. bokarenan.se ska räcka.

Jag har skrivit instruktioner i .htaccess-filen och lyckas på så sätt omdirigera besökarna till rätt adress. Men ju mer jag försöker få den att presentera adresser på rätt sätt desto mer inser jag mina begränsningar. Jag är inte helt nöjd med detta sätt att hantera användarupplevelsen.

Om jag förstått saken rätt så har många MVC-frameworks sina egen router-logik implementerat i PHP. Den grunden som jag har byggt efter Traversy-kursen saknar detta. Jag ska därför se till ytterligare material för att få detta att fungera. Dock misstänker jag att jag alltid kommer behöva .htaccess (RewriteEngine) så länge som jag inte vill placera en index-fil i root-mappen som därifrån kan dirigera trafiken.

Som avslutning denna gång; min uppfattning om MVC-strukturen. Controller är spindeln i nätet som får stå för mycket av backend-logiken.

Bild


Smått och gott

Vad är unset och varför ska det vara bra? Funktionen träffade jag på för första gången när jag följde en kurs för PHP MVC. Som jag läser det så kommer unset att förstöra en variabel. I kontexten för kursen så användes en variabel för att ta ut vilken Controller som skulle användas ur en URL. När en Controller har valts så tas det aktuella elementet bort ur en array. Syftet skulle kunna vara att samma värde inte används igen, eller för att klargöra att elementet inte kommer användas igen över huvudtaget. I så fall är det mer av ett semantiskt ingrepp än en funktionell.

Detta tycker jag är magiskt:
protected $currentController = 'Pages';
$this->currentController = new $this->currentController;
Det innebär att PHP kan omtolka en sträng till en klass och det är ju sjukt användbart. Men jag är också lite rädd inför denna kraft. Det kan bli svårt att särskilja vad som är vad, tänker jag. Det är nog mina Java-demoner som gör sig påminda, där varje objekt är av specifik typ om man inte tydligt anger att det ska vara något annat.

Detta med att kod inkluderas i en fil från en annan och att man sedan förutsätter i en tredje fil att sagda fil har inkluderats är något som jag upplever som förvirrande. Det skulle bli svårt att uppdatera koden eller att använda filen i en annan kontext. Detta var något som jag använde mig mycket av i mitt första utkast till Bokarenan, och något som nu förekommit ett par gånger i Treversys kurs. Det är visserligen mycket tydligare i kursen vad som är vad. Men jag saknar att se varifrån till exempel en konstant har hämtats i från när man tittar i en fil som säger något som <?php echo APPROOT ?>. Det framkommer inte att konstanten har hämtats från en config-fil.

Det finns en hel del jag får med mig från kursen, men jag ser också behov att komplettera. Däribland gillar jag inte att ha views som php-filer. När jag kommer implementera kursens kod till Bokarenan kommer jag använda Twig. Detta har att göra med att låta views stå för presentation och ingen logik. Med PHP finns möjligheten att göra mer än att bara presentera en vy.

Jag kommer göra kursen så långt att grunden blir klar. Då kommer jag att ha byggt ett slags framework för MVC. Resten av veckan kommer jag att ta detta framework och bygga Bokarenan i. Jag får utvärdera om jag vill ta och implementera PHPUnit för att testa vad jag bygger. Saken är att jag vill bygga egna projekt så fort som möjligt som jag har lärt mig något för att på så sätt befästa kunskapen. Om jag skulle lära mig PHPUnit just nu så kan det innebära att jag får ytterligare avstånd till MVC innan jag bygger med det.

På detta sätt börjar jag alltså en ny vecka: många funderingar, mycket vilja och en stor dos experimentlusta.


Att bygga enligt MVC

Det finns mycket som jag vill och behöver lära mig för att kunna bygga något vackert. Därför har jag tagit ett abonnemang på Packt Publishing. Där finns det många böcker om det mesta: UX, GIMP och PHP 7 är några av de ämnena som jag går igenom på deras sida. Utöver böcker så erbjuder de också ett antal video-kurser. En sådan kurs som jag påbörjat är Brad Taversys Object Oriented PHP and MVC. Som framgick av mitt föregående inlägg så var några av de stora bristerna i Bokarenan just nu att det är svårt att särskilja vilka delar av koden som gör vad, och jag identifierade ett sätt att förbättra koden genom att använda objekt och MVC (Model, View, Controller). MVC innebär att ansvarsfördelningen blir tydligare i koden.

Jag kommer följa Traversys kurs och se var jag landar med Bokarenan. Något som saknas i kursen är Test Driven Development, men jag får ta en sak i taget.

Nu fokuserar jag på att lära mig routing och MVC. Förhoppningsvis förstår jag hälften! Men det riktiga lärandet kommer när jag bakar om det jag blir föreläst till något eget.

Nu är det fredag, och då skulle jag vilja lyfta fram något som jag tycker är sjukt bra. När tiden finnes så sätter jag mig ned med Elite: Dangerous. Det är ett spel som jag kör på PS4. Föregångaren samsades jag att spela med mina bröder. Då var det Amiga 500 som gällde och spelet hette Frontier. Nu liksom då handlar spelet om att flyga runt i Vintergatan mellan olika solsystem i rymdskepp som man kan uppgradera eller skaffa nya. Det finns i huvudsak tre olika sysselsättningar: handla, jaga pirater, och utforska rymden. Jag har precis skaffat mig spelet, och på någon timmes spelande har jag åkt fram och tillbaka mellan stjärnorna, utvunnit järn ur en asteroid, förlorat mitt skepp på grund av hetta, samt räddat en kanister med krypterat data. Har jag tid över så blir det mer rymdturism i soffan denna helg.

Trevlig helg!


Manuell refaktorering

Mitt första utkast till en färdig applikation är inte vacker! Detta vet jag. Jag har följt en bok för introduktion till PHP: ”PHP and MySQL for Dynamic Web Sites, Visual QuickPro Guide” (2017) av Larry Ullman. Boken funkade väl i att introducera mig för syntax, datastrukturer och databashantering. Det den introducerade har jag sedan använt till att utforma Bokarenan. Det Bokarenan klarar av är att registrera användare, böcker och recensioner. Men ju fler funktioner jag vill lägga till desto svårare blir det att hålla ordning på vad som gör vad bland alla filer. Och det är detta som jag ser kommer tillbaka på hur jag lärt mig från den inledande boken: den uppmuntrar inte till ”ren kod”. Det gör alltså dels att det är svårt att lägga till fler funktioner, dels gör det svårt att refaktorera när jag lyfter över applikationen till dess egna domän på bokarenan.se.

Det kanske inte låter som det, men jag var högst medveten om att jag skrev ful kod och att det finns bättre sätt att skriva koden på. Jag prioriterade att skriva klart applikationen till dess första form innan jag försökte lära mig nya sätt att skriva kod på. För mig fanns det två anledningar till det: för det första så kommer jag in i mentaliteten att göra klart något innan jag distraheras av andra saker som kan vara roligare. För det andra så ger det mig en referenspunkt som jag kan kolla på och se hur långt jag har kommit.

Några saker som gör koden ful är att det inte finns någon klar indelning över var funktioner finns, det finns inga objekt utan allt sköts i långa funktioner, vissa funktioner utnyttjar andra funktioner och dessa funktioner i sig kan användas men bör inte användas av andra om man inte vill få fel. Koden är alltså i hög grad sammankopplad på sätt som sammankopplad kod inte bör vara.

Ytterligare saker som gör koden ful är att vad som skulle kunna framstå som Modeller också gör sådant som kanske Kontroller ska göra. Funktionerna gör mer än en sak var, och detta bidrar till det förvirrade intrycket.

Men trots allt detta fula, så är jag mycket glad av att ha fått fram något som funkar och jag har lärt mig mycket. Applikationen är inte klar, utan jag kommer använda vad jag lärt mig för att göra koden vackrare. I nästa iteration av applikationen kommer jag använda mig av klasser för att göra objekt, samt dela in ansvarsområdena enligt Model, View och Controller (MVC).

Med vackrare kod och tydligare struktur så kommer framtida refaktorering och tillägg av funktioner att ske enklare.


Det första projektet

Det började när jag lärde mig grunderna i Java. Alla skulle ha ett paket-namn. Jag behövde därför ett domännamn så mina paketnamn kunde vara unika. Nu har det aldrig blivit att jag släppt några Java-paket, men jag gjorde några mindre applikationer. Jag blev klar med två applikationer. Den första applikationen var en visualisering av summa- och differensvågor. Tanken var att klargöra för mig själv hur man kan kombinera sinus-vågor för att få fram en fyrkantsvåg. I applikationen kunde jag ändra fas och våglängd och addera den med en annan våg för att få fram en summa som visualiserades. Den andra applikationen var en Mindmap-applikation. Det var en skrivbordsapplikation där jag kunde göra tankekartor med olika former och färger och spara dem för att kunna titta på dem i ett senare skede.

Jag skaffade mig en domän: femtearenan.se

Här någonstans intresserade jag mig för webbutveckling. Jag kollade på olika lösningar och föreställde mig att utveckla en kommunstatistikapplikation i Spring Boot. Den applikationen kom att bara leva på den lokala datorn. Det var billigare att hitta vad som helst annars än en webbhosting för Javaapplikationer. För mig blev det därför hosting som stödde PHP.

Mitt första projekt i PHP något jag kallar Bokarenan. Det bygger vidare på temat ”arena” och antyder en plats där folk kan mötas – i detta fallet gällande böcker. Liksom tidigare applikationer i Java så kommer detta projektet utifrån ett behov jag själv har. Jag gillar att läsa! Jag skulle gilla att diskutera de böckerna jag läst med andra som läst samma böcker. Tyvärr har jag ofta dåligt minne, och ofta överlappar jag inte med vänner och bekanta vad gäller de böcker vi läser. Därför börjar jag med att skissa på en applikation där vem som helst som är intresserad av att läsa böcker och att dela med sig av sina läsupplevelser kan göra det. Ett antal funktioner som jag ser att applikationen behöver är:

  • Folk ska kunna registrera sig och logga in.
  • Användare som missköter sig ska kunna anmälas av andra användare. Följden blir varning följt av avstängning vid upprepad överträdelse.
  • Användare ska kunna lägga in böcker i en ”Att läsa”-lista.
  • Användare ska kunna beskriva sin läsupplevelse och dela den med andra.
  • Användare ska kunna hitta folk som läst samma bok, eller vill läsa samma bok.
  • Det ska finnas en funktion för en läscirkel. Användare ska kunna skapa och bjuda in varandra. Läscirkeln ska vara förbehållen de som ingår i cirkeln.
  • Användare ska kunna bli påminda om en bok som de läst. Påminnelsen ska inte vara påträngande.
  • Känner jag mig själv rätt så kommer jag på fler funktioner efter hand. Men de får vänta tills jag bockat av ovanstående punkter.

Som ni kan se, så har jag lite idéer. Om ni har förslag så kan ni kontakta mig genom kontaktformuläret.

Som en glad amatör och kodarentusiast; Lev och må’!