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 Answers 3
We can use json_encode with JSON_UNESCAPED_SLASHES:
json_encode($response, JSON_UNESCAPED_SLASHES);
-
1hi, yes, I've did it in my code, but still has slashazol.young– azol.young2016年12月27日 09:05:03 +00:00Commented Dec 27, 2016 at 9:05
-
Did you try with
stripslashes()function orjson_encode($str, JSON_UNESCAPED_SLASHES);?Khoa Truong– Khoa Truong2016年12月27日 09:07:17 +00:00Commented Dec 27, 2016 at 9:07 -
Read my updated answer.Khoa Truong– Khoa Truong2016年12月27日 09:35:03 +00:00Commented Dec 27, 2016 at 9:35
-
1Try $this->_response->representJson(json_encode($data));Pratik– Pratik2016年12月27日 10:37:03 +00:00Commented 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– azol.young2016年12月27日 12:10:21 +00:00Commented Dec 27, 2016 at 12:10
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.
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_replaceor 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);
return json_encode($result, JSON_UNESCAPED_SLASHES);?$json_string = stripslashes($result)andreturn json_decode($json_string, true);