14

I'm writing a custom REST API demo; now it can return numbers and strings in my demo, but I want it to return a JSON object like other REST APIs.

In my demo, I call the Magento 2 API (i.e. get customer info: http://localhost/index.php/rest/V1/customers/1) with curl, and it returns a JSON string:

"{\"id\":1,\"group_id\":1,\"default_billing\":\"1\",\"created_at\":\"2016-12-13 14:57:30\",\"updated_at\":\"2016-12-13 15:20:19\",\"created_in\":\"Default Store View\",\"email\":\"75358050@qq.com\",\"firstname\":\"azol\",\"lastname\":\"young\",\"store_id\":1,\"website_id\":1,\"addresses\":[{\"id\":1,\"customer_id\":1,\"region\":{\"region_code\":\"AR\",\"region\":\"Arad\",\"region_id\":279},\"region_id\":279,\"country_id\":\"RO\",\"street\":[\"abc\"],\"telephone\":\"111\",\"postcode\":\"1111\",\"city\":\"def\",\"firstname\":\"azol\",\"lastname\":\"young\",\"default_billing\":true}],\"disable_auto_group_change\":0}"

The response is a JSON string, but all the keys have a slash within. I know I can remove the slash with str_replace, but it's a stupid way. Is there any other way to return a JSON object without slashes within keys?

************ UPDATE 2016.12.27 ************

I pasted my test code here:

   $method = 'GET';
    $url = 'http://localhost/index.php/rest/V1/customers/1';

    $data = [
        'oauth_consumer_key' => $this::consumerKey,
        'oauth_nonce' => md5(uniqid(rand(), true)),
        'oauth_signature_method' => 'HMAC-SHA1',
        'oauth_timestamp' => time(),
        'oauth_token' => $this::accessToken,
        'oauth_version' => '1.0',
    ];

    $data['oauth_signature'] = $this->sign($method, $url, $data, $this::consumerSecret, $this::accessTokenSecret);

    $curl = curl_init();

    curl_setopt_array($curl, [
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_URL => $url,
        CURLOPT_HTTPHEADER => [
            'Authorization: OAuth ' . http_build_query($data, '', ','),
            'Content-Type: application/json'
        ], 
    ]);

    $result = curl_exec($curl);
    curl_close($curl);

    // this code has slash still
    //return stripslashes("hi i\" azol"); 

    // has slashes still
    //return stripcslashes("{\"id\":1,\"group_id\":1,\"default_billing\":\"1\",\"created_at\":\"2016-12-13 14:57:30\",\"updated_at\":\"2016-12-13 15:20:19\",\"created_in\":\"Default Store View\",\"email\":\"75358050@qq.com\",\"firstname\":\"azol\",\"lastname\":\"young\",\"store_id\":1,\"website_id\":1,\"addresses\":[{\"id\":1,\"customer_id\":1,\"region\":{\"region_code\":\"AR\",\"region\":\"Arad\",\"region_id\":279},\"region_id\":279,\"country_id\":\"RO\",\"street\":[\"abc\"],\"telephone\":\"111\",\"postcode\":\"1111\",\"city\":\"def\",\"firstname\":\"azol\",\"lastname\":\"young\",\"default_billing\":true}],\"disable_auto_group_change\":0}");

    // has slashes still
    //return json_encode(json_decode($result), JSON_UNESCAPED_SLASHES);

    // this code will throw and expcetion:
    // Undefined property: *****\*****\Model\Mycustom::$_response
    //return  $this->_response->representJson(json_encode($data));

    return $result;
  • You try with return json_encode($result, JSON_UNESCAPED_SLASHES);? – Khoa TruongDinh Dec 27 '16 at 12:57
  • yes, I 've try it, it will throw a exception, because $result is a string – azol.young Dec 27 '16 at 15:16
  • Try another way: $json_string = stripslashes($result) and return json_decode($json_string, true); – Khoa TruongDinh Dec 27 '16 at 16:00
1

We can use json_encode with JSON_UNESCAPED_SLASHES:

json_encode($response, JSON_UNESCAPED_SLASHES);
  • hi, yes, I've did it in my code, but still has slash – azol.young Dec 27 '16 at 9:05
  • Did you try with stripslashes() function or json_encode($str, JSON_UNESCAPED_SLASHES);? – Khoa TruongDinh Dec 27 '16 at 9:07
  • Read my updated answer. – Khoa TruongDinh Dec 27 '16 at 9:35
  • 1
    Try $this->_response->representJson(json_encode($data)); – Pratik Dec 27 '16 at 10:37
  • Hi Khoa, Thank you! I've try you code"json_encode($response, JSON_UNESCAPED_SLASHES);" and stripslashes("hi i\" azol");, It's still has slash....... – azol.young Dec 27 '16 at 12:10
1

Create ws.php in root directory of magento 2 and paste below code in file:

<?php
    use Magento\Framework\App\Bootstrap;
    require __DIR__ . '/app/bootstrap.php';
    $params = $_SERVER;
    $bootstrap = Bootstrap::create(BP, $params);


    function sign($method, $url, $data, $consumerSecret, $tokenSecret)
    {
        $url = urlEncodeAsZend($url);
        $data = urlEncodeAsZend(http_build_query($data, '', '&'));
        $data = implode('&', [$method, $url, $data]);
        $secret = implode('&', [$consumerSecret, $tokenSecret]);
        return base64_encode(hash_hmac('sha1', $data, $secret, true));
    }

    function urlEncodeAsZend($value)
    {
        $encoded = rawurlencode($value);
        $encoded = str_replace('%7E', '~', $encoded);
        return $encoded;
    }

    // REPLACE WITH YOUR ACTUAL DATA OBTAINED WHILE CREATING NEW INTEGRATION
    $consumerKey = 'YOUR_CONSUMER_KEY';
    $consumerSecret = 'YOUR_CONSUMER_SECRET';
    $accessToken = 'YOUR_ACCESS_TOKEN';
    $accessTokenSecret = 'YOUR_ACCESS_TOKEN_SECRET';

    $method = 'GET';
    $url = 'http://localhost/magento2/rest/V1/customers/1';

//
$data = [
    'oauth_consumer_key' => $consumerKey,
    'oauth_nonce' => md5(uniqid(rand(), true)),
    'oauth_signature_method' => 'HMAC-SHA1',
    'oauth_timestamp' => time(),
    'oauth_token' => $accessToken,
    'oauth_version' => '1.0',
];

$data['oauth_signature'] = sign($method, $url, $data, $consumerSecret, $accessTokenSecret);

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_RETURNTRANSFER => 1,
    CURLOPT_URL => $url,
    CURLOPT_HTTPHEADER => [
        'Authorization: OAuth ' . http_build_query($data, '', ',')
    ]
]);

$result = curl_exec($curl);
curl_close($curl);

echo $result;

$response = \Zend_Json::decode($result);
echo "<pre>";
print_r($response);
echo "</pre>";

After this run this file using link like http://localhost/magento2/ws.php in browser and check output.

1

I tried using the following the script to test whether I get slashes in the same API response:

<?php
// create a new cURL resource
$ch = curl_init();

// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, "http://www.example.test/rest/all/V1/customers/12408");
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer oc34ouc8lvyvxcbn16llx7dfrjygdoh2', 'Accept: application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// grab URL and pass it to the browser
$result = curl_exec($ch);

var_dump($result);

// close cURL resource, and free up system resources
curl_close($ch);

Which produces this response (truncated by the var_dump function of PHP):

$ php -f apitest2.php 
/var/www/html/dfl/htdocs/apitest2.php:14:
string(1120) "{"id":12408,"group_id":13,"default_billing":"544","default_shipping":"544","created_at":"2018-05-24 08:32:59","updated_at":"2018-05-24 08:32:59","created_in":"Default Store View","email":"...

As you can see, no slashes in my response.

So I suggest you have two options:

  • Investigate why your cURL configuration is returning a response with slashes. Perhaps it is something to do with using oauth? It looks like something is taking the raw response from cURL and then trying to do something (like output it) and in the process adding the slashes
  • Persevere with finding a way of removing the slashes using str_replace or similar.

Once you've got your response without slashes, you can use the following one-line to force PHP to convert the string into a JSON object:

$object = json_decode( $output, false, 512, JSON_FORCE_OBJECT);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.