I have a PHP variable $col with a column name. I want to create a query with PDO, that selects the value of that column. I know how to use bindValue(), and tried the following:
$db = new PDO('mysql:host='. $db_host . ';dbname=' . $db_name . ';charset=utf8', $db_user, $db_password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
function get_user($id, $column){
$sql = "
SELECT :col
FROM users
WHERE `id` = :id;";
try {
$st = $db->prepare($sql);
$st->bindValue('col', $column, PDO::PARAM_STR);
$st->bindValue(':id', $id, PDO::PARAM_INT);
$st->execute();
$result = $st->fetch();
return $result;
} catch (PDOException $e) {
echo "Database query exception: " . $e->getMessage();
return false;
}
}
That results in the following exception: Database query exception: SQLSTATE[42S22]: Column not found: 1054 Unknown column ''name'' in 'field list' for $col = 'name'. Of course, the column name does exist.
It works well on WHERE = :value, but I can not get it working for a column. How to achieve this?
Addition: I did found the function bindColumn(), but I think that does the opposite, binding the column name to a PHP variable instead of binding a variable to the column.
You can use an array of allowed column names to sanitize the query.
$allowed_columns = array('name', 'type1',etc);//Array of allowed columns to sanatise query
Then check if column name is in array.
if (in_array($column, $allowed_columns)){
$result= get_user($id, $column);
}
function get_user($id, $column){
$sql = "
SELECT $column
FROM users
WHERE `id` = :id;";
try {
$st = $db->prepare($sql);
$st->bindValue(':id', $id, PDO::PARAM_INT);
$st->execute();
$result = $st->fetch();
return $result;
} catch (PDOException $e) {
echo "Database query exception: " . $e->getMessage();
return false;
}
}
I would use array_intersect something like a sanitizing function that would extract only the allowed fields. Example:
function get_fields_allowed($input_fields,$allowed){
$input_fields=explode(",",$input_fields);
$allowed=explode(",",$allowed);
return array_intersect($allowed,$input_fields);
}
$select_fields=$_POST["fields"]; //example: "id,name,email"
$fields=get_fields_allowed ($select_fields, "id,name" ) ;
So you then use the $fields as in:
$sql="Select $fields FROM [table] WHERE id=:id etc...";
Related
try {
$conn = new PDO('mysql:host=localhost;dbname=dbtable', $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$data = $conn->prepare('SELECT * FROM table WHERE name = ' . $conn->quote($name).' AND id = '. $conn->quote($id));
$data->execute();
while($row = $data->fetch(PDO::FETCH_ASSOC)) {
echo "ID : ".$row['id'].'</br>';
echo "Name : ".$row['name'].'</br>';
echo "Name : ".$row['header'].'</br>';
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
The above works for one parameter (name) but when i use AND operator it shows no results. URL is as given below.
http://www.mywebsite.com/page.php?id=2&name=xyz
As mentioned in the documentation, you're strongly advised to use parametrized queries, like so:
$data = $conn->prepare('SELECT * FROM table WHERE name = :name AND id = :id');
$data->bindParam(":name", $name);
$data->bindParam(":id", $id);
If this still does not work, I would suggest running a similar query directly against your database, through either phpMyAdmin or the MySQL Workbench, to verify that the query actually returns anything.
$data = $conn->prepare("SELECT * FROM table WHERE name = '$name' AND id <> '$id' ");
The above code worked for me.
I'm having some trouble inputting some data into a table.
I'm retrieving some values from a form and inputting them to a table, but this error shows up every time:
Error: Unknown column 'planner_id' in 'field list'
<?php
session_start();
include 'conexion_data.php';
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$teacherid = $_POST["teacherid"];
$plannerid = $_POST["plannerid"];
$yeargroup = $_POST["yeargroup"];
$subject = $_POST["subject"];
$planner_event = htmlspecialchars($_POST["event_comment"]);
$event_date = $_POST["event_date"];
echo "$teacherid $plannerid $yeargroup $planner_event $event_date <br/><br />";
if (empty($event_date) or empty($planner_event)) {
echo "One of the fields was left blank! <br />";
} else {
$sql = "INSERT INTO subject_directorio (planner_id, teacher_id, subject, yeargroup, date, comment ) VALUES ('$plannerid', '$teacherid', '$subject', '$yeargroup', '$event_date', '$planner_event')";
if (!mysqli_query($con,$sql)) {
die('Error: ' . mysqli_error($con));
} else {
/* header('Location: user_area.php'); */
echo "Data was inputed to DB";
mysqli_close($con);
}
}
?>
It's very straight
while you are getting this type error :{Error: Unknown column 'planner_id' in 'field list'}
Troubleshoot first step will be Just Describe The Table [subject_directorio]
Desc subject_directorio and check planner_id is exist or not. According to to the error
subject_directorio not holding any column called as planner_id
Hope it helps!!
It's self explanatory that your table doesn't have a column planner_id. Even if you see that it has, you may have trialing spaces before or after planner_id in the column name. Check carefully.
Database
You are using wrong way how to connect to database and fetch its data.
Because you database may be hacked using SQL Injection
The right way how to do this is:
Using PDO
$conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
For error catching:
try {
$conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
And data fetching:
$id = 5;
try {
$conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
$stmt->execute(array('id' => $id));
while($row = $stmt->fetch()) {
print_r($row);
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
Using Mysqli
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// do something with $row
}
And your problem
I think problem is in your query and binding params to it.So try to use proper way as I shown you, and then show us results.
SQLFiddle
I am trying to make a function that selects all the data from a table, in which the user defines the field and the value. Like so:
public function fetch($field, $value){
$query = $this->db->prepare("SELECT * FROM `users` WHERE ? = ?");
$query->bindValue(1, $field);
$query->bindValue(2, $value);
try{
$query->execute();
} catch(PDOException $e){
die($e->getMessage());
}
return $query->fetch();
}
I am not getting anything returned, not even an error. Can someone please tell me what I am doing wrong, or if it is even possible in PDO to let the user also choose the field of the table along with the value.
Thank you.
You cannot use placeholders for identifiers (i.e. field names); only for data. You can only make a whitelist of allowed field names:
$allowed = array('name', 'date', 'price');
if (!in_array($field, $allowed, true)) {
throw new InvalidArgumentException;
}
$query = $this->db->prepare("SELECT * FROM `users` WHERE $field = ?");
You cannot use the parameters ? in field names.
Table and Column names cannot be replaced by parameters in PDO. In that case you will simply want to filter and sanitize the data manually.
Source.
To allow for user field edition directly, you could do:
public function fetch($field, $value){
// To avoid injection
if (!in_array($field, array('these', 'are', 'field', 'names')))
echo "Sorry, that's not a valid field";
else
{
$query = $this->db->prepare("SELECT * FROM `users` WHERE `" . $field . "` = ?");
$query->bindValue(1, $value);
try{
$query->execute();
} catch(PDOException $e) {
die($e->getMessage());
}
}
return $query->fetch();
}
Furthermore, I have a small function (a method actually) to do this work automatically:
// Validate the cols names.
private function setCols($TableName)
{
// If this script is still running, $this->Table exists in database and it's sane
$Cols = array();
$STH = $this->DB->query('SHOW COLUMNS FROM `' . $this->Table . '`');
foreach ($STH->fetchAll() as $Name)
$Cols[] = $Name[0];
$this->Columns = $Cols;
}
This will find dynamically the fields for the table.
in my code im trying to get data from my db with PDO and bind params but i keep on getting empty array, this is my code :
try{
$pdo =new PDO('mysql:host=localhost;dbname=***', '***','***');
$pdo->setAttribute(pdo::ATTR_ERRMODE,
pdo:: ERRMODE_EXCEPTION);
$pdo->query('set names "utf8"');
}
catch (PDOException $e) {
die('error connectin database');
}
$table = 'products';
$column = 'id';
$niddle = '70';
$sql = "SELECT * FROM `{$table}` WHERE ";
$sql .= ":column LIKE :niddle";
$pre = $pdo->prepare($sql);
$pre->bindParam(':column', $column ,PDO::PARAM_STR);
$pre->bindParam(':niddle', $niddle, PDO::PARAM_STR);
$result = $pre->setFetchMode(PDO::FETCH_ASSOC);
$pre->execute();
print_r($pre->fetchAll());
there is no exeption thrown, what could be the problem?
You should not bind the column name as a prepared statement parameter string as it will quote the column name. Do like you do with the table name just use it-- after whitelisting it.
This has annoyed me for a while now. I am trying this query in phpmyadmin.
select `id` from `users` where `fb_id` = 507292797 limit 1
This returns the value 13, so why doesn't this work:
$sql = "select `id` from `users` " .
"where `fb_id` = :fb_id " .
"limit 1";
try
{
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':fb_id', $fb_id2, PDO::PARAM_INT);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
$result = $stmt->execute();
$stmt->closeCursor();
}
catch (Exception $e)
{
die ($e->getMessage() );
}
echo "id: " . $fb_id2 . " var_dump: " . var_dump($user);
exit();
This returns:
id: 507292797 var_dump: bool(false)
When var_dump should return $user['id'] = 13
Can somebody see what I am doing wrong here?
ps. here is my db connection function if that matter
$dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME;
$driver_options = array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8' );
try
{
$this->db = new PDO($dsn, DB_USER, DB_PASS, $driver_options);
You are doing things in this order :
Preparing the statement
Binding the variables
Trying to fetch data from the statement
Executing the statement
The two last steps should be in the inverse order : you must execute the statement before you can fetch data (that's obtained by executing it).
Basically, instead of using this :
// fetch, then execute ???
$user = $stmt->fetch(PDO::FETCH_ASSOC);
$result = $stmt->execute();
You should use that :
// Execute, **then** fetch
$stmt->execute();
$user = $stmt->fetch(PDO::FETCH_ASSOC);
Looks like you are fetching before executing?