How to get access to class field which is variable - php

Firstly, look my example json output.
I have next question. I have some fields in json code like 'counter_87' or 'coutner_88' in countersData part. It is a variable. I need to get access to this variable class field.
Ofc, I can write:
foreach($objCounter->countersData as $data)
{
print $data->counter_87;
}
It is working fine. But...
I have counters ID and I need to get access to fields which are named depending on this ID's.
Full code, which will show what I want:
foreach($objCounter->countersData as $data)
{
$row = "<td width=100px>$data->month $data->year</td>";
foreach($objCounter->counters as $counter)
{
$counterId = $counter->id;
$counterValue = "$data->counter_$counterId";
$row .= "<td>$counterValue</td>";
}
$table .= "<tr>$row</tr>";
}
I need same:
$foo = 'bar';
$bar = 'foobar';
echo $$foo; // foobar will be printed
But with classes.
Thank you.

You could also do the following if you don't want to or can't change change your JSON structure as already mentioned in the comments.
$field_name = 'counter_'.$id;
$field_value = $data->$field_name;
$row .= "<td>$field_value</td>";
// or $row .= '<td>'.$data->$field_name.'</td>';
About rewriting the JSON. Here's code that would convert your JSON to the slightly better structure.
$data = json_decode($data_json);
foreach($data->countersData as $counter_data) {
$counters = array();
foreach($counter_data as $key => $val) {
if(substr($key, 0, 8) == 'counter_') {
$counters[substr($key, 8)] = $val;
unset($counter_data->$key);
}
}
$counter_data->counters = $counters;
}
$data_json_new = json_encode($data);
Using an array instead of fields like 'counter_1', 'counter_2' means having structure like this this:
$countersData[0]->counters[90] = 1;
$countersData[0]->counters[89] = 1;
$countersData[0]->counters[88] = 1;
Instead of
$countersData[0]->counters_90 = 1;
$countersData[0]->counters_89 = 1;
$countersData[0]->counters_88 = 1;
This means having an associative array called counters instead of separate fields like 'counter_90' or something. It makes accessing the data programmatically alot easier.
Note that associative array is very similar to the stdClass. Basically a different datatype serving the same purpose. Using an array to represent your data just makes it easier to deal with integer keys. You can use json_decode($data_json, true) to get the data returned as an associative array.

Related

want to convert a key value pair to standard class object

Hi I need help [this is my table structure] and my current [JSON response is like this] and I want to convert this to [like this JSON response]
Can anybody give some idea or any related code so that I can make my JSON response like that.
*Note I can't create another table to store user images
First you don't need to concatenate your base_url to all images, you can use it separately in your front file, unless it must be there.
Second you don't need to store user_id to your image structure, because you have id right in your table's structure.
anyway you can do something like snippet below.
I hope it works fine :)
Edit:
It is easier to work with arrays in PHP so I convert my code to array version and if you need to use object first convert your object to array and after snippet you can convert it to object like (object) $data
foreach ($data as &$user) {
if(!empty($user['main_image'])) {
$user['main_image'] = $image_basepath . $user['main_image'];
}
$user['image'] = [];
for($i = 1; $i <= 6; $i++) {
$imgArr = [];
$img = $user['optnl_img' . $i];
unset($user['optnl_img' . $i]);
if(isset($img) && !empty($img)) {
$imgArr['id'] = $i;
$imgArr['user_id'] = $user['id'];
$imgArr['image'] = $image_basepath . $img;
}
$user['image'][] = $imgArr;
}
}

Variable Variables for Array Key

Currently I am attempting to call a multidimensional array, using a string as a key or keys. I would like to use the following code, but I think the key is being interpreted as a string. Any solution?
$data= [];
$data['volvo'] = "nice whip";
$test = "['volvo']";
$data['drivers']['mike'] = "decent";
$test2 = "['drivers']['mike']";
echo $data$test; // should read 'nice whip'
echo $data$test2; // should read 'decent'
You just use the variable (which should just be the string and not PHP syntax) in place of the string literal.
$cars = [];
$cars['volvo'] = 'nice whip';
$test = 'volvo';
echo $cars[$test];
If you need a dynamic array access solution, you could also write a function, which does the actual array access like this:
function path($array, $path) {
$path = is_array($path) ? $path : explode('.', $path);
$current = $array;
while (count($path)) {
$seg = array_shift($path);
if (!isset($current[$seg])) throw new Exception('Invalid path segment: ' . $seg);
$current = $current[$seg];
}
return $current;
}
In your case, this would look like this
echo path($data, 'volvo');
echo path($data, 'drivers.mike');
or
echo path($data, ['volvo']);
echo path($data, ['drivers', 'mike']);
The problem is you can't pass multiple levels in one string like that. (If so, PHP would have to start looking for code fragments inside string array keys. And how would it know whether to interpret them as fragments and then split the string key up, or keep treating it as one string??)
Alt 1
One solution is to change the structure of $data, and make it a single level array. Then you supply keys for all the levels needed to find your data, joined together as a string. You would of course need to find a separator that works in your case. If the keys are plain strings then something simple like underscore should work just fine. Also, this wouldn't change the structure of your database, just the way data is stored.
function getDbItem($keys) {
// Use this to get the "old version" of the key back. (I.e it's the same data)
$joinedKey = "['".implode("'],['", $keys)."']";
$joinedKey = implode('_', $keys);
return $data[$joinedKey];
}
// Example
$data = [
'volvo' => 'nice whip',
'drivers_mike' => 'decent'
];
var_dump(getDbItem(['drivers', 'mike'])); // string(6) "decent"
Alt 2
Another way is to not change number of levels in $data, but simply traverse it using the keys passed in:
$tgt = $data;
foreach($keys as $key) {
if (array_key_exists($key, $tgt)) {
$tgt = $tgt[$key];
}
else {
// Non existing key. Handle properly.
}
}
// Example
$keys = ['drivers', 'mike'];
// run the above code
var_dump($tgt); // string(6) "decent"

PHP/MYSQL: Access data in Array of Dictionaries

I receive a JSON stream from an iphone that contains some simple strings and numbers as well as an array of dictionaries. I would like to work with these dictionaries, in essence, storing the data in each of them in a separate MYSQL record.
To get access to the strings as well as the array from the JSON stream, I am using the following:
$jsonString = file_get_contents('php://input');
$jsonArray = json_decode($jsonString, true);
$authString = jsonArray['authstring'];
$itemsArray = $jsonArray['itemsArray'];
This is what itemsArray looks like before being sent to the server:
itemsArray = (
{
lasttouchedstr = "2018-07-09 17:24:56";
localiid = 6;
iid = 0;
title = "test";
complete = 1;
userid = 99;
whenaddedstr = "2018-06-21 14:10:23";
},
{
lasttouchedstr = "2018-07-09 17:24:56";
localiid = 37;
iid = 0;
title = "how about this";
userid = 88;
whenaddedstr = "2018-07-07 16:58:31";
},
{
lasttouchedstr = "2018-07-09 17:24:56";
localiid = 38;
iid = 0;
title = reggiano;
userid = 1;
whenaddedstr = "2018-07-07 17:28:55";
}
etc.
I guess I should probably put these dictionaries into an Associative Array in order to save them.
I am struggling, however, with how to reference and get the objects. From what I can tell the following code is returning empty values in so far as $message comes back as empty.
$anitem = $jsonArray['itemsArray'][0];
$message=$anitem;
$title = $jsonArray['itemsArray'][0].[item];
$message.=$title;
Can anyone suggest proper syntax to grab these items and their properties?
Thanks in advance for any suggestions.
I find it strange that people associate things with a dictionary, while it is nothing more then a multidimensional array.
If you can read JSON, you see that the variable will have an index containing each entry.
For PHP:
foreach($jsonArray as $array){
// note that $array is still an array:
foreach($array as $v){
echo "Hurray!: '$v'";
}
}
If it really was an object (or cast to an object), the only thing you need to change is how you access the variable (as in any other language). In PHP it would be:
echo $jsonArray[0]->lasttouchedstr;
Or of it was the same loop:
foreach($jsonArray as $v){
echo $v->lasttouchedstr;
}
Multidimensional?
echo $jsonArray['itemsArray'][0][item]; // array
echo $jsonArray->itemsArray[0][item]; // if items array is an actual array and jsonArray an object.
Most languages associate things written as a . that the left side is an object. In PHP it's written as ->.

How to use variable inside the parameter of $_POST in php

I will be getting some certain amount of data. I will get the number for which the for loop to be run.
For example
I get the number 3 and I will get three parameters like par1,par2 and par3 then how should I pass this par1 in the $_post
like
$i=$_POST["number"];
for($i=1;$i<=$n;$i++)
{
$par.$i = $_POST["par".$i];
}
Here I cant get the value from $_POST["par".$i];
As it is not able to get the variable inside the paramater of $_POST
Any help will be thankful
I suggest that you create a new array $par and there you will put by index all the par you will have like this:
$i=$_POST["number"];
$par = [];
for($i=1;$i<=$n;$i++)
{
$par[$i] = $_POST["par".$i];
}
After that if you want to go throw all pars you can simply use foreach like this:
foreach($par as $key => $value) {
// $key will be 1,2,3
// $value will be the value from $_POST["par" . $i]
}
The . is to concatenate two strings in PHP, and you can't create a new variable like you tried. If you want to have in $par1, $par2 and $par3 you can do like this:
${"par" . $i} = $_POST["par".$i];
But I don't recommend this way because it's more hard to handle.
One Way
According to your question.
<?php
$n = $_POST["number"];
$par = "par";
for($i=1; $i<=$n; $i++){
$par.$i = $_POST["par".$i];
}?>
Alternative Way
In this scenario,
For example I get the number 3 and I will get three parameters like
par1,par2 and par3 then how should I pass this par1 in the $_post.
Better, make 'par' input name as an array type as 'par[]' (<input type='text' name='par[]'>) in your file instead using par1, par2 .. par(n).
And, no need to worry in submit page.
<?php
$n = $_POST["number"];
for($i=1;$i<= $n;$i++){
$newPar = $_POST["par"][$i];
// Write here your logic to use how you want.
}
?>

PHP array copy certain keys, built-in functions? Nested loop performance?

I have a PHP array that I'd like to duplicate but only copy elements from the array whose keys appear in another array.
Here are my arrays:
$data[123] = 'aaa';
$data[423] = 'bbb';
$data[543] = 'ccc';
$data[231] = 'ddd';
$data[642] = 'eee';
$data[643] = 'fff';
$data[712] = 'ggg';
$data[777] = 'hhh';
$keys_to_copy[] = '123';
$keys_to_copy[] = '231';
$keys_to_copy[] = '643';
$keys_to_copy[] = '712';
$keys_to_copy[] = '777';
$copied_data[123] = 'aaa';
$copied_data[231] = 'ddd';
$copied_data[643] = 'fff';
$copied_data[712] = 'ggg';
$copied_data[777] = 'hhh';
I could just loop through the data array like this:
foreach ($data as $key => $value) {
if ( in_array($key, $keys_to_copy)) {
$copied_data[$key] = $value;
}
}
But this will be happening inside a loop which is retrieving data from a MySQL result set. So it would be a loop nested within a MySQL data loop.
I normally try and avoid nested loops unless there's no way of using PHP's built-in array functions to get the result I'm looking for.
But I'm also weary of having a nested loop within a MySQL data loop, I don't want to keep MySQL hanging around.
I'm probably worrying about nested loop performance unnecessarily as I'll never be doing this for more than a couple of hundred rows of data and maybe 10 keys.
But I'd like to know if there's a way of doing this with built-in PHP functions.
I had a look at array_intesect_key() but that doesn't quite do it, because my $keys_to_copy array has my desired keys as array values rather than keys.
Anyone got any ideas?
Cheers, B
I worked it out - I almost had it above.I thought I'd post the answer anyway for completeness. Hope this helps someone out!
array_intersect_key($data, array_flip($keys_to_copy))
Use array_flip() to switch $keys_to_copy so it can be used within array_intersect_keys()
I'll run some tests to compare performance between the manual loop above, to this answer. I would expect the built-in functions to be faster but they might be pretty equal. I know arrays are heavily optimised so I'm sure it will be close.
EDIT:
I have run some benchmarks using PHP CLI to compare the foreach() code in my question with the code in my answer above. The results are quite astounding.
Here's the code I used to benchmark, which I think is valid:
<?php
ini_set('max_execution_time', 0);//NOT NEEDED FOR CLI
// BUILD RANDOM DATA ARRAY
$data = array();
while ( count($data) <= 200000) {
$data[rand(0, 500000)] = rand(0, 500000);
}
$keys_to_copy = array_rand($data, 100000);
// FOREACH
$timer_start = microtime(TRUE);
foreach ($data as $key => $value) {
if ( in_array($key, $keys_to_copy)) {
$copied_data[$key] = $value;
}
}
echo 'foreach: '.(microtime(TRUE) - $timer_start)."s\r\n";
// BUILT-IN ARRAY FUNCTIONS
$timer_start = microtime(TRUE);
$copied_data = array_intersect_key($data, array_flip($keys_to_copy));
echo 'built-in: '.(microtime(TRUE) - $timer_start)."s\r\n";
?>
And the results...
foreach: 662.217s
array_intersect_key: 0.099s
So it's much faster over loads of array elements to use the PHP array functions rather than foreach. I thought it would be faster but not by that much!
Why not load the entire result set into an array, then begin processing with nested loops?
$query_result = mysql_query($my_query) or die(mysql_error());
$query_rows = mysql_num_rows($query_result);
for ($i = 0; $i < $query_rows; $i++)
{
$row = mysql_fetch_assoc($query_result);
// 'key' is the name of the column containing the data key (123)
// 'value' is the name of the column containing the value (aaa)
$data[$row['key']] = $row['value'];
}
foreach ($data as $key => $value)
{
if ( in_array($key, $keys_to_copy))
{
$copied_data[$key] = $value;
}
}

Categories