Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php] system newsów
Forum PHP.pl > Forum > PHP
Hectic
Napisałem skrypt newsów, który dzieli je na strony według idów. Wszystko jest ok dopóki nie skasuje któregoś ida np. 12, 11, 9, 8… Kiedy tak zrobię na końcu 1 i początku 2 wyświetla się ten sam news. I nie wiem dlaczego biggrin.gif

  1. <?php
  2. /****************************/
  3. $page = $_GET['page'];
  4. $page2 = $page - 1;
  5. $select_id = 'Select id FROM news';
  6. $id_news = mysql_query($select_id);
  7. $wiersze = mysql_num_rows($id_news);
  8. $idy = $wiersze + 1;
  9. $idy2 = $page2 * $news_page;
  10. /****************************/
  11. if(!isset($_GET['page']))
  12. {
  13. $stop = $idy;
  14. }
  15. else
  16. { 
  17. $stop = $idy - $idy2;
  18. }
  19. /****************************/
  20.  
  21. $select_news = 'Select title, text, nick, date FROM news WHERE id < '.$stop.' ORDER BY id DESC LIMIT '.$news_page.'';
  22. $zapytanie = mysql_query($select_news);
  23. while($wiersz = mysql_fetch_row($zapytanie)) 
  24. {
  25. if (empty($wiersz[0]) and empty($wiersz[1]) and empty($wiersz[2]) and empty($wiersz[3]))
  26. { } // nie rób nic
  27. else 
  28. {
  29. echo '<BR><table class="news" align="center" width="95%" border="0">'; 
  30. echo '<tr><td><b>Tytuł:</b> ';
  31. echo $wiersz[0]; 
  32. echo '</td><td align="right">';
  33. echo '<b>Data:</b> ';
  34. printf ("%s", $wiersz[3]); 
  35. echo '</td><tr><td colspan="2" align="right"><br>';
  36. printf ("%s", $wiersz[1]); 
  37. echo '</td></tr><tr><td><br>';
  38. echo '<b>Autor:</b> ';
  39. printf ("%s", $wiersz[2]); 
  40. echo '</td><td align="right">Komentarze[0]</td></tr>';
  41. echo '</td></tr></table><hr width="95%">';
  42. }
  43. }
  44.  
  45. echo '<p class="news" align="center">Strona: ';
  46. $ilosc = ceil($wiersze / $news_page);
  47.  
  48. for($strona = 1; $ilosc >= $strona ; $strona++) 
  49. {
  50. echo '[<a href="index.php?go=news&page='.$strona.'">'.$strona.'</a>]';
  51. }
  52. ?>

Oraz ten fragment kodu:
  1. <?php
  2. $select_id = 'Select id FROM news';
  3. $id_news = mysql_query($select_id);
  4. $wiersze = mysql_num_rows($id_news);
  5. ?>

Może bardzo obciążyć serwer mysql (w przypadku dużej ilości newsów i odwiedzających). Jak inaczej to rozwiązać?
LBO
Cytat
  1. <?php
  2. $select_id = 'Select id FROM news';
  3. $id_news = mysql_query($select_id);
  4. $wiersze = mysql_num_rows($id_news);
  5. ?>
Może bardzo obciążyć serwer mysql (w przypadku dużej ilości newsów i odwiedzających). Jak inaczej to rozwiązać?

Nie przesadzaj. Bazy danych Nie są, ąż tak bardzo wrażliwe. Chociaż można twoje zapytanie zoptymalizować.
  1. SELECT COUNT(*)
  2. FROM news

Dalej...
  1. SELECT title, text, nick, date
  2. FROM news
  3. WHERE id < $stop ORDER BY id DESC LIMIT $news_page

...zamień na...
  1. SELECT title, text, nick, date
  2. FROM news
  3. ORDER BY id DESC LIMIT $news_page OFFSET $idy2

...zakładając, że $news_page to ilość newsów na stronę. Konstrukcja zapytania z LIMIT (i OFFSET) wyeliminuje Twóje problemy po wywaleniu id z BD.
A teraz czytaj komentarze.
  1. <?php
  2. //gdzie deklaracja $news_page
  3. /****************************/
  4. //Dzięki konstrukcji poniżej $_GET['page'] posiada domyslną wartość (int) 1
  5. //$page = isset($_GET['page']) ? $_GET['page'] : 1;
  6. $page = $_GET['page'];
  7. //a nie lepiej zwyczajnie $page--? Pozbedziesz się dodatkowej zmiennej. Za dużo ich produkujesz.
  8. $page2 = $page - 1;
  9. //tak jak radziłem wyżej
  10. $select_id = 'Select id FROM news';
  11. //wtedy to
  12. $id_news = mysql_query($select_id);
  13. //i to niepotrzebne
  14. $wiersze = mysql_num_rows($id_news);
  15.  
  16. $idy = $wiersze + 1;
  17. //gubię się w nazwach zmiennych, strasznie się powtarzasz
  18. //utrudnia to sprawdzanie błędów
  19. $idy2 = $page2 * $news_page;
  20.  
  21. //Jeżeli dostosowałeś się do pierwszej rady, musisz koniecznie zmienic konstrukcję
     tego if'a (najlepiej wywal).
  22. if(!isset($_GET['page']))
  23. {
  24. $stop = $idy;
  25. }
  26. else
  27. { 
  28. $stop = $idy - $idy2;
  29. }
  30. //Rada wyżej
  31. $select_news = 'Select title, text, nick, date FROM news WHERE id < '.$stop.' ORDER BY id DESC LIMIT '.$news_page.'';
  32.  
  33. //Dalej nie sprawdzam. Zakładam, że stronnicowanie i drukowanie danych jest poprawne.
  34. ?>

Tylko nie myśl, że jak wkleisz moje zalecenia to skrypt zacznie cudownie działać. Co to, to nie tongue.gif. Ja staram sie tylko pokazać Tobie właściwy kierunek.

Pozdrowienia.
Hectic
Nie rozumiem tego
Cytat
//wtedy to
$id_news = mysql_query($select_id);
//i to niepotrzebne
$wiersze = mysql_num_rows($id_news);


W takim razie czym mam to zastąpić?
Hacker
  1. <?php
  2. $select_id = 'Select COUNT(*) FROM news';
  3. $id_news = mysql_query($select_id);
  4. $wiersze = mysql_fetch_array($id_news);
  5. $wiersze = $wiersze[0];
  6. ?>
Hectic
Ale co oznacza offset? Znalazłem dokumentacje tylko w języku angielskim worriedsmiley.gif
nospor
Cytat
Ale co oznacza offset? Znalazłem dokumentacje tylko w języku angielskim
troche samodzielnosci:
http://www.google.com/search?hs=3Tp&hl=pl&...ukaj&lr=lang_pl
juz pierwszy wynik zawiera to czego szukasz
Kayne
Witam

Denerwuje mnie fakt, że piszecie w ten sposób:

Kod
$select_id = 'Select COUNT(*) FROM news';
$id_news = mysql_query($select_id);


Czy nie lepiej, szybciej i czytelniej jest tak:

Kod
$id_news = mysql_query('Select COUNT(*) FROM news');
LBO
Może i szybciej, ale wyobraź sobie, że te zapytanie, może być jeszcze w międzyczasie modyfikowane. Nie w tym konkretnym przykładzie, ale jednak.

Załóżmy, że chcesz skasować pokaźną liczbę userów z BD. Ich id(ientyfikatory) są przekazane w tablicy $_GET['ids']. Tworzysz funkcję (albo lepiej - metodę), gdzie w prametrze przekazujesz tą tablicę.
  1. <?php
  2.  
  3. public function deleteUsers($ids) {
  4. //podstawowe zapytanie znajduję się w zmiennej
  5. //$this->sql = 'DELETE FROM users WHERE';
  6. foreach ($ids as $id) {
  7. $this->sql .= ' id = '.$id.' OR';
  8. }
  9. //wiem, że po zakończeniu iteracji przez tablice
  10. //zapytanie będzie zawierać nadmiarowe OR, ale
  11. //jest to tylko przykład. sam się możesz pokusić o
  12. //poprawną implementację.
  13.  
  14. $this->executeQuery();
  15. //wysyłasz zapytanie do BD, pobierasz wynik, przetwarzasz etc.
  16. }
  17.  
  18. ?>

Mam nadzieję, że zrozumiałeś.

P.S. Moga byc błędy, bo się spieszę, ale nie mogłem tego zostawić bez odpowiedzi.
P.P.S. Nie trzeba od razu robić, tak jak napisałem, ale jest to chyba przydatny nawyk dla programisty. W jakimś stopniu zwiększa póżniejszą zdolność programu do adaptacji/przeróbek przy mniejszej, włożonej w to pracy.
Hacker
trochę offtop, ale LBO nie lepiej i wydajniej
  1. DELETE
  2. FROM users
  3. WHERE id IN('.imlode(', ', $ids).')
LBO
Może i masz rację... zły przykład dałem, bo - akurat w tym przypadku - SQL posiada odpowiednie funkcje/gramatykę do jego obsłużenia (cały czas zapominam o IN, hyhyhy). Ale to nie zmienia faktu, że może zaistnieć wiele innych czynników, gdzie trzymanie podstawowego zapytania i jego modyfikacja, zależna od zaistniałych warunków jest bardzo przydatna. Weź pod uwagę ADOdb - ten layer posiada (musi je posiadać) odpowiednie narzędzia do zmieniania zapytań z powodu np. nieobługiwania przez daną Bazę konkretnej SQL komendy i za pomoca ich robi do na około.
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.