Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

PHP, MySQL - Błąd przy odczycie z bazy danych.

Maciej.Rek 25 Paź 2013 17:36 2100 9
  • #1 25 Paź 2013 17:36
    Maciej.Rek
    Poziom 11  

    Witam. Z powodu nadmiaru wolnego czasu piszę sobie pewną aplikację w php. Mianowicie aplikacja ta ma sprawdzać czy w bazie danych istnieją już galerie, a jeśli tak to wyświetlić ich nazwy.

    Podstawy PHP gdzieś po głowie się błąkają, jednak chyba są aż za bardzo podstawowe, bo błąd powitał mnie już przy próbie odczytu z bazy danych.

    Mam taki oto kod:

    Kod: php
    Zaloguj się, aby zobaczyć kod


    Pliczek zapisuje, wrzucam na ftp i pojawia mi się taki oto błąd:
    Cytat:
    Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /home/u349285867/public_html/admin/galeria/gallery.php on line 8


    Chcąc więc znaleźć jakieś poszlaki zmodyfikowałem trochę kod, żeby sprawdzić czy baza danych nie jest pusta. Napisałem coś takiego:
    Kod: php
    Zaloguj się, aby zobaczyć kod


    Jednak w niczym to mi nie pomogło, bo błąd występuje podobny:
    Cytat:
    Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given in /home/u349285867/public_html/admin/galeria/gallery.php on line 8 Jest pusto!


    Na końcu widać, że mimo błedu na końcu pojawia się napis "Jest pusto!". Przez chwile myślałem że jednak coś działa, bo tabela faktycznie była pusta. Dopisałem więc do niej jedną galerie, aby sprawdzić czy wyświetli mi się drugi komunikat. Jednak nic z tego, ponieważ błąd nadal jest ten sam. Wnioskuję więc, że bład musi tkwić gdzieś w kwerendzie, która nie chce czytać z tabeli.

    Całość sprawdzałem również poleceniem count(), jednak i w tym wypadku coś jest nie tak, ponieważ mimo pustej tabeli wynik count() pokazuje "1".

    Proszę o pomoc. Zależy mi na wskazówkach gdzie może tkwić błąd i jak mogę sobie z nim poradzic.

    Pozdrawiam Maciej

    0 9
  • Pomocny post
    #2 25 Paź 2013 17:51
    marcinj12
    Poziom 40  

    Rozwiązanie masz tutaj - wystarczy wcześniej sprawdzić wynik: http://stackoverflow.com/questions/2973202/mysql-fetch-array-expects-parameter-1-to-be-resource-boolean-given-in-select.

    Widzę, że mieszasz mysql_ i mysqli_ - nie rób tego. mysql_ wg dokumentacji jest już przestarzały i będzie wycofany w przyszłości, stosuj więc wszędzie mysqli_ lub PDO, przykład tutaj

    0
  • #3 25 Paź 2013 18:26
    Maciej.Rek
    Poziom 11  

    Problem bardzo prosty "No database selected".
    Rozwiązanie też do trudnych nie należy. Mianowicie przez to, że mieszałem mysql_ i mysqli_ funkcja nie wybierała bazy danych (mysql_connect oczekuje 3 parametrów połączenia, ponieważ do wyboru bazy danych służy osobne polecenie).

    Problem rozwiązany, dziękuję marcinj12 :)

    0
  • #4 30 Paź 2013 01:47
    Maciej.Rek
    Poziom 11  

    Jako, że temat jeszcze nie zamknięty chciałbym prosić kolejny raz o pomoc, lub jakieś ukierunkowanie.

    W pętli w której pobieram wyniki z bazy danych dodaję również formularz który pokazuje przycisk przy każdym rekordzie. Przycisk ma na celu usuwanie wybranego rekordu. Wszystko działa ładnie, jednak chciałem aby przed usunięciem pokazywało mi się okienko w jQuery czy na pewno chcę usunąć wybraną galerię, więc starałem się zrobić wysyłanie formularza przez JS. Problem w tym, że teraz zawsze kiedy formularz zostanie wysłany wartość która jest w inpucie wynosi 1, tak jakby wartość była uzupełniana tylko przy pierwszym obrocie pętli.

    Skrypt w pliku index.php

    Kod: javascript
    Zaloguj się, aby zobaczyć kod


    oraz plik który tworzy cały formularz:
    Kod: php
    Zaloguj się, aby zobaczyć kod


    Kombinowałem już na różne sposoby, ale męczę się z tym drugi dzień. Stwierdziłem, że skoro formularz jest w pętli to wina może leżeć po stronie id, więc zmieniałem id na klasę, tylko wtedy pojawia się kolejny problem ponieważ nie wiem jak wysłać do skryptu index o który formularz dokładnie mi chodzi. Próbowałem w ten sposób:
    Kod: javascript
    Zaloguj się, aby zobaczyć kod

    Uprzednio nadając inputowi class='pole' jednak wtedy za każdym razem skrypt zwraca wartość 2 (nie wiem dlatczego, skoro w bazie są 3 rekordy).

    Dodam jeszczę plik, do którego wszystko jest wysyłane, ale jest on na tyle prosty że to raczej nie jego wina.

    Kod: php
    Zaloguj się, aby zobaczyć kod

    0
  • Pomocny post
    #5 30 Paź 2013 10:45
    marcinj12
    Poziom 40  

    Ja zamiast formularza dla każdego rekordu stworzyłbym raczej jeden, dla całej strony albo przynajmniej dla tabeli.

    A tak w ogóle to skoro korzystasz z jQuery, to możesz to zrobić bez formularza:
    np. wygeneruj linki w takiej postaci:

    Kod: html4strict
    Zaloguj się, aby zobaczyć kod
    przerób skrypt usuwający, żeby zamiast z $_POST korzystał z $_GET, a usuwanie załatwisz takim skryptem:
    Kod: jquery
    Zaloguj się, aby zobaczyć kod

    Możesz też, zamiast nawigować do strony usuwającej, wykorzystać funkcję $.POST i wysłać polecenie usunięcia bez przechodzenia na stronę.

    0
  • #6 31 Paź 2013 00:27
    Maciej.Rek
    Poziom 11  

    Marcinie, jak zwykle dziękuję za odpowiedz.
    Problem jest jeden, bo mimo że w sumie jestem początkujący, to chciałbym jednak zachować jakieś podstawy bezpieczeństwa, wobec tego zdecydowałem się na POST'a (stąd ten cały formularz). Teraz sobie myśle, czy może by nie kombinować i nie skorzystać z GET'a, a później w jakiś sposób maskować ten link, tak żeby nie był on bezpośrednio widoczny. Chodzi mi dokładnie o to, że z GETem problemów nie ma, tylko jeśli mam galerie id=1 i link dajmy na to http://mojhost.pl/admin/delete.php?id=1,, to ktoś mógłby wpaść na pomysł "o! a co jeśli wpisze ?id=2 ? I w ten sposób wreszcie by dostrzegł, że ktoś mu ukradł galerię ze strony, albo jakoś zniknęła. Oczywiście jest to też kwestia sesji i całego logowania, ale wolałbym mieć też to ukryte. Następne co jest dla mnie ważne, to jQuery dialog, którym mogę sobie wyświetlić ładny komunikat potwierdzający, czy za pomocą include wyświetlać tam jakieś cząstki kodu. Jenak w tym wypadku tak jak powiedziałem - główne problemy to (może i po części moje "widzi mi się") wysyłanie zmiennej poprzez POST, oraz okienko z potwierdzeniem o normalnym wyglądzie, bo te javascriptowe confirmy bardzo mi się nie podobają, a z tego co wiem raczej nie da się w ich wygląd, lub komunikaty ingerować.

    Pozdrawiam :)

    EDIT: wcześniejszej treści nie usuwam, bo może ktoś podrzuci jeszcze jakieś ciekawe pomysły, spełniające moje "zachcianki". Nie doczytałem ostatniej linijki, a nawet nie wiedziałem że jQuery ma funkcę $.POST (uczę się z książek, a że zaczynam to na półce raczej widnieją pozycje dla początkujących). Więc dla marcinj oczywiście leci pomógł, bo bardzo fajny pomysł wykonywania całej brudnej roboty po stronie jQuery. Dziękuję!

    0
  • Pomocny post
    #7 31 Paź 2013 01:36
    marcinj12
    Poziom 40  

    Maćku :]
    Generalnie nie powinno być większych problemów z przerobieniem GET na POST - użyłem GETa, bo jest z tym nieco mniej zabawy a, szczerze mówiąc, przeysłanie przez POST wcale nie jest o wiele bezpieczniejsze...

    Po pierwsze - nie trzeba wiele wiedzy ani zachodu żeby znaleźć przez google programy czy wtyczki do przeglądarki powalające modyfikować zawartość przesyłaną przez POST równie prosto, jak zmianę numeru parametru w linku.

    Po drugie - sam decydujesz, jakie numery galerii wyświetlić i pozwolić usunąć użytkownikowi. Zakładając, że każdy użytkownik widzi też galerie innych użytkowników, logiczne wydaje się, że powinien mieć wyświetlony link czy przycisk USUŃ tylko obok tej, którą sam założył - powinieneś dodać jakiś dodatkowy warunek if który to zrealizuje. Link z numerem id nie jest bezpośrednio widoczny - jest zaszyty w kodzie strony, ale tak samo będzie w przypadku wartości dla zmiennej przesyłanej przez POST, którą będziesz musiał gdzieś trzymać (np. w ukrytym polu).

    Po trzecie - jeżeli chcesz się zabezpieczyć przed wzajemnym usuwaniem sobie galerii, to w związku z pkt. 2 i tak powinna być jakaś inna metoda autoryzacji usuwania. Możesz zacząć od tego, że zamiast (lub oprócz) kolejnych numerów ID będziesz generował i zapisywał w bazie danych również unikalny numer GUID. Tak w PHP jak i w różnych bazach danych zwykle można w łatwy sposób taki unikalny identyfikator wygenerować - wystarczy trzymać go w dodatkowej kolumnie tabeli z galeriami.
    Linki do GET i zapytanie DELETE zrobisz wtedy po numerze GUID, który nie tak łatwo będzie zgadnąć. Autonumerowanie ID możesz zostawić do innych zapytań.
    Oprócz tego na stronie delete.php wprowadziłbym zabezpieczenie po użytkowniku - przy zakładaniu galerii do bazy dodajesz numer ID albo nazwę użytkownika, który ją założył, a przed usunięciem najpierw sprawdzasz, czy nazwa użytkownika lub jego numer ID zgadza się z właścicielem galerii. Jeżeli nie - wyświetlasz komunikat i nic nie usuwasz.

    Innymi słowy, robisz zabezpieczenie w stylu:

    Kod: php
    Zaloguj się, aby zobaczyć kod


    Po czwarte :] - jeżeli martwisz się o bezpieczeństwo to wiedz, że ten fragment kodu który w tej chwili masz do usuwania galerii to "podręcznikowy" przykład na SQL-injection. Popatrz na przykłady, w jaki sposób z mysqli można użyć parametrów - one zabezpieczają przed takimi atakami.

    0
  • #8 31 Paź 2013 02:12
    Maciej.Rek
    Poziom 11  

    Marcinie - kolejny raz pomogłes. Innymi słowy, mogę rzec, że jesteś wielki :)
    Poczytałem trochę o jQuery i $.POST - faktycznie jest to bardzo prosta metoda, a do tego zamiast tworzenia całego formularza mogę to zrobić samymi "a hrefami", a całym POSTem zajmie się już jQuery. Po drugie faktycznie chyba jestem trochę "nie świeży" - POST jest już równie niebezpieczny co GET. Metroda identyfikacji właściciela to naprawdę fajny sposób, do tego dorzucę GUID i już mam dotakowy stopień bezpieczeństwa. Uświadomiłeś mi bardzo ważne rzeczy niezbędne (przynajmniej moim zdaniem) już od początków programowania - to że programowanie WEBowe nie polega tylko na PHP i HTML, ale również języki oparte na JAVIE mogą wiele pomóc, zdziałać i uprościć. Oraz inne - to że programowanie się rozwija, jest równoznaczne z tym, że i zła strona mocy nie śpi i szuka coraz to nowych metod włamań, które trzeba brać pod uwagę. Dziękuję Ci bardzo za wszystko, chociaż niewykluczam, że dopiszę tu jeszcze kilka kolejnych problemów które mnie zablokują.

    Pozdrawiam, Maciek

    0
  • #9 01 Lis 2013 01:06
    Maciej.Rek
    Poziom 11  

    Marcinie - właśnie do tego usiadłem i w miare możliwości trochę przerobiłem wysłany przez Ciebie skrypt. Wszystko działa świetnie! Problem jest tylko taki, że teraz treść diva używanego przez skrypcik jQuery wyświetla się nie tylko w okienku dialogowym, ale również normalnie na stronie, w miejscu gdzie div ten jest w <body> umiejscowiony. Czy w kodzie który wysłałeś jest to normalne i mam go ukryć w CSS, czy może dopisać coś do skryptu, aby ten na stronie się nie pojawiał?

    Pozdrawiam :)

    0
  • #10 01 Lis 2013 20:08
    marcinj12
    Poziom 40  

    Nie analizowałem tego fragmentu ale możliwe, że musisz domyślnie ukryć to okienko w css. Zobacz firebugiem albo w dokumentacji dla tego okienka co się zmienia i ustaw odpowiedni css.

    0