Turistande på bilkyrkogården i Ryd

För någon vecka sedan besökte jag och Linda bilkyrkogården på Kyrkö Mosse i Ryd, med kameran i högsta hugg. Jag skulle tro att det var mer än 15 år sedan jag var där senast, så det var kul att besöka platsen igen.

Det är ett ställe där naturen har sin gång och turismen är nu ganska omfattande, så det såg faktiskt lite annorlunda än vad jag minns det. Där fanns tyvärr också spår av vandalism, där mindre intelligenta folk (relativt nyligen) hade ristat in saker på bilar och slängt runt på saker. För 15 år sedan fanns det fler emblem och bilmärken som gick att känna igen, så troligen har det stulits en del där ifrån. Det var mer ordning i kaoset förut. Tråkigt, minst sagt.

Bilkyrkogården är fortfarande värt ett besök dock. Man behöver inte vara en motorfantast för att uppskatta det heller :)

Helgpromenad i Elleholm och Mörrum

Idag var det helg mitt i veckan, det var fint väder så det passade med en promenad. Det var väldans länge sedan jag hade kameran med mig, så målet blev att åtminstone få någon bild som blev vettig med mig hem. Vi var i Elleholm och Mörrum och fotograferade, men alla dessa kommer från Elleholm.

Klicka på dem för att se dem större och bläddra mellan dem!

(Det märks att jag är ringrostig med fotograferandet – Inga landskapsbilder blev särskilt bra, de är svårare att få till)

Avslutning på Karlshamns kulturfestival 2015

Karlshamns kulturfestival 2015Det blir lite konstigt idag, när jag skriver om avslutningshelgen på Karlshamns kulturfestival på BTH, men inte skrivit om invigningshelgen. Men bättre sent än aldrig tänker jag :)

För snart två veckor sedan på fredag öppnade vi en väldans trevlig tillställning. Fantastisk konst från många delar av världen, härlig musik och trevliga människor var på plats. Arrangörer är Karlshamnska Snabbhanarna (jodå, de stavar det så) och medarrangörer är Studieförbundet Vuxenskolan, ABF, Karlshamns Kommun och Kultur Knytpunkten Karlshamn.

I helgen avslutas alltså evenemanget med ytterligare en trevlig kväll med livemusik, poesi och konst. Det är på lördag det händer mest mellan 18-21, men lokalerna öppnar redan klockan 12. Härligt!

Jag har ännu en gång insett att Karlshamn (och resten av Blekinge) sprudlar av vilja att sprida högkvalitativ konst och kultur.

Välkomna in och hälsa på!

Sammanfattning av utställningen under konstrundan i påsk

Nu har det gått nio dagar sedan jag och Linda hade vår utställning i Nymölla under konstrundan i östra Skåne under påsken. Det har blivit lite av en tradition, med fyra år i streck nu. Bertil Westerlund som anordnar detta, och har gjort det i över 15 år, ska verkligen ha en stor eloge för ett fantastiskt trevlig arrangemang. Både vi utställare och besökarna uppskattar det förmodligen lika mycket. Tack Bertil! :)

Det ska sägas att jag inte är den mest sociala människan på denna jorden och det är alltid med lite skräckblandad förtjusning som jag ger mig in på fyra dagar av en extremt social helg. Detta året var jag nog ändå mer avslappnad än jag varit tidigare år, jag kan inte förklara varför.

Det är svårt att uppskatta hur många som kom och besökte oss under dagarna, men med en försiktig gissning (lågt räknat) så konstaterade vi att det borde ligga runt 1200 personer. Det är helt fantastiskt att så många uppskattar och vill titta på det vi och de andra kreatörerna skapar. Det hade varit roligt att ta er alla i hand och prata några ord, men det hinns det inte riktigt med. Många trevliga samtal om allt möjligt, inte bara konst, hade vi i varje fall. Ett stort tack till alla besökare!

Dagen för hängning och under perioder då det var lite lugnare dokumenterade vi utställningen och den trevliga omgivningen på Garvaregården. Det ihopklippta resultat kan ni se här:

På Lindas youtube-kanal ligger även en video med lite förberedelser inför utställningen. Den kan också vara värd att titta på :)

Automatisk dependency injection i PHP med hjälp av typhintning

Jag har skrivit om dependency injection förut (anonyma funktioner, dependency injection och php oop kurs del 1) och nu är det faktiskt dags igen. Denna gången med en liten twist. I en del ramverk, i tex Laravel, så har man möjlighet att injicera beroenden in i andra objekt enbart genom att typhinta klassnamnet. Jag vet inte säkert om det heter så på svenska, men på engelska heter det type hinting.

Type hinting använder du genom att skriva namnet på klassen du injicerar till ditt objekt. Vanligast är att man gör det i konstruktorn (constructor injection), och då kan det se ut som så här:

function __construct(Klassnamn $klass)

I detta exemplet, så måste objektet som används som argument vara av typen Klassnamn. Om du försöker injicera ett objekt av en annan typ, så kommer php att generera ett fel. Så varför är detta så bra? Jo, för att ditt objekt ska kunna fungera, så är det beroende av denna specifika typen av objekt. Utan type hinting skulle du kunna injicera vilket objekt som helst, och du kommer säkerligen att få massa saker som inte fungerar. På detta viset vet du att ditt objekt inte kan skapas upp utan att det har alla beroenden det behöver. Det är just det som är dependency injection och type hinting i ett nötskal. Kort sagt – Använd er av det när ni programmerar objektorienterat  php! :)

Men hursomhelst, så måste ett objekt som behöver injiceras senare fortfarande skapas. Många dependency injection containers som finns på nätet löser detta, men jag skulle vilja visa ett sätt som det kan göras på för att visa hur det hela kan fungera.

Observera/Disclaimer Detta är inte är någon kod jag vill ni ska använda i skarpt läge, men det kan kanske vara intressant att läsa igenom och kanske inspireras av?

Koden till en förenklad Service Container

Låt oss se hur den ser ut:

<?php
class ServiceContainer
{
    /* @var Lagrade objekt */
    private $instances;
 
    /**
     * Skapa upp servicecontainern och lagra sig själv.
     */
    public function __construct()
    {
        $this->add($this);
    }
 
    /**
     * Lägg till ett objekt.
     * @param object $instance
     */
    public function add($instance)
    {
        $this->instances[get_class($instance)] = $instance;
    }
 
    /**
     * Hämta ett objekt.
     * @param string $name Klassnamn.
     * @return object
     */
    public function get($name)
    {
        // Använd reflection för att undersöka klassen.
        $reflector = new \ReflectionClass($name);
 
        // Objekt av typen finns redan lagrad.
        if (isset($this->instances[$name])) {
            return $this->instances[$name];
        }
 
        // Skapa en ny instans.
        if ($reflector->getConstructor()) {
            $injections = $this->getInjections($reflector);
            $instance = $reflector->newInstanceArgs($injections);
        } else {
            $instance = $reflector->newInstance();
        }
 
        // Lagra och returnera objektet.
        $this->add($instance);
 
        return $instance;
    }
 
    /**
     * Hämta konstruktorns parametrar.
     * @param ReflectionClass $reflector
     * @return array
     */
    private function getInjections($reflector)
    {
        $parameters = $reflector->getConstructor()->getParameters();
        foreach ($parameters as $parameter) {
            $name = $parameter->getClass()->name;
            $injections[] = $this->get($name);
        }
 
        return $injections;
    }
}

Låt oss gå uppifrån och ner för att förklara hur det fungerar.

Den enda variabeln (instances) vi behöver är för att lagra objekt som redan finns uppskapade. Objekten är delade, d.v.s. att endast ett objekt av samma typ kan existera i samma container.

Konstruktorn (__construct) är enkel. Det enda den gör är att lägga till sig själv i containern.

Metoden add() är lika enkel den. Där kan du manuellt lägga till ett objekt till containern om du skulle behöva. Nyckeln som lagras internt blir klassnamnet.

Nu börjar det bli intressant. Metoden get() används för att skapa och returnera ett efterfrågat objekt från containern. Om en instans av rätt klass redan finns lagrad, så returneras den direkt. Vi använder oss av Reflections för att undersöka den efterfrågade klassen. Om klassen har en konstruktor, undersöks den och vi kan avgöra om den har några argument eller inte. Om konstruktorn tar argument, så kallar vi på metoden getInjections() för att hämta dessa. En ny instans skapas med hjälp av newInstanceArgs(), eller newInstance(). Slutligen lagras instansen i containern och så returneras den tillbaka.

Metoden getInjections() används slutligen för att skapa upp objekt som behöver injiceras till en konstruktor för att ett objekt ska kunna skapas upp. Metoden loopar igenom alla argument och skapar upp objekt med hjälp av get() och returnerar dem tillbaka i en array som kan användas när det beroende objektet sedan skapas upp.

Ett exempel:

// Exempel:
class Engine {}
class Tires {}
class Car {
    public function __construct(Engine $engine, Tires $tires) {}
}
class Owner {
    public function __construct(Car $car, ServiceContainer $sc) {}
}
 
$c = new ServiceContainer();
$owner = $c->get('Owner');
 
var_dump($owner);
var_dump($c);

Först några klasser som vi kan testa att skapa instanser utav. Engine och Tires är enkla klasser som inte har någon konstruktor och således inte har några beroenden heller. Klassen Car däremot är beroende av både Engine och Tires för att fungera. Lägg märke till type hintingen av dessa två klasser i konstruktorn.

Klassen Owner vill ha en Car för att bli tillfredställt och bara för att vi ska se att det fungerar, så slänger vi in även containern som ett beroende. Ett varningens ord här dock – Det är generellt sett inte någon bra idé att skapa ett beroende av en container i en klass. Även om vi har type hintat containern, så vet vi inte om alla containern innehåller alla de objekt koden förväntar sig. Det är bättre att type hinta respektive klass som ett objekt är beroende av i konstruktorn, vilket ju är just det som hela detta inlägget faktiskt går ut på!

Så när vi anropar ServiceContainerns metod get(), så skapas samtliga objekt upp som Owner är beroende av. Genom att dumpa ut $owner och $c så ser vi just detta. Ownerobjektet är skapat och $c, dvs servicecontainern, innehåller alla de objekt som Owner är beroende av:

object(Owner)[5]
object(ServiceContainer)[1]
  private 'instances' => 
    array (size=5)
      'ServiceContainer' => 
        &object(ServiceContainer)[1]
      'Engine' => 
        object(Engine)[9]
      'Tires' => 
        object(Tires)[10]
      'Car' => 
        object(Car)[8]
      'Owner' => 
        object(Owner)[5]

Sammanfattning

Det är inte alla tillfällen som lämpar sig för en sådan här (enkel) lösning. Det finns några stora nackdelar. Till exempel så kan containern bara leverera objekt som har argument med type hintade klasser. Och dessa i sin tur måste också bestå av desamma. Det går inte i denna implementationen att använda sig av argument som tar strängar, arrays eller annat.

Den klarar inte heller av att injicera objekt där man använder interface som typhintning, vilket till viss del motverkar (subtype) polymorfism, vilket egentligen är önskvärt när man programmerar objektorienterat.

Den hanterar endast injektioner till konstruktorn. I vissa situationer så kan injektioner till enskilda metoder också vara praktiskt (s.k. method injection). Om det där tvistar de lärde, men jag föredrar att i största möjliga mån hålla mig till konstruktorn.

Containern lämpar sig helt enkelt bäst till ändamål där man automatiskt behöver skapa beroenden och eventuell input till respektive objekt sker först efter instansieringen. Alternativt beroende av objekt som kan skapas upp mer eller mindre manuellt innan den automatiska instansieringen. Tänk er en controller i MVC som väljs genom URL, eller någon annan routing, och som behöver en eller flera modeller för att kunna göra sitt jobb. I ett automatiserat flöde, så kan vi inte manuellt skapa upp dessa objektberoenden, utan vi måste förlita oss till någon form av objektfabrik, såsom denna service containern.

Hoppas ni förstår kraften med denna typen av funktionalitet och kanske söker er vidare till någon av de mer robusta och testade lösningar som finns där ute. Lösningar som många gånger tar upp de problem som jag nämnt ovan. Sök gärna mer information på er favoritsökmotor. Använd te.x. ”dependency injection container php” som sökord.

Må bäst, tills nästa gång! :)

Nästa sida »