PHP code example of pwm / sfw-container

1. Go to this page and download the library: Download pwm/sfw-container library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

pwm / sfw-container example snippets


// Have some classes, some of them depend on others
class A { public function __construct(int $x) {} }
class B { public function __construct(string $s) {} }
class C { public function __construct(A $a, B $b) {} }

// Create a container
$c = new Container();

// Add resolver functions to the container that will instantiate your classes
$c->add(A::class, function (): A {
    return new A(1);
});
$c->add(B::class, function (): B {
    return new B('x');
});

// Resolving from within resolvers is easy as the Container is passed to the functions as the 1st parameter
$c->add(C::class, function (Container $c): C {
    return new C(
        $c->resolve(A::class),
        $c->resolve(B::class)
    );
});

// Resolve your classes
assert($c->resolve(A::class) instanceof A);
assert($c->resolve(B::class) instanceof B);
assert($c->resolve(C::class) instanceof C);

// X depends on Y and Y depends on X ...
class X { public function __construct(Y $y) {} }
class Y { public function __construct(X $x) {} }

$c = new Container();

$c->add(X::class, function (Container $c): X {
    return new X($c->resolve(Y::class));
});
$c->add(Y::class, function (Container $c): Y {
    return new Y($c->resolve(X::class));
});

try {
    $c->resolve(X::class);
} catch (CycleDetected $e) {
    assert('X -> Y -> X' === $e->getMessage());
}

// Simple class that saves a timestamp
class TS {
    private $timestamp;
    public function __construct(int $timestamp) {
        $this->timestamp = $timestamp;
    }
    public function getTimestamp(): int {
        return $this->timestamp;
    }
}

$c = new Container();

// Add our TS class both cached and as a factory (using different keys)
$c->add('cachedTS', function (): TS {
    return new TS(time());
});
$c->factory('factoryTS', function (): TS {
    return new TS(time());
});

// Get an instance for both
$cTS = $c->resolve('cachedTS'); // instantiate and cache
$fTS = $c->resolve('factoryTS'); // just instantiate

// Wait a sec ...
sleep(1);

// For the cached ones timestamps will match
assert($cTS->getTimestamp() === $c->resolve('cachedTS')->getTimestamp());

// Factory instantiates again, hence timestamps will differ
assert($fTS->getTimestamp() !== $c->resolve('factoryTS')->getTimestamp());

interface Reader {
    public function read(): string;
}
class XmlReader implements Reader {
    public function read(): string {
        return 'Reading Xml...';
    }
}
class JsonReader implements Reader {
    public function read(): string {
        return 'Reading Json...';
    }
}

$c = new Container();

// Reader's resolver has to be added via factory otherwise
// it will be bound to whatever it first resolves to
$c->factory(Reader::class, function (Container $c, string $strategy): Reader {
    switch ($strategy) {
        case 'xml':
            return new XmlReader();
        case 'json':
            return new JsonReader();
        default:
            throw new RuntimeException(sprintf('No reader found for %s', $strategy));
    }
});

assert('Reading Xml...' === $c->resolve(Reader::class, 'xml')-> read());
assert('Reading Json...' === $c->resolve(Reader::class, 'json')-> read());

try {
    $c->resolve(Reader::class, 'csv');
} catch (RuntimeException $e) {
    assert('No reader found for csv' === $e->getMessage());
}