I och med PHP version 7 slutar de klassiska mysql-funktionerna i PHP att fungera varvid man hänvisas till MySQLi eller PDO för att hantera sina databas-anslutningar. Båda dessa innehåller en hel del förbättringar (i:et i MySQLi står för ”improved”). Ökad säkerhet är en viktig aspekt och åstadkoms bland annat med ”prepared statements”.
Hämta data från databasen
Att ansluta till databasen är så enkelt. Lägg in de korrekta uppgifterna för din databas och du är nu ansluten. Här passar vi även på att ställa in teckenkodningen vilket kan vara bra om man vill att till exempel åäö ska fungera som det ska.
$mysqli = new mysqli( "server", "användarnamn", "lösenord", "databasnamn" ); $mysqli->set_charset("utf8");
Istället för att bara köra frågan direkt skapar vi istället ett ”prepared statement”. Det är därefter detta statement vi kör.
$query = "SELECT `id`, `name`, `age` FROM `friends`;"; $stmt = $mysqli->prepare($query); $stmt->execute();
Vi kan hämta resultatet från databasen på flera olika sätt. Ett sätt är att använda funktionen ”get_result” som nedan. Från denna funktion får man array:er i vilka man enkelt hittar sitt resultat.
$result = $stmt->get_result(); while ($row = $result->fetch_assoc()) { var_dump($row); }
array(3) { ["id"]=> int(1) ["name"]=> string(14) "Anna Andersson" ["age"]=> int(42) } array(3) { ["id"]=> int(2) ["name"]=> string(16) "Bosse Bertilsson" ["age"]=> int(25) }
Att frigöra resultatet och stänga objekten efter sig är något man bör ha för vana att göra. På så sätt frigör man minne och databasanslutningar.
$result->free(); $stmt->close(); $mysqli->close();
Lägg till en post i databasen
När man använder prepared statements så lägger man aldrig in variabler direkt i SQL-frågan, istället anger man frågetecken som platshållare där variablerna senare ska infogas. Styrkorna med prepared statements – att samma fråga kan köras om och om igen, samt att SQL-injektioner automatiskt hindras – baseras på detta.
$mysqli = new mysqli( "server", "användarnamn", "lösenord", "databasnamn" ); $mysqli->set_charset("utf8"); $query = "INSERT INTO `friends` (`name`, `age`) VALUES(?, ?);"; $stmt = $mysqli->prepare($query);
Metoden ”bind_param” binder variabler till de frågetecken vi angav i SQL-frågan. Det första argumentet i metoden anger vilken typ av variablerna är. Resterande argument är de variabler man vill binda. Notera att detta måste anges i samma ordning som frågetecknen i SQL-frågan.
$name = 'Cecilia'; $age = 52; $stmt->bind_param('si', $name, $age); $stmt->execute();
Möjliga datatyper: i = integer d = double s = string b = blob
Innan databasen stängs kan du hämta ut det ID som sattes på posten som du nyss infogade.
$last_inserted_id = $mysqli->insert_id; $stmt->close(); $mysqli->close();
Felhantering
Ovanstående exempel har för enkelhetens skull inga funktioner för att upptäcka fel. Detta exempel visar hur man kan göra för att fånga upp dessa.
$mysqli = new mysqli( "server", "användarnamn", "lösenord", "databasnamn" ); if ($mysqli->connect_errno) { printf( "Failed connecting to the database: %s", $mysqli->connect_error ); return false; } if (!$mysqli->set_charset("utf8")) { printf("Failed setting the charset: %s", $mysqli->error); return false; } $query = "INSERT INTO `friends` (`name`, `age`) VALUES(?, ?);"; $stmt = $mysqli->prepare($query); if (!$stmt) { printf("Failed preparing the statement: %s", $mysqli->error); return false; } $name = 'Cecilia'; $age = 52; if (!$stmt->bind_param('si', $name, $age)) { printf("Failed binding the parameters"); return false; } if (!$stmt->execute()) { printf("Failed executing the statement: %s", $stmt->error); return false; } $stmt->close(); $mysqli->close();
Prepared statements med okänt antal parametrar
I vissa fall vet man inte i förväg hur många parametrar man vill skicka in i sitt statement. Detta kan vara fallet när man till exempel har ”WHERE … IN …” i sin SQL-fråga. Här är ett exempel för hur man kan lösa detta.
$mysqli = new mysqli( "server", "användarnamn", "lösenord", "databasnamn" ); if ($mysqli->connect_errno) { printf( "Failed connecting to the database: %s", $mysqli->connect_error ); return false; } if (!$mysqli->set_charset("utf8")) { printf("Failed setting the charset: %s", $mysqli->error); return false; } $parameters = array( array('i', 18), array('i', 25), array('i', 42), ); $placeholders = implode(',', array_fill(0, count($parameters), '?')); $query = "SELECT `id`, `name`, `age` FROM `friends` WHERE `age` IN ($placeholders);"; $stmt = $mysqli->prepare($query); if (!$stmt) { printf("Failed preparing the statement: %s", $mysqli->error); return false; } $bind_data[] = ""; foreach ($parameters as $key => $value) { $bind_data[0] .= $value[0]; $bind_data[] = &$parameters[$key][1]; } if (count($bind_data) > 1) { $ret = call_user_func_array( array($stmt, 'bind_param'), $bind_data ); if (!$ret) { printf("Failed binding the parameters"); return false; } } if (!$stmt->execute()) { printf("Failed executing the statement: %s", $stmt->error); return false; } $result = $stmt->get_result(); while ($row = $result->fetch_assoc()) { var_dump($row); } $result->free(); $stmt->close(); $mysqli->close();