PHP en MySQLeen goed team

SQLite de lichtste database

SQLite, de lichtste database?

Dit stond in het Linux Magazine, ( jaargang 7 - jaar 2006 - nummer 3 )

Een artikel over SQLite met als beschrijving, de lichtste database.
Mijn interesse was gewekt en ik besloot een applicatie te gaan ontwerpen in SQLite.

Na enig ontwerpen had ik het voor elkaar.
Een NAW applicatie.

Informatie over SQLite

Enige hoofdpunten uit bovenstaand artikel zijn:

  • Gebruikt weinig systeem bronnen
  • Zit standaard in PHP 5, met enig bouwwerk ook vanaf PHP 4.3.1
  • Vraagt geen configuratie
  • Kent een beperkt aantal datatypes
    • NULL
    • INTEGER
    • REAL
    • TEXT
    • BLOB
  • SQLite kent geen gebruikersaccounts
  • Kent niet alle MySQL opdrachten, doch slechts een sub set. ( Wel het grootste deel )
  • Bij aanpassingen aan de tabel, wordt de tabel even gesloten


Dit kan voor sommigen voordelen geven en voor anderen nadelen.

Of je het gebruikt, hangt af van je doel.
Voor kleine applicaties is het zeer goed te gebruiken.

Bronnen


Wikipedia (Engels)
Wikipedia (Nederlands)
SQLite Home Page (Engels)

Enige opmerkingen vooraf

Het artikel, naar het kunnen gebruiken van SQLite, richtte zich zowel op Windows als op Linux.
Het volgende artikel is voor mijn gemak onder Windows geschreven.

De standaard PHP installatie onder Linux en Windows ondersteunen SQLite.

Mijn Windows omgeving

Mijn php map is C:/php/
en mijn php extensies map is C:/php/extensions/

Aan het windows pad heb ik C:/php toegevoegd.
Dit om snel aanpassingen te kunnen doen plaatsvinden en alles op 1 plek te houden.

Het aanpassen van het Windows pad

Om het Windows pad aan te passen, diende ik het volgende te doen.

  • Ga naar Start
  • Klik op Configuratiescherm
  • Klik op Prestaties en Onderhoud
  • Klik op Systeem
  • Klik op Geavanceerd
  • Klik op Omgevingsvariabelen
  • Klik op Systeemvariabelen
  • Klik op Path
  • Klik op Bewerken
  • Toevoegen aan het eind ( Laat de rest staan) ;C:/php
  • 2 keer op OK klikken
  • Sluit daarna het venster

 

Het begin

<?php

echo "sqlite versie: ".sqlite_libversion() ;

echo 
"<br /><br />";

echo 
"sqlite&nbsptaal&nbspondersteuning: ".sqlite_libencoding();

?>
 
    info.php



Bovenstaand script geeft bij mij de volgende tekst.

sqlite versie: 2.8.14

sqlite taal ondersteuning: iso8859


Zie je versie nummers niet, kijk dan bijvoorbeeld in de error.log van Apache.
Deze kunnen meer informatie geven.

Het maken van de database

 

<?php

if ( $sqlite_db = sqlite_open( "adres.db", 0666, $sqlite_fouten ) )
    {
        
sqlite_query($sqlite_db"CREATE TABLE adressen (id INTEGER PRIMARY KEY,
                                                          titel TEXT,
                                                          voornaam TEXT,
                                                          tussenvoegsel TEXT,
                                                          achternaam TEXT,
                                                          adres TEXT,
                                                          postcode TEXT,
                                                          woonplaats TEXT,
                                                          telefoon TEXT )"
) ;
    }
 else
    {
        die(
$sqlite_fouten ) ;
    }

?>
 
    begin.php



Begin.php bestaat uit 2 delen.

Het eerste deel checkt of er gebruik gemaakt kan worden van SQLite en handelt daarop volgend naar.
Deel 2 maakt de tabel aan.

Deel 1

Het opvallendste is : sqlite_open ( "adres.db" , 0666 , $sqlite_fouten )

Deze opdracht opent de database met als naam "adres.db"
met als schrijfrechten 0666
en geeft aan de variabele $sqlite_fouten eventuele fouten door.

Bestaat de database niet, probeert SQLite deze alsnog te maken.
Met een lege inhoud dan natuurlijk.
De schrijfrechten komen hier dan ook weer terug.

De naam van de database is willekeurig.
Elke naam wordt geaccepteerd.
Ook zonder een extensie.

Standaard zet SQLite de database op de plaats waar het script wordt uitgevoerd.
Wil je een aparte directorie?
Is geen probleem.

Maak van

"adres.db"

bijvoorbeeld

"./db/adres.db"

en het script maakt dan daar de database.

De fouten afhandelingsroutine:

die( $sqlite_fouten )

treedt in werking als er door één of andere reden de datbase niet geopend kan worden met de vereiste schrijf rechten.
Deze stopt dan het script en geeft de foutmelding weer.
De foutmeldingen van SQLite zijn niet altijd even duidelijk.
Een vergeten haakje of aanhalingsteken kan onbegrijpelijke meldingen geven.
Een voorbeeld


Warning: sqlite_query(): near ")": syntax error in f:\htdocs\sqlite\artikel\voegtoe.php on line 112
Fout in query:
SQL logic error or missing database


Deel 2

Dit deel maakt de tabel.

De query is iets anders dan je van MySQL gewend bent.

Het is allemaal wat simpeler, ook wel logisch als je bedenkt dat er dat er maar een beperkt aantal datatypes zijn.
De CREATE TABLE syntax is self-explaning
( Uiteraard zijn op het Internet diverse bronnen te vinden over dit onderwerp, zie bijvoorbeeld op http://www.sqlite.org/docs.html )

Het vullen van de tabellen

<?php

if ( $sqlite_db = sqlite_open( "adres.db", 0666, $sqlite_fouten ) )
    {

        
sqlite_query($sqlite_db"INSERT INTO adressen (titel, voornaam, tussenvoegsel, achternaam, adres, postcode, woonplaats, telefoon)
                                  VALUES ('Dhr.', 'Jan', '', 'Jansen', 'Laan 1', '1234 AA', 'Assen', '0591 - 123456')"
) ;

    }
    else
    {
        die(
$sqlite_fouten ) ;
    }

?>
 
    vul_tabel.php



Het verschil met het vorige script zit in de INSERT INTO opdracht.
Ook hier wijst de syntax zich van zelf.

Het vullen met meerdere records tegelijk

<?php

if ( $sqlite_db = sqlite_open( "adres.db", 0666, $sqlite_fouten ) )
    {

        
sqlite_query($sqlite_db"INSERT INTO adressen (titel, voornaam, tussenvoegsel, achternaam, adres, postcode, woonplaats, telefoon)
                                  VALUES ('Dhr.', 'Piet', '', 'Pietersen', 'Straat 2', '5678 BB', 'Emmen', '0591 - 3456789')"
) ;

        
sqlite_query($sqlite_db"INSERT INTO adressen (titel,  voornaam, tussenvoegsel, achternaam, adres, postcode, woonplaats, telefoon)
                                  VALUES ('Mw.', 'Jannie', '', 'Jansen', 'Laan 1', '1234 AA', 'Assen', '0591 - 123456')"
) ;

        
sqlite_query($sqlite_db, "INSERT INTO adressen (titel, voornaam, tussenvoegsel, achternaam, adres, postcode, woonplaats, telefoon)
                                  VALUES ('Mw.', 'Jacqueline', 'van het', 'Woud', 'Weg 5', '9876 ZZ', 'Zuidbroek', '0592 - 34 66 77')"
) ;


    }
    else
    {
        die(
$sqlite_fouten ) ;
    }

?>
 
    vul_tabel.02.php



Het lijkt eenvoudig, maar zo werkt het.
Meerdere opdrachten na elkaar kunnen worden ingevoegd.

Het weergeven van records.

<html>
<head><basefont face="Arial"></head>
<body>

<?php


if ( $sqlite_db = sqlite_open( "adres.db", 0666, $sqlite_fouten ) )
    {

// formuleer query string
$query = "SELECT * FROM adressen";

// voer query uit
$resultaat = @sqlite_query($sqlite_db, $query) ;

// als er rijen zijn
if (@sqlite_num_rows($resultaat) > 0) {

    echo
"<table cellpadding=10 border=1>\n";

    
// Maak van elke rij een array
    // geef waarden weer
    
while( $rij = sqlite_fetch_array($resultaat) )
        {
        echo
"<tr>\n";
            echo
"<td>".$rij["id"]."</td>\n";
            echo
"<td>".$rij["titel"]."</td>\n";
            echo
"<td>".$rij["voornaam"]."</td>\n";
            echo
"<td>".$rij["tussenvoegsel"]."</td>\n";
            echo
"<td>".$rij["achternaam"]."</td>\n";
            echo
"<td>".$rij["adres"]."</td>\n";
            echo
"<td>".$rij["postcode"]."</td>\n";
            echo
"<td>".$rij["woonplaats"]."</td>\n";
            echo
"<td>".$rij["telefoon"]."</td>\n";
        echo
"</tr>\n";
        }
        
    echo
"</table>\n";
}


    
// Als er fouten zijn, geef deze weer
    
}
    else
    {
        die(
$sqlite_fouten ) ;
    }

// sluit database file
sqlite_close($sqlite_db);

?>

</body>
</html>
 
    geefweer.php



Allereerst weer de fouten afhandelingsroutine.

Daarna wordt de query gemaakt.
$query = selecteer alles uit de tabel adressen.

Het ampersand teken voor een aantal opdrachten kun je gebruiken om eventuele fout meldingen te onderdrukken.
Op productie servers zeker aan te bevelen, daar een ander niet hoeft te weten waar de scripts staan en hoe deze werken.

Vervolgens wordt de query aangeboden aan SQLite door sqlite_query

Deze kijkt of er resultaten zijn ( lees als er rijen zijn ).

Nu pas wordt de tabel opgebouwd.
Zouden er geen adressen zijn, heb je op deze manier ook geen beeldvervuiling of tabellen welke uit de pas lopen.

De variabele $resultaat wordt naar een array omgezet.
Per rij worden dan de waarden weer gegeven.
In plaats van
$rij["id"]
mag je ook
$rij[0]
schrijven, daar 0 het eerste veld in de tabel is met als naam id.

Een nieuw adres toevoegen

<?php

if ( !$submit )
    {

    echo
"<html>\n";
    echo
"<head>\n";
    echo
"<title> Voegtoe </title>\n";
    echo
"<basefont face=\"Arial\">\n";
    echo
"</head>\n";
    echo
"<body>\n";

    echo
"<h2>Voeg nieuw persoon toe:</h2>\n";

    echo
"<form method=\"post\" action=\"voegtoe.php\">\n";

    echo
"<table cellspacing=5 cellpadding=5 border=0>\n";
    echo
"<tr>\n";
         echo
"<td>";
        echo
"Aanspreek titel:";
        echo
"</td>\n<td>";
        echo
"<input type=\"text\" name=\"titel\" size=\"45\">";
        echo
"</td>\n";
    echo
"</tr>\n";
      echo
"<tr>\n";
         echo
"<td>";
        echo
"Voornaam:";
        echo
"</td>\n<td>";
        echo
"<input type=\"text\" name=\"voornaam\" size=\"45\">";
        echo
"</td>\n";
    echo
"</tr>\n";
    echo
"<tr>\n";
         echo
"<td>";
        echo
"Tussenvoegsel:";
        echo
"</td>\n<td>";
        echo
"<input type=\"text\" name=\"tussenvoegsel\" size=\"45\">";
        echo
"</td>\n";
    echo
"</tr>\n";
    echo
"<tr>\n";
         echo
"<td>";
        echo
"Achternaam:";
        echo
"</td>\n<td>";
        echo
"<input type=\"text\" name=\"achternaam\" size=\"45\">";
        echo
"</td>\n";
    echo
"</tr>\n";
    echo
"<tr>\n";
         echo
"<td>";
        echo
" Adres: ";
        echo
"</td>\n<td>";
        echo
"<input type=\"text\" name=\"adres\" size=\"45\">";
        echo
"</td>\n";
    echo
"</tr>\n";
    echo
"<tr>\n";
         echo
"<td>";
        echo
" Postcode: ";
        echo
"</td>\n<td>";
        echo
"<input type=\"text\" name=\"postcode\" size=\"45\">";
        echo
"</td>\n";
    echo
"</tr>\n";
    echo
"<tr>\n";
         echo
"<td>";
        echo
" Woonplaats: ";
        echo
"</td>\n<td>";
        echo
"<input type=\"text\" name=\"woonplaats\" size=\"45\">";
        echo
"</td>\n";
    echo
"</tr>\n";
    echo
"<tr>\n";
         echo
"<td>";
        echo
" Telefooon: ";
        echo
"</td>\n<td>";
        echo
"<input type=\"text\" name=\"telefoon\" size=\"45\">";
        echo
"</td>\n";
    echo
"</tr>\n";
    echo
"<tr>\n";
         echo
"<td colspan=2 align=\"center\">";
        echo
"<br /><input type=\"submit\" name=\"submit\" value=\"Bewaar\">\n";
        echo
"</td>\n";
    echo
"</tr>";
    echo
"</table>\n";
    
    echo
"</form>\n";

    echo
"</body>\n";
    echo
"</html>\n";

    
// Voeg gegevens toe
    
}
else
    {


if (
$sqlite_db = sqlite_open( "adres.db", 0666, $sqlite_fouten ) )
    {

    
// achternaam en adres dienen te bestaan
    
if ( $_POST['achternaam'] && $_POST['adres'] )
        {

        
// Maak INSERT query
        
$VoegtoeQuery "INSERT INTO adressen (titel, voornaam, tussenvoegsel, achternaam, adres, postcode, woonplaats, telefoon)
                     VALUES ('"
.sqlite_escape_string($_POST['titel'])."',
                              '"
.sqlite_escape_string($_POST['voornaam'])."',
                              '"
.sqlite_escape_string($_POST['tussenvoegsel'])."',
                              '"
.sqlite_escape_string($_POST['achternaam'])."',
                              '"
.sqlite_escape_string($_POST['adres'])."',
                              '"
.sqlite_escape_string($_POST['postcode'])."',
                              '"
.sqlite_escape_string($_POST['woonplaats'])."',
                              '"
.sqlite_escape_string($_POST['telefoon'])."'
                              )"
;

        
// Voer $VoegtoeQuery uit
        
$VoegtoeResultaat = sqlite_query($sqlite_db, $VoegtoeQuery)
            or die(
"Fout in query:<br /> ".sqlite_error_string(sqlite_last_error($sqlite_db)));

        }
    else
        {
        
// missende gegevens
        
echo "<div align=\"center\">\n<br /><br />";
        echo
"<p><i>Het formulier is niet volledig ingevuld.<br />\nRecord is niet toegevoegd.<br />\n";
        echo
"Achternaam of Adres mist.<br />\n";
        echo
"Klik op Vorige. ( linksboven )</i></p>";
        echo
"</div>\n";
        die() ;
        }


    }
    else
    {
        die(
$sqlite_fouten ) ;
    }

    
// sluit database file
    
sqlite_close($sqlite_db);

    }

?>
 
    voegtoe.php


Het eerste gedeelte is een simpel formulier.
Hij vraagt naar een aantal velden.
De velden achternaam em adres zijn hier verplicht.
De verplichte velden zijn uiteraard aanpasbaar.

Het openen van de database is bekend.

Vervolgens wordt gekeken of er verzonden informatie is.
De velden achternaam en adres dienen niet leeg te zijn.
De volgende zin zorgt daarvoor.

if ( $_POST['achternaam'] && $_POST['adres'] )

Zijn de gegevens niet correct, wordt er gestopt met het script en een fout melding verschijnt.

Zijn ze wel correct, gaat het script door met het toevoegen.

De INSERT query op zich is duidelijk.
De velden worden benoemd en de waarden welke hierbij horen.

Het enige bijzondere is de de functie:

sqlite_escape_string

Deze functie escaped single-quotes en kijkt naar binary-onveilige karakters.
Wel zo veilig dus.

Bij het toevoegen heb ik een speciale constructie gebruikt.

sqlite_error_string(sqlite_last_error($sqlite_db) )

In Nederlands staat er:
Geef de omschrijving in tekst   (   van de fout code van de laatste fout   (   van de actuele verbinding   )   )
Je ziet dus zo altijd de fout melding waar het om gaat.
Haal je fout meldingen routines weg bij de querys, vliegt het script gewoon verder zonder een foutmelding te geven en zonder iets te doen.
Je ziet dan niet, wat er fout gaat.
Als je nog aan het ontwikkelen bent, lijkt het raadzaam deze fout meldingen routines wel te handhaven,
daar je anders niet meer weet waar je de fout ingaat.


De volgende functie:

sqlite_close($sqlite_db)

sluit de actuele verbinding en geeft alle bronnen weer vrij.

Het verwijderen van een record.

<?php

// Maak DELETE query
$VerwijderQuery = "DELETE FROM adressen WHERE id = '".$id."'";

// voer query uit
$resultaat = sqlite_query( $sqlite_db , $VerwijderQuery ) ;

// sluit database file
sqlite_close($sqlite_db);

?>
 
    verwijder.php



Dit lijkt mij duidelijk.
De variable $id wordt doorgegeven door een formulier.
Welke vervolgens een delete query vormt en uitvoert.
De check of alles klopt gebeurd in feite al in voorgaande scripts.

Het aanpassen van een record

 

<?php

if ( !$wijzig )
    {

    echo
"<html>\n";
    echo
"<head>\n";
    echo
"<title> Wijzig </title>\n";
    echo
"<basefont face=\"Arial\">\n";
    echo
"</head>\n";
    echo
"<body>\n";

    echo
"<h2>Wijzig persoon</h2>\n";

if (
$sqlite_db = sqlite_open( "adres.db", 0666, $sqlite_fouten ) )
    {

// formuleer query string
$query = "SELECT * FROM adressen WHERE id = '".$id."' ";


// voer query uit
$resultaat = @sqlite_query( $sqlite_db, $query ) ;

    echo
"<form method=\"post\" action=\"wijzig.php?id=".$id."\">\n";

    echo
"<table cellspacing=1 cellpadding=1 border=0>\n";


    while(
$rij = sqlite_fetch_array($resultaat ) )
        {
    echo
"<tr>\n";
         echo
"<td>";
        echo
"Aanspreek titel:";
        echo
"</td>\n<td>";
        echo
"<input type=\"text\" name=\"titel\" size=\"45\" value=\"".$rij["titel"]."\">";
        echo
"</td>\n";
    echo
"</tr>\n";
      echo
"<tr>\n";
         echo
"<td>";
        echo
"Voornaam:";
        echo
"</td>\n<td>";
        echo
"<input type=\"text\" name=\"voornaam\" size=\"45\" value=\"".$rij["voornaam"]."\">";
        echo
"</td>\n";
    echo
"</tr>\n";
    echo
"<tr>\n";
         echo
"<td>";
        echo
"Tussenvoegsel:";
        echo
"</td>\n<td>";
        echo
"<input type=\"text\" name=\"tussenvoegsel\" size=\"45\" value=\"".$rij["tussenvoegsel"]."\">";
        echo
"</td>\n";
    echo
"</tr>\n";
    echo
"<tr>\n";
         echo
"<td>";
        echo
"Achternaam:";
        echo
"</td>\n<td>";
        echo
"<input type=\"text\" name=\"achternaam\" size=\"45\" value=\"".$rij["achternaam"]."\">";
        echo
"</td>\n";
    echo
"</tr>\n";
    echo
"<tr>\n";
         echo
"<td>";
        echo
" Adres: ";
        echo
"</td>\n<td>";
        echo
"<input type=\"text\" name=\"adres\" size=\"45\" value=\"".$rij["adres"]."\">";
        echo
"</td>\n";
    echo
"</tr>\n";
    echo
"<tr>\n";
         echo
"<td>";
        echo
" Postcode: ";
        echo
"</td>\n<td>";
        echo
"<input type=\"text\" name=\"postcode\" size=\"45\" value=\"".$rij["postcode"]."\">";
        echo
"</td>\n";
    echo
"</tr>\n";
    echo
"<tr>\n";
         echo
"<td>";
        echo
" Woonplaats: ";
        echo
"</td>\n<td>";