LENKRAD - The modern PHP core


General flow

Your logic

Where it all begins...

The Request class

As reacting on requests is likely the most common prerequisite to your programmatic logic, LENKRAD has made handling requests as easy as possible. Let's first look at the static public methods:



Returns assoc array of query parameters

Request::getQuery(string $name)

Return the value of the specified query parameter, or null


Returns a Neoan\Enums\RequestMethod case


Returns a string containing the request-uri


Returns client-payload, regardless of method

Request::getInput(string $name)

Returns the value of the specified input, or null


Returns assoc array of route-specific parameters (see Route parameter)

Request::getParameter(string $name)

Returns the value of the specified parameter, or null

Request::getInstance(Request $mockInstance = null)

Return the current instance of the Request facade. (e.g. to mock & test)

Additionally, some useful properties are public:

$request = Request::getInstance();


Array containing all collected headers


Array containing all files submitted via form-data


Returns string of actual webPath before any sanitation and parsing

Request Unit Testing

To ease testing of your application code, you can set/override values at runtime. This is true for all public properties. Additionally, the following setters work statically:


Request::setParameters(array $parameters)

Expects assoc array

Request::setQueries(array $queryParameters)

Expects assoc array


Resets the singleton to null. (NOTE: you likely want to run getInstance() with a mock-instance after that to generate a new instance)

Using Request

You must not inject the Request into your controllers. Instead, the static methods can be used after app-instantiation anywhere in your code.

            use Neoan\Request\Request;

            class RandomClass extends Routable
                public function __invoke(MyValidationClass $validation)
                        'terms-accepted' => $accepted,
                        'email' => $requesterEmail
                    ] = Request::getInputs();

                    if(!$accepted || !$validation->isValidEmail($requesterEmail)){


Request guards

In order to provide a clean input/output structure while separating concerns in a clean manner, you can use validation wrappers called "Request guards". This pattern allows for abstraction similar to models, but for incoming data. Let's take the example above and make the following changes:


            class RandomClass extends Routable
                public function __invoke(RandomGuard $request)
                    // if we are here, all existence and validity is already taken care of

Our RandomGuard extends RouteGuard and may look like this


            use Neoan\Request\RequestGuard;

            class RandomGuard extends RequestGuard
                // the request REQUIRES the property "email"
                public string $email;

                // the request CAN have the property "gender"
                public ?string $gender;

                // the request's value of "termsAccepted" is cast to boolean
                public bool $termsAccepted;

                // we want to further expand on what should be blocked
                public function __invoke(): static
                    // let the parent do it's magic

                    // now let's block requests that don't fulfil our additional requirements
                    $validation = new MyValidationClass();
                    if(!$validation->isValidEmail($this->email) || !$this->termsAccepted) {
                        $response = Response::getInstance();
                        $response->respond('Bad Request');

                    return $this;

The RequestGuard class uses constants to manipulate default behavior. To change the default behavior, simply overwrite them in your guard.


const requestTypes = ['query', 'parameter', 'post'];

Reads from LENKRAD's request types in the provided order. You can change the order or exclude types.

const throwOnError = true;

By default, the guard stops execution and responds with a 400 status code explaining what is missing/malformed. If you want to handle errors yourself, simply set this to false;

As Guards can be chained, you can use them for complex privilege handling as well.

Before you move on

Many references on this page assume default settings. Your project might differ in behavior, paths etc.