Ce este MySQL și cum îl accesăm din PHP
MySQL este un sistem de gestiune a bazelor de date relaționale (RDBMS). Asta înseamnă
că stochează datele în tabele (rânduri și coloane) și îți oferă limbajul SQL pentru a
crea tabele, a introduce, căuta, modifica și șterge date. MySQL rulează ca un server (un proces
separat), iar aplicația ta PHP se conectează la el prin rețea (de obicei la localhost, portul
3306 pe mașina ta).
Termeni esențiali (pe scurt)
- Server MySQL - programul care rulează și gestionează toate bazele de date.
- Bază de date - „cutia” logică ce grupează tabele (ex.:
curs_php). - Tabel - colecție de rânduri cu aceeași structură de coloane (ex.:
userscu coloaneid,name,email). - Rând (înregistrare) - un „obiect”/o entitate completă (ex.: un utilizator).
- Coloană (câmp) - o proprietate a entității (ex.:
emaileste un câmp). - Cheie primară (PRIMARY KEY) - identificator unic al rândului (de obicei
idauto-increment). - Cheie străină (FOREIGN KEY) - leagă rânduri din tabele diferite (ex.:
posts.user_id→users.id). - Index - accelerarea căutărilor pe una sau mai multe coloane (ca un „cuprins”).
- Interogare SQL - o comandă către server (ex.:
SELECT ...).
Ce este SQL (pe înțelesul tuturor)
SQL (Structured Query Language) este limbajul standard pentru a lucra cu date relaționale. Are comenzi pentru:
- DDL (Data Definition Language) - definire de schemă:
CREATE,ALTER,DROP - DML (Data Manipulation Language) - manipulare date:
INSERT,SELECT,UPDATE,DELETE
Exemple SQL ultra-simple
-- Creează o bază de date
CREATE DATABASE curs_php CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- Alege baza de date
USE curs_php;
-- Creează un tabel
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(150) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
-- Citește toți utilizatorii
SELECT id, name, email FROM users;
De ce MySQL pentru proiecte PHP?
- Popular, suportat excelent în hosting-uri și local (XAMPP, MAMP, Laragon).
- Rapid pentru workload-uri comune (site-uri, aplicații CRUD).
- Open-source, comunitate mare, documentație bogată.
Instalare & pornire (pe scurt)
- Instalezi un pachet all-in-one (ex.: XAMPP / MAMP / Laragon).
- Pornești serviciul MySQL din control-panel.
- Accesezi
phpMyAdminlahttp://localhost/phpmyadmin(opțional, UI web pentru MySQL). - Conectare locală tipică:
host = localhost,port = 3306,user = root,password = ''(la XAMPP implicit). Recomandat: setează o parolă și/sau creează un user dedicat aplicației.
Cum accesăm MySQL din PHP (opțiuni)
- mysqli (procedural sau OOP) - doar pentru MySQL.
- PDO (PHP Data Objects) - interfață unificată pentru mai multe SGBD-uri (MySQL, PostgreSQL etc.), cu prepared statements și opțiuni moderne.
Recomandare: folosește PDO pentru portabilitate, securitate și o API coerentă.
Conectare la MySQL cu PDO (recomandat)
Formatul DSN pentru MySQL: mysql:host=HOST;dbname=BAZA; charset=UTF8. Setăm și opțiuni pentru
erori și fetch.
<?php $host = '127.0.0.1'; // sau
'localhost' $db = 'curs_php';// numele bazei de date
$user = 'root'; //userul
MySQL $pass = ''; //parola (la XAMPP e de obicei goală) $charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // aruncă excepții la erori
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // fetch ca array asociativ
PDO::ATTR_EMULATE_PREPARES => false, // prepared statements reale
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
echo "✅ Conexiune reușită la baza de date!";
} catch (PDOException $e) {
echo "❌ Eroare de conexiune: " . $e->getMessage();
}
?>
Separarea credențialelor (config separat)
Nu ține datele de conectare împrăștiate prin cod. Folosește un fișier config.php pe care îl
incluzi unde ai nevoie.
config.php
<?php return [ 'db' => [ 'host' => '127.0.0.1', 'name' => 'curs_php', 'user' => 'root', 'pass' => '', 'charset' => 'utf8mb4', ], ]; ?>
db.php (factory de conexiune)
<?php $config = require __DIR__ . '/config.php'; $db = $config['db'];
$dsn = "mysql:host={$db['host']};dbname={$db['name']};charset={$db['charset']}";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, $db['user'], $db['pass'], $options);
} catch (PDOException $e) {
exit('Eroare conectare DB: ' . $e->getMessage());
}
?>
test-conn.php (verificare rapidă)
<?php require __DIR__ . '/db.php';
$versiune = $pdo->query('SELECT VERSION()')->fetchColumn();
echo "Conectat la MySQL versiunea: " . $versiune;
?>
Erori frecvente & cum le rezolvi
- Access denied - user/parolă greșite sau userul nu are drepturi pe DB. Verifică
în
phpMyAdminsau creează un user dedicat. - Unknown database - nu există baza. Rulează
CREATE DATABASE ...sau verifică numele. - Connection refused - serverul MySQL nu e pornit sau portul diferă. Pornește serviciul, verifică portul.
- Caractere „măcelărite” - nu ai setat
charset=utf8mb4în DSN sau collation-ul la DB/tabele. - Erori „tăcute” - nu ai activat
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION. Activează pentru debugging corect.
Bune practici de bază (securitate)
- Nu folosi
rootîn producție. Creează un user cu drepturi strict necesare. - Nu pune credențialele în repo public. Ține
config.phpîn afara webroot-ului sau folosește variabile de mediu. - Folosește Prepared Statements (cu
$pdo->prepare()) pentru orice input de la utilizator → previne SQL Injection. - Setează mereu
utf8mb4pentru suport complet Unicode (inclusiv emoji).
Conectare la baza de date folosind PDO
Pentru a lucra cu o bază de date MySQL din PHP, cea mai sigură și flexibilă metodă este PDO (PHP Data Objects). Aceasta oferă o interfață unificată pentru mai multe tipuri de baze de date (nu doar MySQL), sprijină prepared statements (care protejează împotriva atacurilor SQL Injection) și oferă metode avansate de lucru.
Sintaxa de bază pentru conexiune
O conexiune PDO necesită: numele serverului (host), numele bazei de date (dbname),
numele de utilizator și parola. Este recomandat să folosim blocuri try...catch pentru a captura
eventualele erori de conexiune.
// Datele de conectare
$host = "localhost";
$dbname = "testdb";
$username = "root";
$password = "";
try {
// Creăm obiectul PDO
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
// Setăm modul de raportare a erorilor
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "✅ Conexiunea la baza de date a reușit!";
} catch (PDOException $e) {
echo "❌ Conexiunea a eșuat: " . $e->getMessage();
}
Explicații
new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password)- stabilește conexiunea la MySQL.setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)- configurăm PDO să arunce excepții în caz de erori (mai ușor de depistat problemele).try...catch- dacă apare o eroare (ex. parola greșită), aceasta va fi prinsă și afișată în$e->getMessage().
Exemplu concret: Crearea bazei de date și a tabelelor
Înainte de a putea salva informații într-o aplicație PHP, avem nevoie de o bază de date. Noi vom folosi MySQL, care vine deja instalat în pachetul XAMPP.
1. Pornirea serverului MySQL
- Deschide XAMPP Control Panel. - Pornește modulele Apache și
MySQL. Acum serverul web și serverul de baze de date rulează pe calculatorul tău.
2. Crearea bazei de date (varianta simplă prin phpMyAdmin)
Accesează http://localhost/phpmyadmin în browser. Acolo ai o interfață grafică unde poți apăsa pe
tab-ul Databases și să creezi manual baza de date traffice-test. Aceasta este cea mai ușoară
metodă pentru începători.
3. Crearea bazei de date din PHP
Dacă vrei să creezi baza de date direct printr-un script PHP, atunci faci așa:
<?php
try {
// Conectare la MySQL (fără a specifica încă baza de date)
$pdo = new PDO("mysql:host=localhost", "root", "");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Comanda SQL pentru a crea baza de date
$sql = "CREATE DATABASE IF NOT EXISTS traffice-test";
$pdo->exec($sql);
echo "✅ Baza de date 'traffice-test' a fost creată cu succes.";
} catch (PDOException $e) {
echo "❌ Eroare la crearea bazei de date: " . $e->getMessage();
}
?>
Unde pui acest cod?
1. Deschizi folderul htdocs din directorul XAMPP (ex: C:\xampp\htdocs).
2.
Creezi un fișier nou, de exemplu create_db.php.
3. Pui în el codul de mai sus.
4. În
browser accesezi http://localhost/create_db.php.
Dacă totul este în regulă, pe ecran vei vedea
mesajul Baza de date 'traffice-test' a fost creată cu succes.
4. Verificarea bazei de date
Pentru a confirma că baza de date există, mergi în phpMyAdmin (http://localhost/phpmyadmin) și ar
trebui să vezi traffice-test în lista din stânga.
Crearea tabelului users în baza de date
După ce avem baza de date traffice-test, următorul pas este să creăm un tabel în care să stocăm
informațiile. Vom crea un tabel simplu numit users, care va avea următoarele coloane:
id- identificator unic pentru fiecare utilizator (cheie primară, auto-increment)name- numele utilizatorului (text)email- adresa de email (text, unică)
1. Comanda SQL pentru crearea tabelului
Aceasta este comanda SQL clasică:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE
);
2. Crearea tabelului printr-un script PHP
Putem executa comanda SQL dintr-un fișier PHP. Creăm un fișier nou, de exemplu create_table.php
în htdocs:
<?php
try {
// Conectare la baza de date traffice-test
$pdo = new PDO("mysql:host=localhost;dbname=traffice-test", "root", "");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Crearea tabelului users
$sql = "CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE
)";
$pdo->exec($sql);
echo "✅ Tabelul 'users' a fost creat cu succes.";
} catch (PDOException $e) {
echo "❌ Eroare la crearea tabelului: " . $e->getMessage();
}
?>
3. Cum rulăm scriptul?
1. Salvează fișierul create_table.php în C:\xampp\htdocs.
2. Deschide browserul
și mergi la http://localhost/create_table.php.
3. Dacă totul a mers bine, vei vedea mesajul
Tabelul 'users' a fost creat cu succes.
4. Verificarea tabelului
Intră din nou în phpMyAdmin → baza de date traffice-test și ar trebui să vezi tabelul
users în lista din stânga. Poți da click pe el și vei observa coloanele id,
name și email.
Explicații
AUTO_INCREMENT- fiecare utilizator primește un ID unic automat.NOT NULL- câmpul nu poate rămâne gol.UNIQUE- fiecare email trebuie să fie unic în tabel (nu se pot înregistra două conturi cu același email).IF NOT EXISTS- evită eroarea dacă tabelul există deja.
Operații CRUD în PHP & MySQL
CRUD este acronimul pentru cele patru operații fundamentale pe care le putem efectua asupra datelor într-o bază de date: Create (Creare), Read (Citire), Update (Actualizare), Delete (Ștergere).
1. Create (Creare)
Operația CREATE înseamnă adăugarea de noi înregistrări (rânduri) într-un tabel. În PHP, acest
lucru se face folosind o interogare SQL INSERT INTO. De exemplu, putem adăuga un utilizator nou în
tabela users cu nume și email.
2. Read (Citire)
Operația READ înseamnă citirea și afișarea datelor existente. În PHP folosim interogarea
SELECT, care poate returna toți utilizatorii sau doar anumite coloane/înregistrări filtrate.
3. Update (Actualizare)
Operația UPDATE este folosită pentru a modifica datele existente. Putem actualiza numele sau
adresa de email a unui utilizator folosind o interogare SQL UPDATE cu o condiție
WHERE.
4. Delete (Ștergere)
Operația DELETE șterge o înregistrare din tabel. Este foarte important să folosim întotdeauna
o condiție WHERE pentru a evita ștergerea tuturor datelor.
Operații CRUD în PHP & MySQL (tabelul users)
Presupunem că avem deja baza de date traffice-test și tabela users creată. Mai jos demonstrăm cele 4
operații fundamentale: INSERT (Create), SELECT (Read), UPDATE, DELETE. Tot codul
este într-un singur fișier crud_demo.php.
<?php
try {
// 1. Conectare la baza de date
$pdo = new PDO("mysql:host=localhost;dbname=traffice-test", "root", "");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "<h2>CRUD pe tabela users</h2>";
// CREATE - Adăugăm utilizatori noi
$pdo->exec("INSERT INTO users (name, email) VALUES ('Ion Popescu', 'ion@example.com')");
$pdo->exec("INSERT INTO users (name, email) VALUES ('Maria Ionescu', 'maria@example.com')");
echo "<p>✅ Utilizatori adăugați.</p>";
// READ - Afișăm toți utilizatorii
echo "<h3>Lista utilizatori:</h3>";
$stmt = $pdo->query("SELECT * FROM users");
foreach ($stmt as $row) {
echo $row['id'] . " - " . $row['name'] . " (" . $row['email'] . ")<br>";
}
// UPDATE - Modificăm emailul lui Ion
$pdo->exec("UPDATE users SET email='ion.popescu@nou.com' WHERE name='Ion Popescu'");
echo "<p>✅ Emailul lui Ion a fost actualizat.</p>";
// Citim din nou după UPDATE
echo "<h3>După Update:</h3>";
$stmt = $pdo->query("SELECT * FROM users");
foreach ($stmt as $row) {
echo $row['id'] . " - " . $row['name'] . " (" . $row['email'] . ")<br>";
}
// DELETE - Ștergem utilizatorul Maria
$pdo->exec("DELETE FROM users WHERE name='Maria Ionescu'");
echo "<p>✅ Maria a fost ștearsă.</p>";
// Citim după DELETE
echo "<h3>După Delete:</h3>";
$stmt = $pdo->query("SELECT * FROM users");
foreach ($stmt as $row) {
echo $row['id'] . " - " . $row['name'] . " (" . $row['email'] . ")<br>";
}
} catch (PDOException $e) {
echo "❌ Eroare: " . $e->getMessage();
}
?>
Exemplu practic CRUD (HTML + PHP)
Mai jos avem un exemplu complet de aplicație simplă CRUD pentru tabela users. Aceasta permite
adăugarea de utilizatori noi, afișarea listei de utilizatori, actualizarea și ștergerea lor.
<?php
// db.php - conexiunea la baza de date
$pdo = new PDO("mysql:host=localhost;dbname=traffice-test", "traffice_php", "!@y3Ge-Z!WQI");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Adăugare utilizator
if (isset($_POST['add'])) {
$name = $_POST['name'];
$email = $_POST['email'];
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->execute([$name, $email]);
}
// Ștergere utilizator
if (isset($_GET['delete'])) {
$id = $_GET['delete'];
$stmt = $pdo->prepare("DELETE FROM users WHERE id = ?");
$stmt->execute([$id]);
}
// Actualizare utilizator
if (isset($_POST['update'])) {
$id = $_POST['id'];
$name = $_POST['name'];
$email = $_POST['email'];
$stmt = $pdo->prepare("UPDATE users SET name=?, email=? WHERE id=?");
$stmt->execute([$name, $email, $id]);
}
// Citire utilizatori
$stmt = $pdo->query("SELECT * FROM users");
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html>
<head>
<title>CRUD Demo</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
table { border-collapse: collapse; width: 60%; margin-top: 20px; }
th, td { border: 1px solid #ccc; padding: 8px; text-align: center; }
form { margin-bottom: 20px; }
</style>
</head>
<body>
<h2>Adaugă utilizator</h2>
<form method="post">
<input type="text" name="name" placeholder="Nume" required>
<input type="email" name="email" placeholder="Email" required>
<button type="submit" name="add">Adaugă</button>
</form>
<h2>Lista utilizatori</h2>
<table>
<tr>
<th>ID</th><th>Nume</th><th>Email</th><th>Acțiuni</th>
</tr>
<?php foreach ($users as $user): ?>
<tr>
<td><?= $user['id'] ?></td>
<td><?= $user['name'] ?></td>
<td><?= $user['email'] ?></td>
<td>
<!-- Formular pentru update -->
<form method="post" style="display:inline;">
<input type="hidden" name="id" value="<?= $user['id'] ?>">
<input type="text" name="name" value="<?= $user['name'] ?>" required>
<input type="email" name="email" value="<?= $user['email'] ?>" required>
<br><br>
<button type="submit" name="update">Actualizează</button>
</form>
<!-- Link pentru delete -->
<br>
<a href="?delete=<?= $user['id'] ?>" onclick="return confirm('Sigur ștergi?')">Șterge</a>
</td>
</tr>
<?php endforeach; ?>
</table>
</body>
</html>
Prepared Statements în PHP (Prevenirea SQL Injection)
O problemă frecventă în aplicațiile web este SQL Injection, adică introducerea intenționată de cod SQL malițios în câmpurile de input pentru a manipula baza de date. Dacă nu validăm și nu securizăm datele trimise de utilizatori, aplicația poate fi compromisă.
Exemplu de query vulnerabil (Așa NU!)
<?php
// Exemplu nesigur (NU faceți așa!)
$name = $_POST['name'];
$sql = "SELECT * FROM users WHERE name = '$name'";
$stmt = $pdo->query($sql); // Vulnerabil la SQL Injection
?>
Dacă un utilizator introduce valoarea ' OR '1'='1 în câmpul name, query-ul va
deveni:
SELECT * FROM users WHERE name = '' OR '1'='1';
Rezultatul? Toți utilizatorii din baza de date vor fi returnați! ⚠️
Soluția: Prepared Statements
Pentru a preveni atacurile de tip SQL Injection, folosim prepared statements (instrucțiuni pregătite). Acestea separă logica SQL de datele introduse de utilizator. Astfel, valorile sunt tratate ca simple date, nu ca instrucțiuni SQL.
Exemplu corect cu PDO (parametri anonimi)
<?php
// Folosind PDO cu placeholderi ?
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = ?");
$stmt->execute([$_POST['name']]);
$results = $stmt->fetchAll();
foreach ($results as $row) {
echo $row['id'] . " - " . $row['name'] . " - " . $row['email'] . "<br>";
}
?>
Exemplu corect cu PDO (parametri denumiți)
<?php
// Folosind PDO cu placeholderi denumiți
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->bindParam(':email', $_POST['email'], PDO::PARAM_STR);
$stmt->execute();
$results = $stmt->fetchAll();
foreach ($results as $row) {
echo $row['id'] . " - " . $row['name'] . " - " . $row['email'] . "<br>";
}
?>
Observați că acum chiar dacă un utilizator încearcă să introducă text malițios, acesta va fi tratat ca simplă valoare de text și nu va putea altera query-ul SQL.
Exemplu complet CRUD cu Prepared Statements (Tabelul users)
Acum că știm cât de importantă este securitatea, vom implementa toate operațiile CRUD (Create, Read,
Update, Delete) folosind Prepared Statements. Exemplul folosește tabela
users cu câmpurile: id (AUTO_INCREMENT, PRIMARY KEY), name,
email.
Cod PHP + HTML pentru CRUD
<?php
// Conectare la baza de date
$pdo = new PDO("mysql:host=localhost;dbname=traffice-test", "root", "");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// CREATE: Inserare utilizator nou
if (isset($_POST['add'])) {
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (:name, :email)");
$stmt->execute([
':name' => $_POST['name'],
':email' => $_POST['email']
]);
}
// UPDATE: Modificare utilizator
if (isset($_POST['update'])) {
$stmt = $pdo->prepare("UPDATE users SET name = :name, email = :email WHERE id = :id");
$stmt->execute([
':name' => $_POST['name'],
':email' => $_POST['email'],
':id' => $_POST['id']
]);
}
// DELETE: Ștergere utilizator
if (isset($_POST['delete'])) {
$stmt = $pdo->prepare("DELETE FROM users WHERE id = :id");
$stmt->execute([':id' => $_POST['id']]);
}
// READ: Afișare toți utilizatorii
$stmt = $pdo->query("SELECT * FROM users ORDER BY id ASC");
$users = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="ro">
<head>
<meta charset="UTF-8">
<title>CRUD Demo</title>
<style>
table { border-collapse: collapse; width: 50%; margin-top: 20px; }
table, th, td { border: 1px solid black; padding: 8px; text-align: left; }
form { margin-top: 20px; }
</style>
</head>
<body>
<h2>Gestionare utilizatori</h2>
<!-- Formular adăugare utilizator -->
<h3>Adaugă utilizator</h3>
<form method="post">
Nume: <input type="text" name="name" required>
Email: <input type="email" name="email" required>
<button type="submit" name="add">Adaugă</button>
</form>
<!-- Tabel utilizatori -->
<h3>Lista utilizatori</h3>
<table>
<tr><th>ID</th><th>Nume</th><th>Email</th><th>Acțiuni</th></tr>
<?php foreach ($users as $user): ?>
<tr>
<td><?= $user['id'] ?></td>
<td><?= htmlspecialchars($user['name']) ?></td>
<td><?= htmlspecialchars($user['email']) ?></td>
<td>
<!-- Formular UPDATE -->
<form method="post" style="display:inline;">
<input type="hidden" name="id" value="<?= $user['id'] ?>">
Nume: <input type="text" name="name" value="<?= htmlspecialchars($user['name']) ?>" required>
Email: <input type="email" name="email" value="<?= htmlspecialchars($user['email']) ?>" required>
<button type="submit" name="update">Modifică</button>
</form>
<!-- Formular DELETE -->
<form method="post" style="display:inline;">
<input type="hidden" name="id" value="<?= $user['id'] ?>">
<button type="submit" name="delete" onclick="return confirm('Ștergi utilizatorul?')">Șterge</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</table>
</body>
</html>
<?php
// Conectare la baza de date
$pdo = new PDO("mysql:host=localhost;dbname=traffice-test", "traffice_php", "!@y3Ge-Z!WQI");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// CREATE: Inserare utilizator nou
if (isset($_POST['add'])) {
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (:name, :email)");
$stmt->execute([
':name' => $_POST['name'],
':email' => $_POST['email']
]);
}
// UPDATE: Modificare utilizator
if (isset($_POST['update'])) {
$stmt = $pdo->prepare("UPDATE users SET name = :name, email = :email WHERE id = :id");
$stmt->execute([
':name' => $_POST['name'],
':email' => $_POST['email'],
':id' => $_POST['id']
]);
}
// DELETE: Ștergere utilizator
if (isset($_POST['delete'])) {
$stmt = $pdo->prepare("DELETE FROM users WHERE id = :id");
$stmt->execute([':id' => $_POST['id']]);
}
// READ: Afișare toți utilizatorii
$stmt = $pdo->query("SELECT * FROM users ORDER BY id ASC");
$users = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="ro">
<head>
<meta charset="UTF-8">
<title>CRUD Demo</title>
<style>
table { border-collapse: collapse; width: 50%; margin-top: 20px; }
table, th, td { border: 1px solid black; padding: 8px; text-align: left; }
form { margin-top: 20px; }
</style>
</head>
<body>
<h2>Gestionare utilizatori</h2>
<!-- Formular adăugare utilizator -->
<h3>Adaugă utilizator</h3>
<form method="post">
Nume: <input type="text" name="name" required>
Email: <input type="email" name="email" required>
<button type="submit" name="add">Adaugă</button>
</form>
<!-- Tabel utilizatori -->
<h3>Lista utilizatori</h3>
<table>
<tr><th>ID</th><th>Nume</th><th>Email</th><th>Acțiuni</th></tr>
<?php foreach ($users as $user): ?>
<tr>
<td><?= $user['id'] ?></td>
<td><?= htmlspecialchars($user['name']) ?></td>
<td><?= htmlspecialchars($user['email']) ?></td>
<td>
<!-- Formular UPDATE -->
<form method="post" style="display:inline;">
<input type="hidden" name="id" value="<?= $user['id'] ?>">
Nume: <input type="text" name="name" value="<?= htmlspecialchars($user['name']) ?>" required>
Email: <input type="email" name="email" value="<?= htmlspecialchars($user['email']) ?>" required>
<button type="submit" name="update">Modifică</button>
</form>
<!-- Formular DELETE -->
<form method="post" style="display:inline;">
<input type="hidden" name="id" value="<?= $user['id'] ?>">
<button type="submit" name="delete" onclick="return confirm('Ștergi utilizatorul?')">Șterge</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</table>
</body>
</html>
Relații între tabele (Users - Posts)
Într-o aplicație reală, tabelele din baza de date nu există izolat. De cele mai multe ori, ele sunt legate între ele prin chei primare și chei externe (primary key & foreign key). De exemplu, într-o aplicație de tip blog, avem:
users- stochează informațiile despre utilizatori (id, nume, email);posts- stochează articolele sau mesajele publicate de utilizatori.
Legătura dintre cele două tabele este de tip 1 la N (un utilizator poate avea mai multe
postări). Această legătură se face printr-o coloană user_id în tabela posts, care face
referire la id din tabela users.
Crearea tabelei posts
Putem crea tabela fie din phpMyAdmin cu SQL simplu, fie direct printr-un script PHP. În phpMyAdmin rulăm codul de mai jos:
CREATE TABLE posts (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(100) NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
Sau rulează dintr-un fișier php:
<?php
try {
$pdo = new PDO("mysql:host=localhost;dbname=traffice-test", "root", "");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "CREATE TABLE IF NOT EXISTS posts (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(100) NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)";
$pdo->exec($sql);
echo "✅ Tabela 'posts' a fost creată.";
} catch (PDOException $e) {
echo "❌ Eroare: " . $e->getMessage();
}
?>
Inserarea unor date de test
În phpMyAdmin rulăm codul de mai jos:
Inserăm mai întâi utilizatorii în tabela users:
INSERT INTO users (name, email) VALUES
('Ion Popescu', 'ion.popescu@example.com'),
('Maria Ionescu', 'maria.ionescu@example.com');
Abia apoi inserăm postările legate de acei useri:
INSERT INTO posts (user_id, title, content) VALUES
(1, 'Primul articol', 'Acesta este primul post scris de utilizatorul 1.'),
(1, 'Al doilea articol', 'Utilizatorul 1 mai are o postare.'),
(2, 'Salutare!', 'Mesaj scris de utilizatorul 2.');
Afișarea postărilor împreună cu utilizatorii
Putem folosi un JOIN pentru a obține într-un singur query atât datele despre utilizator, cât și
postările lui.
<?php
try {
$pdo = new PDO("mysql:host=localhost;dbname=traffice-test", "root", "");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT posts.id, posts.title, posts.content, posts.created_at, users.name, users.email
FROM posts
INNER JOIN users ON posts.user_id = users.id
ORDER BY posts.created_at DESC";
$stmt = $pdo->query($sql);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "<h4>" . htmlspecialchars($row['title']) . "</h4>";
echo "<p>" . htmlspecialchars($row['content']) . "</p>";
echo "<small>Scris de: " . htmlspecialchars($row['name']) . " (" . htmlspecialchars($row['email']) . ") la " . $row['created_at'] . "</small><hr>";
}
} catch (PDOException $e) {
echo "Eroare: " . $e->getMessage();
}
?>
<?php
try {
$pdo = new PDO("mysql:host=localhost;dbname=traffice-test", "traffice_php", "!@y3Ge-Z!WQI");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT posts.id, posts.title, posts.content, posts.created_at, users.name, users.email
FROM posts
INNER JOIN users ON posts.user_id = users.id
ORDER BY posts.created_at DESC";
$stmt = $pdo->query($sql);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "<h4>" . htmlspecialchars($row['title']) . "</h4>";
echo "<p>" . htmlspecialchars($row['content']) . "<p>";
echo "<small>Scris de: " . htmlspecialchars($row['name']) . " (" . htmlspecialchars($row['email']) . ") la " . $row['created_at'] . "</small><hr>";
}
} catch (PDOException $e) {
echo "Eroare: " . $e->getMessage();
}
?>
Demo live: Users & Posts
Acest exemplu arată cum putem adăuga utilizatori și postări și cum le afișăm împreună.
<?php
// Conectare la baza de date
$pdo = new PDO("mysql:host=localhost;dbname=traffice-test", "root", "");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Adăugare utilizator
if(isset($_POST['add_user'])) {
$name = $_POST['name'];
$email = $_POST['email'];
if($name && $email) {
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->execute([$name, $email]);
echo "<p style='color:green;'>✅ Utilizator adăugat!</p>";
}
}
// Ștergere utilizator
if(isset($_GET['delete_user'])) {
$id = (int)$_GET['delete_user'];
$stmt = $pdo->prepare("DELETE FROM users WHERE id=?");
$stmt->execute([$id]);
echo "<p style='color:red;'>🗑️ Utilizator șters!</p>";
}
// Adăugare postare
if(isset($_POST['add_post'])) {
$user_id = $_POST['user_id'];
$title = $_POST['title'];
$content = $_POST['content'];
if($user_id && $title && $content) {
$stmt = $pdo->prepare("INSERT INTO posts (user_id, title, content) VALUES (?, ?, ?)");
$stmt->execute([$user_id, $title, $content]);
echo "<p style='color:green;'>✅ Postare adăugată!</p>";
}
}
// Ștergere postare
if(isset($_GET['delete_post'])) {
$id = (int)$_GET['delete_post'];
$stmt = $pdo->prepare("DELETE FROM posts WHERE id=?");
$stmt->execute([$id]);
echo "<p style='color:red;'>🗑️ Postare ștearsă!</p>";
}
// Preluare utilizatori pentru formular
$users = $pdo->query("SELECT id, name FROM users")->fetchAll(PDO::FETCH_ASSOC);
?>
<h3 class="subtitle">Adaugă utilizator nou</h3>
<form method="post">
Nume: <input type="text" name="name" required>
Email: <input type="email" name="email" required>
<button type="submit" name="add_user">Adaugă utilizator</button>
</form>
<h3 class="subtitle">Adaugă postare nouă</h3>
<form method="post">
Utilizator:
<select name="user_id" required>
<?php foreach($users as $u) { ?>
<option value="<?= $u['id'] ?>"><?= htmlspecialchars($u['name']) ?></option>
<?php } ?>
</select>
Titlu: <input type="text" name="title" required>
Conținut: <textarea name="content" required></textarea>
<button type="submit" name="add_post">Adaugă postare</button>
</form>
<h3 class="subtitle">Lista utilizatorilor</h3>
<table>
<tr><th>ID</th><th>Nume</th><th>Email</th><th>Acțiuni</th></tr>
<?php
$stmt = $pdo->query("SELECT id, name, email FROM users");
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "<tr><td>".$row['id']."</td><td>".htmlspecialchars($row['name'])."</td><td>".htmlspecialchars($row['email'])."</td><td><a href='?delete_user=".$row['id']."' onclick='return confirm(\"Sigur vrei să ștergi?\")'>Șterge</a></td></tr>";
}
?>
</table>
<h3 class="subtitle">Postările utilizatorilor</h3>
<?php
$sql = "SELECT posts.id, posts.title, posts.content, users.name, users.email, posts.created_at
FROM posts
INNER JOIN users ON posts.user_id = users.id
ORDER BY posts.created_at DESC";
$stmt = $pdo->query($sql);
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "<h4>".htmlspecialchars($row['title'])."</h4>";
echo "<p>".htmlspecialchars($row['content'])."</p>";
echo "<small>Scris de: ".htmlspecialchars($row['name'])." (".htmlspecialchars($row['email']).") la ".$row['created_at']."</small>";
echo " <a href='?delete_post=".$row['id']."' onclick='return confirm(\"Sigur vrei să ștergi?\")'>🗑️ Șterge</a><hr>";
}
?>
<?php
// Conectare la baza de date
$pdo = new PDO("mysql:host=localhost;dbname=traffice-test", "traffice_php", "!@y3Ge-Z!WQI");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Adăugare utilizator
if(isset($_POST['add_user'])) {
$name = $_POST['name'];
$email = $_POST['email'];
if($name && $email) {
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->execute([$name, $email]);
echo "<p style='color:green;'>✅ Utilizator adăugat!<p>";
}
}
// Ștergere utilizator
if(isset($_GET['delete_user'])) {
$id = (int)$_GET['delete_user'];
$stmt = $pdo->prepare("DELETE FROM users WHERE id=?");
$stmt->execute([$id]);
echo "<p style='color:red;'>🗑️ Utilizator șters!<p>";
}
// Adăugare postare
if(isset($_POST['add_post'])) {
$user_id = $_POST['user_id'];
$title = $_POST['title'];
$content = $_POST['content'];
if($user_id && $title && $content) {
$stmt = $pdo->prepare("INSERT INTO posts (user_id, title, content) VALUES (?, ?, ?)");
$stmt->execute([$user_id, $title, $content]);
echo "<p style='color:green;'>✅ Postare adăugată!<p>";
}
}
// Ștergere postare
if(isset($_GET['delete_post'])) {
$id = (int)$_GET['delete_post'];
$stmt = $pdo->prepare("DELETE FROM posts WHERE id=?");
$stmt->execute([$id]);
echo "<p style='color:red;'>🗑️ Postare ștearsă!<p>";
}
// Preluare utilizatori pentru formular
$users = $pdo->query("SELECT id, name FROM users")->fetchAll(PDO::FETCH_ASSOC);
?>
<h3 class="subtitle">Adaugă utilizator nou</h3>
<form method="post">
Nume: <input type="text" name="name" required>
Email: <input type="email" name="email" required>
<button type="submit" name="add_user">Adaugă utilizator</button>
</form>
<h3 class="subtitle">Adaugă postare nouă</h3>
<form method="post">
Utilizator:
<select name="user_id" required>
<?php foreach($users as $u) { ?>
<option value="<?= $u['id'] ?>"><?= htmlspecialchars($u['name']) ?></option>
<?php } ?>
</select>
Titlu: <input type="text" name="title" required>
Conținut: <textarea name="content" required></textarea>
<button type="submit" name="add_post">Adaugă postare</button>
</form>
<h3 class="subtitle">Lista utilizatorilor</h3>
<table>
<tr><th>ID</th><th>Nume</th><th>Email</th><th>Acțiuni</th></tr>
<?php
$stmt = $pdo->query("SELECT id, name, email FROM users");
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "<tr><td>".$row['id']."</td><td>".htmlspecialchars($row['name'])."</td><td>".htmlspecialchars($row['email'])."</td><td><a href='?delete_user=".$row['id']."' onclick='return confirm(\"Sigur vrei să ștergi?\")'>Șterge</a></td></tr>";
}
?>
</table>
<h3 class="subtitle">Postările utilizatorilor</h3>
<?php
$sql = "SELECT posts.id, posts.title, posts.content, users.name, users.email, posts.created_at
FROM posts
INNER JOIN users ON posts.user_id = users.id
ORDER BY posts.created_at DESC";
$stmt = $pdo->query($sql);
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "<h4>".htmlspecialchars($row['title'])."</h4>";
echo "<p>".htmlspecialchars($row['content'])."<p>";
echo "<small>Scris de: ".htmlspecialchars($row['name'])." (".htmlspecialchars($row['email']).") la ".$row['created_at']."</small>";
echo " <a href='?delete_post=".$row['id']."' onclick='return confirm(\"Sigur vrei să ștergi?\")'>🗑️ Șterge</a><hr>";
}
?>
<style>
form { margin-bottom: 1rem; padding: 0.5rem; border: 1px solid #ccc; border-radius: 5px; }
input, select, textarea { margin: 0.25rem 0; padding: 0.25rem; width: 100%; }
button { margin-top: 0.25rem; padding: 0.5rem 1rem; cursor: pointer; }
table { border-collapse: collapse; margin-top: 1rem; width: 100%; }
th, td { border: 1px solid #ccc; padding: 0.5rem; text-align: left; }
h3.subtitle { margin-top: 1.5rem; }
</style>
🧠 Quiz - PHP & MySQL: Baze de date