Vetenskap
  Biologi
  Fysik
  Jorden
  Kemi
  Teknik
  Maskiner
  Apparater
  Energi
  Fordon
  Militär
  Uppvärmning
  Datorer
  IT-säkerhet
  Komponenter
  Mac och OS X
  Programmering
  Människan
  Kroppen
  Träning
  Psykologi
  Medicin
  Droger
  Samhälle
  Politik
  Övernaturligt
  Djur
  Ekonomi
  Mat
Allmänna villkor och cookie-policy
Om oss & kontaktinfo
Admin

Hur fungerar egentligen MySQLi och prepared statements i PHP?

Ingen som är intresserad av PHP har väl kunnat undgå att PHP:s mysql-funktioner har varit deprecated sedan PHP 5.5.0, och att det börjar bli dags att använda något av de andra MySQL-API:er som tillhandahålls. Ett bra alternativ är att börja använda den objektorienterade varianten av MySQLi, där i:et står för improved, och givetvis med prepared statements. Prepared statements är för övrigt någonting som verkligen rekommenderas att alla använder! Men, här kommer i alla fall en kort liten guide till objektorienterad MySQLi med prepared statements i PHP (i sin simplaste form)! Jag förutsätter förresten att du som läser det här har hyfsad koll på PHP och MySQL sedan tidigare.

Att ansluta till MySQL

Att ansluta till MySQL är lika enkelt som det alltid har varit, man skapar helt enkelt bara ett mysqli-objekt med hjälp av vilket man sedan kör sina SQL-frågor.

<?php
   // Ansluter till MySQL
   $sqlHost = 'localhost';
   $sqlUsername = 'sqlUsername';
   $sqlPassword = 'xxxxxxxxxx';
   $sqlDatabase = 'sqlDatabase';
   $mysqli = new mysqli($sqlHost, $sqlUsername, $sqlPassword, $sqlDatabase);
?>

Att ställa en fråga till MySQL

När det gäller köra SQL-frågor så blir det några fler rader kod än med den gamla mysql_query()-funktionen, åtminstone om man använder prepared statements. Men vi börjar med ett väldigt simpelt exempel utan några parametrar.

<?php
   // Hämta användarnamnet för användaren med ID = 1
   // Öppnar och förbereder SQL-frågan
   $stmt = $mysqli->prepare("SELECT userName FROM siteUsers WHERE id = 1");
   $stmt->execute(); // Kör frågan
   $stmt->bind_result($userName); // Binder resultatet till en variabel
   $stmt->fetch(); // Hämtar resultatet
   $stmt->close(); // Stänger frågan
   echo $userName; // Innehåller det eftersöka användarnamnet
?>

Frågan ovan med ett prepared statement

Låt säga att vi inte vet vilket vilket ID som skall användas i frågan ovanför, utan att det värdet hämtas från t.ex. data inmatad från en användare, eller från någon annan variabel. Då är det klokt att binda variabeln till en viss datatyp, och genom att göra detta tala om för MySQL att innehållet i den inmatade variabeln bara får vara av just den datatypen - bundna parametrar behöver inte escapeas, det sköter bind_param()!

Möjliga datatyper är:

<?php
   $stmt = $mysqli->prepare("SELECT userName FROM siteUsers WHERE id = ?");
   $stmt->bind_param("i", $userID); // Bestämmer att $userID måste vara en integer
   $stmt->execute();
   $stmt->bind_result($userName);
   $stmt->fetch();
   $stmt->close();
   echo $userName;
?>

Loopa igenom ett result set

Om man kollar på hur man loopar igenom ett result set med de gamla mysql-funktionerna, så var det åtminstone för mig vanligast att skapa en associativ array av varje rad, t.ex. genom while ($row = mysql_fetch_array($res)). Det går att göra med MySQLi också, men vi bygger vidare på de bundna variablerna - och eftersom det är ett result set vi får returnerat, måste vi lagra/buffra resultatet med hjälp av store_result().

<?php
   // Hämtar användarnamn för alla användare med användarnivå över eller lika med ?
   $stmt = $mysqli->prepare("SELECT userName FROM siteUsers WHERE userLevel >= ?");
   $stmt->bind_param("i", $userLevel); // Bestämmer att $userLevel skall vara en integer
   $stmt->execute();
   $stmt->bind_result($userName);
   $stmt->store_result(); // Buffrar resultatet från frågan
   // Loopar igenom individuella resultat
   while ($stmt->fetch()) {
      echo $userName; // Innehåller resultatet från varje rad
   }
   $stmt->close();
?>

Exempel med flera variabler

Vi bygger på föregående SQL-fråga med några fler variabler och ser hur det kan se ut med mixade datatyper (och tabeller). Notera att datatyperna och variablerna i bind_param() måste följa samma ordning som de bundna parametrarna i SQL-frågan.

<?php
   // Hämtar användarnamn och inloggningstid för användare med användarnivå över eller
   // lika med ?, samt som har varit inloggade senast igår
   $stmt = $mysqli->prepare("SELECT u.userName, l.lastLogin 
                               FROM siteUsers u, userLogins l 
                              WHERE u.userLevel >= ? 
                                AND u.id = l.userID 
                                AND l.lastLogin > ?");
   $stmt->bind_param("is", $userLevel, $yesterday);
   $stmt->execute();
   $stmt->bind_result($userName, $lastLogin);
   $stmt->store_result();
   while ($stmt->fetch()) {
      echo $userName.': '.$lastLogin.'<br />';
   }
   $stmt->close();
?>

Andra nyttiga saker att ha koll på

Exemplen ovan illustrerar ett väldigt enkelt enkelt sätt att använda prepared statements med MySQLi, men sedan finns det ju också fler saker som kan vara bra att ha lite koll på vad gäller MySQLi rent generellt, t.ex. num_rows för att ta reda på hur många rader en fråga resulterar i, eller insert_id för att hämta det ID som den senaste INSERT-queryn genererade. Och så klart finns det mycket mer att använda sig av, men det här borde räcka för att komma igång. Läs gärna vidare här!

<?php
   // Exempel på num_rows
   $stmt = $mysqli->prepare("SELECT id, postName FROM blogPosts");
   $stmt->execute();
   $stmt->bind_result($postID, $postName);
   $stmt->store_result();
   // Kollar om det finns några blogginlägg
   if ($stmt->num_rows) {
      echo $stmt->num_rows.' blogginlägg hittades:<br />';
      while ($stmt->fetch()) {
         echo $postID.': '.$postName.'<br />';
      }
   } else {
      echo 'Tyvärr hittades inga blogginlägg. :-/';
   }
   $stmt->close();
   
   // Exempel på insert_id
   $stmt = $mysqli->prepare("INSERT INTO siteUsers SET userName = ?");
   $stmt->bind_param("s", $userName);
   $stmt->execute();
   $userID = $stmt->insert_id; // Lagrar den nya användarens ID i en variabel
   $stmt->close();
   echo $userID; // Skriver ut den nya användarens ID
?>

Skriv en kommentar