pattern mvc su php procedurale

5

Prima di tutto, non ho nulla contro la programmazione OO (sarei arrabbiato se lo credessi). Ma stavo pensando ad una sorta di pattern MVC procedurale con PHP; lasciami spiegare meglio.

Come tutti sappiamo, gli ambiti variabili, a meno che non siano presi da $ _SESSION (, database, redis, ecc.) non sono mai globali e si riferiscono solo a un'esecuzione singolare di uno script. Ad esempio:

class Car {
  this->name = "foo";
  function setName($name) { ... }
  function getName() { return $this->name; }
}

Dove, ovviamente, in una situazione più comune, questi dati saranno presi dal DB, altrimenti qualsiasi oggetto auto, per esecuzione, avrebbe lo stesso nome.

Ora, non è possibile applicare il pattern MVC sul codice procedurale per scopi di semplicità? Immagina un social network molto semplice come l'applicazione; Potrei avere una struttura come questa

*views
  -profileview.php
  -messageview.php
  -loginview.php
  -notloggedin.php
*models
  -user.php
  -message.php
- profile.php
- messages.php
- login.php

dove profilo, messaggi e login.php funzionano come controllori e si dirigono verso la vista giusta; e user e message.php funzionano come le classi, che contengono tutte le funzioni eventualmente necessarie dai controller, come getUserById ($ id), postMessage ($ id, $ meesage), ecc.

L'ho semplificato molto, ma penso che tu possa capire il mio punto.

Cosa penseresti di tale implementazione a lungo termine e perché?

    
posta john smith 24.01.2013 - 12:17
fonte

4 risposte

3

Non discuterò con Stephen, anche se potrei. ;)

In sostanza, se vuoi andare con MVC da solo, avrai bisogno di almeno un dispatcher di richieste e probabilmente un risolutore di viste insieme ad alcune funzioni di configurazione.

Poiché il PHP procedurale non ha alcun supporto reale per i tipi, i problemi di accoppiamento saranno probabilmente un PITA.

In uno scenario di base potresti semplicemente avere un mapping di richiesta come

$mapping = array(
    "show_profile" => "profile.php:showProfile",
    "edit_profile" => "profile.php:editProfile",
    "etc" => "whatever.php:doEtc"
);

e poi recupera l'impostazione corretta e esplora su $ fileToInclude e $ functionToCall . Lì avrai risolto il problema del controller (passando un parametro di $ richiesta generalizzato) o meno.

Come per un'esecuzione molto semplice, il controllore potrebbe fare tutto ciò che dovrebbe e quindi includere esplicitamente il file di visualizzazione o restituire alcuni dati in modo che il resolver di visualizzazione possa essere richiamato con l'identificatore (ad es. percorso file o chiave di mappatura) della vista per renderizzare e visualizzare i dati.

Esistono approcci serveral e il precedente non è nemmeno vicino a una soluzione elegante (diamine, stiamo parlando di codice procedurale: D) ma questa è la più semplice variazione clean-ish che riesco a pensare; puoi estenderlo come preferisci.

Ricorda che vuoi mantenere il codice il più possibile decontestualizzato e gestibile. (Un modo difficile sarebbe creare un framework con il quale si possa usare un codice arbitrario come controller con funzioni e parametri arbitrari, il più semplice è semplicemente una questione di inclusioni esplicite)

PS .: Suggerirei di utilizzare framework esistenti per quella materia, ma gli unici framework PHP disponibili pubblicamente che sono validi sono tutti OO e mescolare OOP con codice procedurale sarebbe una pratica terribile; anche peggio di reinventare le tue ruote. In realtà, se non devi rimanere procedurale a tutti i costi, è meglio passare a OO.

Buona fortuna per il tuo progetto!

    
risposta data 03.03.2013 - 21:58
fonte
0

È molto soggettivo, ma perché dovresti scegliere di farlo "in questo modo" piuttosto che adottare un quadro reale per lo scopo? Se è solo per imparare qualcosa di nuovo, posso vedere il valore in esso, ma ci sono state centinaia se non migliaia di ore di lavoro investite nello sviluppo dell'attuale raccolto di framework PHP MVC, e anche il peggio di loro è probabilmente migliore di facendo così.

Come punto di partenza per utilizzare un quadro reale, questo è un buon inizio - perché incoraggia la separazione delle preoccupazioni - ma come risultato finale? È terribile.

    
risposta data 24.01.2013 - 13:05
fonte
0

Puoi costruire una casa senza fango ma è molto più semplice quando hai a disposizione tavole, chiodi e altri oggetti di dominio utili.

Per espanderci un po ', i motivi per cui la programmazione orientata agli oggetti è più adatta per questa attività rispetto alla programmazione procedurale sono gli stessi motivi per cui la programmazione orientata agli oggetti è migliore nella maggior parte dei compiti:

  • riutilizzo.
  • Il polimorfismo aumenta l'espressività.
  • Modella meglio i processi del mondo reale e del pensiero umano.
  • Aumenta la coesione.
  • Riduce l'accoppiamento.
  • Migliori meccanismi per l'incapsulamento e l'occultamento delle informazioni.

Tutti questi sono discutibili ma nessuno di questi è particolarmente nuovo.

    
risposta data 03.04.2013 - 00:03
fonte
-1

Non c'è alcun beneficio nel farlo in questo modo, c'è solo dolore e sofferenza. Il paradigma MVC è stato in gran parte inventato per allontanarsi dal farlo in un modo lineare strada a senso unico. Ciò che finirai è un pasticcio aggrovigliato che si avvicina rapidamente a zero flessibilità man mano che si aggiungono nel tempo.

Se stai creando il tuo framework, considera:

  • Avere un front controller
  • Rappresentazione della richiesta come singleton
  • Rappresentare i controller come singleton
  • Delega del lavoro ai subcontrollori
  • Chiedi ai tuoi controllori di restituire una vista per il backup della catena di chiamate, consentendo a ciascun controller di modificarlo (o sostituirlo).

Questa strategia ti garantirà una grande flessibilità con un codice molto piccolo.

Quello che segue è una dimostrazione di base molto semplice. Ovviamente vorrai dare corpo ai controller per tenere conto di 404, sanitizzare $_SERVER['REQUEST_URI'] , ecc.

abstract class Request {
    public $tokens;
    final private function __construct() { } // static singleton
}

abstract class View {
    abstract function render();
}

class MyView extends View {
    function render() {
        echo 'Hello, world.';
    }
}

class MyTheme extends View {
    public $content; // nested View
    function render() {
        echo '<h1>Themed</h1>';
        $this->content->render();
    }
}

abstract class Controller {
    final private function __construct() { } // static singleton
    abstract static function route(); // inspect the request and handle it locally,
                               // or send it to a subcontroller
}

abstract class FrontController extends Controller {
    static function route() {
        // inspect current(Request::$tokens) and decide to send it elsewhere
        next(Request::$tokens);
        $themed = new MyTheme();
        $themed->content = MySubController::route();
        return $themed;
    }
}

abstract class MySubController extends Controller {
    static function route() {
        return new MyView();
    }
}

/* in the script that invokes your front controller */
Request::$tokens = explode('/',$_SERVER['REQUEST_URI']);
FrontController::route()->render();
    
risposta data 21.05.2013 - 15:11
fonte

Leggi altre domande sui tag