set4812
18.08.2010, 23:50:26
W odzielnym pliku mam zapis połączenia z bazą danych za pomocą mysql dołączony do głównego pliku. W innym pliku mam stworzona klasę którą teraz dołączam do głównego pliku także. Słyszałem że mysqli jest efektywniejsze a mi nie działa połączenie z bazą danych w klasie na mysqli a na mysql działa bez zastrzeżeń. Proszę aby ktoś mi wytłumaczył jak rozwiązać problem z połączeniem za pomocą mysqli oraz czy jest ogromna różnica miedzy mysql a mysqli.
Dziękuje pozdrawiam set4812
thek
19.08.2010, 07:44:09
Po pierwsze, to mysql i mysqli są osobnymi rozszerzeniami, które włącza się w plikach konfiguracyjnych. Jeśli Twój usługodawca nie zrobił tego, to określone rozszerzenie nie jest dostępne. najlepiej sprawdź w phpinfo czy masz je włączone czy nie. Różnica między nimi zaś to podejście do danych. Jak już wspomniano, mysqli jest obiektową formą współpracy z bazą. Zajrzyj do manuala na php.net a sam zobaczysz w przykładach różnicę.
set4812
20.08.2010, 00:26:20
hmm tyle wiem ze obiektowe , 2 część pytania jak załączyc działanie w classie odzielnej tego obiektu?
znalazłem na forum u was
http://forum.php.pl/lofiversion/index.php/ags/t98272.htmltylko nie rozumiem kilku elementów
Tego przepisania $this->db = $db; oraz w konstruktorze mysqli $db
Dziekuje za wytłumaczenie pozdrawiam set4812
kilas88
20.08.2010, 00:36:13
O tym jak posługiwać się mysqli znajdziesz w manualu,
http://php.net/manual/en/book.mysqli.phpCytat(set4812 @ 20.08.2010, 01:26:20 )

Tego przepisania $this->db = $db; oraz w konstruktorze mysqli $db
Tworzysz klasę na wzór wzorca Singleton, tzn. tylko raz wywołujesz połączenie z bazą danych (ponieważ koszt połączenia z bazą jest wysoki, mówiąc najogólniej). We właściwości db przetrzymujesz 'uchwyt' do bazy danych, czyli otwarte połączenie, po to, aby nie musieć za każdym razem wywoływać nowego połączenia (co jak wspomniałem, jest kosztowne dla serwera). To by było tyle z całej logiki, reszte doczytasz w manualu lub stu innych miejscach (jak i znajdziesz gotowe klasy do obsługi bazy danych).
thek
20.08.2010, 08:17:29
Najogólniej rzecz ujmując, to w przykładach widzisz $db, ponieważ jest to uchwyt do bazy danych zadeklarowany przez programistów. Przypisują do niego identyfikator połączenia i wykorzystują za każdym razem gdy chcą z niej skorzystać. To łącznik między skryptem i bazą. Nawet prostszy mysql tak działa, ale bardzo często nie jest on jawnie przekazywany do funkcji mysql_* gdyż ustawia się domyślnie i można go pominąć przy wywołaniu. Zauważ w manualu że 90% funkcji tego typu ma jako ostatni parametr mysql_identifier czy coś w tym stylu. To jest odpowiednik $db. Uzywa się go bowiem rzadko i jedynie w sytuacjach, gdy obsługujemy kilka baz/serwerów mysql w obrębie jednego skryptu. Dzięki przypisaniu $this->db = $db , identyfikator połączenia jest cały czas dla obiektu dostępny.
PS.: W ostatnim swoim przykładzie masz lukę. Nie sprawdzasz czy $res ma cokolwiek w sobie a od razu walisz przypisanie tablicy wyniku do $row. A skąd wiesz, że dostałeś jakikolwiek rekord? A może nie ma takiego w bazie? Pamiętaj, że powinno się zawsze sprawdzać poprawność pobranych danych nie tylko poprzez sprawdzanie czy wystąpił błąd, ale ile rekordów zwróciło zapytanie.
thek
20.08.2010, 09:15:06
W takim wypadku wszystko od "$row = $res->fetch_assoc()" włacznie - jest zbędne

Napisałem tamten PS, by user niepotrzebnie nie uczył się złych praktyk, gdzie niesprawdzone dane są pchane w głąb skryptu, a potem lecą ostrzeżenia i błędy, których on nie rozumie, bo "tak mi na forum pokazali i tak powinno być dobrze". Jeśli już podajemy kod, to zaznaczmy, że nie jest on uzupełniony o walidację danych by go nie rozwlekać, lub ograniczmy go do naprawdę niezbędnego fragmentu. Ogólnie jednak przykład bez wspomnianego końca jest dobry, bo pokazuje podwójne wykorzystanie $db (sprawdzenie błędu połączenia i wykonanie zapytania). Można by jedynie już tylko zrobić klasę połączenia i pokazać jak to we wzorcu MVP wygląda, gdzie jest faktyczne użycie $this->db przy konstruktorze choćby.
IceManSpy
20.08.2010, 10:39:28
A tak podłączając się do tematu, czy można ten obiekt serializować i przenosić między stronami? Bo to jest chyba lepsze, niż na jednej stronie otwierać połączenie, wykonać skrypt, zamykać połączenie i na innej znowu robić to samo?
thek
20.08.2010, 10:53:42
Można robić coś podobnego. Nie można bowiem przenosić identyfikatora połączenia pomiędzy stronami, ale można utworzyć połączenie stałe (persistent connection -> w mysql funkcja pconnect). Jest one nieco ryzykowne, gdyż trzeba pamiętać o jego kończeniu, inaczej trochę czasu zejdzie zanim wróci ono do puli dostępnych. W skrajnych przypadkach możesz serwis wysypać z powodu przekroczenia dostępnej liczby połączeń. Swego czasu przez to się sypało choćby idg.pl
Ogólnie rzecz biorąc połączenie trwa tak długo jak długo trwa skrypt. Potem i tak z automatu jest zamykane i przesyłanie tutaj jego identyfikatora zwyczajnie nic nie da.
IceManSpy
20.08.2010, 11:12:17
A w jaki sposób to zrobić? Na początku zrobić jedno połączenie, np przy logowaniu, potem na innych stronach używać tego identyfikatora a po wylogowaniu np zakończyć? Mógłbyś jakiś przykład pokazać? I jak sprawdzić max liczbę połączeń?
thek
20.08.2010, 12:00:37
Można, ale osobiście nie używałbym ich. Zauważ, że połączenie stałe "rezerwuje slot" połączenia z bazą i nikt inny nie może go użyć. Jest to ryzykowne, ponieważ do czasu aż baza nie dostanie go z powrotem liczba takich połączeń jest zredukowana o jedno. Jeśli osiągnie ona limit - nikt nie będzie mógł połączyć z bazą, a wtedy Twoja strona leży i kwiczy. Liczba takich połączeń ma swój limit na serwerze i różnie to bywa w zależności od wydajności. Zazwyczaj jest to kilkaset i wydaje się dużo, ale zauważ, że userzy potrafią na stronie siedzieć długo bez jakiejkolwiek interakcji. A połączenie trwa i jest blokowane do użytku innych. Trochę userów się zaloguje a liczba dostępnych połączeń się znacznie zredukuje. Zamiast 150, będziesz miał przykładowo 80. Czyli wszyscy niezalogowani mają do dyspozycji nie 150, ale jedynie 80 slotów do bazy. Między siebie. To wydłuża czas oczekiwania na dane, bo zapytania są kolejkowane dla nich i dostają wyniki zapytań gdy tylko baza zdoła. Tak więc takie połączenia powinni mieć najwyżej Ci, których obecność na stronie jest obowiązkowa i muszą oni mieć zawsze z nią kontakt - admini, moderatorzy. Poza tym czy koszt połączenia jest taki naprawdę istotny? Koszt połączenia w zasadzie nie gra roli aż takiej w porównaniu do czasu działania całego skryptu.
IceManSpy
20.08.2010, 12:11:56
Pytam się dlatego, że @kilas88 napisał "ponieważ koszt połączenia z bazą jest wysoki, mówiąc najogólniej" a może się kiedyś okazać, że np będzie ok 1000 userów, którzy będą pracować na bazie. Więc wtedy stałe połączenie nie będzie potrzebne

Wcześniej pisałem skrypt za pomocą mysql_* ale chyba przejdę na obiektowe mysqli. Bo i tak całą stronę przerabiam na obiekty, więc dodatkowa nauka obiektowego mysqli będzie przydatna
thek
20.08.2010, 12:49:44
Koszt połączenia jest wysoki przy prostych zapytaniach, bo nieraz ich wykonanie trwa krócej niż samo połączenie. Każde bardziej rozbudowane już jest porównywalne lub dłużej trwające niż czas nawiązania połączenia. A że dla skryptu najczęściej nawiązujesz połączenie tylko raz (praktycznie mało kto używa zwalniania zasobów i mysql_close) i trwa ono do końca skryptu, to summa sumarum wcale tak drogie to nie jest przy choćby kilkunastu prostych zapytaniach w obrębie i czasie trwania tegoż skryptu. Kwestia tego co skrypt robi z bazą danych.
IceManSpy
20.08.2010, 14:40:09
A lepiej jest używać obiektowego mysqli czy normalnego funkcyjnego mysql?
thek
20.08.2010, 15:03:53
To zależy tak naprawdę tylko od przyzwyczajenia. Aczkolwiek z tego co pamiętam to mysqli lepiej chronił przez sqlinjection. Bo mysql jako rozszerzenie kompletnie nie chroni

Właściwie to poczytaj na necie o różnicach to sam zobaczysz
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.