Waar gebruik ik het Response object?

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Ventilatiesysteem Productontwikkelaar HBO WO Verwa

Samengevat: Zij bieden flexibele ventilatiematerialen, geluidsdempers, rookgasafvoer producten en industrieslangen. Ben jij een technisch productontwikkelaar? Heb jij ervaring met het ontwikkelen van nieuwe producten? Vaste baan: Technisch Productontwikkelaar HBO WO €3.000 - €4.000 Zij bieden een variëteit aan flexibele ventilatiematerialen, geluiddempers, rookgasafvoer producten, industrieslangen en ventilatieslangen voor de scheepsbouw. Met slimme en innovatieve materialen zorgen wij voor een gezonde en frisse leefomgeving. Deze werkgever is een organisatie die volop in ontwikkeling is met hardwerkende collega's. Dit geeft goede ontwikkelingsmogelijkheden. De branche van dit bedrijf is Techniek en Engineering. Functie: Voor de vacature als Technisch Productontwikkelaar Ede Gld HBO WO ga

Bekijk vacature »

Jan terhuijzen

jan terhuijzen

17/05/2015 14:42:41
Quote Anchor link
Hallo,

In mijn MVC maakte in eerst geen gebruik van een Response object, maar wel van een Request object. Ik ben dus nu een Response object aan het inbouwen. Maar waar doe ik dat eigenlijk?

Het zit zo in elkaar:
index.php
Doet de routing. Hier wordt een router object gemaakt etc. De router krijgt een Request object. De router include de controller die bij de route hoort en de actie van de controller wordt uitgevoerd. Aan de actie wordt het Request object meegegeven als parameter.

In controller
Worden model objecten gemaakt.
Bij mij hebben models nooit een verband met views of controllers.
De controller vraagt met methods aan een model on gegevens, of geeft aan het model een opdracht om gegevens aan te passen.
Wel geef ik bijna altijd een Database object mee aan een model object via de constructor.

De controller include daarna een view bestand, en een array met variabelen voor de view wordt ge-extract.
Bij het includen van de view is eigenlijk alles uitgevoerd, dus wordt er vanzelf een response gegeven, omdat PHP gewoon klaar is (callstack is klaar, of hoe noem je dat?) doordat het view bestand is ge-include wordt dus ook dat bestand weergeven.

Waar doe ik een Response object inbouwen, en wat moet dat object eigenlijk doen?
 
PHP hulp

PHP hulp

19/04/2024 16:02:48
 
Ward van der Put
Moderator

Ward van der Put

17/05/2015 14:54:45
Quote Anchor link
>> Bij het includen van de view is eigenlijk alles uitgevoerd, dus wordt er vanzelf een response gegeven, omdat PHP gewoon klaar is (callstack is klaar, of hoe noem je dat?) doordat het view bestand is ge-include wordt dus ook dat bestand weergeven.

Kort samengevat: je moet de view (die je al hebt) nog in een response verpakken.

Daar zijn verschillende redenen voor te verzinnen. De lastigste: één response kan meerdere views bevatten als er meerdere controllers aan te pas kwamen.
 
Wouter J

Wouter J

17/05/2015 15:07:06
Quote Anchor link
I.p.v. dat de controller de view direct op het scherm rendered "moet" (niks moet...) je deze meegeven aan een variable en het response object, welke door de controller wordt gereturned en door de front-controller wordt gerendered.

Dit omdat je naast gewoon outputten je je controller meer vrijheid wil geven. Zo moet de response vast niet altijd 200 OK zijn, maar bijv. ook wel eens 404 Not Found. Ook dit is de taak van de Response object.

Om nog een ander voorbeeld te noemen, de Content-Type is niet altijd text/html. Zo kan het voorkomen dat een controller een JSON response terug geeft, Content-Type: application/json. Ook dit is de taak van de Response.

Eigenlijk heeft Response dus praktisch dezelfde taken als Request. Waar de Request een wrapper om de request headers (uri, method, parameters, etc.) is is de Response een wrapper om de response headers (content-type, status, body, etc.).
Gewijzigd op 17/05/2015 15:07:28 door Wouter J
 
Jan terhuijzen

jan terhuijzen

17/05/2015 15:35:15
Quote Anchor link
Dus ik heb bijvoorbeeld deze action in een controller:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public function loginPage() {
        
        $form = new Form("POST");
        $form->addElement(new EmailInput("email", "Geen emailadres ingevuld", "Ongeldig emailadres"));
        $form->addElement(new PasswordInput("password", "Geen wachtwoord ingevuld"));
        
        $form->setValidator(new LoginFormValidator());
        
        $form->handleRequest($this->request);
        
        if($form->isSubmit()) {
            
            if($form->isValid()) {

                $this->login();

            } else {

                $data = array("email" => htmlentities($this->request->postVar("email")));
                $this->loadView("views/login.php", $data);
            }
            
        } else {
            
            $data = array("email" => "");
            $this->loadView("views/login.php", $data);
        }
}

private function login() {
    // when login form is submitted and valid
}


Ik laad nu steeds een pagina met loadView(). loadView() is een method van de parent (base) controller.
In plaats van dat ik loadView gebruik, kan ik dus beter een method in de base controller maken zoals response(Response $responseObject).
En dat response object, daar stel ik dan headers op in, zet ik views in etc.
Gewijzigd op 17/05/2015 15:36:04 door jan terhuijzen
 
Frank Nietbelangrijk

Frank Nietbelangrijk

17/05/2015 16:00:17
Quote Anchor link
Ik zou loadView zelf een response object terug laten geven.

Denk dat je wel even bij Symfony mag spieken: http://symfony.com/doc/current/components/http_foundation/introduction.html#response

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php

loadView($template, $data)
{

    $response = new Response();

    //...

    return $response;
}

?>
 
Wouter J

Wouter J

17/05/2015 16:23:09
Quote Anchor link
Even een beetje Symfony achtig voorbeeldje:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
class DemoController
{
    public function helloAction(Request $request)
    {

        return new Response('<h1>Hallo!</h1>');

        // of met een status
        return new Response('<h1>No product found!</h1>', 404);

        // of een template renderen en die als body meegeven
        return new Response($this->templating->render('static/hello.html.twig'));

        // of iets compleet anders
        $response = new Response(json_encode($data));
        $response->headers->set('Content-Type', 'application/json');

        return $response;

        // ... etc
    }
}

?>


Zoals je ziet krijgt de controller op deze manier veel meer vrijheid. De front controller krijgt dan het resultaat en handelt het af (stelt de juiste response headers in, output de body, etc.).
 
Frank Nietbelangrijk

Frank Nietbelangrijk

17/05/2015 16:40:32
Quote Anchor link
Wouter, waar vindt de daadwerkelijke

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
echo $response->getContent();
?>


dan plaats?

Dus waar wordt de content dan daadwerkelijk output (in symfony) ?
 
Ward van der Put
Moderator

Ward van der Put

17/05/2015 16:46:43
 
Wouter J

Wouter J

17/05/2015 16:51:38
Quote Anchor link
Frank, de front controller ziet er zo uit:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
$kernel
= new AppKernel(...);
// ...

$response = $kernel->handle(Request::createFromGlobals());
$response->send(); // het daadwerkelijke versturen van de content

// ... nog een terminate call om alles weer terug te zetten in de goede staat

?>

Dus hier: https://github.com/symfony/HttpFoundation/blob/master/Response.php#L373-385

Zoals je ziet is sendContent slechts een echo'tje en de rest een paar header() calls.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

17/05/2015 17:00:40
Quote Anchor link
En dus inderdaad onderdeel van het Response Object :-) Dank je Wouter.
 
Jan terhuijzen

jan terhuijzen

21/05/2015 16:40:55
Quote Anchor link
Frank Nietbelangrijk op 17/05/2015 16:00:17:
Ik zou loadView zelf een response object terug laten geven.

Denk dat je wel even bij Symfony mag spieken: http://symfony.com/doc/current/components/http_foundation/introduction.html#response

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php

loadView($template, $data)
{

    $response = new Response();

    //...

    return $response;
}

?>


Als ik dus die methode loadView een Response object laat returnen, waar wordt dan een include gedaan ofzo?
Ik lees trouwens wel eens codes van Symfony, dat framework kijk ik veel van af.
Gewijzigd op 21/05/2015 16:42:42 door jan terhuijzen
 
Frank Nietbelangrijk

Frank Nietbelangrijk

21/05/2015 18:02:08
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
        // of een template renderen en die als body meegeven
        return new Response($this->templating->render('static/hello.html.twig'));
?>


Even een stukje van Wouter zijn voorbeeld gepakt.

Hier wordt Twig gebruikt om een pagina te genereren.

Een heel erg simpel voorbeeldje van een Twig template:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// views/customer/show.html.twig

<html>
    <head>
    <title>blabla</title>
    </head>
    <body>
        
        <h1>Klantgegevens</h1>

        <table>
            <tr>        
                <th>naam:</th>
                <td>{{ customer.name }}</td>
            </tr>        
            <tr>        
                <th>email:</th>
                <td>{{ customer.email }}</td>
            </tr>        
        </table>
            
    </body>
</html>


Let dan vooral op de variabelen: {{ customer.name }} en {{ customer.email }}

Twig doet dus geen include maar een file_get_contents() !!!!
Ik hoop dat je het verschil weet hiertussen? anders gaan we daar dieper op in.

Twig vervangt de variabelen voor de daadwerkelijke naam en mailadres van de klant in dit voorbeeld.


Je hebt de controller, een response object (een storage met "het antwoord aan de client") en een class die dat antwoord in elkaar moet sleutelen. Hiervoor kunnen zoals Wouter al aangaf verschillende classes ingezet worden.
Zo heb je behalve een HTML response ook een JSON response, een Image response of een PDF response (etc)
Gewijzigd op 21/05/2015 18:02:28 door Frank Nietbelangrijk
 

21/05/2015 20:25:25
Quote Anchor link
Los van een templating engine; als je zelf je eigen reponse object zou willen bouwen is het handig om die flexibel te laten, bijvoorbeeld door DOMDocument een document te laten bouwen dat je aanvult op plekken die je via XPath queries aangeeft, om vervolgens de output terug te sturen naar de browser. En dan maakt het niet uit of dat weer via tekst/html, of een XML-letje / JSON-netje voor je XHR-object gaat.
Waarbij ik niet zeg dat het niet loont om af te kijken hoe andere frameworks dat doen.
 
Jan terhuijzen

jan terhuijzen

22/05/2015 12:14:20
Quote Anchor link
Dus Frank,
Dit stukje code
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
        // of een template renderen en die als body meegeven
        return new Response($this->templating->render('static/hello.html.twig'));
?>

Daar krijgt het response object de uiteindelijke output meegegeven in zijn constructor.
$this->templating->render('static/hello.html.twig') dat zorgt ervoor dat de inhoud van een template wordt opgehaald, met bijvoorbeeld file_get_contents(), en dat de inhoud van dat bestand wordt gelezen door een templating engine. Die templating engine vervangt dan bepaalde patterns zoals {{ customer.name }} door gegevens die hij ook op een of andere manier weet en dus kan invullen?
Gewijzigd op 22/05/2015 12:14:52 door jan terhuijzen
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.