Skip to content

Instantly share code, notes, and snippets.

@n1215
Last active December 1, 2017 02:06
Show Gist options
  • Save n1215/72e6088977d64a69dd26ba28a21386a5 to your computer and use it in GitHub Desktop.
Save n1215/72e6088977d64a69dd26ba28a21386a5 to your computer and use it in GitHub Desktop.
minimal PSR-15 framework
<?php
// コンテナ生成とキャッシュ
class ContainerBuilder implements ContainerBuilderInterface {
private $providers;
public function __construct(array $providers) {
$this->prividers = $providers;
}
public function build() {
if (file_exists($containerCacheFilePath)) {
return unserialize(file_get_contents($containerCacheFilePath));
}
$container = $this->initContainer();
$this->cache($container);
return $container;
}
private fucntion initContainer() {
$container = new Container();
foreach ($this->providers as $providerClass) {
(new $providerClass())->register($container);
}
return $container;
}
private function cache(ContaienrInterface) {
//todo implements
}
}
// 初期処理
class BootLoader implements BootLoaderInterface {
private $bootstrapperClasses;
public function __construct(array $bootstrapperClasses) {
$this->bootstrapperClasses = $bootstrappers;
}
public function boot() {
foreach($this->bootstrapperClasses as $bootstrapperClass) {
$bootstrapper = new $bootstrapperClass();
$bootstrapper->bootstrap();
}
}
}
// アプリケーションのライフサイクル管理
class HttpApplication implements HttpApplicationInterface {
private $bootLoader;
private $eventManager;
private $requestHandler;
private $responseEmitter;
public function __construct(
BootLoaderInterface $bootLoader,
ServerRequestHandlerInterface $requestHandler,
ResponseEmitterInterface $responseEmitter,
EventMangagerInterface $eventManater
) {
$this->bootLoader = $bootLoader;
$this->reqestHandler = $requestHandler;
$this->responseEmitter = $responseEmitter;
$this->eventManager = $eventManager;
}
public function run(ServerRequestInterface $request) {
$this->bootLoader->boot();
$response = $this->requestHandler->handle($request);
$this->responseEmitter->emit($response);
$this->eventManager->trigger(new TerminateEvent($request, $response));
}
}
// PSR-14は作りが悪いのでどうしたものか……。
class EventManagerServiceProvider {
public function register(Container $container) {
$container->bind(EventManagerInterface::class, public function (Container $container) {
return new EventManager();
});
}
}
class RequestHandlerFactoryServiceProvier {
public function register(Container $container) {
$container->bind(RequestHandlerFactoryInterface::class, public function (Container $container) {
return RequestHandlerFactory::fromContainer($container);
});
}
}
class RoutingServiceProvider {
public function register(Container $container) {
$container->bind(RouterInterface::class, function (Container $container) {
$routeMap = new RouteMap();
$routeMap->add('get', 'fuga');
$router = new Router($routMap);
return $router;
});
$container->bind(
RoutingHandlerInterface::class,
function (Container $container) {
return new RoutingHandler($container->get(RouterInterface::class), new RoutingErrorResponder());
}
);
}
}
class Framework implements FrameworkInterface {
public function __construct(Container $container, $rootPath)
{
$this->container = $container;
$this->rootPath = $rootPath;
}
public function buildApplication() {
$handlerFactory = $container->get(RequestHandlerFactoryInterface::class);
$coreHandler = $container->get(RoutingHandlerInterface::class);
$middlewareConfigPath = $this->path('config/middlewares.php')
$middlewareClasses = require $middlewareConfigPath;
$requestHandler = $handlerFactory->create($coreHandler, $middlewareClasses);
return new HttpApplication(
$container->get(BootLoaderInterface::class),
$requestHandler,
new SapiEmmiter(),
$container->get(EventManagerInterface::class)
);
}
public function path(string $relativePath): string {
// todo implements
}
}
class BootLoaderServiceProvider {
public function register(Container $container) {
$container->bind(BootLoaderInterface::class, public function (Container $container) {
$bootstrapConfigPath = $framework->path('config/bootstrappers.php')
$bootstrapperClasses = require $bootstrapConfigPath;
return new BootLoader($bootstrapperClasses);
});
}
}
// entry point
require __DIR__.'/../vendor/autoload.php';
Dotenv::load([
'filepath' => dirname(__DIR__) . DIRECTORY_SEPARATOR . '.env';
'toEnv' => true,
]);
call_user_func(function () {
$providerClasses = require __DIR__ . '/../config/providers.php';
$container = (new ContainerBuilder($providerClasses))->build();
$framework = new Framework($container, realpath(__DIR__ . '/.../'));
$container->bind(FrameworkInterface, $framework);
$app = $framework->buildApplication();
$container->bind(HttpApplicationInterface::class, $app);
$request = ServerRequestFactory::createFromGlobal();
$app->run($request);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment