PHP 101 (part 9): SQLite My Fire! – Part 1

November 30, -0001

Tutorials

Hard Choices
Making New Friends
The Bookworm Turns
Anatomy Class
Different Strokes
Adding to the Collection
PHP 101 (part 9): SQLite My Fire! – Part 2



Hard Choices

If you’ve been paying attention, you now know how to use PHP’s MySQL
API to perform queries and process result sets. You might even have
started thinking about how to re-program your site to run off a MySQL
database. All of this is a Good Thing – it means you’re getting
comfortable with using PHP’s database support to power your
applications – but there’s still a little further to go.

As you saw in Part Eight, enabling
MySQL support in PHP 5.0 is not as simple as
it used to be. Instead of supporting MySQL out of the box, PHP now
requires you to make all kinds of decisions about versions and
libraries before allowing you to hook your scripts up to a MySQL
database. If you’re lazy (and deep down, we both know you are), you
might instead prefer to try a simpler option: the SQLite database engine.

Built-in SQLite support is new to PHP 5.0, and offers users a
lightweight database system that is fast, efficient and gets the
job done. Since it’s enabled by default in PHP 5.0, it provides a
viable alternative to MySQL; you can use it out of the box, without
spending time on version checks and library downloads; just install PHP 5
and start typing. That’s why I’m devoting a whole tutorial to it -
so get out of bed, make yourself some coffee and let’s get started!


Making New Friends

Before getting into the code, let’s make sure that you have a clear
idea of what SQLite is (and isn’t). Unlike MySQL, which operates on a
client-server paradigm, SQLite is a file-based database engine and uses
file I/O (input/output) functions to store and read databases from
files on disk. It’s also much, much smaller than MySQL – the
command-line version of SQLite weighs in at under 200 KB – and
supports most of the SQL commands you’re used to.

This small size shouldn’t deceive you, however – according to
the official SQLite Web site,
SQLite supports databases up to 2 terabytes in size and is actually
faster than MySQL in certain situations. SQLite database files are easily
portable, and SQLite databases created on Windows work fine on *NIX
platforms and vice-versa.

One of SQLite’s more interesting aspects is that it is completely
typeless. Fields in an SQLite database need not be
associated with a specific type, and even if they are, you can still
insert values of different types into them (there is one exception to
this rule, but I’ll get to that later). This is important, because it
means that if you’re concerned about values of the wrong type getting
into your tables, you need to write code to implement type checking in
your application.

Another important difference between MySQL and SQLite lies in their
licensing policies: unlike MySQL, SQLite source code is completely
public-domain, which means that you can use and distribute it however
you choose in both commercial and non-commercial products. Take a look at
http://sqlite.org/copyright.html
for more on this.

In order to use SQLite and PHP together, your PHP build must include
SQLite. This is enabled by default in both the UNIX and Windows versions
of PHP 5. Read more about this at
http://www.php.net/manual/en/ref.sqlite.php.
If you’re a PHP 4.x user, though, don’t lose heart – you can still use SQLite,
by manually downloading and installing php_sqlite.dll from
http://snaps.php.net
(Windows) or the latest tarball from "http://pecl.php.net/package/SQLite" target="_blank">http://pecl.php.net/package/SQLite
(UNIX). You don’t need to download anything else; the SQLite ‘client’ is its own engine.


The Bookworm Turns

As with MySQL, you use regular SQL commands to interact with an
SQLite database. The exact SQL syntax used by SQLite is listed
at http://sqlite.org/lang.html,
but for most operations SQL commands are standard.

Here’s an example, which sets up the table I’ll be using in this
tutorial:


C:\WINDOWS\Desktop\sqlite>sqlite library.db

SQLite version 2.8.15

Enter ".help" for instructions

sqlite> create table books (

   ...> id integer primary key,

   ...> title varchar(255) not null,

   ...> author varchar(255) not null

   ...>);

sqlite> insert into books (title, author) values ('The Lord Of The Rings', 'J.R.R. Tolkien');

sqlite> insert into books (title, author) values ('The Murders In The Rue Morgue', 'Edgar Allen Poe');

sqlite> insert into books (title, author) values ('Three Men In A Boat', 'Jerome K. Jerome');

sqlite> insert into books (title, author) values ('A Study In Scarlet', 'Arthur Conan Doyle');

sqlite> insert into books (title, author) values ('Alice In Wonderland', 'Lewis Carroll');

sqlite> .exit


You can enter these commands either interactively or
non-interactively through the SQLite commandline program,
which is available at "http://sqlite.org/download.html" target="_blank">http://sqlite.org/download.html

as a precompiled binary for Windows and Linux. SQLite 2.* is the
version currently used in both branches of PHP, with SQLite 3.* support
anticipated for PDO and later PHP 5.* releases.

Extract the downloaded files to a directory of your choice, cd into it from
your shell or DOS box and type ‘sqlite’. You should see the SQLite version
information and the line:

Enter ".help" for instructions

Read
http://sqlite.org/sqlite.html
for more information on how to use the commandline program.

Once the data has been imported into the database file
library.db, run a quick SELECT
query to check if everything is working as it should:


sqlite> select * from books;

1|The Lord Of The Rings|J.R.R. Tolkien
2|The Murders In The Rue Morgue|Edgar Allen Poe
3|Three Men In A Boat|Jerome K. Jerome
4|A Study In Scarlet|Arthur Conan Doyle
5|Alice In Wonderland|Lewis Carroll

If you saw the same output as above, you’re good to go!


Anatomy Class

Now, use PHP to communicate with SQLite, generate the same result
set and format it as an HTML page. Here’s the code:


<html>

<head></head>

<body>

<?php

// set path of database file

$db = $_SERVER['DOCUMENT_ROOT']."/../library.db";

// open database file

$handle = sqlite_open($db) or die("Could not open database");

// generate query string

$query = "SELECT * FROM books";

// execute query

$result = sqlite_query($handle, $query) or die("Error in query: ".sqlite_error_string(sqlite_last_error($handle)));

// if rows exist

if (sqlite_num_rows($result) > 0) {

    
// get each row as an array

    // print values

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

    while($row = sqlite_fetch_array($result)) {

        echo
"<tr>";

        echo
"<td>".$row[0]."</td>";

        echo "<td>".$row[1]."</td>";

        echo
"<td>".$row[2]."</td>";

        echo "</tr>";

    }

    echo
"</table>";

}

// all done

// close database file

sqlite_close($handle);

?>

</body>

</html>

If all goes well, you should see something like this:

Anatomy Class

If you remember what you learned in Part Eight,
the PHP script above should be easy to decipher. In case you don’t, here’s a fast rundown:

  1. The ball starts rolling with the sqlite_open() function, which
    accepts the name of the database file as argument and attempts to open
    it. If this database file cannot be found, an empty database file will
    be created with the supplied name (assuming the script has write access
    to the directory).


    <?php

    $db = $_SERVER['DOCUMENT_ROOT']."/../library.db";

    $handle = sqlite_open($db) or die("Could not open database");

    ?>



    The database file library.db needs to be kept somewhere it
    can’t be accessed through the browser by visitors to your site. That
    means that you need to create it outside your public_html, www or
    htdocs directory, in a directory that allows your scripts read/write
    permissions. Web hosting companies generally will offer a space above
    your web-visible directory where you can do this.

    $_SERVER['DOCUMENT_ROOT']."/.." is the directory
    directly above your web-visible directory.

    If successful, the sqlite_open() function returns a handle
    to the file, which is stored in the variable $handle and
    is used for all subsequent communication with the database.

  2. The next step is to create and execute the query, with the
    sqlite_query() function.


    <?php

    $query = "SELECT * FROM books";

    $result = sqlite_query($handle, $query) or die("Error in query: ".sqlite_error_string(sqlite_last_error($handle)));

    ?>



    This function also needs two parameters: the database handle and the
    query string. Depending on whether or not the query was successful, the
    function returns true or false; in the event of a failure, the
    sqlite_error_string() and sqlite_last_error()
    functions can be used to display the error that took place.

  3. If sqlite_query() is successful, the result set returned by the
    query is stored in the variable $result. You can retrieve the records
    in the result set with the sqlite_fetch_array() function, which
    fetches a single row of data as an array called $row. Fields in that
    record are represented as array elements, and can be accessed using
    standard index notation.

    Each time you call sqlite_fetch_array(), the next record in the
    result set is returned. This makes sqlite_fetch_array() very suitable
    for use in a while() loop, in much the same way as
    mysql_fetch_row() was used earlier.


    <?php

    if (sqlite_num_rows($result) > 0) {

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

        while(
    $row = sqlite_fetch_array($result)) {

            echo "<tr>";

            echo
    "<td>".$row[0]."</td>";

            echo "<td>".$row[1]."</td>";

            echo
    "<td>".$row[2]."</td>";

            echo "</tr>";

        }

        echo
    "</table>";

    }

    ?>

    The number of records returned by the query can be retrieved with
    the sqlite_num_rows() function. Or, if what you’re really interested in
    is the number of fields in the result set, use the sqlite_num_fields()
    function instead. Of course, these are only applicable with queries
    that actually return records; it doesn’t really make sense to use them
    with INSERT, UPDATE or DELETE queries.

  4. Once you’re done, it’s a good idea to close the database handle and return
    the used memory to the system, with a call to sqlite_close():


    <?php

    sqlite_close($handle);

    ?>

In PHP 5 you can also use the SQLite API in an object-oriented way,
wherein each of the functions above becomes a method of the
SQLiteDatabase() object. Take a look at this next listing,
which is equivalent to the one above:


<html>

<head></head>

<body>

<?php

// set path of database file

$file = $_SERVER['DOCUMENT_ROOT']."/../library.db";

// create database object

$db = new SQLiteDatabase($file) or die("Could not open database");

// generate query string

$query = "SELECT *  FROM books";

// execute query

// return result object

$result = $db->query($query) or die("Error in query");

// if rows exist

if ($result->numRows() > 0) {

    
// get each row as an array

    // print values

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

    while($row = $result->fetch()) {

        echo
"<tr>";

        echo
"<td>".$row[0]."</td>";

        echo "<td>".$row[1]."</td>";

        echo
"<td>".$row[2]."</td>";

        echo "</tr>";

    }

    echo
"</table>";

}

// all done

// destroy database object

unset($db);

?>

</body>

</html>

Here, the new keyword is used to instantiate an object
of the class SQLiteDatabase() by passing the object
constructor the name of the database file. If the database file does
not already exist, a new database file is created. The resulting object,
stored in $db, then exposes methods and properties to
perform queries. Every query returns an instance of the class

SQLiteResult(), which in turn exposes methods for
fetching and processing records.

If you look closely at the two scripts above, you’ll see the numerous
similarities between the procedural function names and the object method
names. While the correspondence between the two is not perfect, it’s
usually close enough to make it possible to guess the one if you know the other.


Different Strokes

As with the MySQL API, PHP’s SQLite API offers you more than one way to
skin a cat. For example, you can retrieve each row as an object with the
sqlite_fetch_object() method, and access field values
by using the field names as object properties. Here’s an example:


<html>

<head></head>

<body>

<?php

// set path of database file

$db = $_SERVER['DOCUMENT_ROOT']."/../library.db";

// open database file

$handle = sqlite_open($db) or die("Could not open database");

// generate query string

$query = "SELECT * FROM books";

// execute query

$result = sqlite_query($handle, $query) or die("Error in query: ".sqlite_error_string(sqlite_last_error($handle)));

// if rows exist

if (sqlite_num_rows($result) > 0) {

    
// get each row as an object

    // print field values as object properties

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

    while($obj = sqlite_fetch_object($result)) {

        echo
"<tr>";

        echo
"<td>".$obj->id."</td>";

        echo "<td>".$obj->title."</td>";

        echo
"<td>".$obj->author."</td>";

        echo "</tr>";

    }

    echo
"</table>";

}

// all done

// close database file

sqlite_close($handle);

?>

</body>

</html>

Another option is to retrieve the complete result set in one fell
swoop with the sqlite_fetch_all() function. This function
retrieves the complete set of records as an array of arrays; each
element of the outer array represents a record, and is itself
structured as an array whose elements represent fields in that record.

Here’s an example, which might make this clearer:


<html>

<head></head>

<body>

<?php

// set path of database file

$db = $_SERVER['DOCUMENT_ROOT']."/../library.db";

// open database file

$handle = sqlite_open($db) or die("Could not open database");

// generate query string

$query = "SELECT * FROM books";

// execute query

$result = sqlite_query($handle, $query) or die("Error in query: ".sqlite_error_string(sqlite_last_error($handle)));

// get the complete result set as a series of nested arrays

$data = sqlite_fetch_all($result);

// all done

// close database file

sqlite_close($handle);

// check the array to see if it contains at least one record

if (sizeof($data) > 0) {

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

    
// iterate over outer array (rows)

    // print values for each element of inner array (columns)

    
foreach ($data as $row) {

        echo "<tr>";

        echo
"<td>".$row[0]."</td>";

        echo "<td>".$row[1]."</td>";

        echo
"<td>".$row[2]."</td>";

        echo "</tr>";

    }

    echo
"</table>";

}

?>

</body>

</html>

In all the previous examples, the database remained open while the
result set was processed, because records were retrieved one after
another with the sqlite_fetch_array() or
sqlite_fetch_object() functions. The example above is unique
in that the database can be closed before the result set array is processed.
This is because the entire result set is retrieved at once and stored in the
$data array, so there really isn’t any need to leave the database
open while processing it.

If your result set contains only a single field, use the
sqlite_fetch_single()function, which retrieves the value of the first
field of a row. The PHP manual puts it best when it says “this is the
most optimal way to retrieve data when you are only interested in the
values from a single column of data.” Take a look:


<html>

<head></head>

<body>

<?php

// set path of database file

$db = $_SERVER['DOCUMENT_ROOT']."/../library.db";

// open database file

$handle = sqlite_open($db) or die("Could not open database");

// generate query string

// this query returns only a single record with a single field

$query = "SELECT author FROM books WHERE title = 'A Study In Scarlet'";

// execute query

$result = sqlite_query($handle, $query) or die("Error in query: ".sqlite_error_string(sqlite_last_error($handle)));

// if a row exists

if (sqlite_num_rows($result) > 0) {

    
// get the value of the first field of the first row

    
echo sqlite_fetch_single($result);

}

// all done

// close database file

sqlite_close($handle);

?>

</body>

</html>

You can even use the sqlite_fetch_single() function in combination
with a while() loop to iterate over a result set containing many records
but a single field. Notice also my usage of the sqlite_has_more()

function, to check if the next row exists or not.


<html>

<head></head>

<body>

<?php

// set path of database file

$db = $_SERVER['DOCUMENT_ROOT']."/../library.db";

// open database file

$handle = sqlite_open($db) or die("Could not open database");

// generate query string

$query = "SELECT DISTINCT author FROM books";

// execute query

$result = sqlite_query($handle, $query) or die("Error in query: ".sqlite_error_string(sqlite_last_error($handle)));

// if rows exist

if (sqlite_num_rows($result) > 0) {

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

    
// check for more rows

    
while (sqlite_has_more($result)) {

        // get first field from each row

        // print values

        
$row = sqlite_fetch_single($result);

        echo
"<tr>";

        echo
"<td>".$row."</td>";

        echo "</tr>";

    }

    echo
"</table>";

}

// all done

// close database file

sqlite_close($handle);

?>

</body>

</html>

You can, of course, do the same thing using object notation in PHP 5. However,
you need to know that sqlite_has_more() is one function that
really doesn’t translate to its object method name; in an OO script, you
would need to call $result->valid();.

This script is the OO equivalent of the one above:


<html>

<head></head>

<body>

<?php

// set path of database file

$file = $_SERVER['DOCUMENT_ROOT']."/../library.db";

// create database object

$db = new SQLiteDatabase($file) or die("Could not open database");

// generate query string

$query = "SELECT DISTINCT author FROM books";

// execute query

$result = $db->query($query) or die("Error in query");

// if rows exist

if ($result->numRows() > 0) {

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

    
// check for more rows

    
while ($result->valid()) {

        
// get first field from each row

        // print values

        
$row = $result->fetchSingle();

        echo "<tr>";

        echo
"<td>".$row."</td>";    

        echo "</tr>";

    }

    echo
"</table>";

}

// all done

// destroy database object

unset($db);

?>

</body>

</html>

PHP 101 (part 9): SQLite My Fire! – Part 2


Copyright Melonfire, 2004 (http://www.melonfire.com). All rights reserved.

,

10 Responses to “PHP 101 (part 9): SQLite My Fire! – Part 1”

  1. bbnoad Says:

    If you are using sqlite3 and are having trouble getting this tutorial to work, try this:

    Download sqlite3 using the link provided in the tutorial, and put the sqlite3.exe file in a folder called sqlite which you should put in the directory directly above your web-visible directory.

    Create the database as described in the tutorial…
    C:\…\sqlite>sqlite3 library.db
    SQLite version 3.x.x
    Enter ".help" for instructions
    sqlite> create table books (
    …> id integer primary key,
    …> title varchar(255) not null,
    …> author varchar(255) not null
    …>);
    sqlite> insert into books (title, author) values (‘The Lord Of The Rings’, ‘J.R.R. Tolkien’);
    sqlite> insert into books (title, author) values (‘The Murders In The Rue Morgue’, ‘Edgar Allen Poe’);
    sqlite> insert into books (title, author) values (‘Three Men In A Boat’, ‘Jerome K. Jerome’);
    sqlite> insert into books (title, author) values (‘A Study In Scarlet’, ‘Arthur Conan Doyle’);
    sqlite> insert into books (title, author) values (‘Alice In Wonderland’, ‘Lewis Carroll’);
    sqlite> .exit

    You should now have a file called library.db in the sqlite folder.

    Once the database is created, use the following code to display your database as an html page using php…

    <html>
    <head>
    </head>
    <body>
    <?php
    // set path of database file
    $file = "sqlite:".$_SERVER['DOCUMENT_ROOT']."/../sqlite/library.db";

    // create database object
    $db = new PDO($file) or die("Could not open database");

    // generate query string
    $query = "SELECT * FROM books";

    // execute query
    // return result object
    $result = $db->query($query) or die("Error in query");

    echo "<table cellpadding=10 border=1>";
    while($row = $result->fetch()) {
    echo "<tr>";
    echo "<td>".$row[0]."</td>";
    echo "<td>".$row[1]."</td>";
    echo "<td>".$row[2]."</td>";
    echo "</tr>";
    }
    echo "</table>";

    // all done
    // destroy database object
    unset($db);
    ?>
    </body>
    </html>

  2. dazza007 Says:

    A better solution to my comment above is to use the richer DB abstraction interface that can handle calls to SQLite3, and other DB’s.

    Again I did not need to adjust my .ini file for this to work.

    The PDO interface can be found at:
    http://php.net/manual/en/book.pdo.php

    The file then goes like this:

    <?php
    $file="sqlite:filename.db";
    $db = new PDO($file) or die("Could not open database");

    // generate query string
    $query = "SELECT * FROM books";

    // return PDO Statement object
    $result = $db->query($query);

    echo "<table cellpadding=10 border=1>\n";
    foreach($result as $row) {
    echo "<tr>";
    echo "<td>".$row[0]."</td>";
    echo "<td>".$row[1]."</td>";
    echo "<td>".$row[2]."</td>";
    echo "</tr>";
    }
    echo "</table>\n";
    $db=NULL;
    ?>

  3. dazza007 Says:

    Hi I downloaded PHP5 & Sqlite3 using Apache server in Feb2011 and found I could not get this Sqlite tutorial to work, while previous ones had worked fine. It seems alot of people are having this sort of trouble

    After quite a bit of looking around my solution was to use SQLite3 classes in an OO way, and I did not have to alter anything in my default php.ini file

    See http://www.php.net/manual/en/book.sqlite3.php for the class3 manual

    It is useful to set up an error log file, e.g.
    <?php
    "log_errors" , "1");
    ini_set("error_log" , "Errors.log.txt");
    ini_set("display_errors" , "0");
    ?>

    if you are seeing error messages such as function not defined, then this might be the way to go

    For instance, this now works for me:

    <?php
    $file="filename.db";
    $db = new SQLite3($file) or die("Could not open database");

    // generate query string
    $query = "SELECT * FROM books";

    // return SQLite3Result object
    $result = $db->query($query) or die("Error in query ".$db->lastErrorMsg());

    echo "<table cellpadding=10 border=1>\n";
    while($row = $result->fetchArray()) {
    echo "<tr>";
    echo "<td>".$row[0]."</td>";
    echo "<td>".$row[1]."</td>";
    echo "<td>".$row[2]."</td>";
    echo "</tr>";
    }
    echo "</table>\n";
    ?>

  4. se7ensense7en Says:

    I have Apache 2.2.16, PHP 5.3.3 and MySQL 5.1.51 installed on
    Windows 7 Ultimate OS. All are working properly as I can follow
    all of your examples listed in part 8. I tried doing something
    with sqlite but all sqlite_* functions prevented me from running
    scripts. For example:

    <?php
    $dbPath = $_SERVER['DOCUMENT_ROOT'].’/../db.db’;
    echo $dbPath;
    $hDB = sqlite_open($dbPath) or die(‘Cannot open database’);
    sqlite_close($hDB);
    ?>

    The above script will print out $dbPath but omit the rest. From
    the eclipse pdt view, it displays some information like these:

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The website cannot display the page
    HTTP 500
    Most likely causes:
    The website is under maintenance.
    The website has a programming error.

    What you can try:
    Refresh the page.
    Go back to the previous page.
    More information

    This error (HTTP 500 Internal Server Error) means that
    the website you are visiting had a server problem which
    prevented the webpage from displaying.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    I am really not sure about what is happening? Do I have to change
    something in php’s config file?

    Here are parts of my PHP’s configuration file content:

    [sqlite]
    ; http://php.net/sqlite.assoc-case
    ;sqlite.assoc_case = 0

    [sqlite3]
    ;sqlite3.extension_dir =

    [PHP_BZ2]
    extension=php_bz2.dll
    [PHP_CURL]
    extension=php_curl.dll
    [PHP_GD2]
    extension=php_gd2.dll
    [PHP_GETTEXT]
    extension=php_gettext.dll
    [PHP_IMAP]
    extension=php_imap.dll
    [PHP_MBSTRING]
    extension=php_mbstring.dll
    [PHP_MYSQL]
    extension=php_mysql.dll
    [PHP_MYSQLI]
    extension=php_mysqli.dll
    [PHP_OPENSSL]
    extension=php_openssl.dll
    [PHP_PDO_MYSQL]
    extension=php_pdo_mysql.dll
    [PHP_PDO_ODBC]
    extension=php_pdo_odbc.dll
    [PHP_PDO_SQLITE]
    extension=php_pdo_sqlite.dll
    [PHP_PGSQL]
    extension=php_pgsql.dll
    [PHP_SOAP]
    extension=php_soap.dll
    [PHP_SOCKETS]
    extension=php_sockets.dll
    [PHP_SQLITE3]
    extension=php_sqlite3.dll
    [PHP_TIDY]
    extension=php_tidy.dll
    [PHP_XMLRPC]
    extension=php_xmlrpc.dll
    [PHP_EXIF]
    extension=php_exif.dll

  5. kirstenska Says:

    Oops, sorry… further to my issue, result is just a blank page! MySQL is working fine, and all other pages I call from the htdocs folder seem to be good.

  6. kirstenska Says:

    I’m having trouble getting the connection open to the library.db file. I tried to just put it into the document root too (dev environment, so no security issues), to no avail. Am I missing something? Windows Vista/Apache/2.2.15 (Win32) PHP/5.3.2.

    Thanks for any insight!

  7. antagony Says:

    The page linked to in the tutorial for downloading the SQLite command line utility, only has version 3 – which isn’t built in to PHP 5 (at least not in the version I have: 5.2.132.0). When I tried to access it procedurally, it caused an error saying the file was either encrypted or not a database. However, I found that the OOP methods seemed to work fine.

    The SQLite version which works for all the examples above can be downloaded from here:

    http://www.sqlite.org/sqlite-2_8_17.zip

  8. _____anonymous_____ Says:

    I love the tutorials so far, but sqlite_query and such weren’t working. I’m using SQLite 3.xx and PHP 5.xx. To "replace" this chapter I had to learn about PDO, and (below) was a great resource for me.

    http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html#1

  9. _____anonymous_____ Says:

    Did you actually read the tutorial or are you just trying out a new joke?

  10. zarezadeh Says:

    Is there a way to call sqlite functions in PHP 4?