I am trying to convert a MySQL query result into JSON within an AJAX request.
My code looks like this at the moment.
$offset = empty($_GET['offset']) ? 0 : $_GET['offset'];
$numimagestodisplay = 3;
$items = array();
$allitems // This is the queryset obtained through a call to a function
foreach ($allitems as $i => &$item)
{
if (($i >= $offset) && (count($items) < $numimagestodisplay))
{
$items[$i] = $item;
}
}
$output = '{"items":'.json_encode($items).'}';
I then want to cycle through the returned results in the javascript calling the above code and need to refer to the array items by their keys (I need to alter some HTML element IDs using these values). However, the JSON is returned in the wrong format.
If I change the line
$items[$i] = $item;
to:
$items[] = $item;
Then I can refer to it by key, however the keys are obviously just 0, 1, 2, whereas I need the key to be the value defined in the loop.
How can I alter the PHP code to return the JSON in the correct format?
Any advice appreciated.
Thanks.
The problem is that arrays in Javascript (and most other languages for that matter) can't have user defined keys. You want your array to be encoded to a JSON object instead of an array (arrays in PHP with user-defined keys are in essence objects). This usually happens automatically, for arrays with non-numeric keys.
In your case, you can use the JSON_FORCE_OBJECT flag:
$output = '{"items":'.json_encode($items,JSON_FORCE_OBJECT).'}';
From the documentation:
Non-associative array output as array: [[1,2,3]]
Non-associative array output as object: {"0":{"0":1,"1":2,"2":3}}
Related
I have a php array, and inside the array is a reference to another php object with a numerical value.
How can i access the elements in this array without knowing that numerical id (it could be different for each array)?
In the image below, I need to get the values inside field_collection_item like so....
$content['field_image_columns'][0]['entity']['field_collection_item'][133]['field_image']
For the first array key (0) i have done the following...
$i = 0;
while($i <= 2) {
if(isset($content['field_image_columns'][$i])) {
print '<div class="column-' . $i . '">';
foreach ($content['field_image_columns'][$i]['entity']['field_collection_item'] as $fcid => $values) {
// Print field values
}
print '</div>';
}
$i++;
}
Doing a foreach loop for a single array item seems wrong - is there a method i should be using for this use case?
You can select first item of array for example with:
Use array_shift, but it will modify source array:
$cur = array_shift($content['field_image_columns'][$i]['entity']['field_collection_item']);
print $cur['field_image'];
Get keys of array with array_keys and use first element of result as a key
$ks = array_keys($content['field_image_columns'][$i]['entity']['field_collection_item']);
print $content['field_image_columns'][$i]['entity']['field_collection_item'][$ks[0]]['field_image'];
Use current function:
$cur = current($content['field_image_columns'][$i]['entity']['field_collection_item']);
print $cur['field_image'];
As with most programming, there are quite a few ways you could do it. If a foreach works, then it isn't wrong, but it may not be the best way.
// Get the current key from an array
$key = key($array);
If you don't need the key, then you can just get the value from the array.
// Get the current value from an array
$value = current($array);
Both of these will retrieve the first key/value from the array assuming you haven't advanced the pointer.
current, key, end, reset, next, & prev are all array functions that allow you to manipulate an array without knowing anything about the internals. http://php.net/manual/en/ref.array.php
I am trying to retrieve user data from a SQL table where one of the columns is blob_medium. I run the SQL query properly and get the data in the php script.
if(mysqli_num_rows($result)){
while($row=mysqli_fetch_assoc($result)){
$result_array['user_data'][]=$row;
}
}
Now, to json_encode this data, I need to encode the data of user_pic column to base 64. For that I am trying this. But, it seems I am doing something wrong. Any kind of help would be appreciated.
foreach($result_array as $key){
foreach($key as $key2){
//print_r(base64_encode($key2['user_pic']).'<br/>'.'<br/>');
$key2['user_pic'] = base64_encode($key['user_pic']);
//print_r(($key['user_pic']).'<br/>'.'<br/>');
}
}
When I uncomment the print_r statements my data is printed in base64 format but the data of the assoc array is not changing.
That's because the array's $key and $keys in the for loop are copies. If you want them to modify the original you can either do it by specifying them to be references, not copies:
foreach($result_array['user_data'] as &$key){
$key['user_pic'] = base64_encode($key['user_pic']);
}
Or by explicit index into the original:
foreach($result_array['user_data'] as $index => $key){
$result_array['user_data'][$index] ['user_pic'] = base64_encode($key['user_pic']);
}
That's because you're changing the $key2 array. A temporary value created by your foreachloop. I myself would recommend using a for loop in this specific situation, because I was told to never use a loop within a loop if I can prevent it, and it makes things a lot easier to read:
for($i=0; $i < count($result_array['user_data']); $i++){
$encodedUserPic = base64_encode($result_array['user_data'][$i]['user_pic']);
$result_array['user_data'][$i]['user_pic'] = $encodedUserPic;
}
I want to remove an element from an array (converted from json), but with unset, and reconvert in json, the array become indexed.
Source array:
{"rows":
[{"c":[{"v":"Date(1409052482000)"},{"v":22},{"v":22},{"v":22},{"v":null}]},
{"c":[{"v":"Date(1409052614000)"},{"v":22},{"v":22},{"v":22},{"v":null}]},
{"c":[{"v":"Date(1409052782000)"},{"v":22},{"v":22},{"v":22},{"v":null}]}
]}
Result:
{"rows":
"2":{"c":[{"v":"Date(1409052614000)"},{"v":22},{"v":22},{"v":22},{"v":null}]},
"3":{"c":[{"v":"Date(1409052782000)"},{"v":22},{"v":22},{"v":22},{"v":null}]}
}}
the problem is the "2" and "3" keys. I don't want this keys, because I use the data for google chart, and is sensible for this index key.
PHP code:
$tempdata = json_decode($jsonTempLog, TRUE);
foreach ($tempdata['rows'] as $key => $row) {
if ( $logtime < $showtime) {
unset($tempdata['rows'][$key]);
}
}
echo json_encode($tempdata);
How can I remove element from array, keep the original json syntax?
Just do this:
$tempdata["rows"] = array_values($tempdata["rows"]);
echo json_encode($tempdata);
Otherwise JSON thinks you're sending an associative array rather a numeric one
this is how i work with :
unset($infos[$i]);
$infos = array_values($infos);
maybe like this:
foreach($tempdata as $row){
$tempdata[$rows['keyfield']] = $row;
}
If you have any array $p that you populated in a loop like so:
$p[] = array( "id"=>$id, "Name"=>$name);
What's the fastest way to search for John in the Name key, and if found, return the $p index? Is there a way other than looping through $p?
I have up to 5000 names to find in $p, and $p can also potentially contain 5000 rows. Currently I loop through $p looking for each name, and if found, parse it (and add it to another array), splice the row out of $p, and break 1, ready to start searching for the next of the 5000 names.
I was wondering if there if a faster way to get the index rather than looping through $p eg an isset type way?
Thanks for taking a look guys.
Okay so as I see this problem, you have unique ids, but the names may not be unique.
You could initialize the array as:
array($id=>$name);
And your searches can be like:
array_search($name,$arr);
This will work very well as native method of finding a needle in a haystack will have a better implementation than your own implementation.
e.g.
$id = 2;
$name= 'Sunny';
$arr = array($id=>$name);
echo array_search($name,$arr);
Echoes 2
The major advantage in this method would be code readability.
If you know that you are going to need to perform many of these types of search within the same request then you can create an index array from them. This will loop through the array once per index you need to create.
$piName = array();
foreach ($p as $k=>$v)
{
$piName[$v['Name']] = $k;
}
If you only need to perform one or two searches per page then consider moving the array into an external database, and creating the index there.
$index = 0;
$search_for = 'John';
$result = array_reduce($p, function($r, $v) use (&$index, $search_for) {
if($v['Name'] == $search_for) {
$r[] = $index;
}
++$index;
return $r;
});
$result will contain all the indices of elements in $p where the element with key Name had the value John. (This of course only works for an array that is indexed numerically beginning with 0 and has no “holes” in the index.)
Edit: Possibly even easier to just use array_filter, but that will not return the indices only, but all array element where Name equals John – but indices will be preserved:
$result2 = array_filter($p, function($elem) {
return $elem["Name"] == "John" ? true : false;
});
var_dump($result2);
What suits your needs better, resp. which one is maybe faster, is for you to figure out.
I am trying to calculate percentiles for users in a database. In order to do this I have a $data array that I need to sort.
I have a query object that contains User_ID, Total_User_Orders, and Total_Orders. Here's how the code looks so far:
// Loop through the users
foreach($query->result() as $row)
{
(string)$user_id = (string)$row->user_id;
$data[$user_id] = number_format((($row->total_user_orders/$row->total_orders)*100), 5);
}
// Sort the $data array
array_multisort($data);
print_r($data);
What (I believe) that should do is typecast $row->user_id (an int) as a string. Then, the $data[$user_id] index should be set as a string - right...?
When I sort the array using array_multisort it sorts it as though the index was an Integer, rather than a String. This means it loses the index.
The PHP manual for array_multisort() states, "Associative (string) keys will be maintained, but numeric keys will be re-indexed.". I have also tried using array_multisort($data, SORT_STRING), but the same output occurs. However - it does work when I do $data['#'.$user_id], but this doesn't quite feel like the right solution to me!
Can anyone help? Thanks in advance!
I think you're overcomplicating things. With no testing, I'd think indexing the $data-array like this would work:
$data[(string)$row->user_id] = ...
or
$data[''.$user_id] = ...
EDIT:
Otherwise you could build your array multi-dimensional and sort by one of the indices, like this:
foreach($query->result() as $row) {
$data[] = array(
'user_id' => $row->user_id,
'percent' => number_format((($row->total_user_orders/$row->total_orders)*100), 5);
);
}
Or you could index by the percentage and sort by the keys (using ksort()):
foreach($query->result() as $row) {
$data[number_format((($row->total_user_orders/$row->total_orders)*100), 5)] = $row->user_id];
}
The last solution could be dangerous if several users have the same percentage.
Personally I would probably go with the asort() solution mentioned above.
As described in my comment, array_multisort() is not what you are after here. You don't have multiple arrays or a multi-dimensional array.
To maintain the key => value association in the array and sort the contents use asort().
foreach ($query->result() as $row) {
$percent = ($row->total_user_orders / $row->total_orders) * 100;
$data[$row->user_id] = number_format($percent, 5);
}
asort($data);
If you want descending percentages reverse the array after it's been sorted.
$data = array_reverse($data, true);