Toon posts:

[PHP] MVC: Javascript opbouwen?

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
In essentie een simpele vraag, maar ik kom er met mijn rubberen eend niet uit... Misschien toch meer voor discussie vatbaar.

In een PHP applicatie is MVC vaak wel een doel, maar aan interpretatie onderhevig. De rol van een model is volgens mij redelijk uitgekristalliseerd, al heb je daar soms nog een grijs gebied met libraries. Soit. Mijn vraag gaat echter meer richting de scheidslijn tussen controllers, views en templates.

Views en templates worden nog wel eens door elkaar gehaald. Wat ik vaak zie is dat in de controller alle gegevens worden verzameld en dan naar een template parser (bijv Twig, maar soms ook gewoon een parser van het framework in kwestie) worden gestuurd voor weergave. Eigenlijk zou daar nog een view tussen moeten zitten, maar ik moet zelf zeggen dat ik daar ook niet altijd even strikt in ben.

Maar goed. Stel nu: in een framework waarin templates en views elkaars gelijke zijn, waar definieer je dan JS snippets en/of dynamisch opgebouwde JS? Om een voorbeeld te geven:
  1. Ik haal in mijn controller een gegevensset op uit mijn model
  2. Voor elke rij in die set moet er een event met actie gedefinieerd worden in JS
  3. Die actie is een AJAX call naar een andere controller/functie
Je kunt dan kiezen om die gegevens als array naar de template te sturen en in de template de JS op te bouwen. Een alternatief is om die logica in de controller toe te passen, in de controller de JS op te bouwen en dat als 1 geheel (als string) naar de template te sturen. Voordeel van deze oplossing is dat je alle logica op 1 plek houdt en de template zich alleen bezig hoeft te houden met weergeven van wat de controller uitstuurt. Nadeel is dan weer dat JS opbouwen in een PHP string niet zoveel overzicht geeft, al valt daar omheen te werken natuurlijk.

Wat zijn jullie best practices?

Acties:
  • 0 Henk 'm!

  • leverage010
  • Registratie: Oktober 2012
  • Laatst online: 10-04-2023
Ik ben er zelf een groot voorstander van de template-specifieke JS onderaan de template te zetten. Ik werk weinig met PHP, maar des te meer met ASP.NET MVC. Pagina brede JS gaat in secties, Website-brede JS wordt meegegeven in de layout(View), en template-specifieke javascript pas ik toe onderaan in de template.

Dat alles dan niet meer op 1 plek staat is in mijn ogen dan verwaarloosbaar, omdat het ingedeeld is op logische plekken m.b.t. de context.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Akkoord, maar waar bouw je die dan op?

Het gaat mij voornamelijk om dynamisch opgebouwde JS. Waar je die neerzet is effectief een kwestie van een plaats bepalen en eventueel wat placeholders vervangen natuurlijk. Maar het opbouwen van JS zoals ik die in mijn voorbeeld geef, waar zou jij dat doen?

Acties:
  • 0 Henk 'm!

  • leverage010
  • Registratie: Oktober 2012
  • Laatst online: 10-04-2023
Kan je me uitleggen wat je bedoeld met Dynamische JS? Ik begrijp dat er conditionele fragmenten zijn van de code, maar is dat dan niet gewoon een kwestie van modulair implementeren?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik bedoel dynamisch opgebouwde JS. Oftewel, javascript die variabelen bevat afhankelijk van de situatie. Een voorbeeldje voor het idee:

PHP:
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
public function example($var)
{
    // Retrieve data from model
    $rowset = $this->Example_model->getData($var);
    if (!$rowset) {
        return false;
    }
    $js = '';

    // Loop trough data
    foreach ($rowset as $row) {
        // Decide on action
        switch ($row['action']) {
            case 'actionX':
                $uri = $this->actionLib->translateX($row['uri']);
                break;
            case 'actionY':
                $uri = $this->actionLib->translateY($row['uri'], $row['param']);
                break;
            default:
                $uri = $this->actionLib->defaultActionGet();
        }

        // Build JS
        $js .= '$("#elem' . $row['id'] . '").click(function(e) { 
                   $("#resultDiv").load("' . $uri . '")                        
                }' . PHP_EOL;
    }
    // Send JS to template
    $this->twig->display('example', ['js' => 'js']);
}

Even uit de losse pols dus wellicht zitten er foutjes in, maar ik hoop dat duidelijk is wat ik hier bedoel?

Acties:
  • +3 Henk 'm!

  • BarôZZa
  • Registratie: Januari 2003
  • Laatst online: 22:43
JS op een dergelijke manier opbouwen is een heel slecht idee (heel foutgevoelig door oa het ontbreken van syntax highlighting en vatbaar voor security lekken) en vrijwel altijd geheel onnodig.

In jouw voorbeeld kan je bijvoorbeeld beter een script uitvoeren nadat de template is gerendered. Je kan één functie voor de clickhandler maken en aan de losse elementen hangen door niet aan #elem1 #elem2 te hangen, maar ze bijvoorbeeld een class te geven en dan aan alle elementen met .elem. Of je zet de click handler op de parent (de gehele tabel) en kijkt in de functie welke cel er wordt aangeklikt door te kijken naar de target in het click event. Om extra data eraan te hangen kan je bijvoorbeeld gebruik maken van data attributes die je bij het parsen van de template er al inzet.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
In welke zin is dit dan vatbaar voor security lekken? Uiteindelijk bouw je gewoon normale JS in je output op. Het verschil zit hem eerder in of je die JS bepaalt in de controller of de template.

Acties:
  • 0 Henk 'm!

  • leverage010
  • Registratie: Oktober 2012
  • Laatst online: 10-04-2023
Omdat je code genereert op basis van een dataset, met als gevolg dat als je malafide input verwerkt dit invloed heeft op de code die je platform draait.

Deze afhankelijk moet je in zijn geheel afdichten.

In je voorbeeld wil je een jQuery script genereren op basis van tabellen in je database, terwijl je deze data gewoon door kan geven aan je front end welke hier dan op een veilige basis mee om kan gaan.

[ Voor 4% gewijzigd door leverage010 op 18-12-2018 16:49 ]


Acties:
  • +1 Henk 'm!

  • q-enf0rcer.1
  • Registratie: Maart 2009
  • Laatst online: 02-10 17:52
Je moet op de front-end per route JSON data binnenhalen voor die route, en die JSON data benutten in statische JavaScript code(waardoor de output van je statische JS functies dus alsnog dynamisch is, want de JSON data verschilt per route). Op die manier heb je niet meer het lek waar leverage010 over spreekt.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
oke, bedankt voor de tips :)
Pagina: 1