Up MVC: Minimalistiskt OO MVC för utbildningssyfte

PHPportalen Forum Index » Tips och Trix
Lägg ett bokmärke på hela tråden
Skapa nytt inlägg   Svara på inlägget Gå till sida Föregående  1, 2, 3, 4, 5, 6  Nästa
Visa föregående ämne :: Visa nästa ämne  
Startad av: Meddelande
intedinmamma



Medlem i: 3753 dagar
Från: Göteborg
Status: Offline



#708117
Inlägg Skrivet: 2011-05-27 14:18      Ämne: Citera

Sen kan man ju såklart implementera egna routes i sin .htaccess mha mod_rewrite, vilket väl är så minimalt och prestandabäst det kan bli. Smile (fast lite bökigare såklart)
 

_________________
Statistiskt sett? Kanske.
Till toppen på sidan
Visa användarprofil Skicka privat meddelande
morre_



Medlem i: 3348 dagar

Status: Offline



#708181
Inlägg Skrivet: 2011-05-29 08:38      Ämne: Citera

Snyggt script!
Men jag funderar på hur man hanterar POST och GET data?
Vart ska jag skicka användaren i action i formulären och vart kan jag behandla datan?
Förstår ni hur jag menar?
 
Till toppen på sidan
Visa användarprofil Skicka privat meddelande
Saurid
Moderator



Medlem i: 5637 dagar
Från: Perstorp
Status: Offline



#708184
Inlägg Skrivet: 2011-05-29 10:59      Ämne: Citera

morre_ skrev:
Men jag funderar på hur man hanterar POST och GET data?
Vart ska jag skicka användaren i action i formulären och vart kan jag behandla datan?

Du kan handskas med POST och GET-data på samma sätt som du är van vid idag. Sätt ett frågetecken efter länken eller skicka ett formulär med post method som vanligt.

Men med GET-data har du ett alternativ. Vanligtvis använder man ju inte GET med formulär, utan oftast är det ett id, eller liknande som ska skickas via en länk. I det fallet är det bättre att skicka med som parametrar i URL'en enligt router-reglerna i MVC'n.

Vart du ska skicka användaren är lite en fråga om vad du är ute efter. Om du har behov av att validera datan och ge meddelanden tillbaka till användaren, då är det enklast att skicka formuläret till samma sida du är på. Då kan du fortsätta att skriva ut formuläret igen, med post-data och felmeddelanden.

I fallet med webbshopen tex och köp-knapparna, där går jag till en egen action, behandlar datan och skickar tillbaka till sidan jag var på.

Slutligen så behandlar du i controllern du väljer att skicka din POST-data till. Det är där du validerar data och väljer om den kan sparas i databas eller liknande. Smile

Titta gärna i webbshopen efter exempel. Där finns exempel på allt detta:
http://www.phpportalen.net/viewtopic.php?t=117004
 

_________________
waljefors.se :: waeke.se :: GitHub :: SoundCloud :: Bandcamp
Till toppen på sidan
Visa användarprofil Skicka privat meddelande Besök användarens hemsida
trexake



Medlem i: 4689 dagar
Från: Järfälla
Status: Offline



#708223
Inlägg Skrivet: 2011-05-30 00:33      Ämne: Citera

Funderar på en sak: Om jag vill visa ett felmeddelande om besökaren skriver /lkasklndaklndas i adressfältet, hur ska jag gå till väga?

i och med att frontcontroller försöker skapa ett nytt objekt får man ett felmeddelande om den inte finns. Alltså: Finns klassen, skapa ett objekt, annars: Välj standardklassen.

Håller på med ett CMS och funderar på hur man skall göra saker smidigt. Tex att skriva ut en meny:
Detta i mitt fall görs rekursivt då sidor kan ha "barn".

PHP:
1:
 
2:
   function listPages($parent null) {
3:
      
4:
      $this->db->prepare('select',array('id','link','name','parent'));
5:
      $this->db->prepare('from',page_table);
6:
      $this->db->prepare('order',array('position','ASC'));
7:
      if (is_null($parent)) {
8:
         $this->db->prepare('where',array('parent','IS','NULL'));   
9:
      } else {
10:
         $this->db->prepare('where',array('parent','=',"'$parent'"));
11:
      }
12:
      
13:
      if ($result $this->db->get_result()) {
14:
         
15:
         if (!is_null($parent)) { echo "<ul>\n"; }
16:
         
17:
         foreach ($result as $row) {
18:
            
19:
            echo "<li>\n";
20:
               echo "<a href=\"".BASE."sida/".$row->link."\">".$row->name."</a>\n";
21:
               $this->listPages($row->id);
22:
            echo "</li>\n";
23:
            
24:
         }
25:
         
26:
         if (!is_null($parent)) { echo "</ul>\n"; }
27:
         
28:
      }
29:
      
30:
   }
31:
 


Nu har jag gjort så här, och kör ob_start() etc när jag anropar funktionen från början. Och sparar detta som $menu. Tycker dock att detta känns lite "fult".

Funderar på om man kanske ska skapa en statisk meny-view när man uppdaterar sidorna inne i adminpanelen.


En fråga till:
Sidan i fråga kommer ju ha en del funktionen, men grundutseendet (header,meny,footer etc) är alltid densamma. Dock ändras ju själva innehållet.

Jag kör en sån här på min CMS-klass:
PHP:
1:
 
2:
   function __construct() {
3:
      
4:
      $this->db = new database();
5:
      $this->view = new view();
6:
      
7:
      $settings = array('title','meta_keywords','meta_description','home');
8:
      $this->db->prepare('select',array('_key','_value'));
9:
      $this->db->prepare('from',settings_table);
10:
      $this->db->prepare('where',array('_key','IN',"('".implode("','",$settings)."')"));
11:
      
12:
      if ($result $this->db->get_result()) {
13:
         foreach ($result as $row) {
14:
            $this->data[$row->_key] = $row->_value;
15:
         }
16:
      }
17:
      
18:
      else {
19:
         foreach ($settings as $setting) {
20:
            if (!isset($this->data[$setting])) { $this->data[$setting] = ''; }
21:
         }
22:
      }
23:
      
24:
   }
25:
 


Om jag tex är inne på produkter, är det smartaste att skapa ett CMS objekt där, och hämta denna data därifrån? Och sedan skriva ut innehållet med hjälp av view klassen.
 
Till toppen på sidan
Visa användarprofil Skicka privat meddelande MSN Messenger
Saurid
Moderator



Medlem i: 5637 dagar
Från: Perstorp
Status: Offline



#708246
Inlägg Skrivet: 2011-05-30 15:14      Ämne: Citera

trexake skrev:
Funderar på en sak: Om jag vill visa ett felmeddelande om besökaren skriver /lkasklndaklndas i adressfältet, hur ska jag gå till väga?

i och med att frontcontroller försöker skapa ett nytt objekt får man ett felmeddelande om den inte finns. Alltså: Finns klassen, skapa ett objekt, annars: Välj standardklassen.

Felmeddelande får du ju redan (genom autoloadern), så den frågan förstår jag nog inte riktigt...

Vill du kontrollera att controllern finns innan frontcontrollern försöker skapa en instans, så får du kopiera den kontrollen från autoload till frontcontroller::dispatch. Något liknande nedan:
PHP:
1:
    public function dispatch()
2:
   {
3:
      $class_name str_replace('_''/'$this->controller);
4:
      $file_name $class_name '.php';
5:
      
6:
      if(is_readable($file_name)) {
7:
         $this->controller = new $this->controller();
8:
      } else {
9:
         $this->controller 'controller_index';
10:
         $this->action 'index';
11:
         $this->controller = new $this->controller();
12:
      }
13:
      if(is_callable(array($this->controller$this->action))) {
14:
         $this->controller->{$this->action}($this->parameters);
15:
      } else {
16:
         die("MVC Fel: Controller/action &quot;" get_class($this->controller) . "::{$this->action}&quot; kan inte anropas");
17:
      }
18:
   }
19:
 


trexake skrev:
Håller på med ett CMS och funderar på hur man skall göra saker smidigt. Tex att skriva ut en meny: Detta i mitt fall görs rekursivt då sidor kan ha "barn".

Nu har jag gjort så här, och kör ob_start() etc när jag anropar funktionen från början. Och sparar detta som $menu. Tycker dock att detta känns lite "fult".

Ja, du får nog besluta dig för vad som är mest logiskt. Att göra en fungerande, men väldigt "kluddig" template, eller att sköta det från en funktion/metod och skicka till view. Jag skulle nog luta åt att låta en funktion skapa din meny istället för försöka få ihop en snygg template. Det kommer att innebära så pass mycket logik att jag inte tycker det hör hemma i en template.

Jag förstår inte varför du behöver använda output buffring till detta dock. Du kan lika gärna returnera en sträng med hela menyn från funktionen och sedan skriva ut den i din view.

trexake skrev:
Funderar på om man kanske ska skapa en statisk meny-view när man uppdaterar sidorna inne i adminpanelen.

Jag är osäker på hur du menar nu, men misstänker att du menar en hårdkodad meny i en template? Ja, ska den inte ändras från sida till sida så kan du absolut göra på det viset. Det ser jag inga problem med. Smile

trexake skrev:
Om jag tex är inne på produkter, är det smartaste att skapa ett CMS objekt där, och hämta denna data därifrån? Och sedan skriva ut innehållet med hjälp av view klassen.

Du säger inte i vilket lager din CMS-klass hör till, men som det ser ut så blandar du lite ihop modeller och controllers. Jag säger lite, för din klass ser mest ut som en model. Men du skapar ändå upp ett view-objekt, så det påminner lite om en controller och där hör ingen datahämtning hemma.

Så mitt tips är: Skapa en modell som hämtar informationen från databasen. Ladda in modellen från dina controllers där du behöver den. Använd konstruktorn om du behöver använda samma information i flera actions. Hämta data från modellen i controllern och skicka vidare till view. Det är lite det som hela MVC-principen går ut på. Smile

Om du skickar med hela ditt CMS-objekt (modellen) till view eller om du ska dela upp i olika variabler är lite en smaksak. Är du ensam om att underhålla ditt system så kan det nog kvitta, men om modellen tillåter att man ändrar data i databasen tex, då kan det vara en risk att ge templates (och designers) direkt åtkomst till objektet.

Men har man bara minsta lilla kunskap i detta lilla MVC-system, så är det inga problem att ladda in modeller direkt från templates. Och det är nog inte så sannolikt att detta systemet kommer att användas av en större utvecklingsgrupp där man inte vet vad de andra i gruppen sysslar med Wink
 

_________________
waljefors.se :: waeke.se :: GitHub :: SoundCloud :: Bandcamp
Till toppen på sidan
Visa användarprofil Skicka privat meddelande Besök användarens hemsida
trexake



Medlem i: 4689 dagar
Från: Järfälla
Status: Offline



#708275
Inlägg Skrivet: 2011-05-31 12:33      Ämne: Citera

Hej, när jag tänker efter har jag blandat ihop model och controller lite. Har byggt upp mitt eget MVC ramverk, men inspiration från dig, så det skiljer sig lite annars, tex felmeddelanden.

Så här ser min dispatch ut:
PHP:
1:
 
2:
   public function execute() {
3:
      $this->controller = new $this->controller();
4:
      if (is_callable(array($this->controller,$this->action))) {
5:
         $this->controller->{$this->action}($this->parameters);
6:
      } else {
7:
         $this->controller 'controller_'.std_controller;
8:
         $this->controller = new $this->controller();
9:
         $this->action 'index';
10:
         $this->parameters null;
11:
         $this->controller->{$this->action}(); //Kan ev skicka till ngn error funktion
12:
      }
13:
   }
14:
 


Där är här ($this->controller = new $this->controller()Wink man får ett PHP felmeddelande om den klassen inte existerar, undrar om man kan komma från detta meddelande.

Undrar om man kan lösa det i autostart funktionen.
PHP:
1:
 
2:
   if(is_readable($file_name)) {
3:
      include $file_name;
4:
   } else {
5:
      //Skapa klassen här, för att inte generera ett PHP felmeddelande
6:
   }
7:
 



Ang menyfunktionen så har jag gjort så här:
PHP:
1:
 
2:
   ob_start();
3:
   $this->listPages();
4:
   $this->data['menu'] = ob_get_contents(); //Följer med till view
5:
   ob_end_clean();
6:
 


Ska sätta mig och fila lite mer på detta, kan visa lite vad jag har kommit fram till sen. Vore shysst med lite feedback
 
Till toppen på sidan
Visa användarprofil Skicka privat meddelande MSN Messenger
Saurid
Moderator



Medlem i: 5637 dagar
Från: Perstorp
Status: Offline



#708277
Inlägg Skrivet: 2011-05-31 14:14      Ämne: Citera

Då är det kanske enklast att ta bort felmeddelandet helt i autoloadern och bara behålla felhanteringen i din execute-metod.
PHP:
1:
 function __autoload($class)
2:
{
3:
   $class_name str_replace('_''/'$class);
4:
   $file_name $class_name '.php';
5:
   if(is_readable($file_name)) {
6:
      include $file_name;
7:
   }
8:

Autoload anropas automatiskt när du tex skapar ett object med new. Du ska inte göra något annat än inkludera filer där.

Det är generellt sett en riktigt dålig idé att printa ut saker direkt från en metod/funktion, så lagra istället din utskrift i listPages() i en variabel och använd return $variabel; i slutet av funktionen. Då slipper du använda ob som du säger är en ful lösning att använda när du inte behöver det. Då behöver du bara använda:
PHP:
1:
 $this->data['menu'] = $this->listPages(); 
 

_________________
waljefors.se :: waeke.se :: GitHub :: SoundCloud :: Bandcamp
Till toppen på sidan
Visa användarprofil Skicka privat meddelande Besök användarens hemsida
Sawny



Medlem i: 3379 dagar

Status: Offline



#708338
Inlägg Skrivet: 2011-06-01 22:02      Ämne: Citera

Hmm, funkar PATH_INFO på alla servrar?

Håller på med mitt eget MVC utifrån ditt + net.tuts guiden och får "No input file specified."
Med denna URL: MiniMVC/class/funk/33/

Med MiniMVC/index.php/class/funk/33/ så funkar det.

Min .htaccess fil har "RewriteRule ^(.*)$ index.php/$1 [L]".
 

_________________
HTML, CSS, PHP, JS
Till toppen på sidan
Visa användarprofil Skicka privat meddelande
Saurid
Moderator



Medlem i: 5637 dagar
Från: Perstorp
Status: Offline



#708342
Inlägg Skrivet: 2011-06-01 23:52      Ämne: Citera

Sawny skrev:
Hmm, funkar PATH_INFO på alla servrar?

Jag har aldrig upplevt några problem med det och php.net verkar inte nämna något om det.

Men om man börjar söka runt i Google så verkar det som att en del har problem med PHP som CGI. Men nu ligger vi långt utanför mina kunskaper, servermiljöer är definitivt inte min starka sida.

Denna länken föreslår att ORIG_PATH_INFO möjligen fungerar för dig:
http://www.unitedforums.co.uk/vb/website-development-scripting/11765-path_info-server-variable-not-working.html. Men ORIG_PATH_INFO sätts inte alls i min servermiljö (Apache/2.2.17 (Win32) PHP/5.3.4)...

Testa att köra en phpinfo() med en path i URL'en så ser du om PATH_INFO sätts.

Om någon annan har några smarta tips så tas de tacksamt emot!
Annars finns det ju andra sätt att få fram samma info, men då lite omständigare.
 

_________________
waljefors.se :: waeke.se :: GitHub :: SoundCloud :: Bandcamp
Till toppen på sidan
Visa användarprofil Skicka privat meddelande Besök användarens hemsida
Sawny



Medlem i: 3379 dagar

Status: Offline



#708352
Inlägg Skrivet: 2011-06-02 10:47      Ämne: Citera

Tack Smile

Löste det med att köra $_SERVER['QUERY_STRING'] och RewriteRule ^(.*)$ index.php?/$1 [L]
 

_________________
HTML, CSS, PHP, JS
Till toppen på sidan
Visa användarprofil Skicka privat meddelande
Peppe L-G



Medlem i: 4643 dagar
Från: Mullsjö
Status: Offline



#708989
Inlägg Skrivet: 2011-06-16 11:07      Ämne: Citera

Jag försöker få ihop en gästbok, och jag tror jag är klar med att sköta skrivningen med hjälp av kontrollen nu. Vore snällt om någon kunde kolla igenom och se om jag tänkt rätt.

PHP:
1:
<?php
2:
 
3:
class controller_guestbook{
4:
   
5:
   // När man ska skriva nytt inlägg
6:
   public function write(){
7:
      
8:
      $view = new View();
9:
      
10:
      $post = new model_post();
11:
      $post->loadFromArray($_POST);
12:
      
13:
      if(isset($_POST['addPost'])){
14:
         
15:
         // Man försöker posta ett nytt inlägg
16:
         
17:
         // Kolla efter fel
18:
         $errors = array();
19:
         
20:
         if($post->nameIsEmpty()){
21:
            $errors[] = 'Namnet ej ifyllt';
22:
         }
23:
         if($post->messageIsEmpty()){
24:
            $errors[] = 'Inlägget ej ifyllt';
25:
         }
26:
         
27:
         if(count($errors) == 0){
28:
            
29:
            // Inga fel, bara å spara!
30:
            $post->save();
31:
            
32:
            $successView = new View();
33:
            $successView->set('successMessage''Meddelandet sparades utan problem.');
34:
            $view->set('successView'$successView);
35:
            
36:
            // Börja på ett nytt inlägg
37:
            $post = new model_post();
38:
            
39:
         }else{
40:
            
41:
            // Finns fel, visa dem för besökaren
42:
            $errorView = new View();
43:
            $errorView->set('errorMessage'"Kunde inte spara inlägget på grund av följande problem:");
44:
            $errorView->set('errors'$errors);
45:
            $view->set('errorView'$errorView);
46:
            
47:
         }
48:
         
49:
      }elseif(isset($_POST['preview'])){
50:
         
51:
         // Man vill förhandsgranska sitt inlägg
52:
         $previewView = new View();
53:
         $previewView->set('post'$post);
54:
         $view->set('previewView'$previewView);
55:
         
56:
      }
57:
      
58:
      // Visa formuläret
59:
      $formView = new View();
60:
      $formView->set('post'$post);
61:
      $view->set('formView'$formView);
62:
      
63:
      // Visa vyn!
64:
      echo $view->render('guestbookWrite');
65:
      
66:
   }
67:
   
68:
}


Vad jag tror kan göras bättre är strängarna som skickas till vyerna (raderna 21, 24, 33 och 43). Känns inte som att de borde ligga i kontrollen, men jag vet inte vart man ska göra av dem riktigt.
 
Till toppen på sidan
Visa användarprofil Skicka privat meddelande MSN Messenger
Saurid
Moderator



Medlem i: 5637 dagar
Från: Perstorp
Status: Offline



#709016
Inlägg Skrivet: 2011-06-16 21:47      Ämne: Citera

Peppe L-G skrev:
Jag försöker få ihop en gästbok, och jag tror jag är klar med att sköta skrivningen med hjälp av kontrollen nu. Vore snällt om någon kunde kolla igenom och se om jag tänkt rätt.

Jag tycker det ser ganska bra ut Smile
Det jag ändå reagerar på är att du skapar upp flera view-objekt när det egentligen räcker med ett. Success, error eller preview gör detsamma. Du kan rendrera dem alla till samma variabel som du skriver ut i "guestbookWrite". Beroende på händelse blir det bara olika innehåll.

Att lägga felhanteringen i en modell som du gör är smart, eftersom du då samlar data- och felhantering på ett och samma ställe (det är ju oftast modellen som ska veta om data är rätt och riktigt). Men många skulle nog lägga det i kontrollern också. Se bara till att lägga själva validerings-rutinerna i en egen klass/objekt, så att du kan återanvända den på flera ställen.

Peppe L-G skrev:
Vad jag tror kan göras bättre är strängarna som skickas till vyerna (raderna 21, 24, 33 och 43). Känns inte som att de borde ligga i kontrollen, men jag vet inte vart man ska göra av dem riktigt.

Nej, det kan jag absolut hålla med om (att de är lite malplacerade i kontrollern). Men det allra vanligaste är nog att göra som du gör. Kanske de ska ligga i ett eget datalager? Varför inte vara lite kreativ och lägga upp en egen error-modell som returnerar textsträngar beroende på fel-id?

Jag har nog inte något riktigt bra svar på den frågan faktiskt... Confused
 

_________________
waljefors.se :: waeke.se :: GitHub :: SoundCloud :: Bandcamp
Till toppen på sidan
Visa användarprofil Skicka privat meddelande Besök användarens hemsida
Peppe L-G



Medlem i: 4643 dagar
Från: Mullsjö
Status: Offline



#709021
Inlägg Skrivet: 2011-06-16 22:21      Ämne: Citera

Att lägga valideringen i en egen klass var ju ett strålande förslag (tror någon annan också tipsat mig om det för en tid sedan, men minnet är ju som det är Embarassed).

Tack för dina åsikter!
 
Till toppen på sidan
Visa användarprofil Skicka privat meddelande MSN Messenger
Saurid
Moderator



Medlem i: 5637 dagar
Från: Perstorp
Status: Offline



#711792
Inlägg Skrivet: 2011-08-16 16:54      Ämne: Citera

Har gjort en mycket liten (men ganska trevlig) uppdatering av view.php så att den tillåter method chaining. Se exempel nedan:

PHP:
1:
 
2:
// Utan method chaining:
3:
$view->set('title'$item[0]['name']);
4:
$view->set('cart'$cart);
5:
$view->set('categories'$categories);
6:
$view->set('categorycount'count($categories));
7:
$view->set('item'$item[0]);
8:
$view->set('content'$view->render('item'));
9:
 
10:
 
11:
// Med method chaining:
12:
$view->set('title'$item[0]['name'])
13:
     ->set('cart'$cart)
14:
     ->set('categories'$categories)
15:
     ->set('categorycount'count($categories))
16:
     ->set('item'$item[0])
17:
     ->set('content'$view->render('item'));
18:
 
 

_________________
waljefors.se :: waeke.se :: GitHub :: SoundCloud :: Bandcamp
Till toppen på sidan
Visa användarprofil Skicka privat meddelande Besök användarens hemsida
Sawny



Medlem i: 3379 dagar

Status: Offline



#711797
Inlägg Skrivet: 2011-08-16 19:03      Ämne: Citera

Hur funkar det? Surprised
Aldrig sätt förut.
 

_________________
HTML, CSS, PHP, JS
Till toppen på sidan
Visa användarprofil Skicka privat meddelande
Visa tidigare inlägg:   
Skapa nytt inlägg   Svara på inlägget Gå till sida Föregående  1, 2, 3, 4, 5, 6  Nästa
PHPportalen Forum Index » Tips och Trix
Hoppa till:  
Du kan inte skapa nya inlägg i det här forumet
Du kan inte svara på inlägg i det här forumet
Du kan inte ändra dina inlägg i det här forumet
Du kan inte ta bort dina inlägg i det här forumet
Du kan inte rösta i det här forumet
Du kan inte bifoga filer i detta forum
Du kan inte ladda ner filer från detta forum
Kontakta oss på adressen: info@phpportalen.net
Webbplatsen bygger i grunden på phpBB © 2001, 2002 phpBB Group

Modifieringar har senare gjorts i systemet av PHPportalen
Sid och logotypdesign skapad av Daren Jularic