I need to grab a json-string from this page: https://retracted.com
If you view the source, I json-string starts after var mycarousel_itemList =. I need to parse this string as a correct json-array in my php-script.
How can this be done?
EDIT: I've managed to pull this off using explode, but the method is ugly as heck. Is there no build-in function to translate this json-string to a array?
To clarify: I want the string I grab (which is correct json) to be converted into a php-array.
The JSON in the script block is invalid and needs to be massaged a bit before it can be used in PHP's native json_decode function. Assuming you have already extracted the JSON string from the markup (make sure you exclude the semicolon at the end):
$json = <<< JSON
[ { address: 'Arnegårdsveien 32', … } ]
JSON;
var_dump(
json_decode(
str_replace(
array(
'address:',
'thumb:',
'description:',
'price:',
'id:',
'size:',
'url:',
'\''
),
array(
'"address":',
'"thumb":',
'"description":',
'"price":',
'"id":',
'"size":',
'"url":',
'"'
),
$json
)
,
true
)
);
This will then give an array of arrays of the JSON data (demo).
In other words, the properties have to be double quoted and the values need to be in double quotes as well. If you want an array of stdClass objects instead for the "{}" parts, remove the true.
You can do this either with str_replace as shown above or with a regular expression:
preg_match('
(.+var mycarousel_itemList = ([\[].+);.+function?)smU',
file_get_contents('http://bolig…'),
$match
);
$json = preg_replace(
array('( ([a-z]+)\:)sm', '((\'))'),
array('"$1":', '"'),
$match[1]
);
var_dump(json_decode($json, true));
The above code will fetch the URL, extract the JSON, fix it and convert to PHP (demo).
Once you have your json data, you can use json_decode (PHP >= 5.2) to convert it into a PHP object or array
Related
I working at PHP Project With PHP Version 7.0.13
I was dealing with JSON lately, I have a JSON file that needs to be decode to PHP but before I decode the JSON, I need to clean some abstract string inside the file that JSON obtained inside, to clean the string using substr() to get the JSON.
when i write the code, like this:
$jsonraw = "\"{ JSON should be here, later }\"";
$cutstart = strpos($jsonraw, "{");
$cutend = strrpos($jsonraw, "\"");
$jsonclean = substr($jsonraw, $cutstart, $cutend);
echo $jsonclean;
The output is like this
{ JSON should be here, later }
But when the string is like this
$jsonraw = "\"some abstract string to remove { JSON should be here, later }\"";
The output is became like this
{ JSON should be here, later }"
As we can see there was a quote symbol " at the last of the string, I was trying to decrement the $cutend, like this $jsonclean = substr($jsonraw, $cutstart, --$cutend); and this to $cutend-1
Any help, I appreciate.
Sorry for my bad English
You can use preg_match to get the json from that string:
$string = "some abstract string to remove { JSON should be here, later }";
preg_match('/\{.*\}/', $string, $match);
var_dump($match[0]);
the result would be:
string(30) "{ JSON should be here, later }"
As the third parameter is the length of the string, you need to say that the length is the end position minus the start position...
$jsonclean = substr($jsonraw, $cutstart, $cutend-$cutstart);
I want to parse some json response into php array, the problem is nginx push stream module response with not separated json string, is possible to parse this without using regex?
'{"id":1,"channel":"1","text":"Hello World!"}{"id":2,"channel":"1","text":"Hello World!"}{"id":2,"channel":"1","text":{"key_x": "value_x"}}'
Edit
The real issue was that nginx push-stream module send archive in stream, so thats why there is no separator between json data in my snippet.
$str = '{"id":1,"channel":"1","text":"Hello World!"}{"id":2,"channel":"1","text":"Hello World!"}{"id":2,"channel":"1","text":"Hello World!"}';
$str = str_replace('}{', '},{', $str);
$str = '[' . $str . ']';
print_r(json_decode($str));
https://3v4l.org/BNVTg
I dont think this is actually possible without either changing the output or use regex / str_replace.
If you have control over the output you should change the output to valid json:
{"data":[
{"id":1,"channel":"1","text":"Hello World!"},
{"id":2,"channel":"1","text":"Hello World!"},
{"id":2,"channel":"1","text":"Hello World!"}
]}
It you cant do this then you could try to use str_replace with explode:
$data = str_replace('}{', '}<should_be_absolut_unique>{');
foreach( explode('<should_be_absolut_unique>', $data) as $json ){
# json_decode($json)
}
This is of course very unsave and not guaranteed to work because you dont know if the string replace works correctly if you do not know the data that is send!
Is it possible to have a JSON string containing PHP Code, and to have this string decoded?
For example, this works as it should:
$array = ["page", "is-home", $_SERVER["REQUEST_URI"] == "/"];
var_export($array);
// array (
// 0 => 'page',
// 1 => 'is-home',
// 2 => false,
// )
This, does not work:
$json = '["page", "is-home", $_SERVER["REQUEST_URI"] == "/"]';
$array = json_decode($json); // returns NULL
echo json_last_error_msg(); // Syntax error
The second example will only work if $_SERVER["REQUEST_URI"] == "/" is removed from the json string.
Is there a way to parse this string using json_decode, and if not, are there alternative methods to accomplish this?
Many thanks!
UPDATE
The $_SERVER["REQUEST_URI"] == "/" has to be parsed. I am trying to extend Blade Templating so that I can implement parsed functions such as this:
#add-request('page', 'is-home', $_SERVER["REQUEST_URI"] == '/')
UPDATE #2
To try to simplify the matter, I need to turn a string into an object.
$str = '["page", "is-home", $_SERVER["REQUEST_URI"] == "/"]'; // this is obtained by parsing the top blade extension (not important how)
From the string I need the following array:
$array = ["page", "is-home", true / false ]
Keep in mind that the original string can contain theoretically any PHP object for one of the JSON values.
I think you're on the right track, but instead of trying to "simulate" a decode by putting single-quotes, why not (for your proof of concept) first ENCODE, then 'echo' / 'print' the value that it returns, and then DECODE to see what it returns.
Why don't you use json_encode() to obtain json string??
// create json string by json_encode() from array
$json = json_encode([
"page",
"is-home",
$_SERVER["REQUEST_URI"] == "/"
]);
// decode the encoded string with no error, of course ....
$array = json_decode($json);
As you can clearly see in the output, your first array does not contain any PHP at all.
$array = ["page", "is-home", $_SERVER["REQUEST_URI"] == "/"];
automatically fills $array[2] with the boolean false, not with PHP code.
So, let's assume you can't do such a calculation on the client (in fact, you can do this calculation in javascript as well). So you would have to send it to the server as a json string (properly encoded), decode it, eval it, and post the result back into the array.
$json = '["page", "is-home", "$_SERVER[\"REQUEST_URI\"] == \"/\""]';
$array = json_decode($json);
$array[2]=eval($array[2]);
But please don't do this! It is a big security hole.
Instead, feel free to ask a new question as to how you can do this calculation in javascript as well.
For your case you could do:
$is_home = $_SERVER["REQUEST_URI"] == "/";
$json = '["page", "is-home", '. $is_home .']';
$array = json_decode($json);
That's because you are using a variable in your string which is not parsed. In addition, $_SERVER["REQUEST_URI"] == "/" returns false. Boolean false will be converted to an empty string if it is concatenated to a string.
You should rewrite your code to something like this:
// Is the request URI equal to "/"?
$reqUriTest = ($_SERVER["REQUEST_URI"] == "/");
// If boolean false is converted to a string, it will become an empty string.
// So we need to explicitly use values "true" or "false".
$reqUriStr = ($reqUriTest ? "true" : "false");
// Now we can insert $reqUriStr into the JSON string.
$json = '["page", "is-home", '.$reqUriStr.']';
$array = json_decode($json);
I am stucked with converting the string of specific format to array. Spliting the string using explode doesn't seems to be the right approach and i am not so good with regular expressions. So my question is how can i convert the following string to array?
Current format of the string
maxWidth: 800,
openEffect: elastic,
closeEffect: elastic,
helpers : {
title : {
type: outside
},
thumbs : {
width : 50,
height : 50
}
}
Desired Array
array(
'maxWidth' => 800,
'openEffect' => 'elastic',
'closeEffect' => 'elastic',
'helpers' => array(
'title' => array('type' => 'outside'),
'thumbs' => array('width' => 50, 'height' => 50)
)
)
Any help would be greatly appreciated.
EDIT BASED ON RESPONSES:
The string looks like a JSON but it is not a JSON. Its just a string input from user in that format. The input will be from normal user so i want to keep it simple. There is minimum chance that the normal user will enter a valid JSON.
The string in your example is almost a valid JSON (JavaScript Object Notation) structure!
Here's what your string would look like as valid JSON
{
"maxWidth": 800,
"openEffect": "elastic",
"closeEffect": "elastic",
"helpers": {
"title": {
"type": "outside"
},
"thumbs": {
"width": 50,
"height": 50
}
}
}
So our approach (as suggested by #WiseGuy) would be to first inject a few characters with preg_replace to Turn your string init into valid JSON:
$str = preg_replace('/\b/' , '"' , $str);
$str = '{' . $str . '}';
The regex above is using the Word Boundaries anchor to add quotation marks around all words. Then we wrap the whole thing in curly braces and voilà, we've got a x-language compatible object format.
We can now use a standard function to produce our object:
$objUserConfig = json_decode($str, true);
A good beginners tutorial on JSON here: http://code.drewwilson.com/entry/an-introduction-to-json
Use a linter tool such as http://jsonlint.com/ to validate JSON. I used it to debug your example and convert it into proper JSON for my example.
Your input string looks like a json format. PHP has json_decode() to convert json string to object.
To convert to array, use below code:
json_decode($jsonStr, true);
Refer: http://php.net/manual/en/function.json-decode.php
Edit: I know you are showing the printed output of an array and
not a static representation of a php declared array. This is just an
example of how you might convert it into something that can be parsed
into that array. If php has that ability to do so dynamically (I don't know).
Convert the file, read in $str
In this order, do regex on $str.
Each is global flag.
(?i)([a-z]+) to '$1'
(?i)(?<=[a-z]')\s*:(?=\s*[^{\s]) to =>
(?i)(?<=[a-z]')\s*:\s*{ to => array(
} to )
Finally, $newstr = "array(\n$str\n)"
However, something like this that can be read by a php parser as a static
array. How it gets dynamically interpreted into vars I don't know.
Perl can do this.
I have a variable which contains a path in json_encode
/users/crazy_bash/online/test/
but json_encode converts the path to this:
\/users\/crazy_bash\/online\/test\/
Why? How can i display a normal path?
the code
$pl2 = json_encode(array(
'comment' => $nmp3,
'file' => $pmp3
));
echo($pl2);
It's perfectly legal JSON, see http://json.org/. \/ is converted to / when unserializing the string. Why worry about it if the output is unserialized by a proper JSON parser?
If you insist on having \/ in your output, you can use str_replace():
// $data contains: {"url":"http:\/\/example.com\/"}
$data = str_replace("\\/", "/", $data);
echo $data; // {"url":"http://example.com/"}
Note that it's still valid JSON by the definition of a string:
(source: json.org)
Escaped solidus is legal. But if you want a result without escaping, use JSON_UNESCAPED_SLASHESin json_encode option. However, this was added after PHP 5.4.
So, str_replace('\\/', '/', $pl2); would be helpful.
You'll have to decode it before usage.
json_decode()
That's what json_encode is supposed to do. Once you json_decode or JSON.parse it, it's fine.
var f = {"a":"\/users\/crazy_bash\/online\/test\/"}
console.log(f.a); // "/users/crazy_bash/online/test/"
var h = JSON.parse('{"a":"\/users\/crazy_bash\/online\/test\/"}');
console.log(h.a); // "/users/crazy_bash/online/test/"
I had the same problem, basically you need to decode your data and then do the encode, so it works correctly without bars, check the code.
$getData = json_decode($getTable);
$json = json_encode($getData);
header('Content-Type: application/json');
print $json;