PSR-3 – Tworzenie logów w PHP (Rozdział 11)
PSR-3 definiuje interfejs do tworzenia logów w PHP, zawiera metody takie jak error
, debug
, info
itd., ułatwiając spójne logowanie.
Zobacz oficjalną dokumentację PSR-3
Kup kurs i opanuj PSR-3 🎯<?php
declare(strict_types=1);
namespace DJWeb\Framework\Log;
use DJWeb\Framework\Enums\Log\LogLevel;
use DJWeb\Framework\Log\Contracts\HandlerContract;
use Psr\Log\LoggerInterface;
use Psr\Log\LoggerTrait;
use Stringable;
final class Logger implements LoggerInterface
{
use LoggerTrait;
/**
* @param array $handlers
* @param PlaceholderProcessor|null $placeholderProcessor
*/
public function __construct(
public private(set) array $handlers = [],
private ?PlaceholderProcessor $placeholderProcessor = null
)
{
/** @phpstan-ignore-next-line */
$this->handlers = array_filter($this->handlers, static fn ($handler) => $handler instanceof HandlerContract);
$this->placeholderProcessor ??= new PlaceholderProcessor();
}
/**
* @param LogLevel $level
* @param Stringable|string $message
* @param array $context
*
* @return void
*/
public function log($level, Stringable|string $message, array $context = []): void
{
$message = is_string($message) ? $message : (string) $message;
$processedMessage = new Message(
level: $level,
message: $this->placeholderProcessor?->process($message, new Context($context)) ?? '',
context: new Context($context),
metadata: Metadata::create()
);
array_walk($this->handlers, static fn (HandlerContract $handler) => $handler->handle($processedMessage));
}
}
PSR-6 – Cache system (Rozdział 22)
PSR-6 standaryzuje mechanizm cache w PHP – definiuje Cache Pool, Cache Item i obsługę TTL.
Zobacz oficjalną dokumentację PSR-6
Naucz się cachować z PSR-6 🚀<?php
declare(strict_types=1);
namespace DJWeb\Framework\Cache;
use Carbon\Carbon;
use DateInterval;
use Psr\Cache\CacheItemInterface;
class CacheItem implements CacheItemInterface
{
private mixed $value = null;
private bool $isHit = false;
private ?Carbon $expiry = null;
public function __construct(
private string $key,
) {
}
public function getKey(): string
{
return $this->key;
}
public function get(): mixed
{
return $this->value;
}
public function isHit(): bool
{
return $this->isHit;
}
public function set(mixed $value): static
{
return (clone $this)->with(value: $value);
}
public function expiresAt(?\DateTimeInterface $expiration): static
{
return (clone $this)->with(
expiry: $expiration ? Carbon::instance($expiration) : null
);
}
public function expiresAfter(\DateInterval|int|null $time): static
{
$expiry = match(true) {
$time === null => null,
$time instanceof DateInterval => Carbon::now()->add($time),
default => Carbon::now()->addSeconds($time),
};
return (clone $this)->with(expiry: $expiry);
}
public function withIsHit(bool $hit): static
{
return (clone $this)->with(isHit: $hit);
}
public function getExpiry(): ?Carbon
{
return $this->expiry;
}
private function with(
mixed $value = null,
?Carbon $expiry = null,
?bool $isHit = null,
): static {
$clone = clone $this;
$clone->value = $value ?? $this->value;
$clone->expiry = $expiry ?? $this->expiry;
$clone->isHit = $isHit ?? $this->isHit;
return $clone;
}
}
PSR-7 – HTTP Request/Response (Rozdział 2)
PSR-7 wprowadza interfejsy do obsługi żądań i odpowiedzi HTTP: RequestInterface
, ResponseInterface
i inne.
Zobacz oficjalną dokumentację PSR-7
Opanuj requesty z PSR-7 🌐<?php
declare(strict_types=1);
namespace DJWeb\Framework\Http\Request\Psr7;
use DJWeb\Framework\Http\HeaderManager;
use DJWeb\Framework\Http\Request\AttributesManager;
use DJWeb\Framework\Http\Request\ParsedBodyManager;
use DJWeb\Framework\Http\Request\QueryParamsManager;
use DJWeb\Framework\Http\Request\UploadedFilesManager;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
class ServerRequest extends BaseRequest implements ServerRequestInterface
{
/**
* @param string $method
* @param UriInterface $uri
* @param StreamInterface $body
* @param HeaderManager $headerManager
* @param array $serverParams
* @param array $cookieParams
* @param QueryParamsManager $queryParamsManager
* @param UploadedFilesManager $uploadedFilesManager
* @param ParsedBodyManager $parsedBodyManager
* @param AttributesManager $attributesManager
*/
public function __construct(
string $method,
UriInterface $uri,
StreamInterface $body,
HeaderManager $headerManager,
private ?array $serverParams,
private array $cookieParams,
protected QueryParamsManager $queryParamsManager,
private UploadedFilesManager $uploadedFilesManager,
protected ParsedBodyManager $parsedBodyManager,
private AttributesManager $attributesManager
) {
parent::__construct($method, $uri, $body, $headerManager);
}
/**
* @return array
*/
public function getServerParams(): array
{
return $this->serverParams ?? [];
}
/**
* @return array
*/
public function getCookieParams(): array
{
return $this->cookieParams;
}
/**
* @param array $cookies
*
* @return $this
*/
public function withCookieParams(array $cookies): static
{
$new = clone $this;
$new->cookieParams = $cookies;
return $new;
}
/**
* @return array
* /
*/
public function getQueryParams(): array
{
return $this->queryParamsManager->queryParams ?? [];
}
/**
* @param array $query
*
* @return $this
*/
public function withQueryParams(array $query): static
{
$new = clone $this;
$new->queryParamsManager = $this->queryParamsManager->withQueryParams($query);
return $new;
}
/**
* @return array
* /
*/
public function getUploadedFiles(): array
{
return $this->uploadedFilesManager->uploadedFiles;
}
/**
* @param array $uploadedFiles
*
* @return $this
*/
public function withUploadedFiles(array $uploadedFiles): static
{
$new = clone $this;
$new->uploadedFilesManager = $this->uploadedFilesManager->withUploadedFiles($uploadedFiles);
return $new;
}
/**
* @return array
*/
public function getParsedBody(): array
{
return $this->parsedBodyManager->parsedBody ?? [];
}
/**
* @param ?array $data
*
* @return $this
*/
public function withParsedBody($data): static
{
$new = clone $this;
$new->parsedBodyManager = $this->parsedBodyManager->withParsedBody($data);
return $new;
}
/**
* @return array
*/
public function getAttributes(): array
{
return $this->attributesManager->attributes;
}
public function getAttribute(string $name, mixed $default = null): mixed
{
return $this->attributesManager->getAttribute($name, $default);
}
public function withAttribute(string $name, mixed $value): static
{
$new = clone $this;
$new->attributesManager = $this->attributesManager->withAttribute($name, $value);
return $new;
}
public function withoutAttribute(string $name): static
{
$new = clone $this;
$new->attributesManager = $this->attributesManager->withoutAttribute($name);
return $new;
}
}
PSR-11 – Dependency Container (Rozdział 3)
PSR-11 standaryzuje kontenery zależności, umożliwiając dynamiczne dostarczanie klas i usług.
Zobacz oficjalną dokumentację PSR-11
Zarządzaj zależnościami z PSR-11 🧱<?php
declare(strict_types=1);
namespace DJWeb\Framework\Container;
use DJWeb\Framework\Base\DotContainer;
use DJWeb\Framework\Container\Contracts\ContainerContract;
use DJWeb\Framework\Container\Contracts\ServiceProviderContract;
use DJWeb\Framework\Exceptions\Container\NotFoundError;
class Container implements ContainerContract
{
private DotContainer $entries;
private Autowire $autowire;
/**
* @var array
*/
private array $bindings = [];
public function __construct()
{
$this->entries = new DotContainer();
$this->autowire = new Autowire($this);
}
public function bind(string $key, string|int|float|bool|null $value): void
{
$this->bindings[$key] = $value;
}
public function getBinding(string $key): string|int|float|bool|null
{
return $this->bindings[$key] ?? null;
}
/**
* @param class-string $id
*
* @return mixed
*
* @throws NotFoundError
*/
public function get(string $id): mixed
{
$entry = $this->entries->get($id);
if (! $this->has($id)) {
return $this->autowire->instantiate($id);
}
if ($entry instanceof Definition) {
return $this->autowire->instantiate($entry::class);
}
return $entry;
}
public function has(string $id): bool
{
return $this->entries->has($id);
}
/**
* Sets item in container
*
* @param string $key
* @param mixed $value
*
* @return ContainerContract
*/
public function set(string $key, mixed $value): ContainerContract
{
$this->entries->set($key, $value);
return $this;
}
/**
* Add a definition to the container.
*
* @param Definition $definition
*
* @return self
*/
public function addDefinition(Definition $definition): ContainerContract
{
$this->entries[$definition->id] = $definition;
return $this;
}
/**
* Register a service provider.
*
* @param ServiceProviderContract $provider
*
* @return self
*/
public function register(
ServiceProviderContract $provider
): ContainerContract {
$provider->register($this);
return $this;
}
}
PSR-12 – Styl kodu PHP (Wszystkie rozdziały)
PSR-12 definiuje szczegółowe zasady formatowania kodu: odstępy, nawiasy, struktura funkcji i klas.
Zobacz oficjalną dokumentację PSR-12
Uczyń swój kod czytelnym z PSR-12 ✍️PSR-14 – Event Dispatcher (Rozdział 23)
PSR-14 definiuje mechanizm zdarzeń – luźne powiązania między komponentami i wzorzec Observer.
Zobacz oficjalną dokumentację PSR-14
Wykorzystaj eventy z PSR-14 ⚙️<?php
declare(strict_types=1);
namespace DJWeb\Framework\Events;
use DJWeb\Framework\Config\Config;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\EventDispatcher\ListenerProviderInterface;
class EventManager
{
public EventDispatcherInterface $dispatcher{
get => $this->_eventDispatcher ??= new EventDispatcher($this->listenerProvider);
}
public ListenerProviderInterface $listenerProvider{
get => $this->_listenerProvider ??= $this->createListenerProvider();
}
private ?EventDispatcherInterface $_eventDispatcher = null;
private ?ListenerProviderInterface $_listenerProvider = null;
public function dispatch(object $event): object
{
return $this->dispatcher->dispatch($event);
}
private function createListenerProvider(): ListenerProviderInterface
{
$provider = new ListenerProvider();
$eventConfig = Config::get('events.listeners');
foreach ($eventConfig as $eventClass => $listeners) {
foreach ((array) $listeners as $listenerClass) {
$provider->addListener($eventClass, $listenerClass);
}
}
return $provider;
}
}
PSR-15 – Middleware (Rozdział 12)
PSR-15 definiuje interfejsy middleware dla przetwarzania żądań HTTP w warstwach.
Zobacz oficjalną dokumentację PSR-15
Zbuduj elastyczny flow z PSR-15 🧩<?php
declare(strict_types=1);
namespace DJWeb\Framework\Http\Middleware;
use DJWeb\Framework\Exceptions\Validation\ValidationError;
use DJWeb\Framework\Http\Response;
use DJWeb\Framework\Web\Application;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class ValidationErrorMiddleware implements MiddlewareInterface
{
private const JSON_CONTENT_TYPE = 'application/json';
public function __construct(private ?Application $app = null) {
$this->app ??= Application::getInstance();
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
try {
return $handler->handle($request);
} catch (ValidationError $error) {
return $this->isJsonRequest($request) ?
$this->handleJsonResponse($error) : $this->handleWebResponse($request, $error);
}
}
private function isJsonRequest(ServerRequestInterface $request): bool
{
$contentType = $request->getHeaderLine('Content-Type');
$acceptHeader = $request->getHeaderLine('Accept');
return str_contains($contentType, self::JSON_CONTENT_TYPE)
|| str_contains($acceptHeader, self::JSON_CONTENT_TYPE);
}
private function formatErrorResponse(ValidationError $error): array
{
return [
'message' => $error->getMessage(),
'errors' => $error->validationErrors,
];
}
private function handleJsonResponse(ValidationError $error): ResponseInterface
{
return new Response()->withJson($this->formatErrorResponse($error), status: 422);
}
private function handleWebResponse(ServerRequestInterface $request, ValidationError $error): ResponseInterface
{
$this->app->session->set(
'errors',
json_encode($this->formatErrorResponse($error))
);
return new Response()->redirect($request->getUri()->getPath());
}
}
Zamów praktyczny kurs PHP już teraz!
Dowiedz się jak działają współczesne frameworki PHP

Kup teraz 149 zł
Nasz kurs PHP w praktyce to inwestycja w Twoją karierę. Po zakupie zyskasz:
Pełny dostęp do materiałów kursu
Możliwość czytania e-booka online
Przeglądarkę kodu źródłowego z praktycznymi przykładami
Możliwość pobrania w formatach PDF/EPUB/Markdown