Use PDO exec(array()) with several operands - php

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);

Related

how to use PDO rowCount() function in foreach?

i need some help , i have simple code like count rows in php, i use PDO ,
so i check if rowCount > 0 i do job if no other job but i have it in foreach function, in first step i get true result but in other i get invalid
so i think it is function like a closeCursor() in PDO but i try and no matter . maybe i do it wrong ?
it is part of my code
public function saveClinicCalendar($post){
$daysItm = '';
$Uid = $post['Uid'];
$ClinicId = $post['ClinicId'];
$type = $post['type'];
$resChck = '';
foreach($post['objArray'] as $arr){
foreach($arr['days'] as $days){
$daysItm = $days.",".$daysItm;
}
$daysItm = substr($daysItm, 0, -1);
$dateTime = $arr['dateTime'];
$sqlChck = 'SELECT * FROM clinic_weeks WHERE dates = :dates AND Uid = :Uid AND category = :category AND Cid = :Cid AND type = :type';
$resChck = $this->db->prepare($sqlChck);
$resChck->bindValue(":dates",$dateTime);
$resChck->bindValue(":Cid",$ClinicId);
$resChck->bindValue(":type",$type);
$resChck->bindValue(":Uid",$Uid);
$resChck->bindValue(":category",$Uid);
$resChck->execute();
$co = $resChck->rowCount();
if($co > 0){
/*UPDATE*/
$sql = 'UPDATE clinic_weeks SET dates = :dates ,time = :time, Cid = :Cid, type = :type, Uid = :Uid, category = :category ';
$res = $this->db->prepare($sql);
$res->bindValue(":dates",$dateTime);
$res->bindValue(":time",$daysItm);
$res->bindValue(":Cid",$ClinicId);
$res->bindValue(":type",$type);
$res->bindValue(":Uid",$Uid);
$res->bindValue(":category",$Uid);
}else{
/*INSERT*/
$sql = 'INSERT INTO clinic_weeks (dates,time, Cid,type,Uid,category) VALUES (:dates,:time, :Cid,:type,:Uid,:category)';
$res = $this->db->prepare($sql);
$res->bindValue(":dates",$dateTime);
$res->bindValue(":time",$daysItm);
$res->bindValue(":Cid",$ClinicId);
$res->bindValue(":type",$type);
$res->bindValue(":Uid",$Uid);
$res->bindValue(":category",$Uid);
}
$res->execute();
$resChck->closeCursor();
$resChck = null;
$daysItm = '';
}
}
what i am doing wrong?
many thanks to Barmar, he suggest me a true answer.
here is a code
$sql = "INSERT INTO clinic_weeks
(`timestam`,`time`,dates,Cid,type,Uid,category)
VALUES
('$timestamp','$daysItm','$dateTime','$ClinicId','$type','$Uid','$Uid')
ON DUPLICATE KEY UPDATE `time` = '$daysItm' ";
I use there "ON DUPLICATE KEY UPDATE" and it`s work perfectly!
instead a big code top of page i make a two line of code.

PDO MySQL and php like statement

When I execute this query to the DB:
SELECT * FROM `task` WHERE `date_time_from` like '%0000%'
I get a few results, now I am trying to do the same with PDO and I can not manage to get any results or errors. This is what I have done:
$dbChain = 'mysql:host='.$GLOBALS['dbhost'].';dbname='.$GLOBALS['dbname'];
try{
$dbh = new PDO($dbChain, $GLOBALS['dbuser'], $GLOBALS['dbpassword']);
$sql = "SELECT * FROM task"
. "WHERE date_time_from like CONCAT('%', :dateFrom, '%')";
$a = '0000';
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':dateFrom', $a);
$stmt->execute();
$total = $stmt->rowCount();
echo $total;
while ($row = $stmt->fetch()){
var_dump($row);
}
} catch (Exception $e){
echo 'Error'.$e->getMessage();
}
The result of this is $total = 0. Can anyone tell me what am I doing wrong?
I have also tried this:
$sql = "SELECT * FROM task"
. "WHERE date_time_from like :dateFrom";
$a = "%0000%";
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':dateFrom', $a);
$stmt->execute();
Same result for $total.
bindParam escapes the "%" in the query. It will not work as you expect...
You can, however, use bindValue like so...
$sql = "SELECT * FROM task WHERE date_time_from LIKE ?";
$stmt = $dbh->prepare($sql);
$stmt->bindValue( 1, "%0000%" );
$stmt->execute();
Alternatively, if you want 0 values from a datetime column, you can just do this:
$sql = "SELECT * FROM task WHERE date_time_from = '0000-00-00'";

Deleting Multiple Rows in a MySQL Database using PHP PDO extension

I am using bellow MYSQL query to delete single records from table and working perfect for me but how to write for multiple records with IN operator.
$sql = "DELETE FROM reg WHERE id = :id";
$query = $this->db->prepare($sql);
$query->execute(array(':id' => $id));
For example I have ids from array like $id = array(23,24); and I have treid with loop like bellow but not worked :(
for($i=0; $i<count($id); $i++) {
$id = $id[$i];
$sql = "DELETE FROM $table_name WHERE id = :$id";
$query = $this->db->prepare($sql);
$query->execute(array(':id' => $id));
}
I hope you understand my question and hope you will help me.
Thanks.
for($i=0; $i<count($id); $i++) {
$sql = "DELETE FROM $table_name WHERE id = :id";
$query = $this->db->prepare($sql);
$query->execute(array(':id' => $id[$i]));
}

Working with foreach, issets, arrays?

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.

Select all records when no value is supplied

I have a function in php that does retrieval and display work from a MySql database.
It's like this:
function thisFunction($id,$country,$year){
global $conn;
$conn = connect();
$stmt = $conn->prepare("select * from table where id = :id and countryCode = :country and YEAR(addedDate) = :year and status = 0");
$stmt->execute(array(
':id' => $id,
':country' => $location,
':year' => $year
));
}
The problem is, sometimes $id has a value, sometimes it doesn't. When it does have a value, I'd like to select records with that value, when it doesn't I'd like to select all.
How do I write the sql in there, or do this thing, so that when there is a value it'll select only records with that value, and when there isn't a value, it'll select all. It's the part where when no value is selected - then select all where I'm stuck.
I call the function like anyone would. Nothing unique there.
select * from table where id = 9 -- works fine - displays all records where id = 9
select * from table where id = no value supplies - should display all value. How do I do this?
Can you please help?
select * from table where id = * //Does not work
Just remove the id part if it's empty:
function thisFunction($id,$country,$year){
global $conn;
$conn = connect();
if (!isset($id) || empty($id))
{
$stmt = $conn->prepare("select * from table where countryCode = :country and YEAR(addedDate) = :year and status = 0");
$stmt->execute(array(
':country' => $location,
':year' => $year
));
}
else
{
$stmt = $conn->prepare("select * from table where id = :id and countryCode = :country and YEAR(addedDate) = :year and status = 0");
$stmt->execute(array(
':id' => $id,
':country' => $location,
':year' => $year
));
}
}
select * from table where id = id;
Sample fiddle
You could use something like this:
function thisFunction($id,$country,$year){
global $conn;
$sql_query = "select * from table where status = 0";
$where_data = array();
if(isset($id) && $id != '*'){ // Only add this if ID is set to something other than *
$where_data[':id'] = $id;
$sql_query .= " AND id = :id";
}
if(isset($location)){
$where_data[':country'] = $location;
$sql_query .= " AND countryCode = :country";
}
if(isset($year)){
$where_data[':year'] = $year;
$sql_query .= " AND YEAR(addedDate) = :year";
}
$conn = connect();
$stmt = $conn->prepare($sql_query);
$stmt->execute($where_data);
}
you could potentially select them if the column is not null.
select * from table where id is not null

Categories