Problems with reading objects from another file with php - php

I have some file called main.config which has:
{"name":"wtf","image":"main.PNG","desc":"This is about this that and that.","tags":{"php","js","html"}}
Now in php I am reading this file and getting its content like this:
$string = "";
$handle = fopen("main.config", "r");
while(!feof($handle)){
$string .= fgets($handle);
}
fclose($handle);
And now I have been trying to decode this but it always return either null or string with additional "" around.
"{"name":"wtf","image":"main.PNG","desc":"This is about this that and that.","tags":{"php","js","html"}}"
This is everything I tried:
json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $string), true );
json_decode(preg_replace('/\s+/', '',$string), true);
json_decode(preg_replace('/\x{FEFF}/u', '', $string), true);
json_decode(str_replace('"', '"', $string));
utf8_encode($string);
stripslashes($string);
trim($string);
html_entity_decode($string);
json_decode(print_r($string, true), true);
But nothing seems to work, is it because I used some different file type or what could it be?

It was just an invalid json formatted string.
Change to:
{"name":"wtf","image":"main.PNG","desc":"This is about this that and that.","tags":["php","js","html"]}
You can also read the content with less code using:
json_decode(file_get_contents('main.config', true);
If you want to validate json format you can use this site also: jsonlint.com

Related

php: wanted to replace '\\\/' from string

I wanted to replace en/us with es/es:
<?php
$str = array('url'=>'www.domain.com\/data\/en\/us\/data.gif');
$json = json_encode($str);
$str = str_replace('en\/us', 'es\/es', $json);
echo $str;
You need to 'double escape' the backslash, like so:
<?php
$str = array('url'=>'www.domain.com/data/en/us/data.gif');
$json = json_encode($str);
$str = str_replace('en\\/us', 'es\\/es', $json);
echo $str;
See http://php.net/manual/en/language.types.string.php (section 'Single quoted').
Would be easier to escape the string BEFORE feeding it to json_encode, but I'm assuming this is a test case and the data you want to replace in is already JSON.
JSON is a useful format for moving data between systems. Converting data to JSON and then trying to manipulate it without parsing it first is almost always a terrible (overly complicated and error prone) idea.
Do the replacement before you convert it to JSON.
<?php
function replace_country($value) {
echo $value;
echo "\n";
return str_replace('en\/us', 'es\/es', $value);
}
$str = array('url'=>'www.domain.com\/data\/en\/us\/data.gif');
$str = array_map("replace_country", $str);
$json = json_encode($str);
echo $json;
Try this
$str = array('url'=>'www.domain.com\/data\/en\/us\/data.gif');
$str['url']=str_replace('en\/us', 'es\/es', $str['url']);
$json = json_encode($str);
It produce out put as
It will work for you.

What is the proper way to parse yahoo currency http://finance.yahoo.com/connection/currency-converter-cache?date?

As the code i tried and by trial removal to get json content out of the return is below
method i used.
$date= YYYYMMDD;
//example '20140113'
$handle = fopen('http://finance.yahoo.com/connection/currency-converter-cache?date='.$date.'', 'r');
//sample code is http://finance.yahoo.com/connection/currency-converter-cache?date=20140208 paste the url in browser;
// use loop to get all until end of content
while (!feof($handle)) {
$contents .= fread($handle, 8192);
}
fclose($handle);
the code return a given bulk in yahoo and json format
so remove the unknown format which is
"/**/YAHOO.Finance.CurrencyConverter.addConversionRates (" and ends with ");"
by
$contents = str_replace('/**/YAHOO.Finance.CurrencyConverter.addConversionRates(','',$contents);
$contents = str_replace(');','',$contents);
$obj = json_decode($contents,true);
then loop the content by
foreach($obj['list']['resources'] as $key0 => $value0){
}
I prefer to use file_get_contents to get the html and preg_match_all to cleanup the json, i.e.:
<?php
$json = file_get_contents("http://finance.yahoo.com/connection/currency-converter-cache?date=20140113");
preg_match_all('/\((.*)\);/si', $json, $json, PREG_PATTERN_ORDER);
$json = $json[1][0];
$json = json_decode($json,true);
foreach ($json["list"]["resources"] as $resource){
echo $resource["resource"]["fields"]["date"];
echo $resource["resource"]["fields"]["price"];
echo $resource["resource"]["fields"]["symbol"];
echo $resource["resource"]["fields"]["price"];
}
NOTE:
I've tested the code and it works as intended.

Replacing characters in MIME encoded emails

I am looking for a way to simply replace characters with their ASCII counterparts in MIME encoded emails. I've written preliminary code below, but it seems like the str_replace commands I'm using will keep on going forever to catch all possible combinations. Is there a more efficient way to do this?
<?php
$strings = "=?utf-8?Q?UK=20Defence=20=2D=20Yes=2C=20Both=20Labour=20and=20Tory=20Need=20To=20Be=20Very=20Much=20Clearer=20On=20Defence?=";
function decodeString($input){
$space = array("=?utf-8?Q?","=?UTF-8?Q?", "=20","?=");
$hyphen = array("=E2=80=93","=2D");
$dotdotdot = "=E2=80=A6";
$pound = "=C2=A3";
$comma = "=2C";
$decode = str_replace($space, ' ', $input);
$decode = str_replace($hyphen, '-', $decode);
$decode = str_replace($pound, '£', $decode);
$decode = str_replace($comma, ',', $decode);
$decode = str_replace($dotdotdot, '...', $decode);
return $decode;
}
echo decodeString($strings);
?>
I figured it out - I have to pass $strings to the mb_decode_mimeheader() function.

PHP: json_decode not working

This does not work:
$jsonDecode = json_decode($jsonData, TRUE);
However if I copy the string from $jsonData and put it inside the decode function manually it does work.
This works:
$jsonDecode = json_decode('{"id":"0","bid":"918","url":"http:\/\/www.google.com","md5":"6361fbfbee69f444c394f3d2fa062f79","time":"2014-06-02 14:20:21"}', TRUE);
I did output $jsonData copied it and put in like above in the decode function. Then it worked. However if I put $jsonData directly in the decode function it does not.
var_dump($jsonData) shows:
string(144) "{"id":"0","bid":"918","url":"http:\/\/www.google.com","md5":"6361fbfbee69f444c394f3d2fa062f79","time":"2014-06-02 14:20:21"}"
The $jsonData comes from a encrypted $_GET variable. To encrypt it I use this:
$key = "SOME KEY";
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$enc = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_ECB, $iv);
$iv = rawurlencode(base64_encode($iv));
$enc = rawurlencode(base64_encode($enc));
//To Decrypt
$iv = base64_decode(rawurldecode($_GET['i']));
$enc = base64_decode(rawurldecode($_GET['e']));
$data = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $enc, MCRYPT_MODE_ECB, $iv);
some time there is issue of html entities, for example \" it will represent like this \&quot, so you must need to parse the html entites to real text, that you can do using
html_entity_decode()
method of php.
$jsonData = stripslashes(html_entity_decode($jsonData));
$k=json_decode($jsonData,true);
print_r($k);
You have to use preg_replace for avoiding the null results from json_decode
here is the example code
$json_string = stripslashes(html_entity_decode($json_string));
$bookingdata = json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $json_string), true );
Most likely you need to strip off the padding from your decrypted data. There are 124 visible characters in your string but var_dump reports 144. Which means 20 characters of padding needs to be removed (a series of "\0" bytes at the end of your string).
Probably that's 4 "\0" bytes at the end of a block + an empty 16-bytes block (to mark the end of the data).
How are you currently decrypting/encrypting your string?
Edit:
You need to add this to trim the zero bytes at the end of the string:
$jsonData = rtrim($jsonData, "\0");
Judging from the other comments, you could use,
$jsonDecode = json_decode(trim($jsonData), TRUE);
While moving on php 7.1 I encountered with json_decode error number 4 (json syntex error). None of the above solution on this page worked for me.
After doing some more searching i found solution at https://stackoverflow.com/a/15423899/1545384 and its working for me.
//Remove UTF8 Bom
function remove_utf8_bom($text)
{
$bom = pack('H*','EFBBBF');
$text = preg_replace("/^$bom/", '', $text);
return $text;
}
Be sure to set header to JSON
header('Content-type: application/json;');
str_replace("\t", " ", str_replace("\n", " ", $string))
because json_decode does not work with special characters. And no error will be displayed. Make sure you remove tab spaces and new lines.
Depending on the source you get your data, you might need also:
stripslashes(html_entity_decode($string))
Works for me:
<?php
$sql = <<<EOT
SELECT *
FROM `students`;
EOT;
$string = '{ "query" : "' . str_replace("\t", " ", str_replace("\n", " ", $sql)).'" }';
print_r(json_decode($string));
?>
output:
stdClass Object
(
[query] => SELECT * FROM `students`;
)
I had problem that json_decode did not work, solution was to change string encoding to utf-8. This is important in case you have non-latin characters.
Interestingly mcrypt_decrypt seem to add control characters other than \0 at the end of the resulting text because of its padding algorithm. Therefore instead of rtrim($jsonData, "\0")
it is recommended to use
preg_replace( "/\p{Cc}*$/u", "", $data)
on the result $data of mcrypt_decrypt. json_decode will work if all trailing control characters are removed. Pl refer to the comment by Peter Bailey at http://php.net/manual/en/function.mdecrypt-generic.php .
USE THIS CODE
<?php
$json = preg_replace('/[[:cntrl:]]/', '', $json_data);
$json_array = json_decode($json, true);
echo json_last_error();
echo json_last_error_msg();
print_r($json_array);
?>
Make sure your JSON is actually valid. For some reason I was convinced that this was valid JSON:
{ type: "block" }
While it is not. Point being, make sure to validate your string with a linter if you find json_decode not te be working.
Try the JSON validator.
The problem in my case was it used ' not ", so I had to replace it to make it working.
In notepad+ I changed encoding of json file on: "UTF-8 without BOM".
JSON started to work
TL;DR Be sure that your JSON not containing comments :)
I've taken a JSON structure from API reference and tested request using Postman. I've just copy-pasted the JSON and didn't pay attention that there was a comment inside it:
...
"payMethod": {
"type": "PBL" //or "CARD_TOKEN", "INSTALLMENTS"
},
...
Of course after deletion the comment json_decode() started working like a charm :)
Use following function:
If JSON_ERROR_UTF8 occurred :
$encoded = json_encode( utf_convert( $responseForJS ) );
Below function is used to encode Array data recursively
/* Use it for json_encode some corrupt UTF-8 chars
* useful for = malformed utf-8 characters possibly incorrectly encoded by json_encode
*/
function utf_convert( $mixed ) {
if (is_array($mixed)) {
foreach ($mixed as $key => $value) {
$mixed[$key] = utf8ize($value);
}
} elseif (is_string($mixed)) {
return mb_convert_encoding($mixed, "UTF-8", "UTF-8");
}
return $mixed;
}
Maybe it helps someone, check in your json string if you have any NULL values, json_decode will not work if a NULL is present as a value.
This super basic function may help you. I made the NULL in an array just in case I need to add more stuff in the future.
function jsonValueFix($json){
$json = str_replace( array('NULL'),'""',$json );
return $json;
}
I just used json_decode twice and it worked for me
$response = json_decode($apiResponse, true);
$response = json_decode($response, true);

PHP Generate List of 301 redirects from CSV, and then Check List of 301 redirects for 404 errors

I had an interesting task today and couldn't find much on the subject. I wanted to share this, and ask for any suggestions on how this could have been done more elegantly. I consider myself a mediocre programmer who really wants to improve so any feedback is highly appreciated. There is also a strange bug I can't figure out. So here goes..and hopefully this helps someone who ever has to do something similar.
A client was redoing a site, moving content around, and had a couple thousand redirects that needed to be made. Marketing sent me an XLS with old URLs in one column, new URLs in the next. These were the actions I took:
Saved the XLS as CSV
Wrote a script which:
Formatted the list as valid 301 redirects
Exported the list to a text file
I then copy / pasted all the new directives into my .htaccess file.
Then, I wrote another script that checked to make sure each of the new links was valid (no 404s). The first script worked exactly as expected. For some reason, I can get the second script to print out all the 404 errors (there were several), but the script doesn't die when it finishes traversing the loop, and it doesn't write to the file, it just hangs in command line. No errors get reported. Any idea what's going on? Here is the code for both scripts:
Formatting 301s:
<?php
$source = "301.csv";
$output = "301.txt";
//grab the contents of the source file as an array, prepare the output file for writing
$sourceArray = file($source);
$handleOutput = fopen($output, "w");
//Set the strings we want to replace in an array. The first array are the original lines and the second are the strings to be replaced
$originalLines = array(
'http://hipaasecurityassessment.com',
','
);
$replacementStrings = array(
'',
' '
);
//Split each item from the array into two strings, one which occurs before the comma and the other which occurs after
function setContent($sourceArray, $originalLines = array(), $replacementStrings = array()){
$outputArray = array();
$text = 'redirect 301 ';
foreach ($sourceArray as $number => $item){
$pattern = '/[,]/';
$item = preg_split($pattern, $item);
$item = array(
$item[0],
preg_replace('#"#', '', $item[1])
);
$item = implode(' ', $item);
$item = str_replace($originalLines, $replacementStrings, $item);
array_push($outputArray,$text,$item);
}
$outputString = implode('', $outputArray);
return $outputString;
}
//Invoke the set content function
$outputString = setContent($sourceArray, $originalLines, $replacementStrings);
//Finally, write to the text file!
fwrite($handleOutput, $outputString);
Checking for 404s:
<?php
$source = "301.txt";
$output = "print404.txt";
//grab the contents of the source file as an array, prepare the output file for writing
$sourceArray = file($source);
$handleOutput = fopen($output, "w");
//Split each item from the array into two strings, one which occurs before the space and the other which occurs after
function getUrls($sourceArray = array()){
$outputArray = array();
foreach ($sourceArray as $number => $item){
$item = str_replace('redirect 301', '', $item);
$pattern = '#[ ]+#';
$item = preg_split($pattern, $item);
$item = array(
$item[0],
$item[1],
$item[2]
);
array_push($outputArray, $item[2]);
}
return $outputArray;
}
//Check each URL for a 404 error via a curl request
function check404($url = array(), $handleOutput){
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE);
$content = curl_exec( $handle );
$response = curl_getinfo( $handle );
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
//fwrite($handleOutput, $url);
print $url;
}
};
$outputArray = getUrls($sourceArray);
foreach ($outputArray as $url)
{
$errors = check404($url, $handleOutput);
}
You should have used fgetcsv() for generating the original URL list. This splits up CSV files into an array, simplifying the transformation.
Can't say anything about the 404s or the error cause. But using the wacky curl functions is almost always a bad indicator. For testing purposes I would have used a commandline tool like wget instead so the results can be proof-checked manually.
But maybe you could try PHPs own get_headers() instead. It's supposed to show the raw result headers; shouldn't not follow redirects itself.

Categories