padrão mvc no PHP procedural

5

Primeiro, eu não tenho nada contra a programação OO (eu ficaria louco se eu acreditasse). Mas eu estava pensando em algum tipo de padrão MVC procedural com PHP; deixe-me explicar melhor.

Como todos sabemos, os escopos de variáveis, a menos que sejam retirados de $ _SESSION (, banco de dados, redis, etc.), nunca são globais e referem-se apenas a uma execução singular de um script. Por exemplo:

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

Onde, obviamente, em uma situação mais comum, esses dados serão retirados do banco de dados, caso contrário, qualquer carro objeto, por execução, teria o mesmo nome.

Agora, não é possível aplicar o padrão MVC no código procedural para fins de simplicidade? Imagine uma rede social realmente simples como aplicativo; Eu poderia ter uma estrutura como essa

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

onde perfil, mensagens e login.php funcionam como controladores e direcionam para a visualização correta; e user e message.php funcionam como as classes, que contêm todas as funções que são eventualmente necessárias pelos controllers, como getUserById ($ id), postMessage ($ id, $ meesage), etc.

Eu simplifiquei muito, mas acho que você pode entender o meu ponto de vista.

O que você acha de tal implementação a longo prazo e por quê?

    
por john smith 24.01.2013 / 12:17
fonte

4 respostas

3

Eu não vou discutir com Stephen, mesmo que eu possa. ;)

Basicamente, se você quiser usar o MVC por conta própria, precisará de pelo menos um despachante de solicitações e provavelmente um resolvedor de visualizações, além de alguns recursos de configuração.

Como PHP procedural não tem suporte real para tipos, problemas de acoplamento provavelmente serão um PITA.

Em um cenário mais básico, você poderia ter apenas um mapeamento de solicitação como

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

e depois recuperar a configuração correta e explodir para $ fileToInclude e $ functionToCall . Lá você terá seu problema de controlador resolvido (passando algum parâmetro generalizado $ request para eles ou algo assim).

Quanto a uma execução muito simples, seu controlador pode fazer o que for necessário e incluir explicitamente o arquivo de visualização ou retornar alguns dados para que o resolvedor de exibição possa ser chamado com o identificador (por exemplo, caminho de arquivo ou chave de mapeamento) da exibição para renderizar e os dados a serem exibidos.

Existem abordagens serverais, e a anterior não está nem perto de uma solução elegante (poxa, estamos falando de código procedural: D), mas essa é a variação mais simples e simples que consigo imaginar; você pode estender isso como quiser.

Tenha em mente que você deseja manter seu código o mais decifrado e sustentável possível. (Uma maneira difícil seria criar um framework com o qual você pudesse usar código arbitrário como controlador com funções e parâmetros arbitrários; o mais fácil é simplesmente uma questão de alguns includes explícitos)

PS .: Eu sugeriria usar frameworks existentes, mas os únicos frameworks PHP publicamente disponíveis que são viáveis são todos OO e misturar OOP com código procedural seria uma péssima prática; ainda pior do que reinventar suas rodas. Na verdade, se você não precisa ficar processual a todo custo, é melhor mudar para OO.

Boa sorte com o seu projeto!

    
por 03.03.2013 / 21:58
fonte
0

É muito subjetivo, mas por que você escolheria fazer "dessa maneira" em vez de adotar uma estrutura real para o propósito? Se é apenas para aprender algo novo, posso ver o valor nele, mas tem havido centenas, se não milhares, de horas de trabalho investido no desenvolvimento da atual safra de frameworks PHP MVC, e até mesmo o pior deles é provável que seja melhor do que fazendo desse jeito.

Como ponto de partida para o uso de uma estrutura real, este é um bom começo - porque incentiva a separação de interesses - mas como um resultado final? É horrível.

    
por 24.01.2013 / 13:05
fonte
0

Você pode construir uma casa de barro, mas é muito mais fácil quando você tem pranchas, pregos e outros objetos de domínio úteis disponíveis.

Para expandir isso um pouco, as razões pelas quais a programação orientada a objetos é mais adequada para essa tarefa do que a programação procedural são as mesmas razões pelas quais a programação orientada a objetos é melhor na maioria das tarefas:

  • Reutilizar.
  • O polimorfismo aumenta a expressividade.
  • Modela melhor o mundo real e os processos de pensamento humano.
  • Aumenta a coesão.
  • Reduz o acoplamento.
  • Melhores mecanismos para encapsulamento e ocultação de informações.

Tudo isso é discutível, mas nenhum deles é especialmente novo.

    
por 03.04.2013 / 00:03
fonte
-1

Não há benefício em fazê-lo desta maneira, há apenas dor e sofrimento. O paradigma MVC foi inventado em grande parte para se afastar de fazê-lo de uma forma linear de rua de mão única. O que você vai acabar é uma bagunça emaranhada que rapidamente se aproxima de flexibilidade zero à medida que você adiciona a ela ao longo do tempo.

Se você estiver criando sua própria estrutura, considere:

  • Ter um controlador frontal
  • Representando a solicitação como um singleton
  • Representando controladores como singletons
  • Delegação de trabalho aos subcontroladores
  • Peça aos seus controladores que retornem uma visão de backup da cadeia de chamadas, permitindo que cada controlador modifique (ou substitua) a cadeia.

Esta estratégia irá conceder-lhe alguma flexibilidade com muito pouco código.

O que se segue é uma prova de conceito muito básica. Você obviamente gostaria de dar corpo aos controladores para dar conta dos 404, sanear $_SERVER['REQUEST_URI'] , etc.

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();
    
por 21.05.2013 / 15:11
fonte