Search code examples
sparqlvirtuosofusekieasyrdf

PHP EasyRDF : unable to get graph from construct query


I'm trying to get a EasyRdf_Graph object from a query sent via EasyRdf_Sparql_Client::query.

EasyRDF doc says:

SELECT and ASK queries will return an object of type EasyRdfSparqlResult.

CONSTRUCT and DESCRIBE queries will return an object of type EasyRdf_Graph.

Here is my code :

<?php
require APPPATH .'third_party/vendor/autoload.php';        
$endpointUrl = "http://data.bnf.fr/sparql";        
$dummyConstructQueryString = "construct { ?s ?q ?r } where { ?s ?p ?o . ?o ?q ?r } limit 1";        
$endPoint = new EasyRdf_Sparql_Client($endpointUrl);
$result = $endPoint->query($dummyConstructQueryString);                
var_dump($result);
echo $result;
?>

And here is the output, which is EasyRdf_Sparql_Result as you can see :

object(**EasyRdf_Sparql_Result**)#47 (6) {
  ["type":"EasyRdf_Sparql_Result":private]=>
  string(8) "bindings"
  ["boolean":"EasyRdf_Sparql_Result":private]=>
  NULL
  ["ordered":"EasyRdf_Sparql_Result":private]=>
  NULL
  ["distinct":"EasyRdf_Sparql_Result":private]=>
  NULL
  ["fields":"EasyRdf_Sparql_Result":private]=>
  array(3) {
    [0]=>
    string(1) "s"
    [1]=>
    string(1) "p"
    [2]=>
    string(1) "o"
  }
  ["storage":"ArrayIterator":private]=>
  array(1) {
    [0]=>
    object(stdClass)#48 (3) {
      ["s"]=>
      object(EasyRdf_Resource)#49 (2) {
        ["uri":protected]=>
        string(56) "http://www.w3.org/ns/sparql-service-description#endpoint"
        ["graph":protected]=>
        NULL
      }
      ["p"]=>
      object(EasyRdf_Resource)#50 (2) {
        ["uri":protected]=>
        string(47) "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
        ["graph":protected]=>
        NULL
      }
      ["o"]=>
      object(EasyRdf_Resource)#51 (2) {
        ["uri":protected]=>
        string(42) "http://www.w3.org/2000/01/rdf-schema#Class"
        ["graph":protected]=>
        NULL
      }
    }
  }
}
+-------------+----------+------------+
| ?s          | ?p       | ?o         |
+-------------+----------+------------+
| sd:endpoint | rdf:type | rdfs:Class |

Also tried with different endpoints (http://dbpedia.org/sparql and http://localhost:3030/testFuseki) because I saw this issue : https://github.com/njh/easyrdf/issues/226, but it's the same.

Infos about install

  • EasyRDF version 0.9.1 installed with Composer

  • PHP Version 7.0.30-0+deb9u1 + Apache/2.4.25 (Debian)

Any clue would be appreciated, thanks in advance.


EDIT

Actually it works with my local install of Fuseki. Since http://data.bnf/fr/sparql and http://dbpedia.org/sparql are both Virtuoso endpoints, I wonder if the problem is only with Virtuoso.


Solution

  • Thanks to Ted's suggestion about the headers and updating EasyRDF, I found a solution after reading a bit more about EasyRDF issue #226. The problem is that it requires to re-write php code to use the new namespaces, etc. If anyone knows a solution with 0.9.1 version, it would be very helpful!

    It seems that the returned object type (EasyRdf_Graph / EasyRdf_Sparql_Result) depends on the Accept parameter of the headers. I tried to modify it (added different content-types listed in Virtuoso doc ) via Firebug and re-send the request, but didn't get any EasyRdf_Graph object yet with Virtuoso.


    As Ted asked, here is the relevant part of request headers (with above php code and EasyRDF 0.0.1) :

    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    

    In order to get the endpoint response headers, I added this line :

    print_r(get_headers($endpointUrl));
    

    Here are the response headers for Fuseki (which gives an EasyRdf_Graph object) :

    [0] => HTTP/1.1 200 OK
    [1] => Date: Tue, 11 Sep 2018 06:14:56 GMT
    [2] => Fuseki-Request-ID: 13
    [3] => Vary: Accept,Accept-Encoding,Accept-Charset
    [4] => Content-Type: application/n-quads
    [5] => Vary: User-Agent
    

    And for Virtuoso (http://data.bnf.fr)

    [0] => HTTP/1.1 302 Found
    [1] => Date: Tue, 11 Sep 2018 06:12:29 GMT
    [2] => Server: Apache
    [3] => Location: http://data.bnf.fr/sparql/
    [4] => Content-Length: 210
    [5] => Content-Type: text/html; charset=iso-8859-1
    [6] => Vary: Accept-Encoding,User-Agent
    [7] => Connection: close
    [8] => HTTP/1.1 200 OK
    [9] => Date: Tue, 11 Sep 2018 06:12:29 GMT
    [10] => Server: Apache
    [11] => Last-Modified: Mon, 19 Feb 2018 10:34:21 GMT
    [12] => ETag: "200036-3a99-5658e3ca8a540"
    [13] => Accept-Ranges: bytes
    [14] => Content-Length: 15001
    [15] => Vary: Accept-Encoding,User-Agent
    [16] => Access-Control-Allow-Origin: *
    [17] => Content-Type: text/html
    [18] => Content-Language: fr
    [19] => Connection: close
    

    N.B. : for data.bnf.fr the code is 302 (redirection), but it doesn't seem to make any difference, see dbpedia response :

    [0] => HTTP/1.1 200 OK
    [1] => Date: Tue, 11 Sep 2018 07:17:23 GMT
    [2] => Content-Type: text/html; charset=UTF-8
    [3] => Content-Length: 14172
    [4] => Connection: close
    [5] => Vary: Accept-Encoding
    [6] => Server: Virtuoso/07.20.3229 (Linux) i686-generic-linux-glibc25-64  VDB
    [7] => Expires: Tue, 18 Sep 2018 07:17:23 GMT
    [8] => Cache-Control: max-age=604800
    [9] => Access-Control-Allow-Origin: *
    [10] => Access-Control-Allow-Credentials: true
    [11] => Access-Control-Allow-Methods: GET, POST, OPTIONS
    [12] => Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Accept-Encoding
    [13] => Accept-Ranges: bytes
    

    So here is the solution with new php code and composer update to get EasyRDF dev-master :

    1) Edit composer.json :

    {
        "require": {
            "easyrdf/easyrdf": "dev-master"
        }
    }
    

    2) run

    php composer.phar update
    

    3) rewrite php code :

    require_once './third_party/vendor/autoload.php';
    $endpointUrl = "http://data.bnf.fr/sparql";        
    $dummyConstructQueryString = "construct { ?s ?q ?r } where { ?s ?p ?o . ?o ?q ?r } limit 1";        
    $endPoint = new \EasyRdf\Sparql\Client($endpointUrl); // <-- here use the namespace
    $result = $endPoint->query($dummyConstructQueryString);                
    var_dump($result);
    

    EDIT

    Finally I'm not sure that the http request headers parameter "Accept" is the condition to get an EasyRdf_Graph object. Here are the headers for request and response with updated Easyrdf code ("dev-master" version). Maybe EasyRDF parses the query and the result to build a EasyRdf_Graph object.

    • Request

       Host: localhost
       User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0
       Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
       Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
       Accept-Encoding: gzip, deflate
       DNT: 1
       Connection: keep-alive
       Upgrade-Insecure-Requests: 1
       Cache-Control: max-age=0
      
    • Response from http://data.bnf.fr/sparql/ (obtained with print_r(get_headers($endpointUrl)); )

       [0] => HTTP/1.1 302 Found
       [1] => Date: Wed, 12 Sep 2018 06:21:48 GMT
       [2] => Server: Apache
       [3] => Location: http://data.bnf.fr/sparql/
       [4] => Content-Length: 210
       [5] => Content-Type: text/html; charset=iso-8859-1
       [6] => Vary: Accept-Encoding,User-Agent
       [7] => Connection: close
       [8] => HTTP/1.1 200 OK
       [9] => Date: Wed, 12 Sep 2018 06:21:48 GMT
       [10] => Server: Apache
       [11] => Last-Modified: Mon, 19 Feb 2018 10:34:21 GMT
       [12] => ETag: "200036-3a99-5658e3ca8a540"
       [13] => Accept-Ranges: bytes
       [14] => Content-Length: 15001
       [15] => Vary: Accept-Encoding,User-Agent
       [16] => Access-Control-Allow-Origin: *
       [17] => Content-Type: text/html
       [18] => Content-Language: fr
       [19] => Connection: close