SpatiaLite and PHP
shortly telling my first-hand experience
2011 January 25|
Quick intro: I recently posted two short stories telling my experiences about:
So I'll now tell you the same story yet again: this time using the latest PHP 5.3. PHP is widespread: lots of WEB developers use PHP as their main development language. So I'm quite sure that an up-to-data review about this topic surely is welcome for any people interested in both SpatiaLite and WEB-GIS apps. |
Test environment
|
Caveat The most recent PHP 5.3 seems to be absolutely required in order to support SpatiaLite.I've performed some further test on the oldest Debian Lenny, simply to immediately discover that PHP (and sqlite) where so obsolete that using SpatiaLite was completely impossible. I suppose that if you are strongly interested into using SpatiaLite updating to PHP 5.3 is absolutely required before attempting any preliminary test. |
Configuring PHP
I quickly discovered that using the default PHP configuration SpatiaLite cannot be dynamically loaded as an extension to the basic SQLite connector.|
[sqlite3] ;sqlite3.extension_dir = |
|
[sqlite3] sqlite3.extension_dir = /var/www/sqlite3_ext |
|
# /etc/init.d/apache2 restart |
|
# mkdir /var/www/sqlite3_ext # cp /usr/local/lib/libspatialite.so /var/www/sqlite3_ext |
Testing PHP (full success)
SpatialiteSample.php|
<html> <head> <title>Testing SpatiaLite on PHP</title> </head> <body> <h1>testing SpatiaLite on PHP</h1> <?php # connecting some SQLite DB # we'll actually use an IN-MEMORY DB # so to avoid any further complexity; # an IN-MEMORY DB simply is a temp-DB $db = new SQLite3(':memory:'); # loading SpatiaLite as an extension $db->loadExtension('libspatialite.so'); # enabling Spatial Metadata # using v.2.4.0 this automatically initializes SPATIAL_REF_SYS # and GEOMETRY_COLUMNS $db->exec("SELECT InitSpatialMetadata()"); # reporting some version info $rs = $db->query('SELECT sqlite_version()'); while ($row = $rs->fetchArray()) { print "<h3>SQLite version: $row[0]</h3>"; } $rs = $db->query('SELECT spatialite_version()'); while ($row = $rs->fetchArray()) { print "<h3>SpatiaLite version: $row[0]</h3>"; } # creating a POINT table $sql = "CREATE TABLE test_pt ("; $sql .= "id INTEGER NOT NULL PRIMARY KEY,"; $sql .= "name TEXT NOT NULL)"; $db->exec($sql); # creating a POINT Geometry column $sql = "SELECT AddGeometryColumn('test_pt', "; $sql .= "'geom', 4326, 'POINT', 'XY')"; $db->exec($sql); # creating a LINESTRING table $sql = "CREATE TABLE test_ln ("; $sql .= "id INTEGER NOT NULL PRIMARY KEY,"; $sql .= "name TEXT NOT NULL)"; $db->exec($sql); # creating a LINESTRING Geometry column $sql = "SELECT AddGeometryColumn('test_ln', "; $sql .= "'geom', 4326, 'LINESTRING', 'XY')"; $db->exec($sql); # creating a POLYGON table $sql = "CREATE TABLE test_pg ("; $sql .= "id INTEGER NOT NULL PRIMARY KEY,"; $sql .= "name TEXT NOT NULL)"; $db->exec($sql); # creating a POLYGON Geometry column $sql = "SELECT AddGeometryColumn('test_pg', "; $sql .= "'geom', 4326, 'POLYGON', 'XY')"; $db->exec($sql); # inserting some POINTs # please note well: SQLite is ACID and Transactional # so (to get best performance) the whole insert cycle # will be handled as a single TRANSACTION $db->exec("BEGIN"); for ($i = 0; $i < 10000; $i++) { # for POINTs we'll use full text sql statements $sql = "INSERT INTO test_pt (id, name, geom) VALUES ("; $sql .= $i + 1; $sql .= ", 'test POINT #"; $sql .= $i + 1; $sql .= "', GeomFromText('POINT("; $sql .= $i / 1000.0; $sql .= " "; $sql .= $i / 1000.0; $sql .= ")', 4326))"; $db->exec($sql); } $db->exec("COMMIT"); # checking POINTs $sql = "SELECT DISTINCT Count(*), ST_GeometryType(geom), "; $sql .= "ST_Srid(geom) FROM test_pt"; $rs = $db->query($sql); while ($row = $rs->fetchArray()) { # read the result set $msg = "Inserted "; $msg .= $row[0]; $msg .= " entities of type "; $msg .= $row[1]; $msg .= " SRID="; $msg .= $row[2]; print "<h3>$msg</h3>"; } # inserting some LINESTRINGs # this time we'll use a Prepared Statement $sql = "INSERT INTO test_ln (id, name, geom) "; $sql .= "VALUES (?, ?, GeomFromText(?, 4326))"; $stmt = $db->prepare($sql); $db->exec("BEGIN"); for ($i = 0; $i < 10000; $i++) { # setting up values / binding $name = "test LINESTRING #"; $name .= $i + 1; $geom = "LINESTRING("; if (($i%2) == 1) { # odd row: five points $geom .= "-180.0 -90.0, "; $geom .= -10.0 - ($i / 1000.0); $geom .= " "; $geom .= -10.0 - ($i / 1000.0); $geom .= ", "; $geom .= -10.0 - ($i / 1000.0); $geom .= " "; $geom .= 10.0 + ($i / 1000.0); $geom .= ", "; $geom .= 10.0 + ($i / 1000.0); $geom .= " "; $geom .= 10.0 + ($i / 1000.0); $geom .= ", 180.0 90.0"; } else { # even row: two points $geom .= -10.0 - ($i / 1000.0); $geom .= " "; $geom .= -10.0 - ($i / 1000.0); $geom .= ", "; $geom .= 10.0 + ($i / 1000.0); $geom .= " "; $geom .= 10.0 + ($i / 1000.0); } $geom .= ")"; $stmt->reset(); $stmt->clear(); $stmt->bindValue(1, $i+1, SQLITE3_INTEGER); $stmt->bindValue(2, $name, SQLITE3_TEXT); $stmt->bindValue(3, $geom, SQLITE3_TEXT); $stmt->execute(); } $db->exec("COMMIT"); # checking LINESTRINGs $sql = "SELECT DISTINCT Count(*), ST_GeometryType(geom), "; $sql .= "ST_Srid(geom) FROM test_ln"; $rs = $db->query($sql); while ($row = $rs->fetchArray()) { # read the result set $msg = "Inserted "; $msg .= $row[0]; $msg .= " entities of type "; $msg .= $row[1]; $msg .= " SRID="; $msg .= $row[2]; print "<h3>$msg</h3>"; } # insering some POLYGONs # this time too we'll use a Prepared Statement $sql = "INSERT INTO test_pg (id, name, geom) "; $sql .= "VALUES (?, ?, GeomFromText(?, 4326))"; $stmt = $db->prepare($sql); $db->exec("BEGIN"); for ($i = 0; $i < 10000; $i++) { # setting up values / binding $name = "test POLYGON #"; $name .= $i + 1; $geom = "POLYGON(("; $geom .= -10.0 - ($i / 1000.0); $geom .= " "; $geom .= -10.0 - ($i / 1000.0); $geom .= ", "; $geom .= 10.0 + ($i / 1000.0); $geom .= " "; $geom .= -10.0 - ($i / 1000.0); $geom .= ", "; $geom .= 10.0 + ($i / 1000.0); $geom .= " "; $geom .= 10.0 + ($i / 1000.0); $geom .= ", "; $geom .= -10.0 - ($i / 1000.0); $geom .= " "; $geom .= 10.0 + ($i / 1000.0); $geom .= ", "; $geom .= -10.0 - ($i / 1000.0); $geom .= " "; $geom .= -10.0 - ($i / 1000.0); $geom .= "))"; $stmt->reset(); $stmt->clear(); $stmt->bindValue(1, $i+1, SQLITE3_INTEGER); $stmt->bindValue(2, $name, SQLITE3_TEXT); $stmt->bindValue(3, $geom, SQLITE3_TEXT); $stmt->execute(); } $db->exec("COMMIT"); # checking POLYGONs $sql = "SELECT DISTINCT Count(*), ST_GeometryType(geom), "; $sql .= "ST_Srid(geom) FROM test_pg"; $rs = $db->query($sql); while ($row = $rs->fetchArray()) { # read the result set $msg = "Inserted "; $msg .= $row[0]; $msg .= " entities of type "; $msg .= $row[1]; $msg .= " SRID="; $msg .= $row[2]; print "<h3>$msg</h3>"; } # closing the DB connection $db->close(); ?> </body> </html> |
And that's all.
|
Please note: may well be that using other different Linux distros (or Windows) adjusting any pathname as appropriate for your specific platform should be required. |