PHP code example of clancats / container

1. Go to this page and download the library: Download clancats/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/ */

    

clancats / container example snippets


class Human
{
    public $name;

    public function setName(string $name) {
        $this->name = $name;
    }
}

class SpaceShip
{
    protected $captain; // every ship needs a captain!

    public function __construct(Human $captain) {
        $this->captain = $captain;
    }

    public function ayeAye() {
        return 'aye aye captain ' . $this->captain->name;
    }
}

@malcolm: Human
  - setName('Reynolds')

@firefly: SpaceShip(@malcolm)



// for the consistency of the example I leave this here 
// but I strongly recommend to autolaod your classes with composer.
ate('AppContainer', function($builder)
{
    // create a new container file namespace and parse our `app.ctn` file.
    $namespace = new \ClanCats\Container\ContainerNamespace();
    $namespace->parse(__DIR__ . '/app.ctn');

    // import the namespace data into the builder
    $builder->importNamespace($namespace);
});

echo $container->get('firefly')->ayeAye(); // "aye aye captain Reynolds"

// default environment
:env: 'stage'

// debug mode
:debug: false

// Firewall whitelist
:firewall.whitelisted_ips: {
  '127.0.0.1': 'Local',
  '1.2.3.4': 'Some Office',
  '4.3.2.1': 'Another Office',
}

// application name
:app.name: 'My Awesome application'

import config.env

override :env: 'dev'
override :debug: true

// Firewall whitelist
override :firewall.whitelisted_ips: {
  '127.0.0.1': 'Local',
  '192.168.33.1': 'MyComputer',
}

echo $container->getParameter('app.name'); // 'My Awesome application'
echo $container->getParameter('env'); // 'dev'
echo $container->getParameter('debug'); // true

# Parameters can be defined erverywhere
:pipeline.prefix: 'myapp.'

// you can define aliases to services
@pipeline.queue: @queue.redis
@pipeline.storage: @db.repo.pipeline.mysql

// add function calls that will be run directly after construction of the service
@pipeline: Pipeline\PipelineManager(@pipeline.queue, @pipeline.storage, @pipeline.executor)
  - setPrefix(:pipeline.prefix)
  - bind(@pipeline_handler.image.downloader)
  - bind(@pipeline_handler.image.process)

@pipeline_handler.image.downloader: PipelineHandler\Images\DownloadHandler(@client.curl)
@pipeline_handler.image.process: PipelineHandler\Images\ProcessHandler(@image.processor, { 
  'temp_dir': '/tmp/', 
  'backend': 'imagick'
})

@controller.dashboard.home: App\Controller\Dashboard\HomepageAction
  = route: {'GET'}, '/dashboard/home'

@controller.dashboard.sign_in: App\Controller\Dashboard\SignInAction
  = route: {'GET', 'POST'}, '/dashboard/signin'

@controller.dashboard.sign_out: App\Controller\Dashboard\SignOutAction
  = route: {'GET'}, '/logout'

@controller.dashboard.client: App\Controller\Dashboard\ClientDetailAction
  = route: {'GET'}, '/dashboard/clients/me'
  = route: {'GET'}, '/dashboard/clients/{clientId}'

$dispatcher = \FastRoute\cachedDispatcher(function(RouteCollector $r) use($container)
{
    foreach($container->serviceNamesWithMetaData('route') as $serviceName => $routeMetaData)
    {
        // an action can have multiple routes handle all of them
        foreach($routeMetaData as $routeData)
        {
            $r->addRoute($routeData[0], $routeData[1], $serviceName);
        }
    }
}, [
    'cacheFile' => PATH_CACHE . '/RouterCache.php',
    'cacheDisabled' => $container->getParameter('env') === 'dev',
]);

@signal.exception.http404: App\ExceptionHandler\NotFoundExceptionHandler
  = on: 'http.exception', call: 'onHTTPException'

@signal.exception.http400: App\ExceptionHandler\BadRequestExceptionHandler
  = on: 'http.exception', call: 'onHTTPException'

@signal.exception.http401: App\ExceptionHandler\UnauthorizedAccessExceptionHandler
  = on: 'http.exception', call: 'onHTTPException'

@signal.bootstrap_handler: App\Bootstrap
  = on: 'bootstrap.pre', call: 'onBootstrapPre'
  = on: 'bootstrap.post', call: 'onBootstrapPost'

foreach($container->serviceNamesWithMetaData('on') as $serviceName => $signalHandlerMetaData)
{
    // a action can have multiple routes handle all of them
    foreach($signalHandlerMetaData as $singalHandler)
    {
        if (!is_string($singalHandler[0] ?? false)) {
            throw new RegisterHandlerException('The signal handler event key must be a string.');
        }

        if (!isset($singalHandler['call']) || !is_string($singalHandler['call'])) {
            throw new RegisterHandlerException('You must define the name of the function you would like to call.');
        }

        $priority = $singalHandler['priority'] ?? 0;

        // register the signal handler
        $eventdispatcher->register($singalHandler[0], function(Signal $signal) use($container, $singalHandler, $serviceName)
        {
            $container->get($serviceName)->{$singalHandler['call']}($signal);
        }, $priority);
    }
}

/**
 * Log to Graylog
 */
:gelf.host: 'monitoring.example.com'
:gelf.port: 12201

@gelf.transport: Gelf\Transport\UdpTransport(:gelf.host, :gelf.port)
@gelf.publisher: Gelf\Publisher(@gelf.transport)
@logger.error.gelf_handler: Monolog\Handler\GelfHandler(@gelf.publisher)
  = log_handler

/**
 * Also send a slack notification 
 */
@logger.,error.slack_handler: Example\MyCustom\SlackWebhookHandler('https://hooks.slack.com/services/...', '#logs')
    = log_handler

// gather the log handlers
$logHandlerServices = array_keys($container->serviceNamesWithMetaData('log_handler'));

// bind the log hanlers
foreach($logHandlerServices as $serviceName) {
    $logger->pushHandler($container->get($serviceName));
}

42 # Int
42.01 # Float
-42.12345678912345 # Double

:say: 'Hello it\'s me!'`

:snails: '🐌🐌🐌'

:nothing: null

:positive: true
:negative: false

## <service name>: <class name>
@log.adapter: FileAdapter

@log.adapter: Acme\Log\FileAdapter

@dude: Person("Jeffery Lebowski")

:name: 'Jeffery Lebowski'

@dude: Person(:name)

@mysql: MySQLAdapter('localhost', 'root', '')

@repository.posts: Repositories/Post(@mysql)

@jones: Person('Duncan Jones')
@sam: Person('Sam Rockwell')

@movie.moon: Movie('Moon')
  - setDirector(@jones)
  - addCast(@sam)
  - setTags({'Sci-fi', 'Space'})

@controller.auth.sign_in: Controller\Auth\SignInController(@auth)
  = route: {'GET', 'POST'}, '/signin'

@controller.auth.sign_in: Controller\Auth\SignInController(@auth)
  = route: {'GET', 'POST'}, '/signin'
  = tag: 'users'
  = tag: 'auth'

@app.bootstrap: Bootstrap()
  = on: 'app.start' call: 'onAppStart'

@logger.main: Acme\Logger

@logger.observers.email_devs: Acme\EmailLogObserver('[email protected]')
@logger.observers.email_support: Acme\EmailLogObserver('[email protected]')

@logger.main
  - addObserver(@logger.observers.email_devs)
  - addObserver(@logger.observers.email_support)

@controller.homepage: Controller\Homepage
  = on: '/homepage'


// also show homepage on root
@controller.homepage
  = on: '/'

:ship: 'Star Destroyer'

override :ship: 'X-Wing'

 
if (!defined('DS')) { define('DS', DIRECTORY_SEPARATOR); }

define('PATH_ROOT',         __DIR__);
define('PATH_CACHE',        PATH_ROOT . DS . 'var' . DS . 'cache');
define('PATH_APPCONFIG',    PATH_ROOT . DS . 'app');

$factory = new \ClanCats\Container\ContainerFactory(PATH_CACHE);

$container = $factory->create('AppContainer', function($builder)
{
    $importPaths = [
        'app.env' => PATH_ROOT . '/app.ctn.env',
    ];

    // find available container files
    $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(PATH_APPCONFIG));

    foreach ($rii as $file) 
    {
        // skip directories
        if ($file->isDir()) continue;

        // skip non ctn files
        if (substr($file->getPathname(), -4) !== '.ctn') continue;

        // get the import name
        $importName = 'app' . substr($file->getPathname(), strlen(PATH_APPCONFIG), -4);

        // add the file
        $importPaths[$importName] = $file->getPathname();
    }

    // create a new container file namespace and parse our `app.ctn` file.
    $namespace = new \ClanCats\Container\ContainerNamespace($importPaths);
    $namespace->importFromVendor(PATH_ROOT . '/vendor');

    // start with the app file
    $namespace->parse(__DIR__ . '/app.ctn');

    // import the namespace data into the builder
    $builder->importNamespace($namespace);
});

app.php
app.ctn
composer.json
cache/ # make sure this is writable
src/
  Human.php
  SpaceShip.php