PHP EasyRDF:无法从构造查询中获取图形
PHP EasyRDF : unable to get graph from construct query
我正在尝试从通过 EasyRdf_Sparql_Client::query
发送的查询中获取 EasyRdf_Graph
对象。
SELECT
and ASK
queries will return an object of type EasyRdfSparqlResult
.
CONSTRUCT
and DESCRIBE
queries will return an object of type EasyRdf_Graph
.
这是我的代码:
<?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;
?>
这是输出,如您所见,它是 EasyRdf_Sparql_Result
:
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 |
也尝试了不同的端点(http://dbpedia.org/sparql and http://localhost:3030/testFuseki) because I saw this issue : https://github.com/njh/easyrdf/issues/226,但都是一样的。
关于安装的信息
随 Composer 安装的 EasyRDF 版本 0.9.1
PHP 版本 7.0.30-0+deb9u1 + Apache/2.4.25 (Debian)
任何线索将不胜感激,提前致谢。
编辑
实际上它适用于我本地安装的 Fuseki。由于 http://data.bnf/fr/sparql and http://dbpedia.org/sparql 都是 Virtuoso 端点,我想知道问题是否仅与 Virtuoso 有关。
感谢 Ted 关于 headers 和更新 EasyRDF 的建议,我在阅读了更多有关 EasyRDF 问题 #226 的信息后找到了 a solution。问题是它需要 re-write php 代码才能使用新的命名空间等。如果有人知道 0.9.1 版本的解决方案,那将非常有帮助!
似乎返回的object类型(EasyRdf_Graph
/EasyRdf_Sparql_Result
)取决于headers的Accept
参数。我试图通过 Firebug 和 re-send 请求修改它(添加 Virtuoso doc 中列出的不同 content-types ),但没有得到任何 EasyRdf_Graph
object 还与 Virtuoso。
正如 Ted 所问,这里是请求 headers 的相关部分(使用上述 php 代码和 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
为了获得端点响应 headers,我添加了这一行:
print_r(get_headers($endpointUrl));
这是对 Fuseki 的响应 headers(给出 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
对于 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。 : 对于 data.bnf.fr,代码是 302(重定向),但似乎没有任何区别,请参阅 dbpedia 响应:
[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
所以这里是 解决方案,使用新的 php 代码和作曲家更新 来获取 EasyRDF dev-master :
1) 编辑 composer.json :
{
"require": {
"easyrdf/easyrdf": "dev-master"
}
}
2) 运行
php composer.phar update
3) 重写 php 代码:
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);
编辑
最后我不确定http请求headers参数"Accept"是否是获得EasyRdf_Graph
object的条件。这里是 headers 用于更新 Easyrdf 代码("dev-master" 版本)的请求和响应。也许 EasyRDF 解析查询和结果来构建一个 EasyRdf_Graph
object。
要求
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
来自 http://data.bnf.fr/sparql/ 的回应(通过 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
EasyRDF 发出并张贴在您的答案中的 HTTP 请求 header 揭示了这个问题(所有这些额外的细节实际上都应该编辑到您的问题中)。
EasyRDF请求header --
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
-- 表示 EasyRDF 同样乐意接收 text/html
或 application/xhtml+xml
,然后会更喜欢 application/xml
,其次是 */*
或 "any media type" .
其实不然! text/html
不是 EasyRDF 想要的,在这种情况下它绝对不是 just-as-good 和 application/xhtml+xml
也不比 application/xml
好。
也就是说,Virtuoso 完全按照 EasyRDF 的要求进行,并提供 text/html
... EasyRDF 毫不奇怪地没有将其视为图形。
从 Fuseki 返回的内容(application/n-quads
,这不是 EasyRDF 请求的任何特定 MIME 类型)
EasyRDF 应该 请求某些 RDF MIME 类型(例如 text/turtle
、application/rdf+xml
、application/trig
、application/n-triples
, application/n-quads
, application/ld+json
, sparql-results+xml
... EasyRDF 实际上并不支持所有这些,所以这个列表不应该简单地放入 Accept:
header). EasyRDF 还应该指出这些(可能具有内部优先顺序)优于任何 non-RDF MIME 类型(包括 EasyRDF 当前请求的所有特定 MIME 类型)或通配符(*/*
)。
这应该是 reported as a bug in EasyRDF. Feel free to tag me (@TallTed on github) 在你的报告中。
我正在尝试从通过 EasyRdf_Sparql_Client::query
发送的查询中获取 EasyRdf_Graph
对象。
SELECT
andASK
queries will return an object of typeEasyRdfSparqlResult
.
CONSTRUCT
andDESCRIBE
queries will return an object of typeEasyRdf_Graph
.
这是我的代码:
<?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;
?>
这是输出,如您所见,它是 EasyRdf_Sparql_Result
:
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 |
也尝试了不同的端点(http://dbpedia.org/sparql and http://localhost:3030/testFuseki) because I saw this issue : https://github.com/njh/easyrdf/issues/226,但都是一样的。
关于安装的信息
随 Composer 安装的 EasyRDF 版本 0.9.1
PHP 版本 7.0.30-0+deb9u1 + Apache/2.4.25 (Debian)
任何线索将不胜感激,提前致谢。
编辑
实际上它适用于我本地安装的 Fuseki。由于 http://data.bnf/fr/sparql and http://dbpedia.org/sparql 都是 Virtuoso 端点,我想知道问题是否仅与 Virtuoso 有关。
感谢 Ted 关于 headers 和更新 EasyRDF 的建议,我在阅读了更多有关 EasyRDF 问题 #226 的信息后找到了 a solution。问题是它需要 re-write php 代码才能使用新的命名空间等。如果有人知道 0.9.1 版本的解决方案,那将非常有帮助!
似乎返回的object类型(EasyRdf_Graph
/EasyRdf_Sparql_Result
)取决于headers的Accept
参数。我试图通过 Firebug 和 re-send 请求修改它(添加 Virtuoso doc 中列出的不同 content-types ),但没有得到任何 EasyRdf_Graph
object 还与 Virtuoso。
正如 Ted 所问,这里是请求 headers 的相关部分(使用上述 php 代码和 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
为了获得端点响应 headers,我添加了这一行:
print_r(get_headers($endpointUrl));
这是对 Fuseki 的响应 headers(给出 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
对于 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。 : 对于 data.bnf.fr,代码是 302(重定向),但似乎没有任何区别,请参阅 dbpedia 响应:
[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
所以这里是 解决方案,使用新的 php 代码和作曲家更新 来获取 EasyRDF dev-master :
1) 编辑 composer.json :
{
"require": {
"easyrdf/easyrdf": "dev-master"
}
}
2) 运行
php composer.phar update
3) 重写 php 代码:
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);
编辑
最后我不确定http请求headers参数"Accept"是否是获得EasyRdf_Graph
object的条件。这里是 headers 用于更新 Easyrdf 代码("dev-master" 版本)的请求和响应。也许 EasyRDF 解析查询和结果来构建一个 EasyRdf_Graph
object。
要求
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
来自 http://data.bnf.fr/sparql/ 的回应(通过
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
EasyRDF 发出并张贴在您的答案中的 HTTP 请求 header 揭示了这个问题(所有这些额外的细节实际上都应该编辑到您的问题中)。
EasyRDF请求header --
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
-- 表示 EasyRDF 同样乐意接收 text/html
或 application/xhtml+xml
,然后会更喜欢 application/xml
,其次是 */*
或 "any media type" .
其实不然! text/html
不是 EasyRDF 想要的,在这种情况下它绝对不是 just-as-good 和 application/xhtml+xml
也不比 application/xml
好。
也就是说,Virtuoso 完全按照 EasyRDF 的要求进行,并提供 text/html
... EasyRDF 毫不奇怪地没有将其视为图形。
从 Fuseki 返回的内容(application/n-quads
,这不是 EasyRDF 请求的任何特定 MIME 类型)
EasyRDF 应该 请求某些 RDF MIME 类型(例如 text/turtle
、application/rdf+xml
、application/trig
、application/n-triples
, application/n-quads
, application/ld+json
, sparql-results+xml
... EasyRDF 实际上并不支持所有这些,所以这个列表不应该简单地放入 Accept:
header). EasyRDF 还应该指出这些(可能具有内部优先顺序)优于任何 non-RDF MIME 类型(包括 EasyRDF 当前请求的所有特定 MIME 类型)或通配符(*/*
)。
这应该是 reported as a bug in EasyRDF. Feel free to tag me (@TallTed on github) 在你的报告中。