RDF API for PHP

Using the SPARQL Engine

This tutorial is part of the RAP - Rdf API for PHP documentation.


Tobias Gauss <tobias.gauss@web.de>
Chris Bizer <chris@bizer.de>
Christian Weiske <cweiske@cweiske.de>
April 2007


SPARQL is a query language for RDF, which is currently being standardized by the W3C. This part of the RAP documentation describes RAP's SPARQL engine and its usage. For a detailed description of the SPARQL query language please refer to W3C SPARQL working draft. RAP's SPARQL package allows you to execute SPARQL queries against RDF graphs and RDF datasets which may be stored in memory or in a relational database. We have also included SPARQL as additional query language into RAP's NetAPI RDF server, which allows you to query remote RDF repositories using W3C SPARQL protocol.

RAP's SPARQL package requires PHP version 5.1 or higher.

Preparation

Before you can use the RAP's SPARQL classes, you need to include them properly. The best way to do this is adapting the config.php file in RAP's test/ directory: Copy config.php.dist to config.php and edit it as you need. If config.php stays in test/, the directories are already setup properly.

If you want to use RAP's SPARQL Engine on a DbModel (database based Model), you need to change the $GLOBALS['dbConf'] array. RAP uses ADODB internally, so the type configuration applies to ADODB's driver naming scheme.

Creating a model

SPARQL queries are run against a Model, let it be a DbModel or a MemModel.

Creating a MemModel from a file

Loading a memor model from a file is fairly easy:

$employees = ModelFactory::getDefaultModel();
$employees->load(RDFAPI_INCLUDE_DIR . '../doc/Tutorial/employees.rdf');

Creating a DbModel

To get a database model, you first need to get a database instance and aquire the model from it:

$database = ModelFactory::getDbStore(
   $GLOBALS['dbConf']['type'],
   $GLOBALS['dbConf']['host'],
   $GLOBALS['dbConf']['database'],
   $GLOBALS['dbConf']['user'],
   $GLOBALS['dbConf']['password']
);

$strModel = "http://xmlns.com/foaf/0.1/";
$dbModel = $database->getModel($strModel);

if ($dbModel === false) {
   die('Database does not have a model ' . $strModel . "\n");
}

Usage

The usage of the SPARQL engine is very similar to the RDQL engine. A sparql query can be executed against an RDF dataset, a MemModel or DbModel. The necessary parts of the SPARQL package are loaded automatically when needed.

The usage is very simple:

$result = $datasetOrModel->sparqlQuery($querystring);

This line executes the SPARQL query $querystring against the Dataset or Model $datasetOrModel. The query returns an array $result witch contains the matching variable bindings for the SELECT variables. If you want the result to be returned in the SPARQL Query Results XML Format, simply add an additional 'xml' parameter to the function call:

$result = $datasetOrModel->sparqlQuery($querystring,'xml');

Result renderers

While the default array-based result is good enought most times, you may want to get back XML or HTML, or maybe even JSON to forward it to an AJAX client that queried your server. RAP's SPARQL engine uses the concept of "Renderers" to make it easy to obtain the results in the format you need.

A renderer is a class that implements either SparqlEngine_ResultRenderer or SparqlEngineDb_ResultRenderer interface, depending on which type of query results you want to convert. Since Renderers operate directly on raw results (e.g. database rows), they need to be written separately for each SPARQL engine.

SparqlEngineDb ships with three renderers: The default array object renderer, an XML, and an HTML renderer. To use any of them, pass Default, XML or HTML as second parameter to sparqlQuery. If you omit the second parameter, the default renderer is used.

If you wrote your own renderer, pass either its full class name as second parameter to sparqlQuery, or an instance of it.

Example

The initialization for MemModel and DbModel differs a bit, but once you have the model, both SPARQL engines behave the same.

MemModel initialization

require_once 'C:/Apache/htdocs/rdfapi-php/test/config.php';
// Create a new MemModel and load the document
$employees = ModelFactory::getDefaultModel();
$employees->load(RDFAPI_INCLUDE_DIR . '../doc/Tutorial/employees.rdf');

//continue below

DbModel initialization

require_once '/var/www/rap/rdfapi-php/test/config.php';

$database = ModelFactory::getDbStore(
   $GLOBALS['dbConf']['type'],
   $GLOBALS['dbConf']['host'],
   $GLOBALS['dbConf']['database'],
   $GLOBALS['dbConf']['user'],
   $GLOBALS['dbConf']['password']
);

$strModel = "http://xmlns.com/foaf/0.1/";
$dbModel = $database->getModel($strModel);

if ($dbModel === false) {
   die('Database does not have a model ' . $strModel . "\n");
}

Querying data

Once the model has been created, we can perform our first query which will be: "Find the full name of all employees". So, we create a variable $querystring and assign the corresponding query string:

$querystring = '
PREFIX vcard <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?fullName
WHERE { ?x vcard:FN ?fullName }';

To execute the query, we call the method sparqlQuery() on the MemModel and pass the variable holding the query string as parameter:

$result = $employees->sparqlQuery($querystring);

The result of the query is a two dimension array of variable bindings ($result[]['?varname']). The values of these variables are RAP objects (Resource, Literal, or BlankNode) or an empty string if the variable is unbound . The following code loops over the result set and prints out all bindings of the variable ?fullName.

foreach($result as $line){
  $value = $line['?fullName'];
    if($value != "")
      echo $value->toString()."<br/>";
    else
      echo "undbound<br/>";
}

Another, even more convenient way to display the results of a query in a browser is to use the HTML result renderer. All we have to do is to pass 'HTML' as second parameter to sparqlQuery():

echo $employees->sparqlQuery($querystring, 'HTML');

Which will result in the following output in the browser window:

No. ?fullName
1.

Literal: Bill Parker

2.

Literal: George Simpson

3.

Literal: Monica Murphy

If we want the engine to return the query result in SPARQL Query Results XML Format, we have to add 'xml' as second parameter to the function call:

$result2 = $employees->sparqlQuery($querystring, 'xml');

Now the variable $result2 contains a string which represents the results in SPARQL Query Results XML Format:

<?xml version="1.0"?>
<sparql xmlns="http://www.w3.org/2005/sparql-results#">
   <head>
      <variable name="fullName"/>
   </head>
   <results ordered="false" distinct="false">
      <result>
         <binding name="fullName">
            <literal>Bill Parker</literal>
         </binding>
      </result>
      <result>
         <binding name="fullName">
            <literal>George Simpson</literal>
         </binding>
      </result>
      <result>
         <binding name="fullName">
            <literal>Monica Murphy</literal>
         </binding>
      </result>
   </results>
</sparql>

The result of an ASK query is a boolean value, COUNT returns an integer.

The result of a CONSTRUCT query is a MemModel:

$querystring = '
PREFIX vcard <http://www.w3.org/2001/vcard-rdf/3.0#>
PREFIX rdf <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

CONSTRUCT { ?x vcard:FN ?fullName}
WHERE { ?x vcard:FN ?fullName }';

echo $employees->sparqlQuery($querystring, 'HTML');

A DESCRIBE query also returns a MemModel. Which properties are included into the description can be specified in constants.php:

$sparql_describe = array(
  FOAF_NS.'Person' => array(FOAF_NS.'name',FOAF_NS.'homepage',FOAF_NS.'mbox')
);

Meaning that descriptions of instances of foaf:Person will contain the person's name, homepage and mailbox.

For more SPARQL query examples please refer to the W3C SPARQL Working Draft.