Tredun ohjelmistokehittäjien kurssimateriaaleja
Niin sanotut CRUD-operaatiot ovat tietokantafunktioiden perusta eli käytännössä kaikki muut ovat jollakin tavalla variaatioita näistä eli niissä voi olla esimerkiksi hakuehtoja tms.
Hakufunktioita on kaksi eli sellainen, joka hakee kaikki tiedot tietokannasta (tai variaationa hakee kaikki tietyin ehdoin) ja sellainen, joka hakee tietyn id:n perusteella tietoja tietokannasta.
Ensin tämän fuktion pitäisi hakea kaikki pelit tietokannasta:
/**
* Hakee kaikki pelit taulusta test_games
*/
function getAllGames() {
$pdo = connect();
$sql = "SELECT * FROM test_games";
$stm = $pdo->query($sql);
$games = $stm->fetchAll(PDO::FETCH_ASSOC);
return $games;
}
Funktion kutsu palauttaa taulukon, joka sisältää assosiatiivisia taulukoita. Ensin tarvitsemme HTML-pohjan. Jos haluamme luoda verkkosivulle listan kaikista noudetuista pelien nimistä, se onnistuu seuraavalla koodilla, joka lisätään HTML-sivun body-osioon:
<ul>
<?php
$games = getAllGames();
foreach($games as $game) {
echo "<li>" . $game["name"] . "</li>";
}
?>
</ul>
Tämä funktio hakee yhden pelin sen id:n avulla:
/**
* Palauttaa tietyn pelin
*/
function getGameById($id) {
$pdo = connect();
$sql = "SELECT * FROM test_games WHERE gameid=?";
$stm = $pdo->prepare($sql);
$stm->execute([$id]);
$game = $stm->fetch(PDO::FETCH_ASSOC);
return $game;
}
HTML-osiossa voi lukea esimerkiksi:
$one_game = getGameById(4);
echo "<p> Yksi peli: " . $one_game["name"] .", " . $one_game["company"] . "</p>";
Uuden pelin voi lisätä seuraavalla koodilla (huom, täydennä arvot funktion kutsussa):
function insertNewGame($name, $company, $release) {
$pdo = connect();
$sql = "INSERT INTO test_games (`name`, company, `release`) VALUES (?, ?, ?)";
$stm = $pdo->prepare($sql);
$ok = $stm->execute([$name, $company, $release]);
return $ok;
}
Funktion kutsu voi näyttää esimerkiksi seuraavalta:
insertNewGame("World of Warcraft", "Blizzard", 2004);
Peliä voi muokata seuraavalla koodilla:
function updateGame($name, $company, $release, $id) {
$pdo = connect();
$sql = "UPDATE test_games SET `name`=?, company=?, `release`=? WHERE gameid=?";
$stm = $pdo->prepare($sql);
$ok = $stm->execute([$name, $company, $release, $id]);
return $ok;
}
Kutsu voi näyttää seuraavalta:
updateGame("World of Warcraft: Burning Crusade", "Blizzard", 2007, 18);
Ja seuraava koodi poistaa pelin id:n perusteella:
/**
* Poistaa pelin jonka gameid on $id
*/
function deleteGame($id) {
$pdo = connect();
$sql = "DELETE FROM test_games WHERE gameid=?";
$stm = $pdo->prepare($sql);
$ok = $stm->execute([$id]);
return $ok;
}
Poistamisen kutsu näyttää seuraavalta:
deleteGame(18);
Hae kaikki pelit jollakin kriteerillä eli muokkaa SQL-koodiin jokin ehto esimerkiksi companyn mukaan.
Jatka edelliseen tehtävään.
Ylläolevat toimivat sellaisenaan koodin puolella, mutta yleensä ne halutaan toimivan sivustolla, jotta käyttäjät voivat todella lisätä ja poistaa asioita.
Tyypillisintä sivustolla on, että listassa on jokaisen rivin lopussa joko linkki tai nappi, josta rivin voi poistaa. Tässä tapauksessa esimerkkinä on linkki. Eli lisäämme tällaisen rivin koodia jokaiselle riville: "<a href='./index.php?deletedid=" . $game["gameid"] . "'>Remove</a>" . Linkki siis johtaa reitityksellä sivulle ?deletedid=, johon lisätään kyseisen pelin id. Kaikkien pelien näyttäminen näyttää siis seuraavalta:
<?php
$games = getAllGames();
foreach($games as $game) {
echo $game["name"] . " " . $game["company"] . " " . $game["release"]. "<a href='./index.php?deletedid=" . $game["gameid"] . "'>Remove</a>" . "<br>";
}
?>
Lisäksi täytyy seurata, painetaanko jotain linkeistä. Se onnistuu seuraavalla koodilla:
if (isset($_GET["deletedid"])) {
$id = $_GET["deletedid"];
$ok = deleteGame($id);
// ohjataan sivu lataamaan uudestaan
header("Location: ./index.php");
}
Ensin siis tarkistetaan, onko deletedidtä asetettu, jos se on asetettu, haetaan se ja sitten kutsutaan poistofunktiota, jolle id annetaan. Lopuksi ladataan pääsivu uudelleen, jotta muutos myös päivittyy sivulle.
Lisäämistä varten tarvitaan lomake.
Lomake tarvitsee kolme kenttää eli Name, Company ja Year sekä tallennusnapin.
<form>
<label>Name <input type="text" name="name"></label>
<label>Company <input type="text" name="company"></label>
<label>Release year <input type="number" name="year" min=1950 max=2026></label>
<input type="submit" value="Add a new game" name="add">
</form>
Sitten tarkistamme, onko lomake lähetetty. Lisäksi teemme tarkistuksen, että kaikki syöte on toimivaa, mitä varten meillä on erillinen funktio.
// tarkista, onko muuttujat asetettu
if (isset($_GET["name"], $_GET["company"], $_GET["year"])) {
//luo muuttujat ja sanitoi ne
$name = htmlspecialchars($_GET["name"]);
$company = htmlspecialchars($_GET["company"]);
$year = htmlspecialchars($_GET["year"]);
// käytä apufunktiota, joka tarkistaa vielä syötteen tiedot
if (checkInput($name, $company, $year)) {
$ok = insertNewGame($name, $company, $year);
} else {
echo "<p>Failed to insert a new game. Input is not valid.</p>";
}
}
// funktio saa kaikki lomakkeen tiedot ja tarkistaa, täyttävätkö ne ehdot
function checkInput($name, $company, $year) {
$inputIsFine = false;
if (strlen($name >= 2) || strlen($company >= 2) || $year > 1950) {
$inputIsFine = true;
}
// palautetaan totuusarvo
return $inputIsFine;
}
Myös muokkaamista varten tarvitaan lomake, ja se näyttää täsmälleen samanlaiselta kuin lisäämisessä. Kuitenkin muokkaamista varten tarvitaan jälleen linkki, jotta saadaan tietoon id.
Lisätään siis pelien listaan seuraava koodi, jotta saamme siihen linkin:
<?php
$games = getAllGames();
foreach($games as $game) {
echo $game["name"] . " " . $game["company"] . " " . $game["release"]. "<a href='./index.php?deletedid=" . $game["gameid"] . "'>Remove</a>" . " " . "<a href='./edit.php?editedid=" . $game["gameid"] . "'>Muokkaa</a>" . "<br>";
}
?>
Tehdään muokkaamista varten oma sivu nimeltään edit.php. Jos muokkaaminen halutaan tehdä oikein hyvin, ensin sivulla haetaan kyseinen peli id:n avulla ja vanhat arvot laitetaan kenttiin oletusarvoiksi. Lisätään tähän tiedostoon myös getGamebyId() ja updateGame() -funktiot. Lomake voi siis näyttää seuraavalta:
<?php
require "./dbfunctions.php";
$id = $_GET["editedid"];
$game = getGameById($id);
function updateGame($name, $company, $release, $id) {
$pdo = connect();
$sql = "UPDATE test_games SET `name`=?, company=?, `release`=? WHERE gameid=?";
$stm = $pdo->prepare($sql);
$ok = $stm->execute([$name, $company, $release, $id]);
return $ok;
}
function getGameById($id) {
$pdo = connect();
$sql = "SELECT * FROM test_games WHERE gameid=?";
$stm = $pdo->prepare($sql);
$stm->execute([$id]);
$game = $stm->fetch(PDO::FETCH_ASSOC);
return $game;
}
// tarkista, onko muuttujat asetettu
if (isset($_GET["name"], $_GET["company"], $_GET["release"], $_GET["gameid"])) {
//luo muuttujat ja sanitoi ne
echo "Lomake lähetetty";
$name = htmlspecialchars($_GET["name"]);
$company = htmlspecialchars($_GET["company"]);
$release = htmlspecialchars($_GET["release"]);
// käytä apufunktiota, joka tarkistaa vielä syötteen tiedot
if (checkInput($name, $company, $release)) {
$ok = updateGame($name, $company, $release, $_GET["gameid"]);
header("Location: ./index.php");
} else {
echo "<p>Failed to update the game. Input is not valid.</p>";
}
}
// funktio saa kaikki lomakkeen tiedot ja tarkistaa, täyttävätkö ne ehdot
function checkInput($name, $company, $release) {
$inputIsFine = false;
if (strlen($name >= 2) || strlen($company >= 2) || $release > 1950) {
$inputIsFine = true;
}
// palautetaan totuusarvo
return $inputIsFine;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Muokkaa peliä</h1>
<form action="" method="get">
<label for="name">Name</label><br>
<input type="text" name="name" id="" value="<?= $game['name'] ?>"><br>
<label for="company">Company</label><br>
<input type="text" name="company" id="" value="<?= $game['company'] ?>"><br>
<label for="release">Year</label><br>
<input type="number" name="release" id="" value="<?= $game['release'] ?>"><br>
<input type="hidden" name="gameid" value="<?= $game['gameid'] ?>">
<input type="submit" value="Save">
</form>
</body>
</html>
Muutoin voidaan toimia hyvin pitkälle samoin kuin uuden pelin luomisen kanssa, mutta toki epäonnistuessa teksti on eri.
Toteuta esimerkin pohjalta pelien poistaminen, lisääminen ja muokkaaminen.