PHP cURL:编码/解析使用SPARQL的AWS Neptune

问题描述

我是SPARQL的新手,所以这可能是一个愚蠢的问题,但是在插入数据时遇到了麻烦。我正在使用HTTPS REST端点与数据库进行通信。

我有以下三项内容

<urn:data:Gen`000001>
<urn:data:content>
"This is a literal"

urlencode()的原因是,因为我认为它具有正确的URI格式,所以不会给我任何错误

<urn:data:Gen%60000001>
...

但是%字符会引发错误(因为如果我使用-而不是%,则它会起作用。)由于this answer,我尝试反斜杠%字符:

<urn:data:Gen\%60000001>
...

然后我尝试使用URL代替URN:

<https://test.com/data/Gen%60000001>
<https://test.com/data/content>
...

但是它总是给我同样的错误

The requested URL returned error: 400 Bad Request

那么我在做什么错了?我该如何转义%字符(也许还有其他urlencode字符?)还是我应该问,这是正确的做法吗,在提交之前先做一个urlencode()

编辑:

我的PHP代码

$q = 'update=INSERT DATA { '.
        '<https://test.com/data/Gen%60000001> '.
        '<https://test.com/data/content> '.
        '"This is a literal." }';
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$config->db->public->neptune->cluster."/sparql");
curl_setopt($ch,CURLOPT_FAILONERROR,true);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,2); 
curl_setopt($ch,CURLOPT_TIMEOUT,3);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$q);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$server_output = curl_exec($ch);

if (curl_errno($ch)) {
    $error = curl_error($ch);
}

if(!$error)
    echo $server_output;
else
    echo $error;

同样,如果我只是将%更改为-,它将起作用:

query=select * where {?s ?p ?o}
result:
  "s" : {
    "type" : "uri","value" : "https://test.com/data/Gen-60000001"
  },"p" : {
    "type" : "uri","value" : "https://test.com/data/content"
  },"o" : {
    "type" : "literal","value" : "This is a literal."
  }

EDIT2 +解决方案:

正如Kelvin LaWrence指出的那样,这可能是PHP方面的一些解析/编码问题。我删除CURLOPT_FAILONERROR,现在出现了以下错误

using URN:
    {
        "detailedMessage":"Malformed query: Lexical error at line 1,column 28. 
            Encountered: \"`\" (96),after : \"\"","requestId":"***","code":"MalformedQueryException"
    }

using URL:
    {
        "detailedMessage":"Malformed query: Lexical error at line 1,column 32. 
            Encountered: \"/\" (47),after : \"test.com\"","code":"MalformedQueryException"}

使用URN的错误似乎表明Neptune在我对其进行欠编码之前将其作为原始字符接收(或解码)。因此,如果我在发送之前再次对它进行urlencode,则可以正常工作:

$q = 'update=INSERT DATA { '.
        '<https://test.com/data/'.urlencode(urlencode('Gen`60000001')).'> '.
        '<https://test.com/data/content> '.
        '"This is a literal." }';

但是海王星为什么会接收到已解码的消息或为什么会对其进行解码?它是在POST正文中发送的,因此不需要进行解码,对吗?我想念什么?

EDIT3:

我还要提到的另一件事:

$q = 'query=select * where {?s ?p ?o}';

查询工作完美,而带有换行符的同一查询不起作用:

$q = 'query=select * 
        where {
            ?s
            ?p 
            ?o
        }';

它给了我这个错误

{
    "detailedMessage":"Malformed query: Encountered \"\" at line 1,column 9.\n
        Was expecting one of:\n    \"{\" ...\n    \"from\" ...\n    \"where\" ...\n    
        \"with\" ...\n    ","code":"MalformedQueryException"
}

为什么?我可以通过将查询保持为一行来解决此问题,但这不是它应该工作的方式。

解决方法

尝试利用base64_encode / decode。 在php文件之间传输数据对我来说是有效的

文件A: $ string =“sadfkjæ4#%”#¤%“; $ string_for_transfer = base64_encode($ string);

文件B:

$string = $_GET["string"];
$string_data = base64_decode($string);
echo $string_data;

给予:

sadfkjæ4#%"#¤%

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...