Double Dollar Sign - Assign Array key=>value - php

I would like to create 3 different arrays which can change depending on which fields are pulled from some mysql tables.
This is the code I have:
// Gather db rows with query
$compQuery['subCats'] = mysql_query("SELECT id,name,category FROM subcategories ORDER BY id DESC");
$compQuery['cats'] = mysql_query("SELECT id,name FROM categories ORDER BY id DESC");
$compQuery['mans'] = mysql_query("SELECT id,name,link FROM manufacturers ORDER BY id DESC");
// Place rows into arrays
foreach($compQuery as $name=>$query){
$name = array();
while($data = mysql_fetch_array($compQuery[$name])){
foreach($data as $key=>$value){
$$name[$key] = $value;
}
}
}
What I would expect this to produce is 3 arrays: subCats, cats and mans each with the value pairs. Instead of finding the $$name variable and assigning [$key] = $value to the array it is taking a single letter out of the $$name variable and assigning the $value to this new variable.
For example, if $name = 'subCats', $key = '3', and value = 'machine tools'
It would create the variable $C using the 3rd letter in subCats:
$C = 'machine tools'
What it should do is create:
$subCats[3] = 'machine tools';
Now, obviously there are easier ways to create separate arrays for each query, and I have modified my code to a lazier/easier version. However, I am still curious as to how I would go about assigning a key value pair to a double dollar sign variable.
Any help would be greatly appreciated! I have the simple code working now, but would like to implement this new code to be more dynamic and allow for more queries as needed without hassle.
Thanks!
Josh

${$name}[$key]
But I do not like to create 'unknown' variable, as in variables whose name is not in the code... What if the name is 'key','db','_GET','compQuery' etc? All hell breaks loose...

In this line:
$name = array();
You're overwriting $name. You probably meant to write to $$name:
$$name = array();

Related

Variable naming in foreach

I am using a foreach statement to extract data from a SQL table and am using an array to loop through every single piece of data I need. Previously I just set the variables for the extracted data equal to the array IDs. Now I would like to instead concatenate a string to the array ID names but am not sure how to accomplish this.
Basically I would just like to add "_type" to every single variable name such this it is no longer named $Banana but §Banana_type instead.
I have tried changing the $$val to $$val . '_type'. However this didn't work. I am quite sure I just need to concatenate the '_type' somehow and would appreciate if anyone can help me out.
$variablesArray = array(
"Apple",
"Banana",
);
foreach($variablesArray as $val) {
$query = "SELECT * FROM {$tableName} WHERE ID = '{$CI_NOYEARS}'";
$result = mysqli_query($conn, $query) or die('error');
while($data = mysqli_fetch_array($result)) {
$$val = $data["COINFO"];
}
}
If you really really need to have variable variables you can concatenate the variable name and store it in another variable like this:
$varName = 'foo'.'1';
$$varName = 1; // $foo1 = 1;
or you can concatenate without the variable in between:
$var = 'v';
echo ${$var.'ar'}; // echoes 'v'
But you can see how ridiculously unclear it gets. This is terrible design choice to use variable variables and it will also confuse your IDE intellisense, static analyzers, and so on. Please don't use variable variables. A better choice would be an array:
$myVars = [];
$myVars['foo'] = 'bar';

Implode ids within a while loop and add commas between

I'm trying to display some sub-content so I need to get the child id's of their parent.
This is how I wanted to do it:
$ids = "SELECT * FROM `web_categories` WHERE parent_id = 14 AND published = 1";
$idscon = $conn->query($ids);
while ($ids = $idscon->fetch_array()){
$idss .= $ids['id'];
}
$project1 = "SELECT * FROM `web_content` WHERE catid in ('$idss') AND state = 1";
$projectcon1 = $conn->query($project1);
$projectcr1 = array();
while ($projectcr1[] = $projectcon1->fetch_array());
I tried imploding $idss like this:
$implode = implode(',', $idss);
But this gives me Invalid arguments passed. What am I doing wrong?
You are doing wrong in the first while loop.
Here it is, $idss .= $ids['id'];, You are doing wrong this. You are storing value in a variable as string, but when you try to implode this... It throws an error!!! Cause implode() use to make array into string. So follow the below steps.
Change $idss .= $ids['id']; to $idss[] = $ids['id']; and instead of implode() use the join().
Create an array names $idss, and push or insert the ids into that array. Then implode/join that IDs.
$idss = array();
while ($ids = $idscon->fetch_array()){
$idss[] = $ids['id'];
}
$implode = implode(',', $idss);
Now you can use this $implode variable in the next query.
You just need to store all IDs in an array, something like $yourIDs[] = $ids['id']; inside your first while loop.
With $idss .= $ids['id']; you can't use implode() because result of this action should be something like "1234" without any single comma.
You just need to use like that:
<?php
$yourIDs = array();
while ($ids = $idscon->fetch_array()){
$yourIDs[] = $ids['id']; // this will save all IDs into $yourIDs array.
}
$idss = implode(',',$yourIDs); // result of this should be 1,2,3,4 etc.
?>
I think you could most likely do that in one query
SELECT * FROM `web_content` WHERE `catid` in (
SELECT `id` FROM `web_categories` WHERE `parent_id` = 14 AND `published` = 1
) AND `state` = 1
The original code was, in effect, doing exactly this but in two stages - sub-queries can be slow sometimes but it does depend on the size of the db and the number of expected results. It is true that joins can be and generally are more efficient than dependant subqueries so perhaps that is another option to explore. As mysql executes the query plan from the outside to the inside rather than the intuitive inside to outside subqueries can cause the server to crawl - it really depends on the complexity of the subquery and the amount of data that has to be processed.

Foreach loop, what did I do wrong?

Please see below code
$template->customer = $rephome->getCustomer($user_id);
foreach($template->customer as $value){
echo $value->customer_id;
}
The first line of code will get result of a query. it was fetched as object.
the second line of code will echo out all of the customer id field from the query result. This works fine. it will echo out 1234567.... to however many id there is.
however if I change the code to like the one below, the echo will only get the first customer_id. ie. 1
$template->customer = $rephome->getCustomer($user_id);
foreach($template->customer as $value){
$something = $value->customer_id;
}
echo $something;
so the question is what is the correct way of assigning the list of results to $something. so I can use $something as a list of ids to be used to run other querys.
in another word. I am trying to use result of first query to run a second query.
$template->customers = $rephome->getCustomer($user_id);
foreach ($template->customers as $value){
$template->orders = $rephome->getOrder($value->customer_id);
}
the above code give me the same result as echo. I will get all the customer id as intented but I will only get repeating order information that is assoicated with first customer id. instead of different orders associated to different customer id.
Yes of course, cause you are overwriting the $something variable each iteration of the foreach loop and echo the result afterwards.
A way to solve this is by using an array:
$something = array();
foreach($template->customer as $value){
$something[] = $value->customer_id;
}
This way you are adding a value to the array each iteration.
so the question is what is the correct way of assigning the list of
results to $something. so I can use $something as a list of ids to be
used to run other querys.
To use the ID's for another SELECT query, so it will only return records associated with the id's inside the array, you can do this for example:
$sql = 'SELECT * FROM `table`
WHERE `id` IN (' . implode(',', array_map('intval', $something)) . ')';
Which will result in something like:
$sql = 'SELECT * FROM `table` WHERE `id` IN (1,2,4,6,7,10)';
Does this answer your question?
On this code:
foreach($template->customer as $value){
$something = $value->customer_id;
}
$something will be overrriten on each loop for a new value. So, on last line, your code will output the last value of resultset´s $value->customer_id.
Got it ??
So, use an array:
$something = array();
foreach($template->customer as $value){
$something[] = $value->customer_id;
}
Try this within your loop:
$something[] = $value->customer_id;
and then outside your loop:
print_r($something);

making three dimensional array that has an unknown amount of arrays inside

I'm trying to store data from a table, and I do not know how many lines will be in said table. My idea was to make a main array called data, a sub array for each line with just numeric labels (1,2,3,etc) and then inside each of those would be the actual data from each line, so it would be like this:
data
->1
->item1
->item2
->item3
->2
->item1
->item2
->item3
->3
->item1
->item2
->item3
ETC. I know how to work with multidimensional arrays and I know there are easy ways to accomplish this in java, but I can't for the life of me figure out how to do it in php.
To keep on adding to an array simply use the following code:
$myArray[] = 'another value';
Notice the [] this tells php to add another value to the array (without removing previous elements)
See here for a quick tutorial on mutidimensional arrays:
http://webcheatsheet.com/PHP/multidimensional_arrays.php
And this:
http://www.developerdrive.com/2012/01/php-arrays-array-functions-and-multidimensional-arrays/
Try,
foreach($rows as $v) {
$data[] = array($v['item1'], $v['item2'], $v['item3']);
}
To map mySQL data to a multidimensional array:
$query = mysql_query("SELECT * FROM table WHERE uid = '1' ORDER BY id DESC");
$results = array();
$i = 0;
while($line = mysqli_fetch_array($query, MYSQL_ASSOC)){
$results[$i] = $line;
$i++;
}

php & mysql - loop through columns of a single row and passing values into array

I have a mysql table with columns id, f1, f2, f3, ..., f20 where id is productID and f1,...f20 are product features. Depending on each product, some might have all, none or only some columns filled.
Each column holds a delimited string like a#b#c#d where a,b,c,d are values in different languages (a=english, b=french etc)
I need to select a row by it's id, explode each column's value (f1,f2...) with '#' in order to get the language part I need and then pass the values to an array in order to use in my product spec page.
How do I loop through the fetched row (i'm using $row = my_fetch_array) and put the exploded value into a one dimension array like $specs=('green', 'M', '100', 'kids'...) etc?
PS:I know, is complicated but I cant come up with a better idea right now.
Try this:
$result = mysql_query("...");
while ($row = mysql_fetch_array($result, MYSQL_NUM)) {
$arr = array();
foreach ($row as $k=>$v)
{
$features = explode("#", $v);
$value = $features[1]; // get the specific language feature
$arr[] = $value;
}
$specs = join(", " , $arr);
}
Not sure this is the best way togo but you could define an array with your langs, then access the result by lang
<?php
$langs=array('eng'=>0,'fr'=>1,'ger'=>2,'geek'=>3);
while ($row=mysql_fetch_assoc($result)) {
$specs=explode('#',$row['f1']);
$other=explode('#',$row['f2']);
...
}
//Get lang from cookie that you could set elsewhere
$lang=(isset($_COOKIE['lang']))?$_COOKIE['lang']:'eng';
echo $specs[$langs[$lang]];
?>
My solution for how I understand you question:
// Make a MySQL Connection
$sQuery = "SELECT f1,f2,... FROM table WHERE id = ...";
$oResult = mysql_query($sQuery) or die(mysql_error());
//Fetch assoc to use the column names.
$aRow = mysql_fetch_assoc($oResult);
//Prepare the product properties array
$aProductProperties = array("English"=>array(),"French"=>array(),"Dutch"=>array());
//Loop over all the columns in the row
foreach($aRow as $sColName=>$sColVal){
//Explde the column value
$aExplodedCol = explode("#",$sColVal);
//The code below could be nicer when turned into a looped that looped over every language,
//But that would make the code less readable
$aProductProperties['English'][$sColName] = $aExplodedCol[0];
$aProductProperties['French'][$sColName] = $aExplodedCol[1];
$aProductProperties['Dutch'][$sColName] = $aExplodedCol[2];
}
//Done, you should now have an array with all the product properties in every language

Categories