php array count - php

I have a var dump of my sql query which return the following
I wanna to count in the array below that how many rows of myID = 5 are there. How would I do that. I am using php. Thanks in advance
array
0 =>
object(stdClass)[17]
public 'myID' => string '5' (length=1)
public 'data' => string '123' (length=3)
1 =>
object(stdClass)[18]
public 'myID' => string '5' (length=1)
public 'data' => string '123' (length=3)
2 =>
object(stdClass)[19]
public 'relativeTypeID' => string '2' (length=1)
public 'data' => string '256' (length=3)
3 =>
object(stdClass)[20]
public 'myID' => string '4' (length=1)
public 'data' => string '786' (length=3)
object(stdClass)[21]
public 'myID' => string '4' (length=1)
public 'data' => string '786' (length=3)

Do you always have the same value of data for the same myID? In other words, is data functionally dependant on myID?
If so, you can get the database to do this for you:
SELECT myID, data, COUNT(*) AS cnt
FROM (your query here)
GROUP BY myID, data
This would give you results like the following:
myID data cnt
'5' '123' 3
'2' '256' 1
'4' '786' 2

Or, you can use a foreach statement, like:
$count = 0;
foreach($arr as $item)
{
// Given that your item is an stdClass Object you access its property with "->"
// if an array $item["myID"] instead
if ( $item->myID == '4' )
{
$count ++;
}
}

Related

MYSQL PHP Array grouping

Having trouble wrapping my head around this conceptually. Still new to this. Basically I have this return from my database :
array (size=456)
0 =>
object(stdClass)[358]
public 'id' => string '2432' (length=4)
public 'symbol' => string '.AMLP' (length=14)
public 'last' => string '0.01' (length=4)
public 'volume' => string '3690' (length=4)
public 'the_date' => string '2019-09-13' (length=10)
public 'the_screener' => string '1' (length=1)
public 'notes' => string 'notes here' (length=149)
1 =>
object(stdClass)[726]
public 'id' => string '2417' (length=4)
public 'symbol' => string '.ARCC' (length=14)
public 'last' => string '2.25' (length=4)
public 'volume' => string '1633' (length=4)
public 'the_date' => string '2019-09-13' (length=10)
public 'the_screener' => string '1' (length=1)
public 'notes' => string 'notes' (length=60)
2 =>
object(stdClass)[726]
public 'id' => string '2447' (length=4)
public 'symbol' => string '.ARCC' (length=14)
public 'last' => string '2.25' (length=4)
public 'volume' => string '1633' (length=4)
public 'the_date' => string '2019-09-12' (length=10)
public 'the_screener' => string '1' (length=1)
public 'notes' => string 'notes here 3' (length=60)
3 =>
What I'm trying to do with PHP is create an object/array that I can work with that displays these items like
AMLP 1 found on dates 2019-09-13
ARCC 2 found on dates 2019-09-13, 2019-09-12
In the end I would display these in a table, but conceptually this is what I'm trying to do.
I've tried creating an array in my foreach I use to display this information in a table, but I was thinking about it and it's probably better to just use the same query data and break it down separately.
So I'd like to create an array like :
Array
(
[1] => Array
(
[id] => 1
[symbol] => ARCC
[dates] => Array
(
[3] => Array
(
2019-09-13
2019-09-12
)
)
)
)
Consider your array is $arrDates. If you want to access properties like object properties
$arrFinal = [];
foreach ($arrDates as $intKey => $obj){
$strSymbol = getSubSymbol($obj->symbol);
if(!isset($arrFinal[$strSymbol])) {
$arrFinal[$strSymbol] = [ 'id' => $obj->id, 'symbol' => $obj->symbol];
}
$arrFinal[$strSymbol]['dates'][] = $obj->the_date;
}
// Now loop throuh arrFinal and do print the statements you want.
foreach($arrFinal as $strSubSymbol => $arrData){
echo $strSubSymbol . ' '. count($arrData['dates']) . ' found on dates ' . implode(',', $arrData['dates']). PHP_EOL;
}
Function to get the desired subpart of symbol
function getSubSymbol($symbol_original){
$symbol = preg_split('/(?=\d)/', $symbol_original, 2); //get everything up until first number or the date in the string in this case.
$symbol_here = substr($symbol[0], 1);
return $symbol_here;
}

Join many to one

In Codeigniter I am tryign to join two tables with a one-to-many relation. I want to get one result from my table housetype and all of its values/members from other table housetype_member:
$this->db->select('*');
$this->db->join('housetype_member', 'housetype_member.housetype_id = housetype.PkId', 'left');
$result = $this->db->get_where('housetype', array('PkId' => $id));
return $result->result();
So far I get such result:
array (size=2)
0 =>
object(stdClass)[28]
public 'PkID' => string '4' (length=1)
public 'Name' => string 'Classic' (length=7)
public 'image' => string '1449063250.jpg' (length=14)
1 =>
object(stdClass)[30]
public 'PkID' => string '4' (length=1)
public 'Name' => string 'Classic' (length=7)
public 'image' => string '1449063288.gif' (length=14)
First two object values (PkID, Name) are from the first table and the last one (image) is from the second left table. Everything is good but I get an array with two elements, when I only need one housetype object.
Is there a way to write above code so that my returned object would look like this:
object(stdClass)[28]
public 'PkID' => string '4' (length=1)
public 'Name' => string 'Classic' (length=7)
public 'image' =>
array (size=2)
0 => string '1449063250.jpg' (length=14)
1 => string '1449063288.gif' (length=14)
I need one result from the first table and to it I want to join all of its members from the second table.
Can it be done with Codeigniters active record, can it be done at all?
Add group_by() clause to your query.
$this->db->group_by('housetype.PkId');

How to give each field in an array its own variable

i'm working on a small text based web game for a few friends to play (for nostalgia) but i'm having trouble with the very core of the game, the attacking/defending.
Each player has x amount of each troop type (more can be purchased and will be lost on atk/def)
so far I have a table with troop types and stats and a table with troop qty linked with user id and troop id.
I'm using the user id to get the troop id and qty using;
// Get attacker troop quantities.
$i = 0;
$attacker_deets = $conn->prepare("SELECT * FROM troop_qty WHERE user_id= :attacker_id");
$attacker_deets->bindParam(':attacker_id', $attacker_id);
$attacker_deets->execute();
$attacker_deets_results = $attacker_deets->fetchAll(PDO::FETCH_ASSOC);
foreach($attacker_deets_results as $atk_key=>$atk_result) {
echo "<pre>"; var_dump($atk_result); echo "</pre>";
}
which outputs;
array (size=4)
'troop_qty_id' => string '1' (length=1)
'user_id' => string '2' (length=1)
'troop_id' => string '1' (length=1)
'qty' => string '100' (length=3)
array (size=4)
'troop_qty_id' => string '2' (length=1)
'user_id' => string '2' (length=1)
'troop_id' => string '2' (length=1)
'qty' => string '100' (length=3)
I'm then using the troop id to get the troop details;
// get attacker troop details.
$attacker_troop_deets = $conn->prepare("SELECT * FROM troops WHERE troop_id= :atk_troop_id");
$attacker_troop_deets->bindParam(':atk_troop_id', $attacker_deets_results[$i]['troop_id']);
$attacker_troop_deets->execute();
$returned_results = $attacker_troop_deets->fetchAll(PDO::FETCH_ASSOC);
foreach($returned_results as $key=>$result) {
echo "<pre>"; var_dump($result); echo "</pre>";
}
++$i;
which in total gives me;
array (size=4)
'troop_qty_id' => string '1' (length=1)
'user_id' => string '2' (length=1)
'troop_id' => string '1' (length=1)
'qty' => string '100' (length=3)
array (size=4)
'troop_id' => string '1' (length=1)
'troop_name' => string 'Fist Puncher' (length=12)
'troop_atk' => string '1' (length=1)
'troop_def' => string '1' (length=1)
array (size=4)
'troop_qty_id' => string '2' (length=1)
'user_id' => string '2' (length=1)
'troop_id' => string '2' (length=1)
'qty' => string '100' (length=3)
array (size=4)
'troop_id' => string '2' (length=1)
'troop_name' => string 'Stick Waver' (length=11)
'troop_atk' => string '2' (length=1)
'troop_def' => string '1' (length=1)
Now where i'm stuck is I need to be able to compare the troop_atk of First Puncher with the defence of Stick Waver which is gotten from a different set of duplicate query's getting the defenders details, i also need to be able to multiply and divide the atk and def variables.
so how would i go about achieving this? i would assume i would need to give each field in the array their own variable, but how? i have tried using ${"troop_name" . $i} = $attacker_deets_results[$i]['troop_name']; but it only ever outputs the last entered name.
any help would be amazing. thanks.
Edit: To clear things up a little, my goal is to get the troop qty and multipy it by both atk and def then use these numbers to do some other math with the same fields from the defending player which I'll use to decrease the qty field.
Maybe you could modify your code a little and do the following.
Fetch the data about the user's troops in one query:
$results = $conn->query("SELECT troop_qty.user_id as uid, troop.troop_id, troop.troop_name, troop_qty.qty, troop.troop_atk, troop.troop_def FROM troop_qty join troop on troop.troop_id=troop_qty.troop_qty_id WHERE troop_qty.user_id=:attacker_id
Create a new array which contains information about all user's troops:
$userData = array(
'id' => $attacker_id,
'troops' => array());
while (($res = $results->fetch_assoc()) != null) {
$troopData = array(
'name' => $res['troop_name'],
'qty' => $res['qty'],
'atk' => $res['troop_atk'],
'def' => $res['troop_def']);
$userData['troops'][$res['troop_id']] = $troopData;
}
As result you would have something like this (vardump($userData)):
array (size=2)
'id' => int 2
'troops' =>
array (size=2)
1 =>
array (size=4)
'name' => string 'Fist Puncher' (length=12)
'qty' => string '100' (length=3)
'atk' => string '1' (length=1)
'def' => string '1' (length=1)
2 =>
array (size=4)
'name' => string 'Stick Waver' (length=11)
'qty' => string '100' (length=3)
'atk' => string '2' (length=1)
'def' => string '1' (length=1)
I don't know how exactly you want to manipulate the data later on in the game but I think this would ease the work.
Btw. I've thrown away fetchAll() function because I personaly think it is not a good practice to fetch all data into memory and then modify it or do whatever with it. It's a waste of the memory and when you would deal with a big amount of data, at some point that could cause you some troubles.

Join two tables and display distinct list of column

I have three tables.
Candidates
Skills
CandidateToSkillMap
Candidate and Skill tables are mapped in CandidateToSkillMap table. In that candidate_id and skill_id are foreign keys.
How can i get following output with them ?
Assume i need to display Computer Skills of candidate_id = 1
Computer Skills -
MS Word (x)
MS Excel (x)
MS Paint ()
It should display distinct list of all available computer skills and there should be a check-box in-front. It will be checked if specific candidate has that skill.
EDIT -
I have query database and loaded data into arrays -
$candidate_profile_computer_skills
this array gives all the computer skills
array (size=3)
0 =>
object(Candidate\Model\CandidateProfileSkill)[317]
public 'id' => string '1' (length=1)
public 'skill_name' => string 'MS Word' (length=7)
public 'candidate_id' => null
public 'candidateprofileskill_id' => null
1 =>
object(Candidate\Model\CandidateProfileSkill)[223]
public 'id' => string '3' (length=1)
public 'skill_name' => string 'MS Excel' (length=8)
public 'candidate_id' => null
public 'candidateprofileskill_id' => null
2 =>
object(Candidate\Model\CandidateProfileSkill)[316]
public 'id' => string '6' (length=1)
public 'skill_name' => string 'MS Paint' (length=8)
public 'candidate_id' => null
public 'candidateprofileskill_id' => null
$candidate_profile_skills_map
this array returns Skills and CandidateToSkillMap with LEFT JOIN for specific candidate (candidate_id = 1)
array (size=5)
0 =>
object(Candidate\Model\CandidateProfileSkill)[321]
public 'id' => string '1' (length=1)
public 'skill_name' => string 'MS Word' (length=7)
public 'candidate_id' => string '1' (length=1)
public 'candidateprofileskill_id' => string '1' (length=1)
1 =>
object(Candidate\Model\CandidateProfileSkill)[322]
public 'id' => string '2' (length=1)
public 'skill_name' => string 'Sinhala Reading' (length=15)
public 'candidate_id' => string '1' (length=1)
public 'candidateprofileskill_id' => string '2' (length=1)
2 =>
object(Candidate\Model\CandidateProfileSkill)[323]
public 'id' => string '3' (length=1)
public 'skill_name' => string 'MS Excel' (length=8)
public 'candidate_id' => string '1' (length=1)
public 'candidateprofileskill_id' => string '3' (length=1)
3 =>
object(Candidate\Model\CandidateProfileSkill)[324]
public 'id' => string '4' (length=1)
public 'skill_name' => string 'English Reading' (length=15)
public 'candidate_id' => string '1' (length=1)
public 'candidateprofileskill_id' => string '4' (length=1)
4 =>
object(Candidate\Model\CandidateProfileSkill)[325]
public 'id' => string '4' (length=1)
public 'skill_name' => string 'English Reading' (length=15)
public 'candidate_id' => string '1' (length=1)
public 'candidateprofileskill_id' => string '4' (length=1)
A join will do:
SELECT
s.skill_name,
CASE WHEN c.candidate_id IS NOT NULL THEN '(X)' ELSE '()' END has_skill
FROM
skills s
LEFT JOIN CandidateToSkillMap c ON s.skill_id = c.skill_id
WHERE
c.candidate_id = 1
If it joins the right side successfully and thus c.candidate_id will be not null, then it means the person has that skill and you mark it else - don't.
You can just use this
Select S.SkillName, count(*) from CandidateToSkillMap CTS, Skills S where S.Id = CTS.CandidateProfileSkillId group by CV.Id having CTS.CandidateId = 1
SELECT * FROM [Skills] s
LEFT JOIN [CandidateToSkillMap] csm ON csm.candidateprofileskill_id = s.id
WHERE csm.candidate_id = 1
This will return all rows from the skills table, and you can do a null-check on the column "candidate_id" to ascertain whether or not the candidate in question has the skill on that row.
Here's some pseudo:
for($row in $result) {
Skill name: $row["skill_name"]
Has skill?: $row["candidate_id"] != null ? "Yes" : "No"
}
you can try this
select S.skill_name from CandidateToSkillMap CSM, Skills s where S.id=CSM.candidatesprofileskill_id and CSM.candidate_id=1
Try something like
SELECT s.skill_name, (cm.Candidate_id IS NOT NULL) AS HasSkill
FROM Skills AS s
LEFT OUTER JOIN candidateToSkillMap AS cm
ON s.id = cm.candidateprofileskill_id
WHERE s.skill_type = 'Computer Literacy'
AND (Candidate_id = 1 OR Candidate_id IS NULL)
The above query uses LEFT OUTER JOIN to join the skills and candidatestoskillmap include all the rows from skills tables. This will ensure that any rows not matched in the candidatestoskillmap table are included as null values.
The select section then looks for these values and assigns a true/false for it.
The Where section filters for the skill type and the candidate's id.

Building a form dynamically with Codeigniter and Active Record queries

Model
function get_prices()
{
$table_by_product = 'printer_businesscards'; //replace with URI Segment
//Get all the columns in the table set by the page URI of $table_by_product variable
$get_all_col_names = $this->db->list_fields($table_by_product);
//Loop through the column names. All names starting with 'O_' are optional fields for the
//current product. Get all Distinct values and create a radio button list in form.
foreach ($get_all_col_names as $key => $value) {
//get all o_types for the product by column name
if ($all_O_types = preg_match('/O_/', $value))
{
$O_types = array($value);
foreach ($O_types as $O) {
//echo $O;
$this->db->select($O);
$this->db->distinct();
$qO = $this->db->get($table_by_product);
$qO_Array = $qO->result_object();
}
}
//Get all x_types for the product by column name. All 'X_' types are specific product options.
//Create a dropdown menu with all DISTINCT product options.
if ($all_X_types = preg_match('/X_/', $value))
{
$X_types = array($value);
foreach ($X_types as $X) {
//echo $X;
$this->db->select($X);
$this->db->distinct();
$qX = $this->db->get($table_by_product);
$qX_Array = $qX->result_object();
}
}
}
return array($qX_Array,$qO_Array);
}
}
So each product has different options but all products options are prefixed by "X_" or "O_". I need to get the DISTINCT values of each COLUMN of "X_" and "O_" and in any VIEW I need to build a form with these values. Here is a look at the array:
array (size=3)
0 =>
object(stdClass)[19]
public 'X_SIZE' => string '1.75x3' (length=6)
1 =>
object(stdClass)[20]
public 'X_SIZE' => string '1.75x3.5(slim)' (length=14)
2 =>
object(stdClass)[21]
public 'X_SIZE' => string '2x3' (length=3)
array (size=3)
0 =>
object(stdClass)[17]
public 'X_PAPER' => string '14ptGlossCoatedCoverwithUV(C2S)' (length=31)
1 =>
object(stdClass)[18]
public 'X_PAPER' => string '14ptPremiumUncoatedCover' (length=24)
2 =>
object(stdClass)[24]
public 'X_PAPER' => string '16ptDullCoverwithMatteFinish' (length=28)
array (size=2)
0 =>
object(stdClass)[23]
public 'X_COLOR' => string '1000' (length=4)
1 =>
object(stdClass)[22]
public 'X_COLOR' => string '1002' (length=4)
array (size=4)
0 =>
object(stdClass)[20]
public 'X_QTY' => string '100' (length=3)
1 =>
object(stdClass)[21]
public 'X_QTY' => string '250' (length=3)
2 =>
object(stdClass)[17]
public 'X_QTY' => string '500' (length=3)
3 =>
object(stdClass)[19]
public 'X_QTY' => string '1000' (length=4)
array (size=3)
0 =>
object(stdClass)[25]
public 'O_RC' => string 'YES' (length=3)
1 =>
object(stdClass)[26]
public 'O_RC' => string 'NO' (length=2)
2 =>
object(stdClass)[27]
public 'O_RC' => string 'NA' (length=2)
My current MODEL is only returning X_QTY and O_RC to my view.
What am I doing incorrectly?
You are only returning the last result object of each; ie, you are setting
$qO_Array = $qO->result_object();
to a variable, and it should be:
$qO_Array[] = $qO->result_object();
to get all of them
BTW - do you have a specific reason for calling result_object() instead of the usual result() or result_array()? It's not necessarily wrong, but I wonder if you are doing it intentionally?

Categories