What is the best practise to move for multiple foreach statements to an array? I am repeating the process in my code, when I know there is a better and faster way to do this. Is it possible to isset the foreach? I am starting to work with PDO, how would I shorten my below code or move it into an array of some type?
if (isset($_POST['one'], $_POST['two'], $_POST['three'])) {
foreach($_POST['one'] as $id => $one) {
$sql = "UPDATE table SET one = ? WHERE id = ?";
$q = $db->prepare($sql);
$q->execute(array($one, $id));
}
foreach($_POST['two'] as $id => $two) {
$sql = "UPDATE table SET two = ? WHERE id = ?";
$q = $db->prepare($sql);
$q->execute(array($two, $id));
}
foreach($_POST['three'] as $id => $three) {
$sql = "UPDATE table SET three = ? WHERE id = ?";
$q = $db->prepare($sql);
$q->execute(array($three, $id));
}
}
EDIT: An example of the HTML/PHP (input type='text') for a more clear example:
$stmt = $db->query('SELECT * FROM table ORDER BY id ');
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "
<input type='text' id='one' value='{$row['one']}' name = 'one[{$row['id']}]' />
<input type='text' id='two' value='{$row['two']}' name = 'two[{$row['id']}]' />
<input type='text' id='three' value='{$row['three']}' name = 'three[{$row['id']}]' />";
}
Assuming all the inputs will have the same IDs:
$sql = "UPDATE table set one = :one, two = :two, three = :three where id = :id";
$q = $db->prepare($sql);
$q->bindParam(':one', $one);
$q->bindParam(':two', $two);
$q->bindParam(':three', $three);
$q->bindParam(':id', $id);
foreach ($_POST['one'] as $id => $one) {
$two = $_POST['two'][$id];
$three = $_POST['three'][$id];
$q->execute();
}
You should only prepare the statement once, not every time through the loop. And by using bindParam you can bind all the parameters to variable references. You can then set all the variables in one loop, and execute the query with those values.
Another way to do this:
<?PHP
foreach($_POST as $name => $value) {
if(isset($name,$value)){
$sql = "UPDATE table SET $name = $value WHERE id = $name";
$q->execute($db->prepare($sql));
}
}
?>
If you're posting other information too, you can move this into an array. Then have
foreach($_POST[fieldsToUpdate] as $name => $value) {
Let me know if you have further questions.
Related
I'm having some trouble with php coding. What I want to do is following:
Create an array ($rows) and fil it with the results of a mysqli_query ($query1) --> OK
for each element in that array, replace the value of a certain key (pilot_rule_id) with the result of another mysqli_query ($query2). (the second query will return one row, since the id of the pilot table is the primary key).
So far I have
$id = "96707ac6-ecae-11ea-878d-005056bbb446";
$rows = array();
$query1 = mysqli_query($con, "SELECT * FROM pilot_time_schedule WHERE pilot_id='$id'");
while($r = mysqli_fetch_assoc($query1)) {
$rows[] = $r;
}
foreach($rows as $pilotRuleId) {
$pilotRuleId->$pilot_rule_id;
$query2 = mysqli_query($con, "SELECT name FROM pilot_rule WHERE id='$piloteRuleId'");
while($r = mysqli_fetch_assoc($query2)) {
$result[] = $r;
}
// Don't know how to continue from here
You can something like this:
$id = "96707ac6-ecae-11ea-878d-005056bbb446";
$stmt = $con->prepare('SELECT * FROM pilot_time_schedule WHERE pilot_id=?');
$stmt->bind_param('s', $id);
$stmt->execute();
$rows = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
foreach ($rows as $row) {
$stmt = $con->prepare('SELECT name FROM pilot_rule WHERE id=?');
$stmt->bind_param('s', $row['pilot_rule_id']);
$stmt->execute();
// replace with the `name` returned from the above statement.
$row['pilot_rule_id'] = $stmt->get_result()->fetch_row()[0] ?? null;
}
However, you really should learn about SQL joins instead. Using SQL joins you can avoid N+1 queries to the database.
$id = "96707ac6-ecae-11ea-878d-005056bbb446";
$stmt = $con->prepare('SELECT pilot_time_schedule.*, pilot_rule.name
FROM pilot_time_schedule
JOIN pilot_rule ON pilot_rule.id=pilot_time_schedule.pilot_rule_id
WHERE pilot_id=?');
$stmt->bind_param('s', $id);
$stmt->execute();
$rows = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
foreach ($rows as $row) {
echo $row['name']; // contains the name from pilot_rule
}
My query is below:
$query = 'SELECT * FROM `table_name` WHERE `uid` = ? AND `email` = ?';
$stmt_select = $conn->prepare($query);
$stmt_select->bind_param('is', $user_id, $user_email);
$user_id = $_SESSION['uid'];
$user_email = $_SESSION['user_email'];
$result = $stmt_select->execute();
I want to print results set using fetch_assoc, this is because I don't want to bind_result() to all 23 columns' name, I want to print it using $row['column_name'], what is the correct way of achieving it?
If you want to see my code, I asked another question here:
How to SELECT * with multiple WHERE using fetch_assoc in prepared statements in PHP-MYSQL?
But it didn't get answered correctly, so instead of correcting my code, can you tell me what's the best way to achieve it?
I had the same issue using SELECT * in mysqli. The issue lies with the bind_result part. Normally you would need to add many variables. Meaning if you had about 20 columns, you would need 20 variables to include in the bind_result statement.
I've tailored my solution to fix your issues.
$query = 'SELECT * FROM `table_name` WHERE `uid` = ? AND `email` = ?';
$stmt_select = $conn->prepare($query);
$stmt_select->bind_param('is', $user_id, $user_email);
$user_id = $_SESSION['uid'];
$user_email = $_SESSION['user_email'];
$result = $stmt_select->execute();
$stmt_select->store_result();//after this line we can output the number of rows if you need to check that as well
$number_of_rows = $stmt_select->num_rows;
$meta = $stmt_select ->result_metadata();
$parameters = array();
$results = array();
while ($field = $meta->fetch_field()) {
$parameters[] = &$row[$field->name];
}
call_user_func_array(array($stmt_select , 'bind_result'), $parameters);
while ($stmt_select ->fetch()) {
foreach ($row as $key => $val) {
$x[$key] = $val; //here we get the key => value (Column => Value)
}
$results[] = $x; //lets grab everything here
}
print_r($results);
I would like to secure my requests in my code.
Today my curent functions are like this.
public function UpdatePMS($table,$data,$where) {
$ret = array();
$set_data = "";
foreach($data as $key => $value){
$set_data .= $key."= '".$value."', ";
}
if (isset($where)) {
$where = "WHERE ".$where;
}
$sql = "UPDATE ".$table." SET ".$set_data."".$where;
$sql = str_replace(", WHERE", " WHERE", $sql);
$stm = $this->db->prepare($sql);
$ret = $stm->execute();
return $ret;
}
With this way, i can select any tables, any datas, and any conditions.
For example:
WHERE id = 1 and status < 10
Or only
WHERE id = 10
Or sometimes
WHERE id = 1 and status >= 5
The content of where could change.
A kind of universal request.
Same for Delete, Update, Select, insert.
I tried to do like this, but it doesn't work.
$db = new PDO('mysql:host=localhost;dbname=asterisk','root','');
$table = "my_table";
$where = "WHERE id = 1";
$sql = 'SELECT * FROM :table :where';
$stm = $db->prepare($sql);
$stm->execute(array(":table" => $table, ":where" => $where));
$ret = $stm->fetchall(PDO::FETCH_ASSOC);
Any ideas?
Frankly, you cannot use prepared statements this way. There are rules to follow. So it just makes no sense to write something like this
$table = "my_table";
$where = "WHERE id = 1";
$sql = 'SELECT * FROM :table :where';
$stm = $db->prepare($sql);
$stm->execute(array(":table" => $table, ":where" => $where));
instead you should write this code
$sql = 'SELECT * FROM my_table WHERE id = ?';
$stm = $db->prepare($sql);
$stm->execute(array($id));
Besides, you cannot parameterize table and field names, so it's better to write them as is.
so i need to make one function per different requests, right?
Honestly - yes. It will spare you from A LOT of headaches.
public function UpdatePMS($data, $id)
{
$data[] = $id;
$sql = "UPDATE table SET f1 = ?, f2 = ? WHERE id = ?";
$stm = $this->db->prepare($sql);
$ret = $stm->execute($data);
return $ret;
}
which is going to be used like
$obj->UpdatePMS([$f1, $f2], $id);
I have seperate tables full of data and I require the same data from each table. For example the first table I am selecting from has the value 3623 and the second table has the value 3852.
I am trying to get both of these values into an array to then be plotted on a graph later down the line. The code I am using can be seen below, the issue is that on the value from the first foreach loop gets added and not the second one. so I end up with just 3623 and not the 3852 as well which is an issue.
$datay1 = array();
$yes = "not-set";
$sql = "SELECT * FROM `0530-0605` WHERE SearchTerm = :yes";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":yes", $yes);
$stmt->execute();
foreach($stmt as $row) {
$datay1[] = $row['Clicks'];
}
$sql = "SELECT * FROM `0606-0612` WHERE SearchTerm = :yes";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":yes", $yes);
$stmt->execute();
foreach($stmt as $row) {
$datay1[] = $row['Clicks'];
}
print_r($datay1);
You can use UNION ALL to merge result of two query as
$sql = "SELECT * FROM `0530-0605` WHERE SearchTerm = :yes
UNION ALL
SELECT * FROM `0606-0612` WHERE SearchTerm = :yes1";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":yes", $yes);
$stmt->bindParam(":yes1", $yes);
$stmt->execute();
foreach($stmt as $row) {
$datay1[] = $row['Clicks'];
}
My goal here is to set a variable to a field name from a mysql query. Some pseudo code below
1. $query = "SELECT firstName, lastName FROM users WHERE userName = 'mhopkins321';"
2. $result = mysql_query($result);
3. $while($row = mysql_fetch_assoc($result)){
4. $column1 = name_of_column($row['firstName']);
5. }
6. echo $column1
//Would return the string
firstName
obviously line 4 being the real pseudo part
Is this what you're after?
$query = "SELECT firstName, lastName FROM users WHERE userName = 'mhopkins321';"
$result = mysql_query($result);
$all_results = array();
$while($row = mysql_fetch_assoc($result)) {
$formatted_row = array();
foreach ( $row as $column => $value ) {
$formatted_row[] = array($column, $value);
}
$all_results[] = $formatted_row;
}
Or just use $column and $value how you like inside the foreach loop.
Or do you want specifically the first column, which can be accessed with reset($row); $first_key = key($row);?
You want to name a variable with the name of the column?
$$row['firstName'] = $row['firstName'];
Another way is like this:
$query = "SELECT firstName, lastName FROM users WHERE userName = 'mhopkins321'";
$result = mysql_query($result);
$row = mysql_fetch_assoc($result);
foreach($r as $key=>$value){
$$key = $value;
}
Now you can echo the values out by their column name.
This sounds redundant, but you could always use array_search:
while($row = mysql_fetch_assoc($result)){
$value = $row['firstName'];
$key = array_search($value, $row);
}
See more on array_search.