Biblioteka PDO MySQL w PHP

Poradniki
mysql, php
DBanaszewski
DBanaszewski α-tester v3

PDO MySQL

Kiedyś programiści pragnący komunikować się z bazą danych poprzez PHP musieli zmagać się z wieloma problemami. Każdy serwer DB udostępniał inne API do komunikacji, które zostały na nasze nieszczęście wiernie odtworzone w interpreterze. Jeżeli ktoś chciał napisać elastyczny projekt do uruchamiania na kilku bazach, musiał pisać samodzielnie odpowiednie nakładki, które wybiorą odpowiednią funkcję w zależności od tego, czym się łączymy. Pozostawały też różne gotowe skrypty robiące to zadanie za nas.

PDO to skrót od PHP Data Objects. Jest to nowoczesny interfejs języka PHP przeznaczony do komunikacji z bazami danych, po raz pierwszy napisany wyłącznie w OOP. Jego najważniejszą zaletą jest to, że możemy za jego pomocą łączyć się zarówno z bazą danych MySQL, jak i z bazą danych PostgreSQL (o innych systemach DB nie wspominając). Wersji beta PDO można było używać już w PHP 5.0, natomiast stabilna wersja pojawiła się wraz z PHP 5.1. Gorąco zachęcamy do jego stosowania, gdyż nie tylko jest wygodniejszy od starych rozwiązań, ale też szybszy i bezpieczniejszy.


Tyle słowa wstępu, do dzieła!


Wymagania

  • serwer WWW ze wsparciem PHP (najlepiej PHP w wersji 7)
  • baza danych typu MySQL (np. MariaDB)
  • dodatek do PHP pdo_mysql

Przydałby się również phpMyAdmin ;)


Objeśnienia:

Tekst zapisany w taki sposób:

 

jest komentarzem i nie musi znajdować się w kodzie.


Krok 1 - wstępne przygotowania

Tworzymy pliki o nazwach: database.php, config.php, script.php i index.php. Możemy je edytować w przeznaczonym do tego celu programie np. PHPStorm albo w zwykłym edytorze tekstu - np. Notepad++.

Krok 2 - konfiguracja

Teraz edytujemy plik config.php. Konfiguracja będzie tutaj prostą rzeczą. Musimy utworzyć tablicę, czyli:

 "mysql.mojadomena.pl",
 
        //Port połączenia do bazy danych (standardowy to 3306).
        "port" => 3306,
 
        //Nazwa użytkownika bazy danych
        "username" => "root",
 
        //Hasło użytkownika bazy danych
        "password" => "abcdefghijk123!@#",
 
        //Nazwa tabeli
        "table_name" => "test"
 
    );

Zauważ, że nie ma znacznika zamykającego, czyli ?>. Dlaczego? Jeżeli plik zawiera tylko kod PHP to nie jest wymagane dodawanie znacznika kończącego. Przed zapisaniem uprawniamy się, czy wpisane dane do tablicy są prawidłowe. Jeżeli tak to zapisujemy i jedziemy dalej!

Krok 3 - połączenie z bazą danych

Edytujemy plik database.php.

Musimy załączyć plik config.php, aby PHP mogło się połączyć z bazą danych. Robimy to tak:

 

Plik został załączony, idziemy dalej.

Następnie tworzymy wyłapywanie wyjątków, czyli:

 

Okej, mamy to już za sobą. Jest to potrzebne, jeżeli podczas połączenia wystąpi jakiś błąd (np. literówka w haśle).

Teraz musimy otworzyć połączenie z bazą danych, czyli:

 false,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
        ]);
  }
 
  catch (PDOException $error) {
    exit("Błąd połączenia z bazą danych!");
  }
 
?>

Gotowe. Możesz zauważyć, że użyłem funkcji exit(). Zostanie ona wykonana, jeżeli połączenie z bazą się nie uda, a co idzie dalej, skrypt zatrzyma się i nic dalej nie wykona wypluwając na ekran komunikat Błąd połączenia z bazą danych!.

Lecimy dalej!

Krok 4 - formularz

Teraz edytujemy plik index.php. Jest to strona główna, więc użyjemy tutaj trochę HTMLa. Chcemy, aby dane ze skryptu pobierającego dane pokazały się pod formularzem, więc musimy aktywować sesje, których będziemy używać. Musimy uruchomić system sesji przy pomocy jednej linijki kodu:

 

I sesje zostały uruchomione. W tym poradniku chcemy zrobić formularz, który umożliwi nam odczytanie danych użytkownika z bazy. Ty możesz sam zrobić co chcesz, tutaj jest tylko przykład.

Kod HTML:

 
 
 
    
    Sprawdzanie użytkownika
 
 
 
    Sprawdzanie użytkownika
 
 
    
        
            Nazwa użytkownika 
            
        
    
 
 
 

Owy kod umieszczamy pod kodem PHP, czyli tak powinno to wyglądać (tutaj bez kolorków, bo mix kodów):






    
    Sprawdzanie użytkownika



    Sprawdzanie użytkownika


    
        
            Nazwa użytkownika 
            
        
    


Super! Formularz mamy gotowy! Teraz przydałoby się wyświetlać nam dane z bazy poniżej formularza. Jest to wstęp do kroku 5. Pomiędzy znacznikiem a umieścimy kod PHP, który będzie odpowiadał za wyświetlanie danych z bazy, które zostaną wcześniej umieszczone w sesji przez inny skrypt.

Oto on:

Użytkownik nie został odnaleziony!';
  unset($_SESSION["user_unknown"]);
}
if (isset($_SESSION["user_known"])) {
  echo 'Użytkownik został odnaleziony!';
  echo 'Nazwa użytkownika: '.$_SESSION["username"].'';
  echo 'Numer identyfikacyjny: '.$_SESSION["idnum"].'';
  echo 'Adres e-mail: '.$_SESSION["email"].'';
  echo 'Data rejestracji: '.$_SESSION["regdate"].'';
  unset($_SEaSSION["user_known"]);
  unset($_SESSION["username"]);
  unset($_SESSION["idnum"]);
  unset($_SESSION["email"]);
  unset($_SESSION["regdate"]);
}
?>

A jak to teraz powinno wyglądać (znowu bez kolorków, bo mix 😦) :






    
    Sprawdzanie użytkownika



    Sprawdzanie użytkownika


    
        
            Nazwa użytkownika 
            

            Użytkownik nie został odnaleziony!';
                unset($_SESSION["user_unknown"]);
            }
            if (isset($_SESSION["user_known"])) {
                echo 'Użytkownik został odnaleziony!';
                echo 'Nazwa użytkownika: '.$_SESSION["username"].'';
                echo 'Numer identyfikacyjny: '.$_SESSION["idnum"].'';
                echo 'Adres e-mail: '.$_SESSION["email"].'';
                echo 'Data rejestracji: '.$_SESSION["regdate"].'';
                unset($_SESSION["user_known"]);
                unset($_SESSION["username"]);
                unset($_SESSION["idnum"]);
                unset($_SESSION["email"]);
                unset($_SESSION["regdate"]);
            }
            ?>

        
    


Okej, index.php możemy zapisać, jest gotowy. Teraz przydałoby się odczytać te dane, bo jak na razie to tylko nam coś będzie pokazywać, ale na pewno nie dane z bazy 😛

Krok 5 - główny skrypt, odczyt z bazy danych

Teraz edytujemy plik script.php. Formularz gotowy, teraz backend, czyli strona niewidoczna dla zwykłego użytkownika. W poprzednim kroku uruchomiliśmy sesje. Tutaj też musimy :slight_smile:

więcej informacji), więc musimy je teraz odebrać. Następnie, dane zostaną zapisane w jednej zmiennej, bo przesyłamy tylko nazwę użytkownika. Przydałyby się również zapytania SQL, które przekażą nam dane z bazy danych do PHP. Musimy również wziąć pod uwagę, że dany użytkownik nie istnieje. Zastosujemy tutaj instrukcję `if` i `else`. Po udanym odczycie danych z bazy zostaną one umieszczone w sesji. Strona główna je odczyta i pokaże. Dla świętego spokoju dane w sesji zostaną usunięte, aby zwolnić pamięć RAM (_i zatrzymać wycinkę lasów deszczowych_). Nie będę się rozpisywał, przeanalizuj cały kod :stuck_out_tongue:
```php
prepare("SELECT * FROM users WHERE username = :username");
        $query->bindValue(':username', $username, PDO::PARAM_STR);
        $query->execute();
        if (intval($query->rowCount()) == 1) {
            $user = $query->fetch();
            $_SESSION["user_known"] = true;
            $_SESSION["username"] = $user["username"];
            $_SESSION["idnum"] = $user["idnum"];
            $_SESSION["email"] = $user["email"];
            $_SESSION["regdate"] = $user["regdate"];
            header("Location: index.php");
            exit();
        } else {
            $_SESSION["user_unknown"] = true;
            header("Location: index.php");
            exit();
        }
    } else {
        $_SESSION["user_unknown"] = true;
        header("Location: index.php");
        exit();
    }

Zapisz ten plik i gotowe.

Krok 6 - dodawanie danych do bazy

Tak naprawdę ten krok jest nadobowiązkowy, ale trzeba go dopisać. Pusta baza danych = skrypt będzie zawsze odpowiadał, że taki gracz nie istnieje. Tutaj przygotowałem dla Ciebie skrypt SQL, który możesz wykonać na serwerze MySQL poprzez panel phpMyAdmin. Owy skrypt zawiera kilka wpisów z danymi (oczywiście wymyślone).

CREATE TABLE `users` ( `idnum` INT NOT NULL AUTO_INCREMENT , `username` TEXT NOT NULL , `email` TEXT NOT NULL , `regdate` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP , PRIMARY KEY (`idnum`)) ENGINE = InnoDB;
INSERT INTO `users` (`idnum`, `username`, `email`, `regdate`) VALUES (NULL, 'Maur123', 'maurycy.abc@xyz.eu', CURRENT_TIMESTAMP), (NULL, 'Dawid', 'dawid@dawid.pl', CURRENT_TIMESTAMP), (NULL, 'Tadek', 'tadeusz.r@poczta.ru', CURRENT_TIMESTAMP), (NULL, 'Andrzej', 'andrzej@nazszapoczta.pl', CURRENT_TIMESTAMP), (NULL, 'Jarek1', 'jarek.1@poczta.lp', CURRENT_TIMESTAMP);

KONIEC!

Github: https://github.com/DBanaszewski/PHP-Poradnik-1 Link do kodu: https://s1.dbanaszewski.pl/poradnik-1/php-1.zip Skan (dla spokoju): link Strona testowa: https://s1.dbanaszewski.pl/poradnik-1/ Dane do testowania, czyli nazwa użytkownika, są zawarte w skrypcie SQL (jest wyżej). Proszę wytężyć umysł i wyczytać chociaż jedną nazwę :slight_smile:

Źródło: Wikibooks Błędy lub sugestie proszę pisać poniżej lub na PM.

kacper
kacper

DBanaszewski:

Link do kodu: https://s1.dbanaszewski.pl/poradnik-1/php-1.zip

Mógłbyś wrzucić kod na GitLaba? Boje się że pobiore wirusa 😦

DBanaszewski
DBanaszewski α-tester v3

Wrzuciłem na Githuba ;)

kacper
kacper

Dzięki :D

anon10657637
anon10657637

Czy ja tam widzę printowanie kodu błędu do end-usera czy mi się przewidziało?

Nieznajomy11
Nieznajomy11 Moderator forum.lvlup.pro

Hehe, dobrze widzisz. Do dzisiaj pamiętam jak przez przypadek wywołałem błąd z bazą na kiciusiach jak były odpalone "w trybie beta" (rakportal) i moim oczom szybko ukazało się hasło do mysql wraz z adresem. 😄

DBanaszewski
DBanaszewski α-tester v3

@anon10657637 - naprawię ten błąd bezpieczeństwa.

Dlaczego tak zrobiłem? A otóż dla ułatwienia - błąd + powód. Wkrótce łatka zostanie opublikowana.

Pantoflarz
Pantoflarz

ogólnie to i tak polecam korzystanie z frameworka, który komunikację z bazą ma wbudowaną, wszystko jest sprawdzane i zabezpieczane na bieżąco pod względem bezpieczeństwa itp. itd. przez autorów czy community.

wiadomo, że require'owanie pliku database.php w każdym pliku gdzie łączymy się z bazą też optymalne nie jest, no ale przestane już narzekać, bo wiadomo, od czegoś trzeba zaczynać 😛