PHP code example of phpsoftbox / application

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

    

phpsoftbox / application example snippets


use PhpSoftBox\Application\ApplicationEnvironment;
use PhpSoftBox\Application\Contracts\EnvironmentEnumInterface;

enum Environment: string implements EnvironmentEnumInterface
{
    case DEV = 'dev';
    case DEMO = 'demo';
    case PROD = 'prod';
}

$environment = new ApplicationEnvironment(Environment::DEV);

$environment->current();                 // Environment::DEV
$environment->value();                   // 'dev'
$environment->is(Environment::DEV);      // true

use PhpSoftBox\Application\Application;
use PhpSoftBox\Application\ErrorHandler\JsonExceptionHandler;
use PhpSoftBox\Application\ErrorHandler\HtmlExceptionHandler;
use PhpSoftBox\Application\ErrorHandler\ContentNegotiationExceptionHandler;
use PhpSoftBox\Application\Middleware\ErrorHandlerMiddleware;
use PhpSoftBox\Router\Router;

$router = new Router($resolver, $dispatcher, $collector);
$exceptionHandler = new ContentNegotiationExceptionHandler(
    new JsonExceptionHandler($responseFactory, $streamFactory, 

use PhpSoftBox\Application\ErrorHandler\ContentNegotiationExceptionHandler;
use PhpSoftBox\Application\ErrorHandler\ExceptionFormat;
use PhpSoftBox\Application\ErrorHandler\ExceptionFormatDeciderInterface;
use PhpSoftBox\Application\ErrorHandler\ExceptionFormatDeciderRegistry;
use PhpSoftBox\Application\ErrorHandler\HtmlExceptionHandler;
use PhpSoftBox\Application\ErrorHandler\JsonExceptionHandler;
use Psr\Http\Message\ServerRequestInterface;
use Throwable;

final class ApiExceptionDecider implements ExceptionFormatDeciderInterface
{
    public function __invoke(Throwable $exception, ServerRequestInterface $request): ?ExceptionFormat
    {
        $path = ltrim($request->getUri()->getPath(), '/');
        if (str_starts_with($path, 'api/')) {
            return ExceptionFormat::JSON;
        }

        if ($request->getHeaderLine('X-Inertia') !== '') {
            return ExceptionFormat::HTML;
        }

        return null;
    }
}

$deciders = new ExceptionFormatDeciderRegistry([
    new ApiExceptionDecider(),
]);

$exceptionHandler = new ContentNegotiationExceptionHandler(
    new JsonExceptionHandler($responseFactory, $streamFactory, 

use PhpSoftBox\Application\ErrorHandler\DefaultExceptionHandler;
use PhpSoftBox\Application\ErrorHandler\ErrorHubExceptionReporter;
use PhpSoftBox\Application\ErrorHandler\LoggerExceptionReporter;
use PhpSoftBox\Application\Middleware\ErrorHandlerMiddleware;

$errorhubReporter = new ErrorHubExceptionReporter(
    baseUrl: 'https://errorhub.getstash-dev.ru',
    projectKey: 'YOUR_PROJECT_KEY',
    token: 'YOUR_BEARER_TOKEN', // опционально
    username: null, // опционально (basic auth)
    password: null,
    tags: ['env:prod', 'app:backend'],
);

$fallback = new ContentNegotiationExceptionHandler(
    new JsonExceptionHandler($responseFactory, $streamFactory, 

use PhpSoftBox\Application\ErrorHandler\ErrorHubExceptionInterface;
use PhpSoftBox\Application\ErrorHandler\ErrorHubExceptionTrait;

final class BillingException extends \RuntimeException implements ErrorHubExceptionInterface
{
    use ErrorHubExceptionTrait;
}

$e = new BillingException('Payment failed');
$e->setErrorHubTags(['module:billing']);
$e->setErrorHubContext(['order_id' => 42]);

use PhpSoftBox\Application\ErrorHandler\CompositeExceptionReporter;
use PhpSoftBox\Application\ErrorHandler\ExceptionReportContext;
use PhpSoftBox\Application\ErrorHandler\SoftExceptionMode;
use PhpSoftBox\Application\ErrorHandler\SoftExceptionReporter;

$exceptionReporter = new CompositeExceptionReporter([
    new LoggerExceptionReporter($logger),
    $errorhubReporter,
]);

$softExceptions = new SoftExceptionReporter(
    reporter: $exceptionReporter,
    mode: SoftExceptionMode::Report,
);

try {
    $params['sign'] = SignatureFactory::getSignature($url);
} catch (SignatureException $exception) {
    $softExceptions->report(
        $exception,
        new ExceptionReportContext(
            data: ['integration' => 'marketplace'],
            tags: ['signature'],
        ),
    );

    return null;
}

use PhpSoftBox\Application\RouterFactory;
use PhpSoftBox\Router\Cache\RouteCache;
use PhpSoftBox\Router\Dispatcher;

$cache = new RouteCache($cacheStorage);
$factory = new RouterFactory(new Dispatcher(), $cache);

$router = $factory->create(function ($routes) {
    $routes->get('/users', [UserController::class, 'index']);
});

use PhpSoftBox\Application\AppFactory;

$app = AppFactory::createFromContainer($container, environment: 'prod');

if (!$app->routesCached()) {
    

use PhpSoftBox\Application\Application;
use PhpSoftBox\Application\Middleware\ErrorHandlerMiddleware;
use PhpSoftBox\Application\Middleware\RequestSizeLimitMiddleware;
use PhpSoftBox\Session\SessionMiddleware;

$app = new Application($router, container: $container);

$app->add(new ErrorHandlerMiddleware($exceptionHandler), priority: 100);
$app->add(RequestSizeLimitMiddleware::class);

$app->alias('session', SessionMiddleware::class);
$app->middlewareGroup('web', ['session']);

$webApp = $app->withMiddlewareGroups(['web']);
$response = $webApp->handle($request);

$app->get('/users', [UserController::class, 'index']);
$app->post('/users', [UserController::class, 'store']);

$app->controllerMiddleware(UserController::class, ['auth']);
$app->controllerMiddleware(UserController::class, ['admin'], only: ['store', 'update']);

use PhpSoftBox\Application\Middleware\KernelRouteMiddlewareResolver;
use PhpSoftBox\Router\Dispatcher;
use PhpSoftBox\Router\Router;

$app->alias('auth', \PhpSoftBox\Auth\Middleware\AuthMiddleware::class);
$app->middlewareGroup('api', ['auth']);

$dispatcher = new Dispatcher(
    handlerResolver: null,
    middlewareResolver: new KernelRouteMiddlewareResolver($app->middlewareManager(), $container),
);

$router = new Router($resolver, $dispatcher, $collector);

$collector->group('/api', function ($routes) {
    $routes->get('/users', [UserController::class, 'index']);
}, ['api']);

use PhpSoftBox\Application\Response\JsonResponse;

return new JsonResponse(['ok' => true]);

throw new CodedHttpException(
    statusCode: 406,
    errorCode: 'unsupported_api_version',
    displayMessage: 'Requested API version is not supported.',
    details: ['supported_versions' => ['1.0.0', '1.1.0']],
    title: 'Unsupported API version',
    debugMessage: $internalDiagnostic,
);

$app->add(new TrustedProxyMiddleware(['10.0.0.0/8', 'fd00::/8']), 1000);

$middleware = new RateLimitMiddleware(
    limiter: $redisRateLimiter,
    maxAttempts: 60,
    decaySeconds: 60,
    keyResolver: static fn (ServerRequestInterface $request): string =>
        (string) $request->getAttribute(AuthenticatedNode::class)->id(),
    namespace: 'node_api',
);

use PhpSoftBox\Broadcaster\Pushr\PushrChannelAuth;
use PhpSoftBox\Http\Message\Response;
use Psr\Http\Message\ServerRequestInterface;
use function json_encode;

$app->post('/broadcast/auth', function (ServerRequestInterface $request, \PhpSoftBox\Broadcaster\Channel\ChannelRegistry $channels): Response {
    $data = (array) ($request->getParsedBody() ?? []);

    $socketId = (string) ($data['socket_id'] ?? '');
    $channel = (string) ($data['channel'] ?? '');
    $channelData = $data['channel_data'] ?? null;

    $authorization = $channels->authorize($channel, $request);
    if (!$authorization->authorized()) {
        return new Response(403);
    }

    $channelData = $authorization->channelData() ?? $channelData;

    $auth = PushrChannelAuth::token('app-1', 'secret-1', $socketId, $channel, $channelData);

    return new Response(200, ['Content-Type' => 'application/json'], json_encode([
        'auth' => $auth,
        'channel_data' => $channelData,
    ]));
});