PHP code example of rkistaps / the-app

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

    

rkistaps / the-app example snippets


// src/Routes/WebRoutes.php
namespace Acme\Routes;

use Acme\Handlers\HomeHandler;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ServerRequestInterface;
use TheApp\Components\Router;
use TheApp\Interfaces\RouterConfiguratorInterface;

final class WebRoutes implements RouterConfiguratorInterface
{
    public function configureRouter(Router $router): void
    {
        $router->get('/', HomeHandler::class, 'home');

        $router->get('/users/[i:id]', function (ServerRequestInterface $request, ResponseFactoryInterface $responses) {
            $response = $responses->createResponse();
            $response->getBody()->write('User #' . $request->getAttribute('id'));

            return $response;
        });

        $router->post('/users', function (ServerRequestInterface $request, ResponseFactoryInterface $responses) {
            return $responses->createResponse(201);
        });
    }
}

// src/Handlers/HomeHandler.php
namespace Acme\Handlers;

use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

final class HomeHandler implements RequestHandlerInterface
{
    public function __construct(private ResponseFactoryInterface $responses)
    {
    }

    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        $response = $this->responses->createResponse();
        $response->getBody()->write('Hello from TheApp');

        return $response;
    }
}

// index.php
use Acme\Errors\ErrorHandler;
use Acme\Routes\WebRoutes;
use DI\ContainerBuilder;
use Nyholm\Psr7\Factory\Psr17Factory;
use Nyholm\Psr7Server\ServerRequestCreator;
use Psr\Http\Message\ResponseFactoryInterface;
use TheApp\Components\HttpResponseEmitter;
use TheApp\Factories\AppFactory;

lass => $psr17,
    ])
    ->build();

$app = AppFactory::web($container)
    ->withRouterConfigurators([
        WebRoutes::class,
    ])
    ->withErrorHandler(ErrorHandler::class);

(new HttpResponseEmitter())->emit($app->run($request));

public function configureRouter(Router $router): void
{
    $router->group('/admin', function (Router $admin) {
        $admin->get('/users', UserListHandler::class);    // matches /admin/users
        $admin->group('/reports', function (Router $reports) {
            $reports->get('/daily', DailyReportHandler::class); // matches /admin/reports/daily
        });
    });
}

$router->get('/users/[i:id]/[:tab]?', UserHandler::class, 'user');

// In a handler
$router = $request->getAttribute(Router::class);
$router->url('user', ['id' => 42]);                   // /users/42
$router->url('user', ['id' => 42, 'tab' => 'posts']); // /users/42/posts

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

// In the front controller: every request
$app = AppFactory::web($container)
    ->withMiddleware([
        CorsMiddleware::class,
        function (ServerRequestInterface $request, RequestHandlerInterface $next) {
            return $next->handle($request)->withHeader('X-Frame-Options', 'DENY');
        },
    ])
    ->withRouterConfigurators([WebRoutes::class]);

// In a route configurator: a group and a single route
$router->group('/admin', function (Router $admin) {
    $admin->get('/users', UserListHandler::class);
    $admin->post('/users', CreateUserHandler::class)->addMiddleware(CsrfMiddleware::class);
})->addMiddleware(AuthMiddleware::class);

namespace Acme\Errors;

use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TheApp\Exceptions\MethodNotAllowedException;
use TheApp\Exceptions\NoRouteMatchException;
use TheApp\Interfaces\ErrorHandlerInterface;
use Throwable;

final class ErrorHandler implements ErrorHandlerInterface
{
    public function __construct(private ResponseFactoryInterface $responses)
    {
    }

    public function handle(Throwable $throwable, ServerRequestInterface $request): ResponseInterface
    {
        if ($throwable instanceof MethodNotAllowedException) {
            return $this->responses->createResponse(405)
                ->withHeader('Allow', implode(', ', $throwable->getAllowedMethods()));
        }

        $status = $throwable instanceof NoRouteMatchException ? 404 : 500;
        $message = $status === 404 ? 'Not found' : 'Something went wrong';

        $response = $this->responses->createResponse($status);
        if (str_contains($request->getHeaderLine('Accept'), 'application/json')) {
            $response->getBody()->write(json_encode(['error' => $message]));

            return $response->withHeader('Content-Type', 'application/json');
        }

        $response->getBody()->write($message);

        return $response;
    }
}

if ($isDevelopment) {
    $whoops = new \Whoops\Run();
    $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler());
    $whoops->register();
}

use DI\Container;
use Psr\Http\Message\ServerRequestInterface;
use TheApp\Components\Builders\ResponseBuilder;

$router->get('/api/status', function (ServerRequestInterface $request, Container $container) {
    return $container->make(ResponseBuilder::class)
        ->withStatus(200)
        ->withHeader('Content-Type', 'application/json')
        ->withContent(json_encode(['status' => 'ok']))
        ->build();
});

$router->get('/old-page', function (ServerRequestInterface $request, Container $container) {
    return $container->make(ResponseBuilder::class)->withRedirect('/new-page')->build(); // 301 by default
});

namespace Acme\Console;

use TheApp\Components\CommandRunner;
use TheApp\Interfaces\CommandConfiguratorInterface;
use TheApp\Interfaces\OutputInterface;

final class UserCommands implements CommandConfiguratorInterface
{
    public function configureCommands(CommandRunner $commandRunner): void
    {
        $commandRunner->addCommand('user/greet', function (string $name, OutputInterface $output, int $times = 1) {
            for ($i = 0; $i < $times; $i++) {
                $output->writeln("Hello, {$name}!");
            }
        });

        $commandRunner->addCommand('user/import', ImportUsersCommand::class);
    }
}

namespace Acme\Console;

use TheApp\Interfaces\CommandHandlerInterface;
use TheApp\Interfaces\OutputInterface;

final class ImportUsersCommand implements CommandHandlerInterface
{
    public function __construct(private OutputInterface $output)
    {
    }

    public function handle(array $params = []): int
    {
        $file = $params['file'] ?? 'users.csv';
        if (!is_readable($file)) {
            $this->output->error("Cannot read {$file}");
            return 1;
        }

        $this->output->writeln("Importing users from {$file}");

        return 0;
    }
}

// console.php
use Acme\Console\UserCommands;
use TheApp\Factories\AppFactory;

rCommands::class,
    ])
    ->run($argv);

exit($exitCode);

$output = new BufferedOutput();
$exitCode = AppFactory::console($container)
    ->withCommandConfigurators([UserCommands::class])
    ->withOutput($output)
    ->run(['console.php', 'user/greet', '--name=World']);

$output->getOutput(); // "Hello, World!\n"
$output->getErrors(); // ""

namespace Acme\Console;

use Psr\Log\LoggerInterface;
use TheApp\Interfaces\ConsoleErrorHandlerInterface;
use TheApp\Interfaces\OutputInterface;
use Throwable;

final class ConsoleErrorHandler implements ConsoleErrorHandlerInterface
{
    public function __construct(private LoggerInterface $logger, private OutputInterface $output)
    {
    }

    public function handle(Throwable $throwable, array $argv): int
    {
        $this->logger->error('Command failed: ' . implode(' ', $argv), ['exception' => $throwable]);
        $this->output->error($throwable->getMessage());

        return 1;
    }
}

$exitCode = AppFactory::console($container)
    ->withCommandConfigurators([UserCommands::class])
    ->withErrorHandler(ConsoleErrorHandler::class)
    ->run($argv);
bash
php console.php user/greet --name=World --times=2
php console.php user/import --file=export.csv