PHP cURL : 인코딩 / 파싱 (SPARQL을 사용하는 AWS Neptune)

Sep 16 2020

저는 SPARQL을 처음 사용하므로 어리석은 질문 일 수 있지만 데이터 삽입에 문제가 있습니다. HTTPS REST 엔드 포인트를 사용하여 DB와 통신하고 있습니다.

다음 트리플이 있습니다.

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

어느 나는 urlencode()내가 생각했던대로 적절한 URI 형식을 가지고 있기 때문에, 그것은 나에게 오류를 제공하지 않을 것이다 :

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

그러나 % 문자는 오류를 발생시킵니다 ( -대신 a 를 사용 %하면 작동 하기 때문입니다.) 이 답변 때문에 %문자를 백 슬래시하려고했습니다 .

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

그런 다음 URN 대신 URL을 사용해 보았습니다.

<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\"",
        "requestId":"***",
        "code":"MalformedQueryException"}

URN을 사용하는 오류는 Neptune이 내가 urlencode하기 전에 원래 문자로 수신 (또는 디코딩)한다는 것을 보여줍니다. 따라서 전송하기 전에 한 번 더 urlencode하면 정상적으로 작동합니다.

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

하지만 Neptune이 디코딩 된 데이터를 수신하는 이유 또는 디코딩하는 이유는 무엇입니까? 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    ",
    "requestId":"***",
    "code":"MalformedQueryException"
}

왜? 쿼리를 한 줄로 유지하여이 문제를 해결할 수 있지만 작동 방식은 아닙니다.

답변

osomanden Sep 25 2020 at 16:09

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#%"#¤%