I have a simple query like this
SELECT hometeam.name AS hometeamName, hometeam.shortname AS hometeamShortName,
roadteam.name AS roadteamName, roadteam.shortname AS roadteamShortName,
smatch.startdate
FROM smatch
JOIN team hometeam
ON smatch.hometeamid = hometeam.uid
JOIN team roadteam
ON smatch.roadteamid = roadteam.uid
which be default returns a one dimensional array, like this:
array(5) {
["homeTeamName"] => "Brasil"
["homeTeamShortName"] => "BRA"
["roadTeamName"] => "Norway"
["roadTeamShortName"]=> "NOR"
["startdate"]=> "1309709700"
}
Question is, is there a mysql-way to let the result be a nested array, with a structure like the following?
result =>
hometeam =>
name
shortname
roadteam =>
name
shortname
startdate
And if not, is there a (php) post processing best practice to do this conversion?
Many thanks,
Robson
I don't think there's a way to directly get the result you want, but to generate that array after the query shouldn't be hard.
Something like this?
foreach($rows as $row) {
$resultArray[] = array(
'hometeam' => array(
'name' => $row['homeTeamName'],
'shortname' => $row['homeTeamShortName']
),
'roadteam' => array(
'name' => $row['roadTeamName'],
'shortname' => $row['roadTeamShortName']
),
'startdate' => $row['startdate']
);
}
MySQL (or any database) has no concept of arrays.
The only way I can think of is that you'd need to do it in a Stored Procedure and serialise the result in some way - essentially creating a serialised string... wich you'd then need to re-construct the array from.
However, would be better doing this in PHP to be honest, the gain from doing it in an SP will be minimal. Will be more efficient to query the main and then query within using loops PHP-side.
You have to fetch the result in PDO::FETCH_CLASS mode.
by specifying the __set()-method respectively you can store the result-field-data how ever you like.
This class should also extend ArrayAccess so you can access it like an array or have it return one.
Related
I'm currently manually building an array.
$this->array_list = array('Alaska' => 'Alaska',
'Amanda' => 'Amanda',
'America' => 'America',
'Anthea' => 'Anthea',
'Arena' => 'Arena',
'Atlantis' => 'Atlantis'
);
I have a database that i can query this list from, My question is how do I create the array with key and value once getting the list from the query? Key and Value will always be the same. Using mysql and codeigniter.
Query DB for list, create two arrays and use combine? Has to be an easier way?
Here is what I ended up doing. Probably not the best way, feel free to give better way to do this.
$sofa_list2 = $this->get_media_model->get_sofas();
foreach ( $sofa_list2 as $k=>$v )
{
$newkey = $sofa_list2[$k]['collection_name'];
$sofa_list2[$k] ["$newkey"] = $sofa_list2[$k] ['collection_name'];
unset($sofa_list2[$k]['collection_name']);
}
$sofa_list2 = call_user_func_array('array_merge', $sofa_list2);
I'm working on a PHP script to hold a lot of information.
Lets try to explain our situation!
I have actually 33 different stations.
For each of that 33 stations I have 5 different categories.
And for each of that 33 stations with each 5 different categories i have 37 different values per category.
Do I need an 2d of 3d array for store this information in it ?
Thanks you!
Something like this will work, just add more data as needed:
$station_array =
array(
'station1' => array(
'cat1' => array ('val1','val2','val3'),
'cat2' => array ('val1','val2','val3'),
'cat3' => array ('val1','val2','val3')
),
'station2' => array (
'cat1' => array ('val1','val2','val3'),
'cat2' => array ('val1','val2','val3'),
'cat3' => array ('val1','val2','val3')
),
'station3' => array (
'cat1' => array ('val1','val2','val3'),
'cat2' => array ('val1','val2','val3'),
'cat3' => array ('val1','val2','val3')
)
);
Sounds like a job for a relational database!
But you're correct in your initial assumption. You will need a 3-dimensional array to hold your information because your data has 3 tiers: the stations, the categories, and the values.
A php array will be fine for this
$MyArray = array('Station1' => array('Category1' =>
array('Value1'=> 1000,'Value2'=> 1001),
'Category2' => array('Value1' => 2332)), etc...
'Station2' => array('Category1' =>
array('Value1'=> 1000,'Value2'=> 1001),
'Category2' => array('Value1' => 2332)), etc
etc
);
Once you pass more than two dimensions in an associative array, it's good to start considering using objects to store your information. Objects make it a lot easier to understand how things are organized, they can enforce validation restrictions on your data (make sure it's in the form it should be), and you can call functions on the data to manipulate it (instead of having random external functions manipulating your entire array). An example would be:
class CategoryValue {
var $val; // your value
function __construct($val) {
$this->val = $val;
}
}
class Category {
var $values = array(); // an array of CategoryValue objects
function addValue(CategoryValue $val) {
$this->values[] = $val;
}
}
class Station {
var $categories = array(); // an array of Category objects
function addCategory(Category $category) {
$this->categories[] = $category;
}
}
well, all depends on how you want to acheive, if you dont need to loop through the values, but you just want to store data and alway know whay you want to get, you could use hashes for that, the table would look like:
$data = array(
md5('StationX'.'CategoryY'.'PropertyZ') => 'ValueU',
md5('StationA'.'CategoryB'.'PropertyC') => 'ValueQ'
);
This way you can get the data right away and dont have to bother to check if you initialised CategoryB array for StationA when you want to add value for PropertyZ
php stores associative arrays as hastables technically
... thats all if you really insist on not using databases ;)
I'm not familiar with CakePHP too close. Recently I've ran into problem using Model. I need to get exaclty one row from database, modify some columns values and save it back. Pretty simple, right?
What do I try to do:
$condition = array('some_id_column' => $another_models_id);
$model = $this->MyModel->findFirst($condition);
BUT i get FALSE in $model variable. At hte same time
$condition = array('some_id_column' => $another_models_id);
$model = $this->MyModel->findAll($condition);
returns array. Its structure is something like:
array (
0 =>
array (
'MyModel' =>
array (
'id' => '1',
'some_id_column' => '123456',
'some_field' => 'some text',
...
),
),
I'd go with findAll if it did not return an array of arrays, but array of models (in my case - of one model). What do I want to achieve:
$condition = array('some_id_column' => $another_models_id);
$model = $this->MyModel->findFirst($condition);
$model->some_field = 'some another text';
$model->save();
Could you help me out to understand how it's usually done in CakePHP?
I'd also like to hear why findAll finds row and findFirst fails to find it... It just does not make sense to me... They should work in almost the same way and use the same database APIs...
If I can not do what I want in CakePHP, would you write a receipt how it is usually done there ?
There is no such method as findFirst.
You're probably looking for find('first', array('conditions' => array(...))).
Which of the following two data structures is "better"?
array('key'=>array(1,2,3,4))
OR:
array('key',array(1,2,3,4))
i.e., is it better to store the array as the second element in a two element array, or as the single element in an array with the key, 'key'.
Assume that for my purposes, in matters of convenience, they are equivalent. I am only curious whether one uses more resources than the other.
You use whichever one is appropriate for what you're trying to store.
If the key relates to the array of values and its unique then use key/value.
Worrying about resources used in this kind of situation are micro-optimizations and an irrelevant distraction.
if that's the full size of the array, then that's fine.
However, if you actually have an array like
array(
array('key', array(...)),
array('key', array(...)),
array('key', array(...)),
etc
);
instead of
array(
'key' => array(...),
'key' => array(...),
'key' => array(...),
);
Then it's not only odd, it's very unreadable.
The beaut thing of having named key to value is this:
"I want the value of Bob"
$bob = $myArray['bob'];
instead of
foreach($myArray as $key => $value) {
if ($value[0] === 'bob') { // the first value of your 2nd type
$bob = $myArray[1]; // get the next value.
}
}
Of course, for the 2nd example you could consider end(). But compare the 2, it is obvious the first example wins!
I am having a play around with codeigniter and trying to get my head around the active record system and such like.
I have set up a couple of tables and am attempting to run a join on them, as such:
function GetOrganisationsAndBuildingDetails()
{
$this->db->select('organisations.organisation_name,
organisations.organisation_id,
buildings.building_name,
buildings.address1');
$this->db->from('organisations')->join('buildings', 'buildings.organisation_id = organisations.organisation_id');
$query = $this->db->get();
return $query->result();
}
In my database i have one organisation with two related buildings. The above query returns two objects (one for each building) - however, the organisation is duplicated.
stdClass Object (
[organisation_name] => This is an example org
[organisation_id] => 1
[building_name] => test building
[address1] => 123456 )
stdClass Object (
[organisation_name] => This is an example org
[organisation_id] => 1
[building_name] => teeeest building
[address1] => 123456 )
I suppose I was expecting something along the lines of one return object with a series of nested objects for related buildings. Is this possible?
If not, is their a recommend way of arranging the return data so I can easily loop through it in the view? (foreach org, foreach building etc etc).
Apologies if I'm being a little dense here. Im coming from .net and (linq to SQL in particular) where this stuff is a little different)
The query will inevitably return duplicate data as you say, you have to organize them after you get the result like this
$buildings = array();
foreach ( $result_object as $organization ) {
$building_data = array(
'building_name' => $organization->building_name,
'address' => $organization->address,
);
$buildings[$organization->organization_name][] = $building_data;
}
this way organizations will be "compacted" in the first key of the multidimensional array, and one level deeper you will have info about the buildings. Hope this helps.