I'm developing a php app that uses a database class to query MySQL.
The class is here: http://net.tutsplus.com/tutorials/php/real-world-oop-with-php-and-mysql/*note there are multiple bad practices demonstrated in the tutorial -- it should not be used as a modern guide!
I made some tweaks on the class to fit my needs, but there is a problem (maybe a stupid one).
When using select() it returns a multidimensional array that has rows with 3 associative columns (id, firstname, lastname):
Array
(
[0] => Array
(
[id] => 1
[firstname] => Firstname one
[lastname] => Lastname one
)
[1] => Array
(
[id] => 2
[firstname] => Firstname two
[lastname] => Lastname two
)
[2] => Array
(
[id] => 3
[firstname] => Firstname three
[lastname] => Lastname three
)
)
Now I want this array to be used as a mysql result (mysql_fetch_assoc()).
I know that it may be used with foreach(), but this is with simple/flat arrays. I think that I have to redeclare a new foreach() within each foreach(), but I think this could slow down or cause some higher server load.
So how to apply foreach() with this multidimensional array the simplest way?
You can use foreach here just fine.
foreach ($rows as $row) {
echo $row['id'];
echo $row['firstname'];
echo $row['lastname'];
}
I think you are used to accessing the data with numerical indices (such as $row[0]), but this is not necessary. We can use associative arrays to get the data we're after.
You can use array_walk_recursive:
array_walk_recursive($array, function ($item, $key) {
echo "$key holds $item\n";
});
With arrays in php, the foreach loop is always a pretty solution.
In this case it could be for example:
foreach($my_array as $number => $number_array)
{
foreach($number_array as $data = > $user_data)
{
print "Array number: $number, contains $data with $user_data. <br>";
}
}
This would have been a comment under Brad's answer, but I don't have a high enough reputation.
Recently I found that I needed the key of the multidimensional array too, i.e., it wasn't just an index for the array, in the foreach loop.
In order to achieve that, you could use something very similar to the accepted answer, but instead split the key and value as follows
foreach ($mda as $mdaKey => $mdaData) {
echo $mdaKey . ": " . $mdaData["value"];
}
Hope that helps someone.
Holla/Hello,
I got it! You can easily get the file name,tmp_name,file_size etc.So I will show you how to get file name with a line of code.
for ($i = 0 ; $i < count($files['name']); $i++) {
echo $files['name'][$i].'<br/>';
}
It is tested on my PC.
To get detail out of each value in a multidimensional array is quite straightforward once you have your array in place. So this is the array:
$example_array = array(
array('1','John','Smith'),
array('2','Dave','Jones'),
array('3','Bob','Williams')
);
Then use a foreach loop and have the array ran through like this:
foreach ($example_array as $value) {
echo $value[0]; //this will echo 1 on first cycle, 2 on second etc....
echo $value[1]; //this will echo John on first cycle, Dave on second etc....
echo $value[2]; //this will echo Smith on first cycle, Jones on second etc....
}
You can echo whatever you like around it to, so to echo into a table:
echo "<table>"
foreach ($example_array as $value) {
echo "<tr><td>" . $value[0] . "</td>";
echo "<td>" . $value[1] . "</td>";
echo "<td>" . $value[2] . "</td></tr>";
}
echo "</table>";
Should give you a table like this:
|1|John|Smith |
|2|Dave|Jones |
|3|Bob |Williams|
Example with mysql_fetch_assoc():
while ($row = mysql_fetch_assoc($result))
{
/* ... your stuff ...*/
}
In your case with foreach, with the $result array you get from select():
foreach ($result as $row)
{
/* ... your stuff ...*/
}
It's much like the same, with proper iteration.
Ideally a multidimensional array is usually an array of arrays so i figured declare an empty array, then create key and value pairs from the db result in a separate array, finally push each array created on iteration into the outer array. you can return the outer array in case this is a separate function call. Hope that helps
$response = array();
foreach ($res as $result) {
$elements = array("firstname" => $result[0], "subject_name" => $result[1]);
array_push($response, $elements);
}
I know this is quite an old answer.
Here is a faster solution without using foreach:
Use array_column
print_r(array_column($array, 'firstname')); #returns the value associated with that key 'firstname'
Also you can check before executing the above operation
if(array_key_exists('firstname', $array)){
print_r(array_column($array, 'firstname'));
}
Wouldn't a normal foreach basically yield the same result as a mysql_fetch_assoc in your case?
when using foreach on that array, you would get an array containing those three keys: 'id','firstname' and 'lastname'.
That should be the same as mysql_fetch_assoc would give (in a loop) for each row.
foreach ($parsed as $key=> $poke)
{
$insert = mysql_query("insert into soal
(pertanyaan, a, b, c, d, e, jawaban)
values
('$poke[question]',
'$poke[options][A]',
'$poke[options][B]',
'$poke[options][C]',
'$poke[options][D]',
'$poke[options][E]',
'$poke[answer]')");
}
If you need to do string manipulation on array elements, e.g, then using callback function array_walk_recursive (or even array_walk) works well. Both come in handy when dynamically writing SQL statements.
In this usage, I have this array with each element needing an appended comma and newline.
$some_array = [];
data in $some_array
0: "Some string in an array"
1: "Another string in an array"
Per php.net
If callback needs to be working with the actual values of the array,
specify the first parameter of callback as a reference. Then, any
changes made to those elements will be made in the original array
itself.
array_walk_recursive($some_array, function (&$value, $key) {
$value .= ",\n";
});
Result:
"Some string in an array,\n"
"Another string in an array,\n"
Here's the same concept using array_walk to prepend the database table name to the field.
$fields = [];
data in $fields:
0: "FirstName"
1: "LastName"
$tbl = "Employees"
array_walk($fields, 'prefixOnArray', $tbl.".");
function prefixOnArray(&$value, $key, $prefix) {
$value = $prefix.$value;
}
Result:
"Employees.FirstName"
"Employees.LastName"
I would be curious to know if performance is at issue over foreach, but for an array with a handful of elements, IMHO, it's hardly worth considering.
A mysql result set object is immediately iterable within a foreach(). This means that it is not necessary to call any kind of fetch*() function/method to access the row data in php. You can simply pass the result set object as the input value of the foreach().
Also, from PHP7.1, "array destructuring" allows you to create individual values (if desirable) within the foreach() declaration.
Non-exhaustive list of examples that all produce the same output: (PHPize Sandbox)
foreach ($mysqli->query("SELECT id, firstname, lastname FROM your_table") as $row) {
vprintf('%d: %s %s', $row);
}
foreach ($mysqli->query("SELECT * FROM your_table") as ['id' => $id, 'firstname' => $firstName, 'lastname' => $lastName]) {
printf('%d: %s %s', $id, $firstName, $lastName);
}
*note that you do not need to list all columns while destructuring -- only what you intend to access
$result = $mysqli->query("SELECT * FROM your_table");
foreach ($result as $row) {
echo "$row['id']: $row['firstname'] $row['lastname']";
}
Related
I have a data set being returned from a database and the keys are the names of the fields I need to print on a table.
For example, if I have a array of 5 keys (fields), I need to create an HTML table that had a heading with each of the keys on it. I would then need to print the results to the table.
Esentially, I need to create an HTML table from an array and the keys in the first result can act as the headers.
Here is my data:
SimpleXMLElement Object
(
[data] => SimpleXMLElement Object
(
[primaryFields] => SimpleXMLElement Object
(
[primary] => Array
(
[0] => SimpleXMLElement Object
(
[Project_Title] => Test
[Project_Description_Preview] => Test Desc
)
[1] => SimpleXMLElement Object
(
[Project_Title] => Blueprint Development Project
[Project_Description_Preview] => We are continuing to improve Blueprint as a tool by collecting feedback from our internal users and developing new features.
)
What would be the best way to go about getting the keys from the first result in the array? Should this be two separate loops; first one loops to create the headers from the keys and then the second one prints the data?
Project_Title & Project_Description_Preview would be the table headers in this case.
I will leave it to you to parse the data you get back. From the look of the object get to primary.
<?php
//You will need to parse the object to get this.
$primary = array(
array(
"Project_Title" => "Test",
"Project_Description_Preview" => "Test Desc"
),
array(
"Project_Title" => "Blueprint Development Project",
"Project_Description_Preview" => "We are continuing to improve Blueprint as a tool by collecting feedback from our internal users and developing new features."
)
);
echo "<table>";
for($i = 0; $i < count($primary); $i++){
//Only create the head on your first object
if($i==0){
echo "<thead>";
//build header here
echo "<tr>";
foreach($primary[$i] as $key => $value){
echo "<th>" . $key . "</th>";
}
echo "</tr>";
echo "</thead><tbody>";
}
//Then create the rows and data like all php...
echo "<tr>";
foreach($primary[$i] as $value){
echo "<td>" . $value . "</td>";
}
echo "</tr>";
}
echo "</tbody></table>";
?>
you have to browse your array from a certain place, say
$arr->data->primaryFields->primary as $primary.
considering the array from primary.
foreach($primary as $values){
foreach($values as $key => $ value){
echo $key." & ".$value;
}
}
My typical approach would be just to grab the keys when you first descend into the data on your first iteration, assuming you're looping over it.
Looping like so (as a bonus lets extract the keys just in case):
$primary = $obj->data->primaryFields->primary; //an array
$first = true;
$keys = array();
foreach ($primary as $obj) {
if ($first) {
$first = false;
$keys = get_array_keys((array)$obj));
make_headers($obj,$keys); //do header things here
}
make_table_stuff($obj,$keys); //do table stuff
}
But, you could always do:
$keys = get_object_vars($obj->data->primaryFields->primary[0]);
Note: this will work for any number of database columns, whether they are known or not.
You should be able to build the whole table like this:
//where $obj = your output...
//get the column names, convert to an object and store inside an array of one element
$keys = array(json_decode(json_encode(array_keys(get_object_vars($obj[0])))));
//create the output array by merging the keys as the first element with the existing dataset into a new array
$output = array_merge($keys, $obj);
//here is the output step
echo "<table><thead>";
foreach($output as $record_num => $record) {
echo '<tr>';
$cells = get_object_vars($record);
foreach ($cells as $column => $cell) {
echo '<td class="' . $column . '">' . $cell . '</td>';
}
echo '</tr>';
//if this is the first element of the array, it is the column names. After these are output, the rest should be in the tbody tag
if ($record_num == 0) { echo '</thead><tbody>';}
}
echo "</tbody></table>";
This also adds a class name to each cell that corresponds to its database column, which can be used for vertical css styling or javascript selectors after the fact for UI considerations. This can be removed if not needed though.
I have the following snippet of code that is creating the following array...
while ($stmt->fetch()) {
foreach($row as $key => $val) {
$x[$key] = $val;
}
$results[] = $x;
}
Results in the follow array:
Array ( [0] => Array ( [cap_login] => master [cap_pword] => B-a411dc195b1f04e638565e5479b1880956011badb73361ca ) )
Basically I want to extract the cap_login and cap_pword values for testing. For some reason I can't get it!
I've tried this kind of thing:
echo $results[$cap_login];
but I get the error
Undefined variable: cap_login
Can someone put me right here?
Thanks.
cap_login is in an array within $results so you would have to do $results[0]['cap_login']
You would have to do the following:
echo $x[0]['cap_login'] . '<br />';
echo $x[0]['cap_pword'];
The reson $results[$cap_login] wont work is because there isn't a variable called $cap_login, there is a string called cap login. In addition, there isn't a key in $results called $cap_login. There is a value in $results called 'cap_login'
I have 2 arrays, both from a SQL query, each from a different database. Since it's not possible to merge these 2 SQL queries into 1 query to get 1 array (due to some restrictions), I am forced to combine the 2 arrays. Problem is, I can't seem to get this working.
This is array 1:
echo '<ul id="friends">';
foreach($result as $friend => $value)
{
echo '<li><img src="'.$value['pic_square'].'" alt="" />'.$value['uid'].' ' . $value['name'] . '</li>';
}
echo '</ul>';
And will output:
picture 12345 Dave
picture 67890 Mike
Etc
This is array 2:
echo '<ul id="friends">';
while($value = mysql_fetch_array($query))
{
echo '<li> '.$value['fbid'] .' '. $value['userphone'] .'</li>';
}
echo '</ul>';
And will output:
12345 020-12345
67890 020-56789
Etc
What do I need? I want to merge these 2 arrays so that the phonenr from array 2 will be added behind the username from array 1.
Example what the output should look like:
picture Dave 020-12345
picture Mike 020-56789
Etc
fbid and uid are the id's to link each other, but are not shown in the combined array.
Hope someone knows how to do this!
Kind regards,
Maurice
This is the simplest and most efficient way I could think of doing it. The foreach loop iterates through your first array and basically add new key/value pairs using the "uid" as the key. This will enable you to easily find them when you loop through the second query's results.
<?php
// First query.
foreach ( $result as $key => $value )
{
// Add a new key/value pair in the array using the "uid" as the key and $value as the value.
$result[$value['uid']] = $value;
// Remove the previous key/value pair value.
unset($result[$key]);
}
// Second query.
while ( $value = mysql_fetch_array($query) )
echo sprintf('<li>%s %s %s</li>', $result[$value['fbid']]['pic_square'], $result[$value['fbid']]['name'], $value['userphone']);
As the array collection names are different (different column name) I am not sure direct merging will work.
$result = array_merge($result, $query);
print_r($result);
But you can work around like below.
Give loops and store in a third array from both the arrays and do necessary actions on third array.
This is the set of result from my database
print_r($plan);
Array
(
[0] => Array
(
[id] => 2
[subscr_unit] => D
[subscr_period] =>
[subscr_fee] =>
)
[1] => Array
(
[id] => 3
[subscr_unit] => M,Y
[subscr_period] => 1,1
[subscr_fee] => 90,1000
)
[2] => Array
(
[id] => 32
[subscr_unit] => M,Y
[subscr_period] => 1,1
[subscr_fee] => 150,1500
)
)
How can I change the $plan[0] to $plan[value_of_id]
Thank You.
This won't do it in-place, but:
$new_plan = array();
foreach ($plan as $item)
{
$new_plan[$item['id']] = $item;
}
This may be a bit late but I've been looking for a solution to the same problem. But since all of the other answers involve loops and are too complicated imho, I've been trying some stuff myself.
The outcome
$items = array_combine(array_column($items, 'id'), $items);
It's as simple as that.
You could also use array_reduce which is generally used for, well, reducing an array. That said it can be used to achieve an array format like you want by simple returning the same items as in the input array but with the required keys.
// Note: Uses anonymous function syntax only available as of PHP 5.3.0
// Could use create_function() or callback to a named function
$plan = array_reduce($plan, function($reduced, $current) {
$reduced[$current['id']] = $current;
return $reduced;
});
Note however, if the paragraph above did not make it clear, this approach is overkill for your individual requirements as outlined in the question. It might prove useful however to readers looking to do a little more with the array than simply changing the keys.
Seeing the code you used to assemble $plan would be helpful, but I'm going assume it was something like this
while ($line = $RES->fetch_assoc()) {
$plan[] = $line;
}
You can simply assign an explicit value while pulling the data from your database, like this:
while ($line = $RES->fetch_assoc()) {
$plan[$line['id']] = $line;
}
This is assuming $RES is the result set from your database query.
In my opinion, there is no simpler or more expressive technique than array_column() with a null second parameter. The null parameter informs the function to retain all elements in each subarray, the new 1st level keys are derived from the column nominated in the third parameter of array_column().
Code: (Demo)
$plan = array_column($plan, null, 'id');
Note: this technique is also commonly used to ensure that all subarrays contain a unique value within the parent array. This occurs because arrays may not contain duplicate keys on the same level. Consequently, if a duplicate value occurs while using array_column(), then previous subarrays will be overwritten by each subsequent occurrence of the same value to be used as the new key.
Demonstration of "data loss" due to new key collision.
$plans = array();
foreach($plan as $item)
{
$plans[$item['id']] = $item;
}
$plans contains the associative array.
This is just a simple solution.
$newplan = array();
foreach($plan as $value) {
$id = $value["id"];
unset($value["id"]);
$newplan[$id] = $value;
}
Basically I currently put a bunch of values into an array like so:
$flavors = array('Original','Cherry','Chocolate','Raspberry','Mango');
and from this I might execute a foreach like so:
foreach($flavors as $flav) {
echo doSomething($flav);
}
This all works a treat, until I get to the next stage of my learning which is to perhaps put 2 variables into doSomething().
For example, say I want to include the ingredients of Cherry e.g
echo doSomething($flav, $ingredient_of_this_flav);
I'm not sure if there is any way to go about doing this... I imagine I might need a second array entirely where I use the values above as my keys? e.g
$ingredients = array('Original' => 'boring stuff', 'Cherry' => 'cherries and other stuff') etc
And then I would doSomething() like so
foreach($flavors as $flav) {
echo doSomething($flav, $ingredients[$flav]);
}
I suppose I should go try this now. Is this the best approach or is there a better way to go about this? Ideally I would just have the one array not have to set $flavors and $ingredients.
Thanks for your time.
Arrays in php are associative, as you've noticed. And if I understand correctly, you're looking for the syntax to loop through each key/value pair?
foreach($ingredients as $flav => $ingredient) {
echo doSomething($flag, $ingredient);
}
Is this what you're looking for?
If you're looking to have complex values for each key, than you might want to look into objects, or the more brutal version, arrays of arrays.
$ingredients = array('Cherry' => array('Cherries', 'Other stuff'));
And your $ingredient in the loop above will be an array.
You can foreach over the keys and values of an array.
foreach ($ingredients as $flav => $ingredients)
{
echo doSomething($flav, $ingredients);
}
I would use an associative array (aka hash table) with a flavor => ingredients approach. Something like this:
$flavors = array ('Cherry' => array('stuff1', 'stuff2'),
'Mango' => array('stuff1', 'stuff3'));
echo $flavors['Cherry'][0]; // stuff1
foreach($flavors as $flavor => $ingredients)
{
print $flavor;
// $ingredients is an array so we need to loop through it
foreach($ingredients as $ingredient)
{
print $ingredient;
}
}
This is known as a nested loop and will print the flavor and each ingredient.
You are nearly there. I would set the array to be something like:
$ingredients = array('Original' => array('boring stuff', 'boring stuff2'), 'Cherry' => array('cherries', 'other stuff'));
And then loop as follows:
foreach($flavors as $flav => $ingredient) {
echo doSomething($flav, $ingredient);
}
Of course, it all depends on what you do in "doSomething()"