Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Przebudowa skryptu + integracja z innym
#1
Witam,
mam własny skrypt zintegrowany z forum na phpBB3, postanowiłem przerobić go aby był bardziej przenośny i mógł posłużyć do tworzenia innych serwisów dopiętych do for tego typu.
Wszystko było na funkcjach i strukturalnie, postanowiłem zamknąć ile się da w OOP, przez przypadek wyszło że warto od razu wszystko odseparować używając MVC.

Skrypt ma przyjazne adresy, lecz nie mam żadnego routera, bo faktycznie zajmuje się tym .htaccess. Nie mam zamiaru puszczać wszystkich żądań (np. takich, które zwracają 404) na jeden plik. Są określone moduły i nie ma problemu aby wypisać je w htaccesie, wszystkie wymienione będą jednak iść przez główny plik.

Plik rozruchowy wygląda tak:

Kod PHP:
<?php
include('main/initializer.php');
initializer::initialize();

$module = (isset($_GET['module'])) ? $_GET['module'] : '';
$action = (isset($_GET['action'])) ? $_GET['action'] : '';

$modules = array('News''NewsCat''Article''ArticleCat');
if (!
in_array($module$modules))
{
  
$module 'News';
}

if (
$action == '')
{
  
$action 'baseAction';
}   
$controller loader::getController($module'controller');

if (
method_exists($controller$action))
{
  
// phpBB3 integration
  
$phpEx substr(strrchr(__FILE__'.'), 1);
  
$phpbb_root_path '../forum.safegroup.pl/';
  include(
$phpbb_root_path 'common.' $phpEx);
  
  
$user->session_begin();
  
$auth->acl($user->data);
  
$user->setup();

  
$controller->{$action}();
}
?>

Initializer dołącza pliki z podstawowymi klasami oraz zestaw używanych stałych.
Później odczytanie danych z żądania, wybór kontrolera, jeżeli wszystko ok to załączam pliki phpBB3 i wykonuję akcję.
Oto przykładowy kontroler dla newsa:

controllers/controllerNews.php
Kod PHP:
<?php
class controllerNews extends controller
{
  public function 
baseAction()
  {
    
$this->index();
  }
  
  
  public function 
index()
  {
    
$this->page = (isset($_GET['page']) && $_GET['page'] > 0) ? $_GET['page'] : 1;
    
    
$this->view loader::getView('News''view');
    
$this->view->urls loader::get('urls');
    
$this->view->urls->zeroDuplicate('index');
    
    
$this->view->model loader::getModel('News''model');

    
$this->view->renderNewsList($this->page);
    
$this->view->renderPage();
  }
  
  
  public function 
view()
  {
    
$this->id request_var('id'0);
    
    
$this->view loader::getView('News''view');
    
$this->view->urls loader::get('urls');
    
$this->view->model loader::getModel('News''model');
    
    
$this->view->renderNews($this->id);
    
$this->view->model->updateNewsReadsById($this->id);
    
$this->view->renderPage();        
  } 


Wszystkie ładowane widoki / modele rozszerzają ich klasy bazowe, które zawierają w konstruktorach min. odwołanie do innych potrzebnych elementów np. dla modelu jest to dodanie obiektu $db z phpBB3 odpowiedzialnego za połączenia z bazą. Poza tym klasy bazowe udostępniają również metody "globalne" z punktu widzenia serwisu, np. widok daje renderPage, która jak nazwa wskazuje pozwala na wyświetlanie strony poza zawartością wygenerowaną przez akcję, czy też komunikat o błędzie.

Tutaj mam pytanko, jak widać obie metody-akcje kontrolera ładują ten sam widok i ten sam model - warto to wrzucać do konstruktora tego kontrolera?
Nie wykluczam oczywiście, że w wypadku innych kontrolerów coś takiego nie będzie możliwe, więc nie wiem czy to minimalizacja, czy robienie bałaganu (w jednym kontrolerze tak, w innym inaczej, wydaje się bałaganiarskie).

Jak widać, w wypadku akcji index (czyli strona główna, lista newsów) jest z url'i wywoływana metoda zeroDuplicate - sprawdza ona, czy adres jest poprawny i jeżeli nie, robi redirecta.
To samo zachodzi również w drugiej akcji, ale obecnie jest zaszyte w view->renderNews() bo... aby sprawdzić czy adres newsa jest prawidłowy, muszę mieć jego dane, a one są pobierane przez widok właśnie w tej metodzie:

views/viewNews.php:
Kod PHP:
public function renderNews($id)
    {
    
$content $this->model->getNewsById($id);
    if (
$content)
    {
    
$this->urls->zeroDuplicate('news'$content); 


No i teraz mam dylemat... w sumie myślę, że powinienem to jednak przenieść do kontrolera i dzięki if'owi wybierać, jeżeli znaleziono news:
- sprawdzam adres
- wyświetlam newsa
- aktualizacja licznika czytań
Jeżeli nie ma to z głównej klasy widoku wywołuję metodę np. renderError (której de facto nie ma jeszcze, ale właśnie uznałem że tak by można zrobić).
Czyli mniej więcej tak by to wyglądało:

Kod PHP:
public function view()
  {
    
$this->id request_var('id'0);
    
    
$this->view loader::view('News');
    
$this->view->urls = new urls(true);
    
$this->view->model loader::model('News');
    
    
$this->content $this->view->model->getNewsById($this->id); #1
    
if ($this->content)
    {
      
$this->view->urls->zeroDuplicate('news'$content); #2
      
$this->view->renderNews($this->id);
      
$this->view->model->updateNewsReadsById($this->id); #1
    
}
    else
    {
      
$this->view->renderError('notFound');
    }
    
$this->view->renderPage();        
  } 

Tutaj pojawia się pytanie o sam styl - zaznaczone jako #1 - dane te są potrzebne widokowi i pobierane z niego, ale jak widać dzieje się to w kontrolerze. Oczywiście to działa, ale czy nie kłóci się z żadną zasadą? Czy nie powinienem tego pobierać / aktualizować (aktualizacja licznika czytań) poprzez kontroler? Obecnie jak widać nie ma on innego dostępu do modelu, jak przez widok, chyba lepszym rozwiązaniem będzie zrobić jednak tak:
Kod PHP:
$this->model loader::model('News'); 
    
$this->view->model $this->model

Podobnie ma się sprawa z url'ami oznaczonymi w kodzie jako #2 - widok musi korzystać z jego metod, tego jestem pewien. Czy jednak sprawdzanie adresu przez kontroler powinno się odbywać właśnie za pośrednictwem widoku, czy lepiej zrobić tak samo jak w powyższym kodzie, czyli dać url'e najpierw do kontrolera, a potem do widoku? Tutaj nie wiem jak wygląda sprawa wydajności, czy nie tracę na takim rozwiązaniu? W sumie jeżeli tak zrobię, to chyba mam jakieć MVCU Smile

Ogólnie rzecz biorąc, są obiekty które potrzebne mogą być w modelu, widoku, kontrolerze. Nie wiem czy umieszczać je w jednej z tych części i przez nią używać, czy wrzucać do każdej w której są potrzebne, acz to drugie rozwiązanie wydaje mi sie strasznie bałaganiarskie.


------
Druga sprawa - komentarze. Powiedzmy, że do tego newsa chcę dodać komentowanie. Na razie rozpatruję tylko przypadek ich wyświetlania, a i to mam poważny problem. Jak to rozwiązać? Metoda kontrolera news, ma stworzyć obiekt comments, który również zostanie wyposażony we własny model i widok (czyli mówiąc prosto: będzie to co a'la podkontroler wywołany z kontrolera newsa)? Z pewnością mam wtedy czystszy kod, bo komentarze będą traktowane jako coś zupełnie oddzielnego i łatwo można je używać w wielu miejscach po prostu nadając im inne modele / widoki jeżeli zajdzie taka potrzeba. Ale czy taki podkontroler to w ogóle sensowny pomysł?


------
Ostatnia rzecz - modele. Obecnie są to u mnie metody dopasowane do potrzeb, a nie tak jak niektórzy proponują, czyli 1 model = 1 tabela w bazie. To drugie rozwiązanie wydaje mi się niespecjalnie optymalne. Powiedzmy że chcę wyciągnąć newsy wraz z ich kategoriami: albo najpierw pobieram newsy a potem do każdego dane kategorii (lub też tablicę ich identyfikatorów do zapytania typu WHERE IN), albo robię nowy model będący połączeniem newsów z ich kategoriami... no ale to ogrom dodatkowego kodu i ogrom kombinacji, więc od razu rzucam: po co? Ma to w ogóle sens, czy lepiej robić pod potrzeby?


Za wszelką pomoc / uwagi będę niesamowicie wdzięczny. Obecnie musiałem z powodu tych rozterek wstrzymać nad tym prace, bo wiem, że jeżeli skopię szkielet, to potem całość niestety będzie już nieciekawa i trudna do jakichkolwiek zmian.
Odpowiedz


Podobne wątki…
Wątek: Autor Odpowiedzi: Wyświetleń: Ostatni post
  Limit czasu wykonywania skryptu jasikj 3 5,088 23-09-2013, 14:26
Ostatni post: Engine
  [PHP][MYSQL] Niepoprawne działanie skryptu z komentarzami i stronicowaniem komentarzy martinprz 3 4,139 26-11-2012, 14:17
Ostatni post: andrzejhi
  naprawa skryptu pablo92 1 2,349 12-09-2012, 03:24
Ostatni post: Pedro84
  [php] > usuwanie stringu z tablicy, jesli został użyty i zastąpienie go innym eremen 14 9,338 25-02-2012, 15:14
Ostatni post: eremen
  Wykonanie skryptu lomek 5 4,559 01-11-2011, 23:38
Ostatni post: Marcin

Skocz do:


Użytkownicy przeglądający ten wątek:
Sponsorzy i przyjaciele
SeoHost.pl