Remove double quotes from json array and fix link - php

Hi i have this code to output a array list
$Sql1 = "SELECT * FROM tabmp3
WHERE Mp3_Player = 1
";
$Query1 = mysql_query($Sql1, $Conn)or die(mysql_error($Conn));
$musicas = array();
while($Rs1 = mysql_fetch_array($Query1)){
$musicas[] = array( title => $Rs1['Musica_Nome'], autor => "Grupo Fronteiras", mp3 => "http://site/Musicas/".$Rs1["Disco_Id"]."/".$Rs1["Musica_Mp3"] );
}
echo ( json_encode($musicas) );
this output
[{"title":"Alegria do Pov\u00e3o","autor":"Grupo Fronteiras","mp3":"http:\/\/site\/Musicas\/3\/201302140204413c390efdb9957eebd8d85c262f2a4929.mp3"}, {"title":"Bem na moda da fronteira","autor":"Grupo Fronteiras","mp3":"http:\/\/site\/Musicas\/2\/20130214032235fabd12471ffc7790c9204f891919bca8.mp3"}]
i need to remove double quotes from keys and fix the http link to looks like this
[{title:"Alegria do Pov\u00e3o",autor:"Grupo Fronteiras",mp3:"http://site/Musicas/3/201302140204413c390efdb9957eebd8d85c262f2a4929.mp3"},{title:"Bem na moda da fronteira",autor:"Grupo Fronteiras",mp3:"http://site/Musicas/2/20130214032235fabd12471ffc7790c9204f891919bca8.mp3"}]
Thanks

Try this..I know it is not very good way to do it.. I am writing this to show you that you have to make the form that you wanted in your php code only.
$json = json_encode($musicas);
$json = preg_replace('/["]/', '' ,$json);
$json = str_replace(':',':"', $json);
$json = str_replace(',','",',$json);
$json = str_replace('}]','"}]',$json);
echo $json;
By this way you will acheive what you wanted. But please find something good way to do it.
The correct answer should be this, as commented by #AlvaroLouzada
$json = json_encode($musicas);
$json = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', $json);
echo $json ;

I looked a lot for an elegant solution to fix this issue without doing changing things over javascript or just replace quotes via preg_replace (for the case that the values would contain quotes) and end up doing it by myself. even if it's too late, I hope it would help those who are looking for the same solution.
function json_encode_advanced(array $arr, $sequential_keys = false, $quotes = false, $beautiful_json = false) {
$output = "{";
$count = 0;
foreach ($arr as $key => $value) {
if ( isAssoc($arr) || (!isAssoc($arr) && $sequential_keys == true ) ) {
$output .= ($quotes ? '"' : '') . $key . ($quotes ? '"' : '') . ' : ';
}
if (is_array($value)) {
$output .= json_encode_advanced($value, $sequential_keys, $quotes, $beautiful_json);
} else if (is_bool($value)) {
$output .= ($value ? 'true' : 'false');
} else if (is_numeric($value)) {
$output .= $value;
} else {
$output .= ($quotes || $beautiful_json ? '"' : '') . $value . ($quotes || $beautiful_json ? '"' : '');
}
if (++$count < count($arr)) {
$output .= ', ';
}
}
$output .= "}";
return $output;
}
function isAssoc(array $arr) {
if (array() === $arr) return false;
return array_keys($arr) !== range(0, count($arr) - 1);
}
usage:
$array = [
'someField' => '"value"', // double quotes for string if needed
'labelField' => '"label"', // double quotes for string if needed
'boolean' => false,
'numeric' => 5,
'render' => [
'option' => 'function() {
console.log("Hello World!");
console.log(\'Hello World!\');
}',
],
];
echo json_encode_advanced($array);
result:
{
someField : "value",
labelField : "label",
boolean : false,
numeric : 5,
render : {
option : function() {
console.log("Hello World!");
console.log('Hello World!');
}
}
}

Instead of doing echo ( json_encode($musicas) );, do something like this:
$json_string = json_encode($musicas);
$json_string = str_replace('\/', '/', $json_string);
echo $json_string;

Related

Check for empty values in associative array

I'm having a hard time checking for empty values in my associative array. And if a value is empty/null replace it with the wording "not entered"
My $_SESSION['gift'] array:
Array
(
[0] => Array
(
[giftGiveMy] => 1a
[giftTo] => 2a
)
[1] => Array
(
[giftGiveMy] => 1b
[giftTo] => '' //### empty ###
)
)
if (empty($_SESSION['gift']) && 0 !== $_SESSION['gift']) {
$gifts = "No specific gifts identified.\n";
} else {
$gifts = [];
foreach( $_SESSION['gift'] as $value) {
$gifts[] = "I give my ". $value['giftGiveMy'] ." to ". $value['giftTo'] .".\n";
}
$gifts = join($gifts);
}
The above outputs:
I give my 1a to 2a.
I give my 1b to .
I would like it read:
I give my 1a to 2a.
I give my 1b to not entered.
You can replace all empty and NULL value with not entered with the help of array_walk_recursive and use you code as it is
array_walk_recursive($arrayMain, 'not_entered');
function not_entered(& $item, $key) {
if (($item === "") || ($item ==NULL)){
$item = "not entered";
}
}
var_dump($arrayMain);
Just use foreach to loop all values and check if it's empty
$emptyText = '<b>not entered</b>';
// `empty` will also be true if element does not exist
if (empty($_SESSION['gift'])) {
$gifts = "No specific gifts identified.\n";
} else {
$gifts = [];
foreach($_SESSION['gift'] as $value) {
$myGive = !empty($value['giftGiveMy']) ? $value['giftGiveMy'] : $emptyText;
$giftTo = !empty($value['giftTo']) ? $value['giftTo'] : $emptyText;
$gifts[] = "I give my {$myGive} to {$giftTo}.";
}
$gifts = implode("\r\n", $gifts); // Or `<br/>` if outputted to HTML
}
You should modify your code and write it this way:
if (!isset($_SESSION['gift']) || empty($_SESSION['gift'])) {
$gifts = "No specific gifts identified.\n";
} else {
foreach( $_SESSION['gift'] as $value) {
$gift_to = !empty($value['giftTo']) ? $value['giftTo'] : '<strong>Not entered<strong>';
$gifts[] = "I give my ". $value['giftGiveMy'] ." to ". $gift_to .".\n";
}
}
You might want to try this:
if (empty($_SESSION['gift']) && 0 !== $_SESSION['gift']) {
$gifts = "No specific gifts identified.\n";
} else {
$gifts = [];
foreach( $_SESSION['gift'] as $value) {
$gifts[] = "I give my ". $value['giftGiveMy'] ." to ". (!empty($value['giftTo']) ? $value['giftTo'] : '<b>not entered</b>') .".\n";
}
$gifts = join($gifts);
}
If you would like to make it a little cleaner you could extract the ternary operator into something like this;
$giftTo = !empty($value['giftTo']) ? $value['giftTo'] : '<b>not entered</b>';
$gifts[] = "I give my ". $value['giftGiveMy'] ." to ". $giftTo .".\n";
Try:
$arr = $_SESSION['gift'];
foreach($arr as $key => $array) {
if($array['giftGiveMy'] == null || empty($array['giftGiveMy'])) {
$arr[$key]['giftGiveMy'] = 'not entered.';
}
if($array['giftTo'] == null || empty($array['giftTo'])) {
$arr[$key]['giftTo'] = 'not entered.';
}
}
I'd write that this way:
$gifts = "No specific gifts identified.\n";
$filter = function($str) {
return empty($str) ? 'not entered' : $str;
};
if(!empty($_SESSION['gift'])) {
$gifts = '';
array_walk($_SESSION['gift'], function($given) use(&$gifts,$filter){
$gifts .= 'I give my ' . $filter($given['giftGiveMy']) . ' to ' . $filter($given['giftTo']) . ".\n";
});
}
You can use for the below code also there is no need any extra Php functions.
$arr = array(
0 => array(
'giftGiveMy' => '1a',
'giftTo' => '2a'
),
1 => array(
'giftGiveMy' => '1b',
'giftTo' => ''
)
);
$str = '';
if (!empty($arr)) {
foreach ($arr as $key => $value) {
if ($value['giftGiveMy'] == '')
$value['giftGiveMy'] = 'not entered';
if ($value['giftTo'] == '')
$value['giftTo'] = '<strong>not entered</strong>';
//$new[$key] = $value;
$str .= "I give my " . $value['giftGiveMy'] . " to " . $value['giftTo'] . "<br />";
}
}else {
$str = 'No specific gifts identified.<br />';
}
echo $str;
This validates an associative array with empty() (see array_filter), but may not respond to the original question.
<?php
$var = array();
$var['position'] = 'executive';
$var['email'] = 'a#email.com';
$var['message'] = 'This is the message';
$var['name'] = 'John Doe';
$var['telephone'] = '123456789';
$var['notneededparam'] = 'Nothing';
$expectedParams = ['position', 'email', 'message', 'name', 'telephone'];
$params = array_intersect_key($var, array_flip($expectedParams));
// check existence of keys and that they are valid
if(count($params) != count($expectedParams) || count(array_filter($params)) != count($expectedParams)){
echo "not valid\n";
die();
}
extract($params);
var_dump($name);
Other functions used here: array_flip(), array_intersect_key(), count(), extract(), var_dump(),

Need help php to json array

I am having a string below
$string = ot>4>om>6>we>34>ff>45
I would like the JSON output be like
[{"name":"website","data":["ot","om","we","ff"]}]
and
[{"name":"websitedata","data":["4","6","34","45"]}]
what I've tried
$query = mysql_query("SELECT month, wordpress, codeigniter, highcharts FROM project_requests");
$category = array();
$category['name'] = 'website';
$series1 = array();
$series1['name'] = 'websitedata';
while($r = mysql_fetch_array($query)) {
$category['data'][] = $r['month'];
}
$result = array();
array_push($result,$category);
array_push($result,$series1);
print json_encode($result, JSON_NUMERIC_CHECK);
but the above code is applicable only if the data are present in rows from a mysql table, what i want is achieve the same result with the data from the above string. that is
$string = ot>4>om>6>we>34>ff>45
NEW UPDATE:
I would like to modify the same string
$string = ot>4>om>6>we>34>ff>45
into
json output:
[
{
"type" : "pie",
"name" : "website",
"data" : [
[
"ot",
4
],
[
"om",
6
],
[
"we",
34
]
]
}
]
I have updated the answer please check the json part, I would like the php code.
regards
You can explode() on the >s, and then loop through the elements:
$string = "ot>4>om>6>we>34>ff>45";
$array1 = [
'name'=>'website',
'data'=>[]
]
$array2 = [
'name'=>'websitedata',
'data'=>[]
]
foreach(explode('>', $string) as $index => $value){
if($index & 1) //index is odd
$array2['data'][] = $value;
else //index is even
$array1['data'][] = $value;
}
echo json_encode($array1); //prints {"name":"website","data":["ot","om","we","ff"]}
echo json_encode($array2); //prints {"name":"websitedata","data":["4","6","34","45"]}
A solution using preg_match_all():
$string = "ot>4>om>6>we>34>ff>45";
preg_match_all('/(\w+)>(\d+)/', $string, $matches);
$array1 = [
'name'=>'website',
'data'=> $matches[1]
];
$array2 = [
'name'=>'websitedata',
'data'=> $matches[2]
];
echo json_encode($array1); //prints {"name":"website","data":["ot","om","we","ff"]}
echo json_encode($array2); //prints {"name":"websitedata","data":["4","6","34","45"]}
Update:
To get the second type of array you wanted, use this:
//since json_encode() wraps property names in double quotes (which prevents the chart script from working), you'll have to build the json object manually
$string = "ot>4>om>6>we>34>ff>45";
preg_match_all('/(\w+)>(\d+)/', $string, $matches);
$data = [];
foreach($matches[1] as $index => $value){
if(isset($matches[2][$index]))
$data[] = '["' . $value . '",' . $matches[2][$index] . ']';
}
$type = 'pie';
$name = 'website';
echo $jsonString = '[{type:"' . $type . '",name:"' . $name . '",data:[' . implode(',', $data) . ']}]'; // prints [{type:"pie",name:"website",data:[["ot",4],["om",6],["we",34],["ff",45]]}]
Update #2:
This code uses explode(), and although it's probably not the most efficient way of doing it, it works.
//since json_encode() wraps property names in double quotes (which prevents the chart script from working), you'll have to build the json object manually
$string = "ot>4>om>6>we>34>ff>45";
$keys = [];
$values = [];
foreach(explode('>', $string) as $key => $value){
if(!($key & 1)) //returns true if the key is even, false if odd
$keys[] = $value;
else
$values[] = $value;
}
$data = [];
foreach($keys as $index => $value){
if(isset($values[$index]))
$data[] = '["' . $value . '",' . $values[$index] . ']';
}
$type = 'pie';
$name = 'website';
echo $jsonString = '[{type:"' . $type . '",name:"' . $name . '",data:[' . implode(',', $data) . ']}]'; // prints [{type:"pie",name:"website",data:[["ot",4],["om",6],["we",34],["ff",45]]}]
This should work, though there are probably better ways to do it.
$string = "ot>4>om>6>we>34>ff>45";
$website = ["name" => "website", "data" => []];
$websiteData = ["name" => "websitedata", "data" => []];
foreach(explode(">", $string) as $i => $s) {
if($i % 2 === 0) {
$website["data"][] = $s;
} else {
$websiteData["data"][] = $s;
}
}
echo json_encode($website);
echo json_encode($websiteData);
A regex alternative:
preg_match_all("/([a-z]+)>(\d+)/", $string, $matches);
$website = ["name" => "website", "data" => $matches[1]];
$websiteData = ["name" => "websitedata", "data" => $matches[2]];
Try this code:
$string = 'ot>4>om>6>we>34>ff>45';
$string_split = explode('>', $string);
$data = array("name" => "website");
$data2 = $data;
foreach ($string_split as $key => $value)
{
if (((int)$key % 2) === 0)
{
$data["data"][] = $value;
}
else
{
$data2["data"][] = $value;
}
}
$json1 = json_encode($data, JSON_NUMERIC_CHECK);
$json2 = json_encode($data2, JSON_NUMERIC_CHECK);
echo $json1;
echo $json2;
Output:
{"name":"website","data":["ot","om","we","ff"]}
{"name":"website","data":[4,6,34,45]}
Regards.
Try this snippet:
$strings = explode('>', 'ot>4>om>6>we>34>ff>45');
// print_r($string);
$x = 0;
$string['name'] = 'website';
$numbers['name'] = 'websitedata';
foreach ($strings as $s)
{
if ($x == 0) {
$string['data'][] = $s;
$x = 1;
} else {
$numbers['data'][] = $s;
$x = 0;
}
}
print_r(json_encode($string));
echo "<br/>";
print_r(json_encode($numbers));
As usual - it is long winded but shows all the steps to get to the required output.
<?php //https://stackoverflow.com/questions/27822896/need-help-php-to-json-array
// only concerned about ease of understnding not code size or efficiency.
// will speed it up later...
$inString = "ot>4>om>6>we>34>ff>45";
$outLitRequired = '[{"name":"website","data":["ot","om","we","ff"]}]';
$outValueRequired = '[{"name":"websitedata","data":["4","6","34","45"]}]';
// first: get a key / value array...
$itemList = explode('>', $inString);
/* debug */ var_dump(__FILE__.__LINE__, $itemList);
// outputs ------------------------------------
$outLit = array();
$outValue = array();
// ok we need to process them in pairs - i like iterators...
reset($itemList); // redundant but is explicit
// build both output 'data' lists
while (current($itemList)) {
$outLit[] = current($itemList);
next($itemList); // advance the iterator.
$outValue[] = current($itemList);
next($itemList);
}
/* debug */ var_dump(__FILE__.__LINE__, $itemList, $outLit, $outValue);
// make the arrays look like the output we want...
// we need to enclose them as arrays to get the exact formatting required
// i do that in the 'json_encode' statements.
$outLit = array('name' => 'website', 'data' => $outLit);
$outValue = array('name' => 'websitedata', 'data' => $outValue);
// convert to JSON.
$outLitJson = json_encode(array($outLit));
$outValueJson = json_encode(array($outValue));
// show required and calculated values...
/* debug */ var_dump(__FILE__.__LINE__, 'OutLit', $outLitRequired, $outLitJson);
/* debug */ var_dump(__FILE__.__LINE__, 'OutValue', $outValueRequired, $outValueJson);

array to generate form

I am trying to use an array to output a form with the following function:
public function createArrayForm($table, $do, $formDesc = '', $id, $array, $markFields = false) {
if (!isset($table) && !isset($do)) {
self::show_error('One or more parameters are missing in ' . __FUNCTION__);
} elseif ($table == 'update' && !isset($id)) {
self::show_error('For this form to be built, and ID must be set. Missing parameter `ID` in ' . __FUNCTION__);
}
if (is_array($array) && $do == 'insert') {
$out .= '<form action="' . $_SERVER['PHP_SELF'] . '?id=' . $id . '&table=' . $table . '" method="post" class="form-horizontal" ' . $formAppend . '>';
$out .= '<div class="form-desc">' . $formDesc . '</div>';
$out .= $markFields ? '<h3>Input Fields</h3>' : '';
foreach ($array as $type => $fieldname) {
if ($type == 'input') {
$out .= generateInputField($fieldname);
}
}
$out .= $markFields ? '<h3>Content Fields</h3>' : '';
foreach ($array as $type => $fieldname) {
if ($type == 'textarea') {
$out .= generateTextarea($fieldname, $cke);
}
}
$out .= $markFields ? '<h3>Images Fields</h3>' : '';
foreach ($array as $type => $fieldname) {
if ($type == 'image') {
$out .= generateImgField($fieldname);
}
}
$out .= form_hidden('user_data', '1');
$out .= form_hidden('id', self::generateID());
$out .= form_close();
return $out;
}
And call:
$arr = array("textarea"=>"project_name", "input"=>"created", "input"=>"last_modified", "input"=>"published");
echo $automate->createArrayForm('projects', 'insert', 'Some form desc', '123', $arr, true);
But it only outputs:
When it should look something like this:
Only one of each, for example input, is returned. Rather than all instances of it. So "input"=>"created", "input"=>"last_modified", "input"=>"published" should make three inputs, but it only returns one.
You're re-using array keys. So
$arr = array("textarea"=>"project_name", "input"=>"created", "input"=>"last_modified", "input"=>"published");
will end up looking like this:
$arr = array("textarea"=>"project_name", "input"=>"published");
Instead, modify your code to something like this:
$arr = array("textarea"=>array("project_name"), "input"=>array("created", "last_modified", "published"));
Then take those individual arrays, and iterate through them.
foreach ($array['input'] as $fieldname) { // etc and so on
In PHP, you cannot have arrays that share keys.
You'll be best creating a simple array, and creating sub-entries, so that you maintain order, but can have more than one input/textarea.
Like so:
$arr = array(
array('type' => 'textarea', 'name' => 'project_name'),
array('type' => 'input', 'name' => 'created'),
array('type' => 'input', 'name' => 'published'),
array('type' => 'input', 'name' => 'last_modified')
)
This would also allow you to add more parameters than type/name.
The problem is that you use the same key for everything in the array.
A possibility would be to exchange values and keys
$arr = array("textarea"=>"project_name", "input"=>"created", "input"=>"last_modified", "input"=>"published");
[...]
foreach ($array as $fieldname => $type) {
if ($type == 'textarea') {
$out .= generateTextarea($fieldname, $cke);
}
}
[...]

json encode and replacement for JSON_UNESCAPED_UNICODE

Since I cant use JSON_UNESCAPED_UNICODE because my php is < 5.4, I have tried some replacements from json_encode() manual page:
$final = array (
0 => array (
'id' => 26629,
'content' => 'преди 5 сек'
),
1 => array (
'id' => 26628,
'content' => 'преди 5 сек'
),
2 => array (
'id' => 26627,
'content' => 'преди 5 сек'
)
);
$myDirtyString = json_encode($final);
$myDirtyString = str_replace("\/","/",$myDirtyString);
$myDirtyString = str_replace('"','\\"',$myDirtyString);
echo $myCleanedString = json_decode('"'.$myDirtyString.'"');
And the result is:
[
{"id":"26629","timestamp":"преди 5 сек"},
{"id":"26628","timestamp":"преди 5 сек"},
{"id":"26625","timestamp":"¿Ñеди 5 Ñек"}
]
Why the last item is such a mess?
I tried
header('Content-Type: application/json; charset=utf-8');
...but still dosent work.
If your on a version of PHP before 5.4, this might help:
<?php
if (!function_exists('json_encode')) {
function json_encode($data) {
switch ($type = gettype($data)) {
case 'NULL':
return 'null';
case 'boolean':
return ($data ? 'true' : 'false');
case 'integer':
case 'double':
case 'float':
return $data;
case 'string':
return '"' . addslashes($data) . '"';
case 'object':
$data = get_object_vars($data);
case 'array':
$output_index_count = 0;
$output_indexed = array();
$output_associative = array();
foreach ($data as $key => $value) {
$output_indexed[] = json_encode($value);
$output_associative[] = json_encode($key) . ':' . json_encode($value);
if ($output_index_count !== NULL && $output_index_count++ !== $key) {
$output_index_count = NULL;
}
}
if ($output_index_count !== NULL) {
return '[' . implode(',', $output_indexed) . ']';
} else {
return '{' . implode(',', $output_associative) . '}';
}
default:
return ''; // Not supported
}
}
}
?>

PHP — How to determine number of parents of a child array?

I'm not so strong with arrays but I need to determine how to count the number of parents a child array has in order to determine the indenting to display it as an option in a SELECT.
So, if I have this array:
array(
'World'=>array(
'North America'=>array(
'Canada'=>array(
'City'=>'Toronto'
)
)
)
);
How would I go about determining how many parents 'City' has in order to translate that into the number of spaces I want to use as an indent?
Thanks for any help.
EDIT: Let's see if I can explain myself better:
I have this code I'm using to build the OPTIONS list for a SELECT:
function toOptions($array) {
foreach ($array as $key=>$value) {
$html .= "<option value=\"" . $key . "\" >";
$html .= $value['title'];
$html .= "</option>";
if (array_key_exists('children', $value)) {
$html .= toOptions($value['children']);
}
}
return $html;
}
print toOptions($list);
So, I'm trying to determine how to get the number of parents in order to add spaces before the title in this line:
$html .= $value['title'];
Like:
$html .= " " . $value['title'];
But, I'm not sure how to figure out how many spaces to add.
Hopefully this is more clear.
Thanks for any help so far.
$x = array(
'World'=>array(
'North America'=>array(
'Canada'=>array(
'City'=>'Toronto'
)
)
)
);
// This function do something with the key you've found in the array
function visit($name, $depth)
{
echo $name . ' has ' . $depth . ' parents.';
}
// This function visits all the contents aff $array
function find_recursive($array, $depth = 0)
{
if (is_array($array)) {
foreach ($array as $k => $value) {
visit($k, $depth + 1);
find_recursive($array, $depth + 1);
}
}
}
For visiting:
find_recursive($x);
Well. Off the top what you are dealing with is a multi dimensional array.
You could run a count w/ foreach on each level of the array, and use the count number returned +1 for each level the foreach loops through.
I'm not sure if this answers your question, but I am trying to see exactly what it is you are trying to achieve.
As you are already using a recursive function to display that data, you can just extend your function. There is no need to traverse the array more often than one time:
function getWhitespaces($count) {
$result = '';
while($count--) {
$result .= '$nbsp;';
}
return $result;
}
function toOptions($array, $level=0) {
foreach ($array as $key=>$value) {
$html .= "<option value=\"" . $key . "\" >";
$html .= getWhitespaces($level) + $value['title'];
$html .= "</option>";
if (array_key_exists('children', $value)) {
$html .= toOptions($value['children'], $level + 1);
}
}
return $html;
}
print toOptions($list);
Try the following.. Your solution screams for recursion in my mind. Its a bit ugly but it seems to work
$totraverse = array(
'Moon' => array(
'Dark Side' => "Death Valley"
),
'Halley Commet' => "Solar System",
'World' => array(
'North America' => array(
'Canada' => array(
'City' => 'Toronto'
)
), 'South America' => array(
'Argentina' => array(
'City' => 'Toronto'
)
)
)
);
function traverse($totraverse_, $path="", $count=0) {
global $array;
// echo count($totraverse_) . " count\n";
if (!is_array($totraverse_)) {
echo "returning $path and $key\n";
return array($path, $count);
} else {
foreach ($totraverse_ as $key => $val) {
echo "assting $path and $key\n";
$result = traverse($val, $path . "/" . $key, $count + 1);
if($result){
$array[]=$result;
}
}
}
echo false;
}
$array = array();
traverse($totraverse);
foreach($array as $item){
echo "{$item[0]}--->{$item[1]}\n";
}

Categories