Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Optymalizacja kodu, instrukcja switch
Forum PHP.pl > Forum > PHP
alkamid
Cześć!

Napisałem pewien prosty skrypt php i chcę go teraz zoptymalizować. Mam jedną zagwozdkę, na którą nie mam pomysłu. Oto ona:

W skrypcie ważną rolę odgrywa zmienna miesiąc wybrana przez użytkownika - chodzi o to, że użytkownik ma do wyboru kilka miesięcy, przekazuje wybór za pomocą $_GET, a następnie wyświetlane są dane z wybranego miesiąca.
Jest jednak mały problem: jeśli istnieją dane z miesiąca poprzedniego, to ostatni ich wiersz musi się pojawić w bieżącym zestawieniu. Zmienna $_GET['mth'] (czyli ta przechowująca aktualnie wybrany miesiąc) ma format MM, a zapytanie sql które stosuję do wyciągnięcia wierszy z danego miesiąca:
  1. SELECT DATA, wartosc FROM fw WHERE DATA LIKE "%-'.$_GET['mth'].'-%" ORDER BY DATA ASC;

Jeśli nie widać tego od razu, to tłumaczę: dla marca zapytanie to wyszukuje wyrazów z "-03-", dla kwietnia z "-04" etc.
Żeby pobrać ostatni wiersz z poprzedniego miesiąca stosuję:
  1. SELECT wartosc FROM fw WHERE DATA LIKE "%-'.$prev.'-%" ORDER BY DATA DESC LIMIT 1 ;


Niestety, zmienną $prev otrzymuję w nieelegancki sposób, a mianowicie instrukcją switch:
  1. <?php
  2. switch($_GET['mth']) { // ustawienie poprzedniego miesiąca... jakby to zrobić krócej?
  3.        case '02':
  4.            $prev='01';
  5.            break;
  6.        case '03':
  7.            $prev='02';
  8.            break;
  9.        case '04':
  10.            $prev='03';
  11.            break;
  12.        case '05':
  13.            $prev='04';
  14.            break;
  15.        case '06':
  16.            $prev='05';
  17.            break;
  18.        case '07':
  19.            $prev='06';
  20.            break;
  21.        case '08':
  22.            $prev='07';
  23.            break;
  24.        case '09':
  25.            $prev='08';
  26.            break;
  27.        case '10':
  28.            $prev='09';
  29.            break;
  30.        case '11':
  31.            $prev='10';
  32.            break;
  33.        case '12':
  34.            $prev='11';
  35.            break;
  36.        }
  37. ?>


Nie wiem jednak jak zrobić to inaczej, bo zmienna $_GET['mth'] nie jest przecież liczbą, więc nie mogę po prostu odjąć od niej jedności.
Bardzo proszę o wskazówki - być może już sam pomysł na pobieranie wierszy z danego miesiąca jest zbyt skomplikowane, bo można to zrobić za pomocą narzędzi ukrytych w MySQL, kto wie?
Fifi209
Kod
$_GET['mth']

$mth = (int) $_GET['mth'];


Zostanie przekonwertowany na int ;d

@edit

Radzę wyłączyć dyrektywę register globals w apache ;d (chyba że korzystasz z hostingu to pewnie wyłączyli)

Kod
if (($mth > 1) && ($mth < 13)) {
$prev = $mth-1;
}
alkamid
Cytat(fifi209 @ 28.03.2009, 10:04:23 ) *
Kod
$_GET['mth']

$mth = (int) $_GET['mth'];


Zostanie przekonwertowany na int ;d

Ale wtedy będzie to "1", "2"..., zamiast "01", "02" - a to robi różnicę w zapytaniu do bazy danych.
Mógłbym zrobić dwa różne zapytania: jeśli $month<10 to niech szuka %-0'.$month.'-%, a jeśli >=10 to po prostu %-".$month.", bez dopisanego 0. Na razie ten pomysł wygrywa (jest trochę mniej kodu niż switch, ale mimo wszystko wolałbym w jakiś sposób być zdolnym do zmieniania "02" na "01").

Edit: Musiałem dopisać dwa zapytania:
  1. <?php
  2. if(($month>=1) && ($month<10)) {
  3.        $list = 'SELECT data, wartosc FROM fw
  4.        WHERE data LIKE "%-0'.$month.'-%" order by data asc;';
  5.    }
  6.    else {
  7.         $list = 'SELECT data, wartosc FROM fw
  8.        WHERE data LIKE "%-'.$month.'-%" order by data asc;';
  9.    }
  10. ?>


I to samo ze zmienną $prev. Nie wiem więc czy switch nie był jednak lepszy.
dr_bonzo
Masakra, to zes wymyslil switcha.

Odejmij po prostu 1 i dopisz ew. zero z przodu.

A pozatym jesli trzymasz daty w bazie jako DATE to mozesz uzyc mysqlowej funkcji MONTH() i sobie porownujesz normalnie z 1, 4, 12, 11
alkamid
Cytat(dr_bonzo @ 28.03.2009, 13:40:00 ) *
A pozatym jesli trzymasz daty w bazie jako DATE to mozesz uzyc mysqlowej funkcji MONTH() i sobie porownujesz normalnie z 1, 4, 12, 11

Świetne, właśnie o to mi chodziło. Wielkie dzięki!

To jeszcze jedno: do wyświetlenia listy dostępnych miesięcy używam takiej konstrukcji:
  1. <?php
  2. $months_exist = 'SELECT data FROM fw;'; // sprawdza jakie miesiące istnieją w bazie
  3.  
  4.    if($zap0 = $mysqli->query($months_exist)) {
  5.        
  6.        $months_num_rows = $zap0->num_rows;
  7.        
  8.        for($i=0; $i<$months_num_rows; $i++) {
  9.            $months_element = $zap0->fetch_assoc();
  10.            for($j=1; $j<13; $j++) { // jeśli znajdzie datę która zawiera w sobie j (1-12), to przypisze elementowi tablicy $miesiace $j (do wydrukowania listy)
  11.                if (($j<10) && (preg_match("/-0".$j."-/", $months_element['data'])))
  12.                    $miesiace[$j] = "0".$j;
  13.                elseif (($j>9) && (preg_match("/-".$j."-/", $months_element['data'])))
  14.                    $miesiace[$j] = $j;
  15.                
  16.            }
  17.        }
  18.    }
  19. ?>

Co też jest trochę głupie, bo muszę robić dwa przypadki dla j od 1 do 9 i od 10 do 12. Skoro już się uporałem z tamtym to tu też mogłyby być liczby w zwykłym formacie: 1,2,3...
Wyobrażam sobie to tak:
  1. <?php
  2. if($j == month($months_element['data']))
  3. $miesiace[$j] = $j;
  4. ?>

Tylko w php nie ma funkcji tak samo działającej jak ta w MySQL, tzn. pewnie jest ale ja się nie mogę jej doszukać.
dr_bonzo
explode" title="Zobacz w manualu PHP" target="_manual ?
albo bardziej poprawnie, ale raczej wolno: strtotime() + date('m')
alkamid
Dzięki raz jeszcze!
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.