Projektowanie stron WWW od podszewki

Artykuły na każdy temat

[PHP] Prosty wzorzec tworzenia mapy witryny/strony/sitemap

Dodano 07.01.2013r. o 00:42
Kilka dni temu zostałem zapytany o to czy istnieje możliwość abym opisał jak wygląda generowanie mapy witryny. Z racji deficytu czasu ostatnimi dniami pozwolę sobie tylko na drobny pseudo wzorzec. Prawdopodobnie jeżeli w przyszłości znajdę chwilkę czasu lub będzie występować większe zapotrzebowanie/parcie na skrypt to zapewne przykład/artykuł. Esencją tworzenia sitemap jest tworzenie relacji. Jeżeli chodzi o tworzenie relacji/drzew to moim zdaniem wystarczającym materiałem edukacyjnym jest ten artykuł. Krótko i na temat wygląda mniej więcej tak:
Kod:
<?php
include './sitemap.class.php';
$sitemap = new sitemap();

$sitemap -> add_node(array('name' => 'Kategoria 1'));
$sitemap -> map[0] -> add_node(array('name' => 'Punkt 1.1'));

$sitemap -> add_node(array('name' => 'Kategoria 2'));
$sitemap -> map[1] -> add_node(array('name' => 'Punkt 2.1'));
$sitemap -> map[1] -> add_node(array('name' => 'Punkt 2.2'));
$sitemap -> map[1] -> add_node(array('name' => 'Punkt 2.3'));

$sitemap -> add_node(array('name' => 'Kategoria 3'));
$sitemap -> map[2] -> add_node(array('name' => 'Punkt 3.1'));
$sitemap -> map[2] -> add_node(array('name' => 'Punkt 3.2'));

$sitemap -> map[2] -> map[1] -> add_node(array('name' => 'Punkt 3.2.1'));
$sitemap -> map[2] -> map[1] -> add_node(array('name' => 'Punkt 3.2.2'));
$sitemap -> map[2] -> map[1] -> add_node(array('name' => 'Punkt 3.2.3'));

// Generate sitemap (HTML version)
echo rendering_list($sitemap);

function rendering_list($sitemap)
{
 $data '<ul>';

 foreach($sitemap -> map as $item)
 {
  if($sitemap -> is_having_child($item))
  {
   $data .= '<li><a href="'.$item -> address.'">'.$item -> name.'</a>';
   $data .= rendering_list($item);
   $data .= '</li>';
  }
  else
  {
   $data .= '<li><a href="'.$item -> address.'">'.$item -> name.'</a></li>';
  }
 }

 $data .= '</ul>';

 return $data;
}
?>
W największym skrócie wygląda to właśnie tak. Funkcja rendering_list() służy jako swojego rodzaju odpowiednik warstwy wyglądu. Jeżeli chodzi o tworzenie węzłów to radzę poeksperymentować z polem map - w ostateczności stary dobry var_dump($sitemap) może być pomocny.
Kod:
<?php
class sitemap
{
 public $map;

 public function add_node($data)
 {
  $this -> map[] = new node($data);
 }

 public function is_having_child($node)
 {
  return $node -> map;
 }
}

class node extends sitemap
{
 public $name;
 public $address;

 public function node($data)
 {
  $this -> name $data['name'];
  $this -> address $data['address'];
 }
}
?>
Właściwie tak mały fragment kodu nie wymaga chyba tłumaczenia? W zależności od zapotrzebowania rodzaju budowania mapy można sobie do node dodać dodatkowe pola.

Czego skrypt nie posiada? Lista @todo

  • Możliwości wyboru rodzaju generowanej mapy strony (HTML, XML, TXT, inne)
  • Metody sprawdzającej czy aktualny węzeł posiada rodzica
  • Metody zwracającej listę rodziców
  • Metody zwracającej aktualny poziom zagłębienia
  • Mechanizmu statystyk tj. ile jest węzłów/obiektów na określonym poziomie głębokości
  • Metody zwracającej ostatni dodany węzeł
  • Metody zwracającej aktualny offset (węzeł)
  • Mechanizmu pamiętającego ostatni ID węzła na określonym poziomie
  • Metody odpowiedzialnej za usuwanie określonego węzła/węzłów
  • Metody sprawdzającej najgłębszy poziom zanurzenia
  • I innych rzeczy, których teraz nie pamiętam

Komentarze

Publikowane komentarze są prywatnymi opiniami użytkowników serwisu. Serwis nie ponosi odpowiedzialności za treść opinii. W trosce o zachowanie poziomu dyskusji wszystkie komentarze podlegają akceptacji przed ich publikacją dlatego proszę cierpliwie czekać aż komentarz zostanie opublikowany.

CapaciousCore

Dodano 15.10.2013r. o 04:33
@dinosaurus hehe no cóż jest subtelna różnica pomiędzy funkcją, a metodą jeżeli rozmawiamy o OOP. Po prostu w momencie wywołania add_node() dorzucamy węzeł do miejsca, który wskazaliśmy (widać to wyraźnie na pierwszym listingu). Każdy kolejny element ma indeks podniesiony o jeden, co jest normalne jak mniemam. Dlatego właśnie proponuje poeksperymentować ze strukturą gdzie deklaruje się węzły w różnych miejscach i dlatego napisałem właśnie o var_dump(sitemap) lub jak kto woli print_r($sitemap), aby łatwiej było zrozumieć to, co się dzieję. Jest też taka fajna pomocna funkcja która się zwie debug_backtrace(). W mojej ocenie wyczerpałem możliwości tłumaczenia. Można to odpalić pod dbg i zobaczyć co się dzieję (jak buduję się struktura i skąd są wywołania lub przepisać to na inny język np. C# i tam pod dbg zobaczyć jeszcze bardziej czytelnie w VS).

dinosaurus

Dodano 03.10.2013r. o 17:26
Ja chyba nie mam talentu do tłumaczenia. Postaram się.
1. nie mam i nigdy nie miałem zastrzeżeń do działania zmiennej $data. Obie są lokalne i nie wchodzą sobie w drogę. Jednak dla osoby wgryząjącej się w kod to dodatkowe utrudnienie i komplikacja.
2.Napisałeś
$sitemap -> add_node(array('name' => 'Kategoria 2'));
Po wejsciu do funkcji mamy
$this -> map[] = new node($data);
O ile wiem w momencie utworzenia obiektu zostaje wywołany konstruktor ktorym wedlug mnie jest funkcja node ponieważ ma tą samą nazwę co klasa a poza tym nigdzie nie jest jawnie wywoływana.
public function node($data)
{
$this -> name = $data['name'];
$this -> address = $data['address'];
}
a w niej są ustawiane wartości dwu pół tego egzemplarza obiektu node a więc $data ma dwa elementy o identyfikatorze "name" i "adres". Tak ja to rozumiem i byłbym wdzięczny za wskazanie gdzie popełniam błąd. Bo jeśli moje rozumowanie jest błędne to znaczy że czegoś zupełnie nie rozumiem i dopóki tego mi ktoś nie wyjaśni nie mam szans na ogarnięcie całości zagadnienia.
Pozdrawiam i dziękuję za cierpliwość.

CapaciousCore

Dodano 02.10.2013r. o 10:54
@dinosaurus przy założeniu gdzie tworzy się projekty, które potem publikuje się w sieci to wypadałoby, aby kod był zangielszczony, bo w przeciwnym wypadku wyglądać będzie to tak, że polskie nazewnictwo zostanie zrozumiane tylko przez osoby posługujące się tym językiem, a reszta co? Miałem już styczność z takim kodem tyle, że napisanym przez Turków. Powiadam Ci, że to istna tragedia i marnowanie czasu na odszyfrowywanie. To już lepiej pisać od nowa. Zmienna $data w funkcji rendering_list() jest lokalna to po raz, a po dwa jeżeli pytasz o "zmienną" w metodzie add_node() przekazywana przez argument to cóż... ona także jest lokalna? Dwie niepowiązane ze sobą bezpośrednio zmienne jak i fragmenty kodu.

Ad. 1
Po pierwsze proponuje zapoznać się z definicją deklaracji, bo w żadnym miejscu nie występuję wieloelementowość jako argument. To co się dzieje wewnątrz metody ze zmienna (tablicą) przekazaną jako argument to inna bajka.
Ad. 2
Co uznajesz za konstruktor w wersji PHP4? Chyba mi nie powiesz, że nawiasy po nazwie klasy, co? http://www.php.net/manual/en/language.oop5.basic.php - ładnie pokazany konstruktor w wersji PHP5.

Nie będę odpowiadał mailowo, bo może jeszcze komuś przyda się taka wiedza z komentarzy. Nie jesteś sam w sztuce samodoskonalenia siebie. A komentarze zawsze są w cenie swoją drogą.

dinosaurus

Dodano 29.09.2013r. o 14:41
Dzięki za reakcję ale ja wcale nie jestem dobrym programistą. Właśnie usiłuję się uczyć na dobrych wzorcach. Interesuje mnie OOP bo PHP strukturalnym posługuję się. Spędziłem nad tym kodem wiele godzin wspomagając się źródłami pisanymi i nadal wiele rzeczy jest dla mnie niejasnych.
Wspomniałem o nazwach nie dla tego że są angielskie choć według mnie można znać angielski i niekoniecznie stosować go w nazwach. Co innego jeśli tworzy sie duże projekty ktore być może będą uzyteczne dla ogółu. Mnie chodziło nie o angielski tylko o to że np. zastosowałeś $data jako parametr i jako zmienną. Jeśli więc możesz wyjaśnij mi dwie rzeczy
1. dlaczego w wywołaniu add_node(array('name' => 'Kategoria 1')); w parametrze jest tablica jednoelementowa a w deklaracji dwuelementowa
public function node($data)
{
$this -> name = $data['name'];
$this -> address = $data['address'];
}
2.Z jakiej przyczyny zastosowałeś konstruktor w wersji PHP 4.
Nie muszę wspominać że będę wdzieczny za oświecenie mnie a może OOP zdobędzie kolejnego zwolennika. Jeśli nie chcesz zaśmiecać komentarzy to może być na maila
Pozdrawiam.

CapaciousCore

Dodano 26.09.2013r. o 21:12
@dinosaurus bez obrazy jednak dobry programista charakteryzuje się chociażby dobra znajomością języka angielskiego stąd nazewnictwo jak i sam kod powinien być czytelny szczególnie gdzie jest go raptem kilka linijek. Chce zauważyć, że dokumentacje określonych języków jak i fachowe artykuły są właśnie w takim, a nie innym języku. Nie uważam ażeby cokolwiek co opublikowałem wymagało głębszego tłumaczenia. Wobec konstrukcji sprawa jest prosta. Jeżeli jest to pytanie, a jest na moje oko to według mnie nie rozumiesz samego zamysłu/szkicu/wzoru. Jest to model uniwersalny, który można dostosować do każdej witryny. Implementacja jak i obsługa klasy nie leży po mojej stronie.

dinosaurus

Dodano 24.09.2013r. o 19:26
Właściwie tak mały fragment kodu nie wymaga chyba tłumaczenia? Właśnie dlatego że mały komentarze nie zabiorą dużo miejsca i czasu a mogą niejednemu rozjasnić temat zwłaszcza przy zastosowanych nazwach. Nie wspomniano też czy strona musi mieć konkretną konstrukcję.

Dodaj komentarz

Zostaw komentarz jeżeli możesz! Nie bądź przysłowiowym botem! Nie bądź obojętny! Ciebie to nic nie kosztuje, a mi sprawi uśmiech na twarzy.
Zezwolono używać: BBCode
Zabroniono używać:
znaczników HTML

(Wymagany)

(Wymagany, niepublikowany)

(Nie wymagana)

Token:

Obrazek dla bota

(Przepisz tylko cyfry!)

(Wymagana)