{"id":767,"date":"2024-04-01T13:00:27","date_gmt":"2024-04-01T11:00:27","guid":{"rendered":"https:\/\/piotrgabriel.pl\/wiki\/?p=767"},"modified":"2024-11-13T12:14:32","modified_gmt":"2024-11-13T11:14:32","slug":"podstawy-crud-create-read-update-delete-w-php-i-mysql","status":"publish","type":"post","link":"https:\/\/piotrgabriel.pl\/wiki\/podstawy-crud-create-read-update-delete-w-php-i-mysql\/","title":{"rendered":"Podstawy CRUD (Create, Read, Update, Delete) w PHP i MySQL"},"content":{"rendered":"<p>Nie od dzi\u015b wiemy, \u017ce w tera\u017aniejszym, cyfrowym \u015bwiecie, zarz\u0105dzanie danymi to klucz do sukcesu wielu aplikacji webowych. W artykule dowiecie si\u0119, czym jest CRUD, jak z niego korzysta\u0107, jak przydatnym &#8222;zlepkiem narz\u0119dzi&#8221; jest ten akronim.<!--more--><\/p>\n<p>PHP i MySQL s\u0105 pot\u0119\u017cnym duetem, kt\u00f3ry umo\u017cliwia tworzenie dynamicznych i interaktywnych stron internetowych z zaawansowanym zarz\u0105dzaniem danymi. Owszem, i zgodz\u0119 si\u0119 z tym, \u017ce znajd\u0105 si\u0119 zwolennicy u\u017cywania PHP i MySQL do tworzenia dynamicznych stron WWW tak samo jak przeciwnicy, kt\u00f3rzy uwa\u017caj\u0105, \u017ce s\u0105 znacznie wydajniejsze technologie, a tak w og\u00f3le to PHP to nie programowanie \ud83d\ude42 Ale nie o tym tu i teraz.<\/p>\n<p>Tu przyjrzymy si\u0119, jak mo\u017cna zaimplementowa\u0107 operacje <strong>CRUD<\/strong> (Create, Read, Update, Delete) w PHP 8 i MySQL, tworz\u0105c prost\u0105 baz\u0119 danych i interfejs u\u017cytkownika do zarz\u0105dzania danymi.<\/p>\n<h2>Czym jest CRUD?<\/h2>\n<p><strong>CRUD<\/strong> to akronim od angielskich s\u0142\u00f3w <strong>Create, Read, Update, Delete<\/strong>, kt\u00f3re odnosz\u0105 si\u0119 do czterech podstawowych funkcji zarz\u0105dzania danymi w bazach danych.<\/p>\n<ul>\n<li>Create &#8211; tworzenie nowych rekord\u00f3w;<\/li>\n<li>Read &#8211; odczytywanie istniej\u0105cych rekord\u00f3w;<\/li>\n<li>Update &#8211; aktualizowanie istniej\u0105cych rekord\u00f3w;<\/li>\n<li>Delete &#8211; usuwanie istniej\u0105cych rekord\u00f3w.<\/li>\n<\/ul>\n<p>Na tych 4 elementach skupimy si\u0119 w tym artykule, tworz\u0105c przyk\u0142adow\u0105 baz\u0119 danych i j\u0105 za pomoc\u0105 CRUD edytuj\u0105c.<\/p>\n<h2>Utworzenie bazy danych i tabeli<\/h2>\n<p>Pierwszym krokiem jest utworzenie bazy danych MySQL, kt\u00f3ra b\u0119dzie przechowywa\u0107 nasze dane. U\u017cyjemy do tego MySQL Workbench, phpMyAdmin lub innego narz\u0119dzia do zarz\u0105dzania baz\u0105 danych.<\/p>\n<p><code>CREATE DATABASE blogData;<\/code><br \/>\n<code>USE blogData;<\/code><\/p>\n<p><code>CREATE TABLE articles (<\/code><br \/>\n<code>id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,<\/code><br \/>\n<code>title VARCHAR(50) NOT NULL,<\/code><br \/>\n<code>content TEXT,<\/code><br \/>\n<code>publication_date TIMESTAMP<\/code><br \/>\n<code>);<\/code><\/p>\n<p>Kolejno, \u017ceby\u015bmy tak na prawd\u0119 mieli na czym wst\u0119pnie \u0107wiczy\u0107, wstawimy kilka przyk\u0142adowych rekord\u00f3w, aby m\u00f3c na nich pracowa\u0107:<\/p>\n<p><code>INSERT INTO articles (title, content, publication_date) VALUES <\/code><br \/>\n<code>('Pierwszy artyku\u0142', 'To jest tre\u015b\u0107 pierwszego artyku\u0142u.', NOW()),<\/code><br \/>\n<code>('Drugi artyku\u0142', 'To jest tre\u015b\u0107 drugiego artyku\u0142u.', NOW());<\/code><\/p>\n<h2>Implementacja CRUD w PHP 8<\/h2>\n<p>Teraz, kiedy mamy baz\u0119 danych i tabel\u0119, przejd\u017amy do implementacji funkcji CRUD w PHP. Poni\u017cej znajduje si\u0119 przyk\u0142adowy kod pokazuj\u0105cy, jak te operacje mog\u0105 by\u0107 wykonane.<\/p>\n<h3>Po\u0142\u0105czenie z baz\u0105 danych<\/h3>\n<p>Utworzymy plik <code>db.php<\/code>, kt\u00f3ry b\u0119dzie odpowiedzialny za nawi\u0105zanie po\u0142\u0105czenia z baz\u0105 danych. Dobr\u0105 praktyk\u0105 jest trzymanie w oddzielnym pliku danych konfiguracyjnych, zwi\u0105zanych z po\u0142\u0105czeniem z baz\u0105, podobnie jak trzymanie wszystkich funkcji w 1 pliku, odseparowywanie sta\u0142ych element\u00f3w widoku stron do oddzielnych plik\u00f3w, czy tworzenie plik\u00f3w ze stylami, np. style.css w kt\u00f3rym trzymane s\u0105 wszystkie nasze kaskadowe arkusze styli, klasy, identyfikatory. Jest to o tyle wa\u017cne, by w chwili konieczno\u015bci dokonania zmiany, kt\u00f3ra ma zadzia\u0142a\u0107 globalnie, dokonywa\u0107 j\u0105 tylko w 1 pliku, include&#8217;owanym do wszystkich widok\u00f3w naszej strony\/serwisu, kt\u00f3rego dotyczy.<\/p>\n<p>Zawarto\u015b\u0107 pliku db.php<\/p>\n<p><code>&lt;?php<\/code><br \/>\n<code>$servername = \"localhost\";<\/code><br \/>\n<code>$username = \"username\";<\/code><br \/>\n<code>$password = \"password\";<\/code><br \/>\n<code>$dbname = \"blogData\";<\/code><\/p>\n<p><code>\/\/ Utworzenie po\u0142\u0105czenia<\/code><br \/>\n<code>$conn = new mysqli($servername, $username, $password, $dbname);<\/code><\/p>\n<p><code>\/\/ Sprawdzenie po\u0142\u0105czenia<\/code><br \/>\n<code>if ($conn-&gt;connect_error) {<\/code><br \/>\n<code>die(\"Connection failed: \" . $conn-&gt;connect_error);<\/code><br \/>\n<code>}<\/code><br \/>\n<code>?&gt;<\/code><\/p>\n<h3>Create &#8211; Dodawanie nowych rekord\u00f3w<\/h3>\n<p>Utworzymy prosty formularz HTML, aby u\u017cytkownik m\u00f3g\u0142 doda\u0107 nowy artyku\u0142, oraz skrypt PHP, kt\u00f3ry przetworzy formularz i doda rekord do bazy danych.<\/p>\n<p><strong>Formularz (create.html)<\/strong><\/p>\n<p><code>&lt;form action=\"create.php\" method=\"post\"&gt;<\/code><br \/>\n<code>Tytu\u0142: &lt;input type=\"text\" name=\"title\"&gt;&lt;br&gt;<\/code><br \/>\n<code>Tre\u015b\u0107: &lt;textarea name=\"content\"&gt;&lt;\/textarea&gt;&lt;br&gt;<\/code><br \/>\n<code>&lt;input type=\"submit\"&gt;<\/code><br \/>\n<code>&lt;\/form&gt;<\/code><\/p>\n<p><strong>Skrypt PHP (create.php)<\/strong><\/p>\n<p><code>&lt;?php<\/code><br \/>\n<code>include 'db.php';<\/code><\/p>\n<p><code>$title = $_POST['title'];<\/code><br \/>\n<code>$content = $_POST['content'];<\/code><\/p>\n<p><code>$sql = \"INSERT INTO articles (title, content, publication_date) VALUES (?, ?, NOW())\";<\/code><br \/>\n<code>$stmt = $conn-&gt;prepare($sql);<\/code><br \/>\n<code>$stmt-&gt;bind_param(\"ss\", $title, $content);<\/code><br \/>\n<code>$stmt-&gt;execute();<\/code><\/p>\n<p><code>echo \"Artyku\u0142 dodany pomy\u015blnie\";<\/code><br \/>\n<code>$stmt-&gt;close();<\/code><br \/>\n<code>$conn-&gt;close();<\/code><br \/>\n<code>?&gt;<\/code><\/p>\n<h3>Read &#8211; Odczytywanie rekord\u00f3w<\/h3>\n<p>Aby wy\u015bwietli\u0107 artyku\u0142y, u\u017cyjemy poni\u017cszego skryptu PHP:<\/p>\n<p><strong>Skrypt PHP (read.php)<\/strong><\/p>\n<p><code>&lt;?php<\/code><br \/>\n<code>include 'db.php';<\/code><\/p>\n<p><code>$sql = \"SELECT id, title, content, publication_date FROM articles\";<\/code><br \/>\n<code>$result = $conn-&gt;query($sql);<\/code><\/p>\n<p><code>if (!$result) {<\/code><br \/>\n<code>die(\"B\u0142\u0105d zapytania: \" . $conn-&gt;error);<\/code><br \/>\n<code>}<\/code><\/p>\n<p><code>if ($result-&gt;num_rows &gt; 0) {<\/code><br \/>\n<code>while($row = $result-&gt;fetch_assoc()) {<\/code><br \/>\n<code>echo \"id: \" . $row[\"id\"] . \" - Tytu\u0142: \" . $row[\"title\"] . \" - Tre\u015b\u0107: \" . $row[\"content\"] . \"&lt;br&gt;\";<\/code><br \/>\n<code>}<\/code><br \/>\n<code>} else {<\/code><br \/>\n<code>echo \"0 results\";<\/code><br \/>\n<code>}<\/code><br \/>\n<code>$conn-&gt;close();<\/code><br \/>\n<code>?&gt;<\/code><\/p>\n<p>&nbsp;<\/p>\n<h3>Update i Delete<\/h3>\n<p>Aby zaj\u0105\u0107 si\u0119 tymi dwoma mechanizmami, czyli mechanik\u0105 <strong>Update<\/strong>, aktualizacji danych poszczeg\u00f3lnego rekordu w bazie oraz <strong>Delete<\/strong>, czyli mo\u017cliwo\u015bci\u0105 usuni\u0119cia rekordu z poziomu PHP, stworzony zostanie plik <em>index.php<\/em>, w kt\u00f3rym wy\u015bwietlona zostanie tabela, zawieraj\u0105ca wszystkie rekordy z tabeli, z naszego przyk\u0142adu. W tabeli zawarte b\u0119d\u0105 te\u017c akcje, w postaci link\u00f3w dynamicznych, kieruj\u0105ce do plik\u00f3w <em>edit.php<\/em> oraz <em>delete.php<\/em>. Te jak to nazwa\u0142em &#8222;akcje&#8221; musz\u0105 jednak pos\u0142ugiwa\u0107 si\u0119 konkretnym identyfikatorem, \u017ceby skrypt wiedzia\u0142, kt\u00f3ry rekord w bazie chcemy usun\u0105\u0107 lub wyedytowa\u0107. Przejd\u017amy wi\u0119c do realizacji tego problemu:<\/p>\n<p>Plik <code>index.php<\/code> wy\u015bwietli wszystkie rekordy z tabeli <code>articles<\/code> wraz z przyciskami do edycji i usuwania.<\/p>\n<h3>Skrypt PHP (index.php)<\/h3>\n<p><code>&lt;?php<\/code><br \/>\n<code>include 'db.php';<\/code><\/p>\n<p><code>$sql = \"SELECT id, title, publication_date FROM articles\";<\/code><br \/>\n<code>$result = $conn-&gt;query($sql);<\/code><br \/>\n<code>?&gt;<\/code><br \/>\n<code>&lt;!DOCTYPE html&gt;<\/code><br \/>\n<code>&lt;html lang=\"pl\"&gt;<\/code><br \/>\n<code>&lt;head&gt;<\/code><br \/>\n<code>&lt;meta charset=\"UTF-8\"&gt;<\/code><br \/>\n<code>&lt;title&gt;Lista Artyku\u0142\u00f3w&lt;\/title&gt;<\/code><br \/>\n<code>&lt;\/head&gt;<\/code><br \/>\n<code>&lt;body&gt;<\/code><br \/>\n<code>&lt;h2&gt;Lista Artyku\u0142\u00f3w&lt;\/h2&gt;<\/code><br \/>\n<code>&lt;table&gt;<\/code><br \/>\n<code>&lt;tr&gt;<\/code><br \/>\n<code>&lt;th&gt;Tytu\u0142&lt;\/th&gt;<\/code><br \/>\n<code>&lt;th&gt;Data Dodania&lt;\/th&gt;<\/code><br \/>\n<code>&lt;th&gt;Akcje&lt;\/th&gt;<\/code><br \/>\n<code>&lt;\/tr&gt;<\/code><br \/>\n<code>&lt;?php if ($result-&gt;num_rows &gt; 0): ?&gt;<\/code><br \/>\n<code>&lt;?php while($row = $result-&gt;fetch_assoc()): ?&gt;<\/code><br \/>\n<code>&lt;tr&gt;<\/code><br \/>\n<code>&lt;td&gt;&lt;?php echo $row[\"title\"]; ?&gt;&lt;\/td&gt;<\/code><br \/>\n<code>&lt;td&gt;&lt;?php echo $row[\"publication_date\"]; ?&gt;&lt;\/td&gt;<\/code><br \/>\n<code>&lt;td&gt;<\/code><br \/>\n<code>&lt;a href=\"edit.php?id=&lt;?php echo $row[\"id\"]; ?&gt;\"&gt;Edytuj&lt;\/a&gt;<\/code><br \/>\n<code>&lt;a href=\"delete.php?id=&lt;?php echo $row[\"id\"]; ?&gt;\" onclick=\"return confirm('Czy na pewno chcesz usun\u0105\u0107 ten rekord?');\"&gt;Usu\u0144&lt;\/a&gt;<\/code><br \/>\n<code>&lt;\/td&gt;<\/code><br \/>\n<code>&lt;\/tr&gt;<\/code><br \/>\n<code>&lt;?php endwhile; ?&gt;<\/code><br \/>\n<code>&lt;?php else: ?&gt;<\/code><br \/>\n<code>&lt;tr&gt;&lt;td colspan=\"3\"&gt;Brak artyku\u0142\u00f3w&lt;\/td&gt;&lt;\/tr&gt;<\/code><br \/>\n<code>&lt;?php endif; ?&gt;<\/code><br \/>\n<code>&lt;\/table&gt;<\/code><br \/>\n<code>&lt;\/body&gt;<\/code><br \/>\n<code>&lt;\/html&gt;<\/code><br \/>\n<code>&lt;?php<\/code><br \/>\n<code>$conn-&gt;close();<\/code><br \/>\n<code>?&gt;<\/code><\/p>\n<h3>Skrypt PHP (edit.php)<\/h3>\n<p>Strona <code>edit.php<\/code> wy\u015bwietla formularz do edycji wybranego rekordu.<\/p>\n<p><code>&lt;?php<\/code><br \/>\n<code>include 'db.php';<\/code><\/p>\n<p><code>\/\/ Pobieranie danych rekordu na podstawie przekazanego ID<\/code><br \/>\n<code>if(isset($_GET['id'])) {<\/code><br \/>\n<code>$id = $_GET['id'];<\/code><br \/>\n<code>$sql = \"SELECT * FROM articles WHERE id = ?\";<\/code><br \/>\n<code>$stmt = $conn-&gt;prepare($sql);<\/code><br \/>\n<code>$stmt-&gt;bind_param(\"i\", $id);<\/code><br \/>\n<code>$stmt-&gt;execute();<\/code><br \/>\n<code>$result = $stmt-&gt;get_result();<\/code><br \/>\n<code>if($result-&gt;num_rows == 1) {<\/code><br \/>\n<code>$row = $result-&gt;fetch_assoc();<\/code><br \/>\n<code>$title = $row['title'];<\/code><br \/>\n<code>$content = $row['content'];<\/code><br \/>\n<code>} else {<\/code><br \/>\n<code>echo \"Nie znaleziono artyku\u0142u.\";<\/code><br \/>\n<code>exit;<\/code><br \/>\n<code>}<\/code><br \/>\n<code>} else {<\/code><br \/>\n<code>echo \"Nieprawid\u0142owe ID.\";<\/code><br \/>\n<code>exit;<\/code><br \/>\n<code>}<\/code><br \/>\n<code>?&gt;<\/code><br \/>\n<code>&lt;!DOCTYPE html&gt;<\/code><br \/>\n<code>&lt;html lang=\"pl\"&gt;<\/code><br \/>\n<code>&lt;head&gt;<\/code><br \/>\n<code>&lt;meta charset=\"UTF-8\"&gt;<\/code><br \/>\n<code>&lt;title&gt;Edycja Artyku\u0142u&lt;\/title&gt;<\/code><br \/>\n<code>&lt;\/head&gt;<\/code><br \/>\n<code>&lt;body&gt;<\/code><br \/>\n<code>&lt;h2&gt;Edycja Artyku\u0142u&lt;\/h2&gt;<\/code><br \/>\n<code>&lt;form action=\"update.php\" method=\"post\"&gt;<\/code><br \/>\n<code>&lt;input type=\"hidden\" name=\"id\" value=\"&lt;?php echo $id; ?&gt;\"&gt;<\/code><br \/>\n<code>Tytu\u0142: &lt;input type=\"text\" name=\"title\" value=\"&lt;?php echo $title; ?&gt;\"&gt;&lt;br&gt;<\/code><br \/>\n<code>Tre\u015b\u0107: &lt;textarea name=\"content\"&gt;&lt;?php echo $content; ?&gt;&lt;\/textarea&gt;&lt;br&gt;<\/code><br \/>\n<code>&lt;input type=\"submit\" value=\"Zaktualizuj\"&gt;<\/code><br \/>\n<code>&lt;\/form&gt;<\/code><br \/>\n<code>&lt;\/body&gt;<\/code><br \/>\n<code>&lt;\/html&gt;<\/code><\/p>\n<h3>Skrypt PHP (update.php)<\/h3>\n<p>Plik <code>update.php<\/code> przetwarza \u017c\u0105danie aktualizacji rekordu.<\/p>\n<p><code>&lt;?php<\/code><br \/>\n<code>include 'db.php';<\/code><\/p>\n<p><code>if(isset($_POST['id']) &amp;&amp; isset($_POST['title']) &amp;&amp; isset($_POST['content'])) {<\/code><br \/>\n<code>$id = $_POST['id'];<\/code><br \/>\n<code>$title = $_POST['title'];<\/code><br \/>\n<code>$content = $_POST['content'];<\/code><\/p>\n<p><code>$sql = \"UPDATE articles SET title = ?, content = ? WHERE id = ?\";<\/code><br \/>\n<code>$stmt = $conn-&gt;prepare($sql);<\/code><br \/>\n<code>$stmt-&gt;bind_param(\"ssi\", $title, $content, $id);<\/code><\/p>\n<p><code>if($stmt-&gt;execute()) {<\/code><br \/>\n<code>echo \"Artyku\u0142 zaktualizowany pomy\u015blnie.\";<\/code><br \/>\n<code>} else {<\/code><br \/>\n<code>echo \"B\u0142\u0105d podczas aktualizacji artyku\u0142u.\";<\/code><br \/>\n<code>}<\/code><br \/>\n<code>$stmt-&gt;close();<\/code><br \/>\n<code>} else {<\/code><br \/>\n<code>echo \"Wszystkie pola s\u0105 wymagane.\";<\/code><br \/>\n<code>}<\/code><\/p>\n<p><code>$conn-&gt;close();<\/code><br \/>\n<code>?&gt;<\/code><\/p>\n<h3>Skrypt PHP (delete.php)<\/h3>\n<p>Plik <code>delete.php<\/code> odpowiada za usuni\u0119cie rekordu.<\/p>\n<p><code>&lt;?php<\/code><br \/>\n<code>include 'db.php';<\/code><\/p>\n<p><code>if(isset($_GET['id'])) {<\/code><br \/>\n<code>$id = $_GET['id'];<\/code><\/p>\n<p><code>$sql = \"DELETE FROM articles WHERE id = ?\";<\/code><br \/>\n<code>$stmt = $conn-&gt;prepare($sql);<\/code><br \/>\n<code>$stmt-&gt;bind_param(\"i\", $id);<\/code><\/p>\n<p><code>if($stmt-&gt;execute()) {<\/code><br \/>\n<code>echo \"Artyku\u0142 usuni\u0119ty pomy\u015blnie.\";<\/code><br \/>\n<code>} else {<\/code><br \/>\n<code>echo \"B\u0142\u0105d podczas usuwania artyku\u0142u.\";<\/code><br \/>\n<code>}<\/code><br \/>\n<code>$stmt-&gt;close();<\/code><br \/>\n<code>} else {<\/code><br \/>\n<code>echo \"Nieprawid\u0142owe ID.\";<\/code><br \/>\n<code>}<\/code><\/p>\n<p><code>$conn-&gt;close();<\/code><br \/>\n<code>?&gt;<\/code><\/p>\n<h2>Komentarz<\/h2>\n<p>Na koniec, kilka s\u0142\u00f3w komentarza. Ot\u00f3\u017c pami\u0119taj, \u017ce dla ka\u017cdego z powy\u017cszych skrypt\u00f3w trzeba dostosowa\u0107 dane dost\u0119pu do bazy danych w pliku db.php. Je\u015bli przenosisz sw\u00f3j skrypt, np, ze szko\u0142y do domu, chcesz nad nim nadal pracowa\u0107, zacznij od sprawdzenia czy dane dost\u0119powe do Twojej bazy w pliku db.php s\u0105 poprawne na stanowisku, na kt\u00f3rym aktualnie pracujesz. Ka\u017cdy plik php, om\u00f3wiony w przyk\u0142adzie posiada na pocz\u0105tku <code><span class=\"hljs-keyword\">include<\/span> <span class=\"hljs-string\">'db.php'<\/span>;<\/code> kt\u00f3ry to w\u0142a\u015bnie &#8222;include-uje\/za\u0142\u0105cza kod zawarty w db.php tak, by plik docelowy, np. delete.php m\u00f3g\u0142 z niego korzysta\u0107.<\/p>\n<p>Om\u00f3wmy jeszcze kilka zawartych w przyk\u0142adzie element\u00f3w:<\/p>\n<h4>Czym jest <span class=\"hljs-variable\">$stmt<\/span>-&gt;<span class=\"hljs-title function_ invoke__\">bind_param<\/span>(<span class=\"hljs-string\">&#8222;i&#8221;<\/span>, <span class=\"hljs-variable\">$id<\/span>);?<\/h4>\n<p>Metoda <code>$stmt-&gt;bind_param()<\/code> w PHP jest u\u017cywana do przypisania zmiennych do odpowiednich miejsc zast\u0119pczych (placeholder\u00f3w) w zapytaniu SQL przygotowanym przez metod\u0119 <code>prepare()<\/code>. Pozwala to na bezpieczne przekazywanie zmiennych do zapytania SQL, pomagaj\u0105c zapobiega\u0107 atakom SQL Injection poprzez oddzielenie instrukcji SQL od danych wej\u015bciowych u\u017cytkownika. Metoda <code>bind_param()<\/code> jest cz\u0119\u015bci\u0105 rozszerzenia mysqli, kt\u00f3re umo\u017cliwia interakcj\u0119 z bazami danych MySQL.<\/p>\n<p>W wywo\u0142aniu metody <code>bind_param(\"i\", $id);<\/code> w kontek\u015bcie pliku <code>delete.php<\/code>, kt\u00f3ry dotyczy usuwania rekordu:<\/p>\n<ul>\n<li><code>\"i\"<\/code> &#8211; okre\u015bla typ danych, kt\u00f3ry zostanie przekazany. W tym przypadku <code>\"i\"<\/code> oznacza, \u017ce przekazany argument b\u0119dzie traktowany jako liczba ca\u0142kowita (<code>integer<\/code>). Jest to wa\u017cne, poniewa\u017c informuje baz\u0119 danych o typie danych, kt\u00f3re s\u0105 przekazywane, co mo\u017ce by\u0107 istotne dla poprawnego przetwarzania zapytania. Dost\u0119pne typy to:\n<ul>\n<li><code>i<\/code> &#8211; integer (liczba ca\u0142kowita),<\/li>\n<li><code>d<\/code> &#8211; double (liczba zmiennoprzecinkowa),<\/li>\n<li><code>s<\/code> &#8211; string (\u0142a\u0144cuch znak\u00f3w),<\/li>\n<li><code>b<\/code> &#8211; blob (dane binarne).<\/li>\n<\/ul>\n<\/li>\n<li><code>$id<\/code> &#8211; to zmienna zawieraj\u0105ca warto\u015b\u0107, kt\u00f3ra zostanie przekazana do zapytania w miejscu zast\u0119pczym. W kontek\u015bcie usuwania rekordu jest to identyfikator (ID) rekordu, kt\u00f3ry ma zosta\u0107 usuni\u0119ty.<\/li>\n<\/ul>\n<p>Przyk\u0142ad u\u017cycia metody <code>bind_param(\"i\", $id);<\/code> w zapytaniu do usuni\u0119cia rekordu gwarantuje, \u017ce do zapytania zostanie przekazany bezpiecznie identyfikator rekordu, unikaj\u0105c ryzyka wstrzykni\u0119cia szkodliwego kodu SQL. To sprawia, \u017ce przygotowane zapytania s\u0105 rekomendowanym sposobem na interakcj\u0119 z baz\u0105 danych w aplikacjach PHP.<\/p>\n<h4>Czym jest <span class=\"hljs-variable\">$row<\/span> = <span class=\"hljs-variable\">$result<\/span>-&gt;<span class=\"hljs-title function_ invoke__\">fetch_assoc<\/span>();?<\/h4>\n<p>Metoda <code>$result-&gt;fetch_assoc()<\/code> w PHP jest u\u017cywana do pobrania pojedynczego wiersza z zestawu wynik\u00f3w zapytania do bazy danych jako tablic\u0119 asocjacyjn\u0105. W tablicy asocjacyjnej klucze odpowiadaj\u0105 nazwom kolumn w wynikowym wierszu z bazy danych. Metoda ta jest cz\u0119\u015bci\u0105 rozszerzenia MySQLi i PDO, s\u0142u\u017c\u0105cego do interakcji z bazami danych MySQL.<\/p>\n<p>Kiedy wykonujesz zapytanie do bazy danych za pomoc\u0105 metod takich jak <code>mysqli_query()<\/code> lub przygotowanego zapytania za pomoc\u0105 <code>mysqli_prepare()<\/code>, wynik zwracany przez baz\u0119 danych jest reprezentowany przez obiekt klasy <code>mysqli_result<\/code> (w przypadku rozszerzenia MySQLi). Aby przetworzy\u0107 wyniki zapytania, mo\u017cesz u\u017cy\u0107 r\u00f3\u017cnych metod. Jedn\u0105 z nich jest w\u0142a\u015bnie <code>fetch_assoc()<\/code>, kt\u00f3ra pozwala na iteracyjne przetwarzanie ka\u017cdego wiersza wynikowego.<\/p>\n<p>Przyk\u0142adowo, je\u015bli masz zapytanie, kt\u00f3re zwraca wyniki z tabeli u\u017cytkownik\u00f3w, ka\u017cde wywo\u0142anie metody <code>fetch_assoc()<\/code> zwr\u00f3ci nast\u0119pny dost\u0119pny wiersz wynik\u00f3w jako tablic\u0119 asocjacyjn\u0105, gdzie klucze tablicy b\u0119d\u0105 nazwami kolumn, a warto\u015bci \u2013 odpowiadaj\u0105cymi im danymi u\u017cytkownika z tego wiersza. Je\u015bli w tabeli by\u0142yby kolumny <code>id<\/code>, <code>name<\/code>, i <code>email<\/code>, ka\u017cde wywo\u0142anie <code>fetch_assoc()<\/code> zwr\u00f3ci\u0142oby co\u015b w stylu:<\/p>\n<p><code>[<\/code><br \/>\n<code>'id' =&gt; '1',<\/code><br \/>\n<code>'name' =&gt; 'Jan Kowalski',<\/code><br \/>\n<code>'email' =&gt; 'jan.kowalski@example.com'<\/code><br \/>\n<code>]<\/code><\/p>\n<p>Zastosowanie <code>$row = $result-&gt;fetch_assoc();<\/code> w p\u0119tli pozwala iterowa\u0107 przez wszystkie wiersze zwr\u00f3cone przez zapytanie. Na przyk\u0142ad:<\/p>\n<p><code>while($row = $result-&gt;fetch_assoc()) {<\/code><br \/>\n<code>echo $row[\"name\"] . \" - \" . $row[\"email\"];<\/code><br \/>\n<code>}<\/code><\/p>\n<p>W tym kodzie dla ka\u017cdego wiersza wynikowego tworzona jest tablica asocjacyjna <code>$row<\/code>, a nast\u0119pnie dane s\u0105 wy\u015bwietlane. Gdy wszystkie wiersze zostan\u0105 przetworzone, <code>fetch_assoc()<\/code> zwr\u00f3ci <code>null<\/code>, co zako\u0144czy p\u0119tl\u0119 <code>while<\/code>.<\/p>\n<h4>Czym jest zapis $stmt-&gt;bind_param(&#8222;ssi&#8221;, $title, $content, $id); ?<\/h4>\n<p>Metoda <code>$stmt-&gt;bind_param()<\/code> jest cz\u0119\u015bci\u0105 rozszerzenia MySQLi w PHP, u\u017cywan\u0105 w kontek\u015bcie przygotowanych zapyta\u0144 (prepared statements) do bezpiecznego przekazywania zmiennych do zapytania SQL. S\u0142u\u017cy do powi\u0105zania zmiennych PHP z odpowiednimi parametrami w zapytaniu SQL, kt\u00f3re s\u0105 oznaczone jako miejsca zast\u0119pcze znakami zapytania <code>?<\/code>. Dzi\u0119ki temu mechanizmowi mo\u017cna unikn\u0105\u0107 wielu problem\u00f3w zwi\u0105zanych z bezpiecze\u0144stwem, takich jak SQL Injection, poniewa\u017c dane przekazywane do bazy danych s\u0105 automatycznie sanitowane.<\/p>\n<p>Wywo\u0142anie <code>$stmt-&gt;bind_param(\"ssi\", $title, $content, $id);<\/code> wskazuje na kilka rzeczy:<\/p>\n<ol>\n<li><strong>&#8222;ssi&#8221;<\/strong> &#8211; Ci\u0105g znak\u00f3w okre\u015blaj\u0105cy typy danych przekazywanych zmiennych. Ka\u017cda litera w tym ci\u0105gu odpowiada jednej zmiennej, kt\u00f3ra zostanie przekazana do zapytania, a jej pozycja w ci\u0105gu odpowiada kolejno\u015bci miejsca zast\u0119pczego w zapytaniu SQL. W tym przypadku:\n<ul>\n<li><code>s<\/code> &#8211; oznacza <code>string<\/code> (\u0142a\u0144cuch znak\u00f3w). Pierwsza <code>s<\/code> odpowiada zmiennej <code>$title<\/code>, a druga <code>s<\/code> zmiennej <code>$content<\/code>.<\/li>\n<li><code>i<\/code> &#8211; oznacza <code>integer<\/code> (liczba ca\u0142kowita), co odpowiada zmiennej <code>$id<\/code>.<\/li>\n<\/ul>\n<\/li>\n<li><strong>$title, $content, $id<\/strong> &#8211; S\u0105 to zmienne PHP, kt\u00f3re zostaj\u0105 przekazane do zapytania. Ich warto\u015bci zostan\u0105 u\u017cyte w miejscach zast\u0119pczych zapytania SQL w kolejno\u015bci, w jakiej s\u0105 podane w <code>bind_param()<\/code>.<\/li>\n<\/ol>\n<p>Przyk\u0142ad u\u017cycia mo\u017ce wygl\u0105da\u0107 tak:<\/p>\n<p><code>$sql = \"UPDATE articles SET title = ?, content = ? WHERE id = ?\";<\/code><br \/>\n<code>$stmt = $conn-&gt;prepare($sql);<\/code><br \/>\n<code>$stmt-&gt;bind_param(\"ssi\", $title, $content, $id);<\/code><\/p>\n<p>W tym przyk\u0142adzie <code>$title<\/code> i <code>$content<\/code> s\u0105 typu <code>string<\/code>, natomiast <code>$id<\/code> jest typu <code>integer<\/code>. Przygotowane zapytanie aktualizuje rekord w tabeli <code>articles<\/code>, ustawiaj\u0105c nowe warto\u015bci dla kolumn <code>title<\/code> i <code>content<\/code> dla rekordu o okre\u015blonym <code>id<\/code>.<\/p>\n<p>U\u017cycie przygotowanych zapyta\u0144 i powi\u0105zanie zmiennych z parametrami zapytania w ten spos\u00f3b jest zalecan\u0105 praktyk\u0105, poniewa\u017c znacznie zwi\u0119ksza bezpiecze\u0144stwo aplikacji poprzez eliminacj\u0119 ryzyka wstrzykni\u0119cia SQL.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nie od dzi\u015b wiemy, \u017ce w tera\u017aniejszym, cyfrowym \u015bwiecie, zarz\u0105dzanie danymi to klucz do sukcesu wielu aplikacji webowych. W artykule dowiecie si\u0119, czym jest CRUD, jak z niego korzysta\u0107, jak przydatnym &#8222;zlepkiem narz\u0119dzi&#8221; jest ten akronim.<\/p>\n","protected":false},"author":1,"featured_media":769,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[48,244],"tags":[238,24,67,49],"class_list":["post-767","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-bazy-danych","category-php","tag-crud","tag-mysql","tag-php","tag-podstawy-sql"],"_links":{"self":[{"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/posts\/767","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/comments?post=767"}],"version-history":[{"count":1,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/posts\/767\/revisions"}],"predecessor-version":[{"id":1046,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/posts\/767\/revisions\/1046"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/media\/769"}],"wp:attachment":[{"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/media?parent=767"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/categories?post=767"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/tags?post=767"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}