17

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\":\"[email protected]\",\"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\":\"[email protected]\",\"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;
3
  • You try with return json_encode($result, JSON_UNESCAPED_SLASHES);? Dec 27, 2016 at 12:57
  • yes, I 've try it, it will throw a exception, because $result is a string
    – azol.young
    Dec 27, 2016 at 15:16
  • Try another way: $json_string = stripslashes($result) and return json_decode($json_string, true); Dec 27, 2016 at 16:00

3 Answers 3

1

We can use json_encode with JSON_UNESCAPED_SLASHES:

json_encode($response, JSON_UNESCAPED_SLASHES);
8
  • hi, yes, I've did it in my code, but still has slash
    – azol.young
    Dec 27, 2016 at 9:05
  • Did you try with stripslashes() function or json_encode($str, JSON_UNESCAPED_SLASHES);? Dec 27, 2016 at 9:07
  • Read my updated answer. Dec 27, 2016 at 9:35
  • 1
    Try $this->_response->representJson(json_encode($data));
    – Pratik
    Dec 27, 2016 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, 2016 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 and acknowledge that you have read and understand our privacy policy and code of conduct.

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