I have a result of an SQL query that looks like this
Array
(
[0] => stdClass Object
(
[field_number] => 1
[value] => Joe
)
[1] => stdClass Object
(
[field_number] => 2
[value] => Bloggs
)
[2] => stdClass Object
(
[field_number] => 3
[value] => 12566
)
[3] => stdClass Object
(
[field_number] => 4
[value] => 2000-07-24
)
)
It wont always return all the fields as some are not required therefore not saved to the database.
I know that first name is stored with field number 1. How can I look this up in the object.
EG
$first_name = $result => field_number == 1
I know thats not right, but Im sure there must be a simple way to get this info?
Thanks
If the values in the array are not in order (eg array[0] does not always contain field_number 1) then you will need to iterate the array:
foreach($array as $item){
if($item->field_number==1){
$first_name = $item->value;
break;
}
}
However, if this is the result of an SQL query, probably you need to rewrite the query to give you data in a more useable form
Related
I'm new to backend programming and CodeIgniter is my first framework. This is new to me. Right now, the thing that I'm working is that I need to create a query based on the JSON encoded data saved at my table.
I have here a segmentation form that should build a query to look/search for the customers profiles based on the condition set
Segmentation form
$segment = array(
...
'filters' => json_encode($post['filters']), //to insert the filters in json
...
);
if ($this->model->addSegments($segment))
The filters saved in the database are like this :
{"data":[{"data":{"condition":"0","attribute":"gender","sign":"=","value":"Male"},"type":"condition","operator":"0","filter":{"operator":"0"}}],"type":"match","operator":"0"}
Looking for the answers, I found this forum and I relate it to the problem that I had: http://www.codingforums.com/php/202207-turning-json-object-into-nested-sql-where-clause.html
Calling the same like function (solution at the link) to the controller using this lines:
$filter = $this->model->getSegmentsFilters($id_segment);
$filters = $this->model->parseFilterToQuery(json_decode($filter['filters'], true));
With the parameter TRUE from the json_decode, It throws the filters in array and using print_r shown like this:
Array (
[0] => Array (
[data] => Array (
[condition] => 0
[attribute] => firstname
[sign] => =
[value] => John )
[type] => condition
[operator] => 0
[filter] => Array (
[operator] => 0 )
)
[1] => Array (
[data] => Array (
[condition] => 0
[attribute] => gender
[sign] => =
[value] => Male )
[type] => condition
[operator] => condition
[filter] => Array (
[operator] => 0 )
)
)
the $sql inside if(is_array) doesn't show any value to concatenate with. I want it to concatenate with another query as a WHERE clause like this idea.
$sql = "SELECT * FROM customers WHERE" . parseFilterToQuery($filters);
If you think that the solution/procedure that I came up is correct. My question is that inside the if(is_array) condition,
how should I work on it with associative JSON array?
I have the following array in my Moodle plugin:
Array (
[0] => stdClass Object (
[id] => 32
[sessionid] => 5
[sessiontimezone] => CET
[timestart] => 1464071400
[timefinish] => 1464102000 )
[1] => stdClass Object (
[id] => 33
[sessionid] => 5
[sessiontimezone] => CET
[timestart] => 1465281000
[timefinish] => 1465311600 )
)
How to get the data. Right now, when I make:
$pluginsessiondates = $DB->get_record('plugin_sessions', array('id'=>$sessionid));
I get only data from the frist array [0]
How to get the data from every array key and then the single values? Thanks in advance.
The Moodle DB functions are for getting data out of the database, rather than from an array somewhere inside your plugin.
If you have an array somewhere, then you can get fields from it by writing:
echo $myarray[0]->id;
echo $myarray[1]->id;
etc.
If you are not trying to get data out of an existing array and want, instead, to get it out of the database, then $DB->get_record() will, as its name implies, get you only a single record, whereas $DB->get_records() will get you all the matching records:
$sessions = $DB->get_records('plugin_sessions', array('sessionid' => $sessionid));
foreach ($sessions as $session) {
echo $session->id;
}
I want to store the contents of a specific database into an array, grouped by their primary keys. (Instead of the useless way PDO fetchAll() organises them).
My current code:
$DownloadsPDO = $database->dbh->prepare("SELECT * FROM `downloads`");
$DownloadsArray = $DownloadsPDO->execute();
$DownloadsArray = $DownloadsPDO->fetchAll();
Which then outputs:
Array ( [0] => Array ( [id] => 0 [0] => 0 [path] => /xx-xx/testfile.zip [1] => /xx-xx/testfile.zip [name] => Test Script [2] => Test Script [status] => 1 [3] => 1 ) [1] => Array ( [id] => 1 [0] => 1 [path] => /xx-xx/test--file.zip [1] => /xxxx/testfile.zip [name] => New Script-UPDATE [2] => New Script-UPDATE [status] => 1 [3] => 1 ) )
I was considering to use PDO::FETCH_PAIR, however I will be very soon expanding the amount of data I want to be able to use on this script. This works currently, but when I start to expand the amount of downloads and more clients come into play, obviously the way the data is grouped causes an issue.
Is it possible for me to group each array by their primary key (which is id)?
You can just use
$results = array_map('reset', $stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC))
PDO::FETCH_GROUP|PDO::FETCH_ASSOC returns an array of arrays. The first column is used as the key, and then within key is an array of all the results for that key. However, in our scenario each key will only contain 1 row. reset() returns the first element in array, thus eliminating 1 level of nesting.
This should yield what you are looking for :
$results = $pdos->fetchAll(\PDO::FETCH_UNIQUE|\PDO::FETCH_ASSOC);
I decided to just loop through the results with fetch() and enter them into an array as I go along, this is the code I have used and it works just fine:
$DownloadsPDO = $database->dbh->query("SELECT * FROM `downloads`");
$Array = array();
while ($d = $DownloadsPDO->fetch()) {
$Array[$d['id']]["id"] = $d['id'];
$Array[$d['id']]["name"] = $d['name'];
$Array[$d['id']]["path"] = $d['path'];
}
// Outputs
Array ( [1] => Array ( [id] => 1 [name] => Test Script [path] => /xxxx/testfile.zip ) [2] => Array ( [id] => 2 [name] => New Script-UPDATE [path] => /xxxx/testfile.zip ) )
Which uses the primary key (being id) as the name for the array key, and then adds the data into it.
Thought I would add this as the answer as this solved it, thanks to the guys that helped out and I hope this is helpful to anyone else hoping to achieve the same thing.
I'd like to point out the only solution that works for me:
fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_UNIQUE|\PDO::FETCH_ASSOC);
Beware that this will strip the first column from the resultset. So the query must be:
SELECT id_keyname AS arrkey, id_keyname, .... FROM ...
I'm still suggesting you to loop using fetch() method. Otherwise, you can use array_reduce() to iterate over the array. A sample on codepad is here.
The code(in human readable form) will be:
$myFinalArray = array_reduce($myInputArray, function($returnArray, $temp) {
$temp2 = $temp['id'];
unset($temp['id']);
$returnArray[$temp2] = $temp;
return $returnArray;
}
);
So, my question is; is it possible for me to group each array by their
primary key (which is id)
Off course, you have 2 options here: Either to change the query or parse a result-set.
So, I'm sure you don't want to change query itself, so I'd go with parsing result-set.
Note:
You should use prepared SQL statements when they make sense. If you want to bind some parameters then its OKAY. But in this case, you only want get get result-set, so prepare() and fetch() will be kinda overdo.
So, you have:
Array ( [0] => Array ( [id] => 0 [0] => 0 [path] => /xx-xx/testfile.zip [1] => /xx-xx/testfile.zip [name] => Test Script [2] => Test Script [status] => 1 [3] => 1 ) [1] => Array ( [id] => 1 [0] => 1 [path] => /xx-xx/test--file.zip [1] => /xxxx/testfile.zip [name] => New Script-UPDATE [2] => New Script-UPDATE [status] => 1 [3] => 1 ) )
And you want:
Array( [id] => Array('bar' => 'foo') ....)
Well, you can do something like this:
$stmt = $database->dbh->query("SELECT * FROM `downloads`");
$result = array();
foreach($stmt as $array){
$result[$array['id']] = $array;
}
print_r($result); // Outputs: Array(Array('id' => Array(...)))
If I have the following array in session, can I get a item position number in each [cat]:
Array
(
[0] => stdClass Object
(
[id] => 1
[cat] => 1
[que] => Description here.
)
[1] => stdClass Object
(
[id] => 2
[cat] => 1
[que] => Description here.
)
[2] => stdClass Object
(
[id] => 3
[cat] => 1
[que] => Description here.
)
)
For example the following will give me the second description, but how do I get that it has position #2 (out of 3) in [cat] == 1:
$item = $_SESSION['questions'][2]->que;
The actual array is much larger and has more than 1 [cat]. The count I am trying to get is withing each such group.
I'm sure you're looking for a more native way, but worse case scenario, you could add another element to hold the index value.
By adding a dummy entry at the beginning of the array:
array_unshift($_SESSION['questions'], array());
$item = $_SESSION['questions'][2]->que;
foreach($_SESSION['questions'] as $key=>$val)
{
if($val->id == 3)
echo $key;
}
//or
foreach($_SESSION['questions'] as $key=>$val)
{
if($val->que == "Description here.")
echo $key;
}
//do what ever you want
I've seen similar questions on here but I can't seem to apply the solutions to my problem. I have a variable called $results which I got from an API. I'll change the proper nouns so as to protect my work's customers:
stdClass Object
(
[out] => stdClass Object
(
[count] => 2
[transactions] => stdClass Object
(
[RealTimeCommissionDataV2] => Array
(
[0] => stdClass Object
(
[adId] => 12345678
[advertiserId] => 123456789
[advertiserName] => Chuck E. Cheese, inc.
[commissionAmount] => 50
[country] => US
[details] => stdClass Object
(
)
[eventDate] => 2009-11-16T09:44:25-08:00
[orderId] => X-XXXXXXXXXX
[saleAmount] => 0
[sid] => 123456789
[websiteId] => 2211944
)
[1] => stdClass Object
(
[adId] => 987654321
[advertiserId] => 12345
[advertiserName] => Chorizon Wireless.
[commissionAmount] => 50
[country] => US
[details] => stdClass Object
(
)
[eventDate] => 2009-11-16T09:58:40-08:00
[orderId] => X-CXXXXXX
[saleAmount] => 0
[sid] => 61-122112
[websiteId] => 1111922
)
)
)
)
)
I shortened it to two entries here but the number of entries will vary, it's the result of a check for transactions in the past hour, there may sometimes be only one and sometimes as many as a dozen.
I want to assign these entries to variables like websiteId1 websiteId2 etc. I know I need to do a foreach loop but can't seem to figure it out. How can I write it so that I get the "[details]" as well?
foreach ($results->out->transactions->RealTimeCommissionDataV2 AS $commissionData) {
// you can access the commissionData objects now, i.e.:
$commissionData->adId;
$commissionData->details;
}
<?
foreach ($result->out->transactions->RealTimeCommissionDataV2 as $item)
{
// do somthing with each item.
print_r($item);
// or the details array
$num_details = sizeof($item->details)
}
I think this is what you want.
EDIT
Updated based on some notes in the documentation. Specifically, these two
a numerically indexed array will not
produce results unless you use
EXTR_PREFIX_ALL or
EXTR_PREFIX_INVALID.
Prefixes are automatically separated
from the array key by an underscore
character.
echo extract( $results->out->transactions->RealTimeCommissionDataV2, EXTR_PREFIX_ALL, 'websiteId' );
// test the extract
print_r( $websiteId_0 );