0.6.0 2022-12-08 21:03 UTC


Latest Stable Version Build status Coverage Status License

A SPARQL client library for the rdfInterface ecosystem with the API inspired by the PDO.

  • It can work with any PSR-17 / PSR-18 compliant HTTP libraries.
  • It can work with huge query results.
    The response is parsed in a lazy way as a stream (the next row is parsed only when you try to read it). This assures iterating through results without acumulating them in an array, which has neglectable memory footprint.


  • Obtain the Composer
  • Run composer require sweetrdf/sparql-client
  • Run composer require guzzlehttp/guzzle to install an HTTP client (but you can use any client supporting PSR-18).
  • Run composer require http-interop/http-factory-guzzle to install PSR-17 bindinds for Guzzle (but you can use any PSR-17 implementation)
  • Run composer require sweetrdf/quick-rdf to install RDF terms factory (you can use any terms factory compatible with the rdfInterface).

Automatically generated documentation


It's very incomplete but better than nothing.
RdfInterface documentation is included which provides documentation for terms (objects representing RDF named nodes, literals, etc.).


include 'vendor/autoload.php';
$connection = new \sparqlClient\StandardConnection('https://query.wikidata.org/sparql', new \quickRdf\DataFactory());
$results    = $connection->query('select * where {?a ?b ?c} limit 10');
foreach ($results as $i) {

Parameterized queries

The StandardConnection class provides a PDO-like API for parameterized queries (aka prepared statements). Parameterized queries:

  • Are the right way to assure all named nodes/blank nodes/literals/quads/etc. in the SPARQL query are properly escaped.
  • Protect against SPARQL injections.
  • Don't provide any speedup (in contrary to SQL parameterized queries).
include 'vendor/autoload.php';
$factory    = new \quickRdf\DataFactory();
$connection = new \sparqlClient\StandardConnection('https://query.wikidata.org/sparql', $factory);

// pass parameters using execute()
// the single `?` is a positional parameter while the `:sf` is a named parameter
$query      = $connection->prepare('SELECT * WHERE {?a ? ?c . ?a :sf ?d .} LIMIT 10');
    'sf' => $factory->namedNode('http://schema.org/softwareVersion'),
foreach ($query as $i) {

// bind a (positional) parameter to a variable
$query = $connection->prepare('SELECT * WHERE {?a ? ?c .} LIMIT 2');
$value = $factory->namedNode('http://creativecommons.org/ns#license');
$query->bindParam(0, $value);
foreach ($query as $i) {
$value = $factory->namedNode('http://schema.org/softwareVersion');
foreach ($query as $i) {

There are some differences comparing to the PDO API:

  • Mixing positional and named parameters in one query is allowed (see the example above).
  • Mixing bindParam()/bindValue() and passing (some or all) parameters trough execute() is allowed.
    • The only constraint is that all parameters have to be set.
    • Parameters passed to execute() overwrite ones set with bindParam()/bindValue().
  • As strong typing is used parameter values have to be of type rdfInterface\Term.
    • It makes unnecessary specifying the type in bindParam()/bindvalue().

Advanced usage

  • You may also provide any PSR-18 HTTP client and/or PSR-17 HTTP request factory to the \sparqlClient\StandardConnection constructor. E.g. let's assume your SPARQL endpoint requires authorization and you want to benefit from Guzzle connection allowing to set global request options:
    $connection = new \sparqlClient\StandardConnection(
        new \quickRdf\DataFactory(),
        new \GuzzleHttp\Client(['auth' => ['login', 'pswd']])
  • If your SPARQL endpoint doesn't follow the de facto standard of accepting the SPARQL query as the query request parameter, you may use the \sparqlClient\Connection class which takes PSR-7 requests instead of a query string and allows you to use any specific HTTP request you need.


  • What about integration of INSERT/UPDATE/DELETE queries with the \rdfInterface\Dataset or \rdfInterface\QuadIterator?
    Will be added in the future.