Pergunta

Então, eu estou escrevendo um quadro em que eu quero basear alguns apps que eu estou trabalhando (o quadro está lá, por isso tenho um ambiente para trabalhar com, e um sistema que vai me deixar, por exemplo, usar um single sign-on)

Eu quero fazer este quadro, e os aplicativos que tem usar um Resource Oriented Architecture.

Agora, eu quero criar uma classe de roteamento de URL que é expansível por escritores APP (e possivelmente também por usuários CMS App, mas isso é WAYYYY à frente no futuro) e eu estou tentando descobrir a melhor maneira de fazê-lo olhando como outros aplicativos fazê-lo.

Foi útil?

Solução

Eu prefiro usar ex reg sobre fazendo meu próprio formato, uma vez que é de conhecimento comum. Eu escrevi uma pequena classe que eu uso que me permite ninho estes ex tabelas de roteamento reg. Eu uso a usar algo semelhante que foi implementado pela herança, mas ele não precisa de herança, então eu reescrevi-lo.

Eu faço um reg ex em uma chave e um mapa para a minha string de controle. Tomemos o exemplo abaixo. I visitar /api/related/joe e minha classe roteador cria uma nova ApiController objeto e chama isso de método relatedDocuments(array('tags' => 'joe'));

// the 12 strips the subdirectory my app is running in
$index = urldecode(substr($_SERVER["REQUEST_URI"], 12)); 

Route::process($index, array(
    "#^api/related/(.*)$#Di"    => "ApiController/relatedDocuments/tags",

    "#^thread/(.*)/post$#Di"    => "ThreadController/post/title",
    "#^thread/(.*)/reply$#Di"   => "ThreadController/reply/title",
    "#^thread/(.*)$#Di"         => "ThreadController/thread/title",

    "#^ajax/tag/(.*)/(.*)$#Di"  => "TagController/add/id/tags",
    "#^ajax/reply/(.*)/post$#Di"=> "ThreadController/ajaxPost/id",
    "#^ajax/reply/(.*)$#Di"     => "ArticleController/newReply/id",
    "#^ajax/toggle/(.*)$#Di"    => "ApiController/toggle/toggle",

    "#^$#Di"                    => "HomeController",
));

A fim de manter os erros para baixo e simplicidade se você pode subdividir a sua mesa. Desta forma, você pode colocar a tabela de roteamento para a classe que ele controla. Tomando o exemplo acima, você pode combinar as três chamadas de rosca em um único.

Route::process($index, array(
    "#^api/related/(.*)$#Di"    => "ApiController/relatedDocuments/tags",

    "#^thread/(.*)$#Di"         => "ThreadController/route/uri",

    "#^ajax/tag/(.*)/(.*)$#Di"  => "TagController/add/id/tags",
    "#^ajax/reply/(.*)/post$#Di"=> "ThreadController/ajaxPost/id",
    "#^ajax/reply/(.*)$#Di"     => "ArticleController/newReply/id",
    "#^ajax/toggle/(.*)$#Di"    => "ApiController/toggle/toggle",

    "#^$#Di"                    => "HomeController",
));

Em seguida, você define ThreadController :: rota para ser assim.

function route($args) {
    Route::process($args['uri'], array(
        "#^(.*)/post$#Di"    => "ThreadController/post/title",
        "#^(.*)/reply$#Di"   => "ThreadController/reply/title",
        "#^(.*)$#Di"         => "ThreadController/thread/title",
    ));
}

Além disso, você pode definir o que quer que os padrões que você deseja para sua seqüência de encaminhamento à direita. Só não se esqueça de documentá-los ou você vai confundir as pessoas. Atualmente estou chamando índice se você não incluir um nome de função no lado direito. Aqui é meu código atual. Você pode querer mudá-lo para erros punho como você gosta e ou padrão ações.

Outras dicas

No entanto, outro quadro? - de qualquer maneira ...

O truque é com roteamento é passá-lo todo para o seu controlador de roteamento.

Você provavelmente gostaria de usar algo semelhante ao que eu tenho documentado aqui:

http://www.hm2k.com/posts/friendly-urls

A segunda solução permite que você use URLs semelhantes a Zend Framework.

Use uma lista de regexs a partida que objeto eu deveria estar usando

Por exemplo

^/users/[\w-]+/bookmarks/(.+)/$
^/users/[\w-]+/bookmarks/$
^/users/[\w-]+/$

Pros: Nice e simples, me permite definir rotas diretamente Contras: teria que ser encomendado, não torná-lo fácil de adicionar novas coisas em (muito propenso a erros)

Esta é, afaik, como o Django faz

Eu acho que um monte de estruturas de usar uma combinação de mod_rewrite do Apache e um controlador de frente. Com mod_rewrite, você pode transformar uma URL como esta: pessoas / / obter / 3 para o seguinte: index.php? controller = pessoas & method = get & id = 3. Index.php iria implementar o controlador de frente, que encaminha a solicitação de página com base nos parâmetros fornecidos.

Como você poderia esperar, há uma série de maneiras de fazer isso.

Por exemplo, em Magro Framework , um exemplo do mecanismo de roteamento pode ser a folllowing (com base na padrão ${OBJECT}->${REQUEST METHOD}(${PATTERM}, ${CALLBACK})):

$app->get("/Home", function() {
    print('Welcome to the home page');
}

$app->get('/Profile/:memberName', function($memberName) {
    print( 'I\'m viewing ' . $memberName . '\'s profile.' );
}

$app->post('/ContactUs', function() {
    print( 'This action will be fired only if a POST request will occure');
}

Assim, a instância inicializada ($app) recebe um método por método de solicitação (por exemplo, get, post, put, excluir etc.) e recebe uma rota como o primeiro parâmetro e de retorno de chamada como o segundo.

A rota pode obter fichas - que é "variável" que vai mudar em tempo de execução com base em alguns dados (como nome de membro, o artigo id, nome da organização local ou qualquer outra coisa - você sabe, assim como em todos os controladores de roteamento).

Pessoalmente, eu gosto desta forma, mas eu não acho que vai ser o suficiente flexível para um quadro avançado.

Desde que eu estou trabalhando atualmente com ZF e Yii, eu tenho um exemplo de um roteador que eu criei como parte de um quadro para uma empresa que estou trabalhando para:

O motor de rota é baseado em regex (semelhante a um @ do gradbot), mas com uma conversa de duas vias, por isso, se um cliente seu não pode executar mod_rewrite (em Apache) ou adicionar regras de reescrita em seu servidor, ele ou ela ainda pode usar os URLs tradicionais com string de consulta.

O arquivo contém uma matriz, cada um dos que, cada item é semelhante a este exemplo:

$_FURLTEMPLATES['login']    =   array(
    'i' => array( // Input - how the router parse an incomming path into query string params
        'pattern' => '@Members/Login/?@i',
        'matches' => array( 'Application' => 'Members', 'Module' => 'Login' ),
    ),
    'o' => array( // Output - how the router parse a query string into a route
        '@Application=Members(&|&)Module=Login/?@' => 'Members/Login/'
    )
);

Você também pode usar combinações mais complexas, tais como:

$_FURLTEMPLATES['article']  =   array(
    'i' => array(
        'pattern' => '@CMS/Articles/([\d]+)/?@i',
        'matches' => array( 'Application' => "CMS",
            'Module' => 'Articles',
            'Sector' => 'showArticle',
            'ArticleID' => '$1' ),
    ),
    'o' => array(
     '@Application=CMS(&|&)Module=Articles(&|&)Sector=showArticle(&|&)ArticleID=([\d]+)@' => 'CMS/Articles/$4'
    )
);

A linha de fundo, como eu penso, é que as possibilidades são infinitas, ele só depende de quão complexo você deseja que seu quadro ser eo que você deseja fazer com ele.

Se for, por exemplo, apenas a intenção de ser um serviço web ou simples invólucro website - basta ir com estilo de Slim quadro da escrita - muito fácil e code-boa aparência.

No entanto, se você deseja desenvolver sites complexos de usá-lo, eu acho que regex é a solução.

Boa sorte! :)

Você deve verificar se Pux https://github.com/c9s/Pux

Aqui está a sinopse

<?php
require 'vendor/autoload.php'; // use PCRE patterns you need Pux\PatternCompiler class.
use Pux\Executor;

class ProductController {
    public function listAction() {
        return 'product list';
    }
    public function itemAction($id) { 
        return "product $id";
    }
}
$mux = new Pux\Mux;
$mux->any('/product', ['ProductController','listAction']);
$mux->get('/product/:id', ['ProductController','itemAction'] , [
    'require' => [ 'id' => '\d+', ],
    'default' => [ 'id' => '1', ]
]);
$mux->post('/product/:id', ['ProductController','updateAction'] , [
    'require' => [ 'id' => '\d+', ],
    'default' => [ 'id' => '1', ]
]);
$mux->delete('/product/:id', ['ProductController','deleteAction'] , [
    'require' => [ 'id' => '\d+', ],
    'default' => [ 'id' => '1', ]
]);
$route = $mux->dispatch('/product/1');
Executor::execute($route);

framework MVC do Zend por padrão utiliza uma estrutura como

/router/controller/action/key1/value1/key2/value2

onde router é o arquivo router (mapeados via mod_rewrite, controller é de um manipulador de ação do controlador que é definido por uma classe que deriva de referências Zend_Controller_Action e action um método no controlador, actionAction nomeado. Os pares de chave / valor pode ir em qualquer ordem e estão disponíveis para o método de acção como uma matriz associativa.

Eu usei algo semelhante no passado no meu próprio código, e até agora tem funcionado bastante bem.

Tente tomar olhada MVC padrão.
Zend Framework usa-lo, por exemplo, mas também CakePHP, CodeIgniter, ...

Me pessoalmente não gosto do modelo MVC, mas é na maioria das vezes implementados como "Ver para web" componente.

A decisão praticamente depende da preferência ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top