Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [smarty]przekazanie funkcji do szablonu
Forum PHP.pl > Forum > Gotowe rozwiązania > Systemy szablonów
matyskiewicz
Witam. Borykam sie dzisiaj z problemem
  1. <?php
  2. //polaczenie z baza
  3.  
  4. function pokaz($categoryId) {
  5. global $wciecie;
  6. $wciecie++;
  7. $sqlQuery = mysql_query("SELECT * FROM wdb_category WHERE subcategoryId='$categoryId' ORDER BY categoryName");
  8.  
  9. while($row = mysql_fetch_array($sqlQuery)) {
  10. $odstep = str_repeat(" ", $wciecie-1);
  11. print $odstep .'ť <a href="index.php?category='.$row["categoryId"].'">'.$row["categoryName"].'</a> ['.mysql_num_rows(mysql_query("SELECT * FROM wdb_news WHERE categoryId=".$row["categoryId"])).']<br />';
  12. pokaz($row["categoryId"]);
  13. }
  14. $wciecie--;
  15. }
  16. pokaz(0);
  17. ?>


  1. -- phpMyAdmin SQL Dump
  2. -- version 2.6.0-pl2
  3. --
  4. -- Host: localhost
  5. -- Czas wygenerowania: 09 Paź 2007, 22:22
  6. -- Wersja serwera: 3.23.58
  7. -- Wersja PHP: 4.3.9
  8. --
  9. -- Baza danych: `dev-blog`
  10. --
  11.  
  12. -- --------------------------------------------------------
  13.  
  14. --
  15. -- Struktura tabeli dla `wdb_category`
  16. --
  17.  
  18. CREATE TABLE `wdb_category` (
  19. `categoryId` int(11) NOT NULL AUTO_INCREMENT,
  20. `subcategoryId` int(11) NOT NULL DEFAULT '0',
  21. `categoryName` text NOT NULL,
  22. PRIMARY KEY (`categoryId`)
  23. ) TYPE=MyISAM AUTO_INCREMENT=10 ;
  24.  
  25. --
  26. -- Zrzut danych tabeli `wdb_category`
  27. --
  28.  
  29. INSERT INTO `wdb_category` VALUES (1, 0, 'as1');
  30. INSERT INTO `wdb_category` VALUES (2, 3, 'as2');
  31. INSERT INTO `wdb_category` VALUES (3, 5, 'as13');
  32. INSERT INTO `wdb_category` VALUES (4, 5, 'as4');
  33. INSERT INTO `wdb_category` VALUES (5, 0, 'as5');
  34. INSERT INTO `wdb_category` VALUES (6, 5, 'as6');
  35. INSERT INTO `wdb_category` VALUES (8, 0, 'as7');
  36. INSERT INTO `wdb_category` VALUES (9, 8, 'as8');


Jak przerobić powyższą funkcję bym mógł ją spokojnie przekazać do smartów?
prgTW
Jeśli chodzi o przekazanie jakiejś funkcji to:
http://smarty.php.net/manual/en/api.register.function.php

-----
Aczkolwiek biorąc ten konkretny przypadek proponuję przeczytaj resztę - trudne to, ale jak będziesz tworzył w oparciu o model MVC (lub inny) to docenisz moje rozwiązanie (choć nie jest optymalne).
-----

A na cholerę przekazywać funkcję do Smarty !? Wykonaj kod który Ci wylistuje co potrzebujesz w TABLICY a tablicy przekaż smarty i foreach'em przejedz. Programuj zgodnie z MVC, nie przekazuj kontroli nad aplikacją do szablonu odpowiadającego za wygląd, niechaj w kodzie PHP będzie sterowanie a tylko w plikach TPL wygląd - staraj się nie mieszać tego.

Skrypt SQL tworzący szkielet rekkurencyjnej bazy kategorii
  1. CREATE TABLE wdb_category (
  2. cat_id int(11) NOT NULL AUTO_INCREMENT,
  3. cat_root_id int(11) NOT NULL DEFAULT 0,
  4. cat_name varchar(100) NOT NULL,
  5.  
  6. PRIMARY KEY (cat_id)
  7. );
  8.  
  9. -- przykładowe drzewo kategorii
  10.  
  11. INSERT INTO wdb_category VALUES (1, 0, '1');
  12. INSERT INTO wdb_category VALUES (2, 0, '2');
  13. INSERT INTO wdb_category VALUES (3, 1, '3');
  14. INSERT INTO wdb_category VALUES (4, 1, '4');
  15. INSERT INTO wdb_category VALUES (5, 4, '5');
  16. INSERT INTO wdb_category VALUES (6, 4, '5');
  17. INSERT INTO wdb_category VALUES (7, 2, '7');
  18. INSERT INTO wdb_category VALUES (8, 7, '8');
  19. INSERT INTO wdb_category VALUES (9, 8, '9');
  20. INSERT INTO wdb_category VALUES (10, 8, '10');


A teraz skrypt PHP tworzący drzewo:
  1. <?php
  2. # funkcja tworzenia drzewa
  3. function find_subcats(&$cat){
  4. global $categories;
  5.  
  6. if(count($categories)) # jezli pozostaly jakies kategorie
  7. foreach($categories as $cat_info) # przelecmy po nich
  8. if($cat_info['cat_root_id'] == $cat['cat_id']){ # jak naleza do korzenia
  9. $cat['subs'][$cat_info['cat_id']] = array( # dodajmy ja ...
  10. 'cat_id' => $cat_info['cat_id'],
  11. 'cat_name' => $cat_info['cat_name'],
  12. 'subs' => array()
  13. );
  14. find_subcats($cat['subs'][$cat_info['cat_id']]); # ... i dla niej znowu wyszukajmy podaktegorie
  15. }
  16. }
  17.  
  18. # funkcja wyciągająca kategorie z bazy i wywołująca tworzenie drzewa
  19. function get_cats(){
  20. # wyciagamy wszystkie istniejace kategorie
  21. $query = mysql_query('
  22. select
  23. cat_id,
  24. cat_root_id,
  25. cat_name
  26. from
  27. wdb_category
  28. ');
  29.  
  30. # w tablicy je wyciagamy do tablicy $categories
  31. $categories = array();
  32. while($row = mysql_fetch_assoc($query))
  33. $categories[] = $row;
  34. unset($row); # zwalniamy pamiec
  35.  
  36. # reszta zajmie sie PHP
  37.  
  38. # ustawiamy korzen - kategorie nadrzedna dla wszstkich
  39. $cats[0] = array('cat_id' => 0, 'subs' => array());
  40.  
  41. #wyszukujemy podkategorie dla drzewa
  42. find_subcats($cats[0]);
  43.  
  44. #zwracamy drzewo kategorii, poczawszy od korzeni wlasnych; bez 'nad-korzenia' 0
  45. return $cats[0]['subs'];
  46. }
  47.  
  48. #
  49. # skrypt wlasciwy
  50. #
  51.  
  52. # pobierzmy kategorie jako tablice
  53. $categories = get_cats();
  54.  
  55. # i teraz mozna ja traktowac roznorako np.
  56. print '<pre>';
  57. print_r($categories);
  58. print '</pre>';
  59.  
  60. #lub
  61. var_dump($categories);
  62.  
  63. #albo do Smarty
  64. $smarty->assign('categories', $categories)
  65. ?>


Powiem tylko, że jest to tablica ze zmienno-wymiarowa (głębokość zagnieżdzenia elementów się zmienia) a Smarty operuje liniowo na tablicach i normalnie nie posiada rekurencji, aczkolwiek można to obejść stosując (oczywiście pomijam czysty kod php w {php}...{/php}) rekurencyjne dołączanie tego samego pliku:


  1. <!-- categories.tpl -->
  2.  
  3. {if count($categories)}
  4. <ul>
  5. {foreach from=$categories item=category}
  6. <li>{$category.cat_id}: {$category.cat_name}</li>
  7. {if $category.subs}
  8. {include file="categories.tpl" categories=$category.subs}
  9. {/if}
  10. {/foreach}
  11. </ul>
  12. {/if}


Powyższy skrypt dokładnie dla tych danych (chociaż to mało danych) u mnie na kompie (c2d e6300) zajął
- pamięci = 97592 bajtów
- czasu: 0.001 - 0.0015 s

Edit:
Skrypt nie jest optymalny, tablica kategorii jest kilka razy skanowana w pętli (najoptymalniej by było tylko raz oczywiście). Można by było zrobić jakąś procedurę na serwerze bazodanowym w PL/SQL, aczkolwiek i tak PHP musiałby po tym jeszcze przelecieć bo SQL zwróciłby ewentualnie tylko troszkę przyjaźniej ułożone dane do ułożenia z nich drzewa.
matyskiewicz
Mógłbyś Tomku jeszcze raz sprawdzić skrypt bo mnie wyskakuje tylko:

  1. Array(
  2. )
prgTW
A masz w ogole mysql_connect, sprawdz po mysql_query jaki blad daje baza (print mysql_error()). Nie pisałem już tego bo zakładałem, że to oczywiste ale mogłem się mylić - nie wiem na jakim etapie znajomości PHP i MySQL jesteś. Ja u siebie nie stawiałem bazy, tylko podałem skryptowi gotową tablicę kategorii tak jakby zwróciła to baza i wszystko było ok, więc może coś tkwi w samym wyjęciu danych z bazy.

PS: Poprawiłem powyższy skrypt nieco, więc sobie go zaktualizuj (zarówno php jak i kod Smarty).
matyskiewicz
Oczywiście używałem funkcje raportowania błędów z MySqla; nie zwróciła ona nic. Wydaje mi się że błąd polega nietyle na pobraniu z bazy co narysowaniu z funkcji: var_dump($categories); ponieważ ją stosuje do testowania. Jak bedzie chodziła to prześlę ja do Smartów.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.