Avatar billede kasbas91 Nybegynder
05. juni 2011 - 15:24 Der er 10 kommentarer og
1 løsning

Hej jeg er ved at lave mit eget mvc framework. men i min url hvis jeg skriver :id skal den ignorere den??

Hej..

Jeg er ved at lave et mvc framework, og det virker også helt som

det nu skal, hvis jeg skriver user i url'en finder den controlleren.

også videre user/sign_in

men hvis jeg nu skriver min route sådan her:

$application_routes -> match_connect('/user/sign_in/:id', 'user#sign_in');

så skal :id ignoreres, altså så man kan skriver user/sign_in/12 fx. så er 12 et param mere i url'en. 

eller den kan også se sådan her ud:

$application_routes -> match_connect('/user/:id/sign_in', 'user#sign_in');

men jeg ved bare ikke hvordan man kan lave det...



<?php

    $application_routes = new ApplicationRoutes;
   
    $application_routes -> match_connect('/user', 'user#index');
   
    $application_routes -> match_connect('/user/sign_in/:id', 'user#sign_in');
   
?>




Router:

<?php

    class ApplicationRoutes {
           
        protected $controller;
       
        protected $action;
       
        function __construct() {
           
            $this->view = new ApplicationView();
           
        }
       
        function match_connect($url, $route) {
                       
            if($this->find_matchs($url)) {   
               
                // jeg splitter lige route fx user#index til user index.
                               
                $explode = explode('#', $route);
               
                // smider controller i denne variabel.
           
                $this->controller = $explode[0];
               
                // smider action for denne controller i denne variabel.
                               
                $this->action = $explode[1];
                               
                // vi smider lige den ind i en variabel.

                $this->controller_path = CONTROLLERS.$this->controller.'_controller.php';

                // tjekker lige om controller findes.

                if(!file_exists($this->controller_path)) {
               
                    echo "<pre>MVC kunne ikke åbne filen: <b>".$this->controller_path."</b></pre>";
                   
                } else {
               
                    // åbner efterspurgte controller.

                    require $this->controller_path;
                   
                    // instance for den efterspurgte controller.
                   
                    $this->instance = new $this->controller;
                                       
                    // tjekker lige om action findes.
                   
                    if(method_exists($this->instance, $this->action)) {
                       
                        // åbner action i denne controller.
                                               
                        $this->instance->{$this->action}();
                                                                       
                    } else {
                       
                        echo "<pre>MVC kunne ikke finde action: <b>".$this->action."</b> i denne controller: <b>".$this->controller_file."</b></pre>";
                       
                    }
               
                }
                               
            }
       
        }
       
        function find_matchs($url) {
           
            // tjekker om ruten findes, med den som brugeren skriver i url'en og den som ligger i config.
           
            if(rtrim(strtolower($_GET['url']), '/') == ltrim(strtolower($url), '/')) {
               
                // return true hvis ruten er fundet.
               
                return true;
               
            }
           
        }
       
    }
   
?>


men sådan som mit system er lavet så tjekker den i url'en som man

skriver og ser om det kan matche i mine routes...

så jeg er tvunget til at skrive /user/sign_in/:id

istedet for /user/sign_in/12

håber i forstår mig...
Avatar billede JensPeterSvensson Nybegynder
05. juni 2011 - 18:38 #1
Kunne du ikke i find match transformere url'en om til et regulært udtryk, hvor du udskifter for eks :id med  [a-zA-Z1-9]+
så du får det regulære udtryk:

$url = '/'.preg_replace_all('/:[a-z]+/','[a-zA-Z1-9]+',str_replace('/','\/',$url))";

så kan du

return preg_match($url, $_GET['url']));

Det kunne så udvides mere så du kunne specificere de lovlige væredier i :id delene i en url som det 2 + n argument til funktionen match hvor n er numeret på :id i url i forhold til andre.

$application_routes -> match_connect('/user/sign_in/:id1/:id2', 'user#sign_in', ApplicationRoutes::LETTERS, ApplicationRoutes::LETTERS & ApplicationRoutes::NUMBERS);

Man kan jo i php sende argumenter til funktioner, hvor argumenterne ikke er specificeret i funktionen.

Eller hvis du er imod at have sådanne variable argument funktion indkapsle typerne i et array:

$application_routes -> match_connect('/user/sign_in/:id1/:id2', 'user#sign_in', array(ApplicationRoutes::LETTERS, ApplicationRoutes::LETTERS & ApplicationRoutes::NUMBERS));
Avatar billede kasbas91 Nybegynder
05. juni 2011 - 19:15 #2
jov men jeg aner ikke hvordan..

Den der preg_replace_all virker ikke. :)

Men jeg har tænkte på at man kan bruge Regular expression.

Men jeg er ikke sikker på

hvordan man kan sende det videre til url'en. Eller hvordan man

nu skal gøre det..

hvis min route ser således ud:

$application_routes -> match_connect('/user/sign_in/:id1/:id2', 'user#sign_in');

hvordan kan min kode så finde ud af at ale efter sign_in/ skal

være valgfri nummere eller bogstaver og at det ikke skal hedde

:id i adresselinjen.
Avatar billede JensPeterSvensson Nybegynder
05. juni 2011 - 20:08 #3
ja preg_replace_all vil nok ikke virke når den ikke findes, den heder bare preg_replace.

<?php
$_GET['url'] = '/user/sign_in/alpha/omega3';
function find_matchs($url){
  $url = '/'.preg_replace('/:[a-z0-9]+/','[a-zA-Z1-9]+',str_replace('/','\/',$url)).'/';
  return preg_match($url, $_GET['url']) == 1;
}

var_dump(find_matchs('/user/sign_in/:id1/:id2'));
?>
Avatar billede kasbas91 Nybegynder
05. juni 2011 - 23:14 #4
Ja jeg kan godt se hvor vi skal hen med dette, men den skriver bar bool(false) hvis jeg sætter det op som dig..

            $url = '/'.preg_replace('/:[a-z]+/','[a-zA-Z1-9]+',str_replace('/','\/',$url)).'/';
             
            return preg_match($url, $_GET['url') == 1;

men hvis jeg skriver:

            $url = '/'.preg_replace('/:[a-z]+/','[a-zA-Z1-9]+',str_replace('/','\/',$url)).'/';
             
            return preg_match($url, 'http://prowmvc:8888/user/sign_in/12') == 1;

så siger den bool(true)

men den kan ikke selv hente det fra router til url til scriptet.

kun hvis jeg sætter det statisk ind i preg_match.
Avatar billede JensPeterSvensson Nybegynder
06. juni 2011 - 06:11 #5
Den sidste kode jeg skrev er jo en test i sig selv, den returnere true, hvis $_GET['url'] er '/user/sign_in/alpha/omega3' og $url er '/user/sign_in/:id1/:id2'.

I den kode du viser er der kun et variabelt led så du skal skrive $url som:

'/user/sign_in/:id1'

Hvis den fejler er den eneste grund, jeg kan se, til det, at du ikke har den værdi i $_GET['url'], som du tror du har.

Hvis $_GET['url'] er lig med 'http://prowmvc:8888/user/sign_in/12' så ville disse to kald give det samme:

preg_match($url, 'http://prowmvc:8888/user/sign_in/12')
preg_match($url, $_GET['url'])
Avatar billede kasbas91 Nybegynder
06. juni 2011 - 09:28 #6
men jeg kan ikke se hvordan den kan gå ind og se i:

$application_routes -> match_connect('/user/:id/sign_in', 'user#sign_in');

og finde :id og erstatte den med

så der kan skrives tal / bogstaver istedet i url'en for at jeg skal

skrive :id i url'en også, og jeg kan godt se at det er regex jeg

skal over i. men jeg kan bare ikke få det til at virke ordentligt..
Avatar billede JensPeterSvensson Nybegynder
06. juni 2011 - 10:01 #7
det første argument du giver til match_connect er $url argumentet i find_matchs. I find_matchs bruges preg_replace til at udskift alle :[a-z]+ i $url med [a-zA-Z0-9]+ og str_replace til at udskifte / med \/. Dermed laver den i det eksempel du lige viste det regulære udtryk:
/\/user\/[a-zA-Z1-9]+\/sign_in/

Som vil få fra preg_match til at returnere 1, når $_GET['url'] er:
/user/bla1/sign_in/
/user/1111/sign_in/
etc...

Hvis du påstår det ikke virker må du lige skrive den værdi du giver som første argument til match_connect og den værdi der er i $_GET['url'].
Avatar billede kasbas91 Nybegynder
06. juni 2011 - 10:14 #8
Hej jeg har fået det til at virke..

smid et svar JensPeterSvensson. tak for hjælpen.
Avatar billede kasbas91 Nybegynder
06. juni 2011 - 10:22 #9
Men jeg har lige et sidste spørgsmål, hva nu hvis jeg vil have

en for id og en anden for string:

$id = '/'.preg_replace('/:[id]+/','(\d+)+',str_replace('/','\/',$url)).'/';

Det er id og den virker fint, men hva nu hvis jeg skal have en

der tjekker på string for bogstaver..
Avatar billede kasbas91 Nybegynder
06. juni 2011 - 10:24 #10
men jeg ved ikke hvordan jeg sætter de 2 op så de køre hver for sig.

og ikke på samme tid ellers får jeg en fejl

hvis jeg sætter den her 2 gange:

return preg_match($id, 'http://prowmvc:8888/'.$_GET['url']) == 1;

return preg_match($string, 'http://prowmvc:8888/'.$_GET['url']) == 1;
Avatar billede kasbas91 Nybegynder
19. juli 2011 - 20:12 #11
lukker
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester