PHP MVC передает данные в объекте ответа в тело (представление)?

Я использую php + blade и написал простой mvc, и теперь мне интересно, как передать данные для просмотра. Мой объект ответа содержит заголовок, код состояния и тело (представление). Можно ли передавать данные в раздел тела ответа рядом с представлением?
->setBody(['view'=>'result','somedata'=>$somedata]);

или объект ответа должен иметь код состояния, заголовок, тело (представление) и данные отдельно от тела (представления)?

теперь в контроллере у меня есть:

return Response::create()
    ->setStatusCode(200)
    ->setHeader(['Content-Type' => 'text/html'])
    ->setBody(['view'=>'result']);

мой класс ответа:

class response implements ResponseInterface
{
    protected $statusCode;
    protected $headers;
    protected $body=[];

    public function setStatusCode(string $code) :object
    {
        $this->statusCode = $code;
        return $this;
    }

    public function setHeader(array $header):object
    {
        $this->headers=$header;
        return $this;
    }

    public function setBody(array $body): object
    {
        $this->body = $body;
        return $this;
    }

    public function getStatusCode():string
    {
        return $this->statusCode;
    }
    public function getHeaders():array
    {
        return $this->headers;
    }
    public function getBody():array
    {
        return $this->body;
    }
    public static function create(string $statusCode = null, array $headers = null, string $body = null): response
    {
        return new Response($statusCode, $headers, $body);
    }
    public function send(): void
    {
        foreach ($this->headers as $header => $value) {
            header(strtoupper($header).': '.$value);
        }

        if ($this->headers['Content-Type']== = "text/html" && $this->statusCode === "200") {
            View::renderTemplate($this->body['view']);
        }


    }
}

я могу передавать такие данные, добавляя переменную fx datatable в контроллеры, и это работает:

 return Response::create()
        ->setStatusCode(200)
        ->setHeader(['Content-Type' => 'text/html'])
        ->setBody(['view'=>'result','datatable'=>$datatable]);

а затем необходимо настроить действие отправки ответа на:

public function send(): void
{
    foreach ($this->headers as $header => $value) {
        header(strtoupper($header).': '.$value);
    }

    if ($this->headers['Content-Type']== = "text/html" && $this->statusCode === "200") {
        View::renderTemplate($this->body['view'],'datatable'=>$this->body['datatable']);
    }

}

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Фабрика ответов

Экземпляр Response не должен нести ответственность за создание объекта Response. Эта задача должна выполняться Фабрика ответов. Пример:

class ResponseFactory extends MessageFactory implements ResponseFactoryInterface {

    //...

    public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface {
        return new Response($this->body, $code, $reasonPhrase, $this->headers, $this->protocolVersion);
    }

    //...

}

Излучатель ответа

Экземпляр Response не должен отвечать за отправку заголовков ответа HTTP. Эта задача, наряду с выводом содержимого тела ответа на экран, должна выполняться Излучатель ответа. Пример:

class ResponseEmitter implements ResponseEmitterInterface {

    //...

    public function emit(ResponseInterface $response): void {
        $this
            ->checkHeadersSent()
            ->sendStatusLine($response)
            ->sendResponseHeaders($response)
            ->outputBody($response)
        ;

        exit();
    }

    //...

}

Визуализатор/движок шаблонов

Экземпляр Response не должен отвечать за отрисовку файлов шаблонов (также известных как взгляды). Таким образом, его не следует связывать с каким-либо модулем визуализации шаблонов или экземпляром View для визуализации файлов шаблонов. Задача рендеринга файлов шаблонов должна выполняться визуализатор/движок шаблонов. Пример:

class TemplateRenderer extends BaseTemplateRenderer implements TemplateRendererInterface {

    //...

    public function render(string $templateName, array $context = []): string {
        $templateFile = $this->templatesPath . $this->buildTemplateName($templateName);

        $this
            ->validateTemplateFile($templateFile)
            ->saveContextValuesToContextCollection($context)
        ;

        return $this->renderTemplateFile($templateFile);
    }

    private function renderTemplateFile(string $filename): string {
        ob_start();

        extract($this->contextCollection->all());

        require $filename;

        $content = ob_get_contents();

        ob_end_clean();

        return $content;
    }

    //...

}

Визуализированный контент (нить!) Затем передается в тело экземпляра Response.

Пример

Вот пример класса, метод которого addUser отвечает за рендеринг данного файла шаблона, создание экземпляра ответа, запись отображаемого содержимого в тело ответа и возврат ответа.

/**
 * A view to handle the users.
 */
class Users extends Primary {

    //...

    /**
     * Add a user.
     * 
     * @return ResponseInterface The response to the current request.
     */
    public function addUser(): ResponseInterface {
        $bodyContent = $this->templateRenderer->render('@Templates/Users/Users.html.twig', [
            'activeNavItem' => 'Users',
            'message' => 'User successfully added',
            'users' => $this->getAllUsers(),
        ]);

        $response = $this->responseFactory->createResponse();
        $response->getBody()->write($bodyContent);

        return $response;
    }

    //...

}

Ответ, возвращенный Users:addUser, далее обрабатывается эмиттером ответа. Содержимое его тела, наконец, выводится на экран.

// Create a request.
$request = $container->get('request');

// Create a middleware queue.
$middlewareQueue = $container->get('middleware-queue');

// Handle the request and produce a response.
$response = $middlewareQueue->handle($request);

// Emit the response.
$responseEmitter = $container->get('response-emitter');
$responseEmitter->emit($response);

Вернуться к... вашему упрощенному ответу

Итак, в вашем случае ответ можно упростить до следующего. В ваших силах разработать остальные компоненты — те, что я упомянул выше.

class Response implements ResponseInterface {

    public function getStatusCode(): int {
        //...
    }

    public function setStatusCode(int $code): static {
        //...
    }

    public function getHeaders(): array {
        //...
    }

    public function setHeader(array $header): static {
        //...
    }

    public function getBody(): string {
        //...
    }

    public function setBody(string $content): static {
        //...
    }

}

Примечание: Если вы используете return $this; в методе, используйте static вместо object в качестве возвращаемого типа данных.

Некоторые предложения

Если можно, я бы предложил вам разработать приложение на основе MVC, которое использует внешние библиотеки для своих компонентов. Например, вместо того, чтобы разрабатывать собственную реализацию HTTP-сообщения (запрос, ответ, URI, загруженные файлы и т. д.), что займет у вас очень много времени!, я бы рекомендовал использовать пакет Ламинас Диакторос. Или использовать Веточка в качестве механизма шаблонов и средства визуализации для вашего приложения. И так далее.

Примечание: Кстати, метод оказывать шаблонизатора Twig даст вам ответ на ваш вопрос (Можно ли передавать данные в раздел тела ответа рядом с представлением?).

Кроме того, для ваших PHP-приложений, если вы еще этого не сделали, я бы посоветовал следовать Рекомендации по стандартам PHP.

Ресурсы

Спасибо, я посмотрю насчет фабрики и эмиттеров. это простой проект, который я написал для изучения php, поэтому я новичок. Я некоторое время изучил laravel и вернулся к чистому php, чтобы узнать, что именно происходит за кулисами приложения - чтобы понять ответы, запросы и прочее :) спасибо за ваше время.

Filip9191 23.03.2022 19:35

Другие вопросы по теме