Using PDO with numbers versus strings - php

I have the following PHP code:
$comp1 = $_POST['cohort_id1'];
$comp2 = $_POST['cohort_id2'];
$comp3 = $_POST['cohort_id1'];
$comp4 = $_POST['cohort_id2'];
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT cat_code, value, :comp1 , :comp2, round(:comp3/:comp4 * 100) as index_number FROM {$table}";
$stmt = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY) );
$stmt->execute(array(':comp1' => $comp1, ':comp2' => $comp2, ':comp3' => $comp3, ':comp4' => $comp4 ));
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
header('Content-type: application/json');
echo json_encode($result);
Here is how one of the objects is returned:
?: "national_percent"
cat_code: "edu"
index_number: null
value: "Some College"
What I can't understand is why the first line returns with a "?", but more importantly, why the index_number is null. I suspect it is because those values are being converted into strings, but I'm not sure how to handle that.

To prevent SQL injection of user input that contains column names, check the input against an array of valid column names:
$valid_columns = array('col1', 'col2', 'col3');
if (in_array($user_input_col, $valid_columns))
{
$sql = "SELECT {$user_input_col} from table...";
...
}
else
{
die('Invalid column name');
}

Related

Construct http_build_query with PDO and Select

I am trying to create an http_build_query array but it is inserting some diferent characters, this is my Code:
function Conectar(){
try{
$opcoes = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8');
$con = new PDO("mysql:host=localhost; dbname=*****;", "*****", "*****", $opcoes);
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $con;
} catch (Exception $e){
echo 'Erro: '.$e->getMessage();
return null;
}
}
$pdo = Conectar();
$sql = "
SELECT dominio
FROM dominios_extraidos
WHERE verificado='0' LIMIT 3
";
$stm = $pdo->prepare($sql);
$stm->execute();
while ($rows = $stm->fetch()) {
$query = http_build_query(array(
'domains' => array(
''.$rows['dominio'].'',
)
));
print_r($query);
}
Creating this output:
domains%5B0%5D=0002021web.com.br%0Adomains%5B0%5D=007import.com.br%0Adomains%5B0%5D=00pet.com.br%0A
But this is my desire output:
domains%5B0%5D=0002021web.com.br&domains%5B1%5D=007import.com.br&domains%5B2%5D=00pet.com.br
My desire output could be generated manually using this code:
$query = http_build_query(array(
'domains' => array(
'0002021web.com.br',
'007import.com.br',
'00pet.com.br',
)
));
print_r($query);
Thank you for your time :)
You want to build up your array properly first, so that it looks like your manual array, then use http_build_query:
$domains = ['domains' => []];
while ($rows = $stm->fetch()) {
$domains['domains'][] = trim($rows['dominio']);
}
$query = http_build_query($domains);
print_r($query);
Create an array of domains in the loop and then after the loop is complete pass it as a param to the http_build_query().
while ($rows = $stm->fetch()) {
$doms[] = trim($rows['dominio']);
}
$query = http_build_query( ['domains' => $doms] );
print_r($query);
This will produce
domains%5B0%5D=0002021web.com.br%0A&domains%5B1%5D=007import.com.br%0A&domains%5B2%5D=00pet.com.br%0A
which equates to
domains[0]=0002021web.com.br
&domains[1]=007import.com.br
&domains[2]=00pet.com.br
0A decoded is \n or Line Feed;
perhaps try sanitizing first with
$query= trim($query, "\x00..\x20\x7F");
this code remove ASCII character from 00 to 20 hex and 7f hex

Mysql Return all values of a table where column is equal to user input

I have some sql statements that accepts a number and if that number is equal to the value of a column in a database, it should return all rows in the database that has the same value. Unfortunately the rows only return blog_post_id that has a value 0.
This is my codes below:
<?php
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
);
$blog_post_id = !empty($_POST['blog_post_id']) ? $_POST['blog_post_id']
: '';
$pdo=new PDO("mysql:dbname=db;host=localhost","username","password",
$options);
$statement=$pdo->prepare("SELECT * FROM comment WHERE blog_post_id =
'$blog_post_id'");
$statement->execute();
$results=$statement->fetchAll(PDO::FETCH_ASSOC);
$json=json_encode($results);
if ($json)
echo $json;
else
echo json_last_error_msg();
?>
You are actually missing the point of using the function prepare() and you need to check if the query does actually return any results..
<?php
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
);
$blog_post_id = !empty($_POST['blog_post_id']) ? $_POST['blog_post_id'] : '';
$pdo = new PDO("mysql:dbname=db;host=localhost", "username", "password", $options);
$statement = $pdo->prepare("SELECT * FROM comment WHERE blog_post_id = ?");
$statement->execute([$blog_post_id]);
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
$json = array();
if (count($results) > 0) {
foreach ($results as $row) {
$json[] = array(
'id' => $row['blog_post_id'],
'Field' => $row['Column'],
'AnotherField' => $row['AnotherColumn'],
'AnotherField1' => $row['AnotherColumn1'],
'ETC' => $row['AnotherColumnName']
);
}
echo json_encode($json);
} else {
echo "no data found";
}
?>
You should do variable binding like so:
$pdo=new PDO("mysql:dbname=db;host=localhost","username","password", $options);
$statement=$pdo->prepare("SELECT * FROM comment WHERE blog_post_id = :blog_post_id");
$statement->execute(['blog_post_id' => $blog_post_id]);
This will also prevent 1st level SQL-Injection as described here: Are PDO prepared statements sufficient to prevent SQL injection?

PDO insert array

Reccently I have been attempting to insert an array into a database, I keep getting the error message "Notice: Array to string conversion", I not really sure how to resolve this issue, any advice would be greatly appreciated
<?php
try{
$db = new PDO("mysql:host=localhost;dbname=test", 'root', '');
$db ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e){
echo $e->getMessage();
die();
}
if ($_SERVER["REQUEST_METHOD"] == "POST"){
$sort = $_POST['sort'];
$count = $_POST["count"];
$error = $_POST["error"];
$audit = array( ':sort' => $sort,
':count' => $count,
':error' => $error
);
foreach($audit as $completeAudit => $display) {
//print_r($display);
$sql = implode("INSERT INTO `audits` (`sort`, `count`, `error`, `timeentered`) VALUES ('$sort','$count','$error', NOW())");
}
$query = $db->prepare($sql);
$query->execute(array(
':sort' => $sort,
':count' => $count,
':error' => $error
));
}
EDIT
$db = new PDO("mysql:host=localhost;dbname=test", 'root', '');
$db ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if ($_SERVER["REQUEST_METHOD"] == "POST"){
$sql = "INSERT INTO `audits` (`sort`, `count`, `error`, `timeentered`) VALUES (?,?,?, NOW())";
$stmt = $db->prepare($sql);
$query->execute(array($_POST['sort'], $_POST["count"], $_POST["error"]));
}
This is how it looks now, I deleted everything and used code supplied below
The problem is probably with the implode() call. It requires an array as parameter but you're passing a string.
However, you're overriding the $sql variable in every iteration inside the loop so I'm not sure what it's supposed to do.
Last thing, your code is subject to SQL inejctions so have a look at using prepared statements.
this error has nothing to do with PDO - it's just basic PHP syntax.
However, your PDO is wrong as well. Here is the proper code:
$db = new PDO("mysql:host=localhost;dbname=test", 'root', '');
$db ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if ($_SERVER["REQUEST_METHOD"] == "POST"){
$sql = "INSERT INTO `audits` (`sort`, `count`, `error`, `timeentered`) VALUES (?,?,?, NOW())");
$stmt = $db->prepare($sql);
$stmt->execute(array($_POST['sort'], $_POST["count"], $_POST["error"]));
}

No data returned with PDO

Here's the relevant piece of my PHP code:
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//get values from AJAX
$whereCategory = isset($_GET['cat_code'])? "{$_GET['cat_code']}" : '';
$sortvalue = isset($_GET['sortvalue'])? "{$_GET['sortvalue']}" : '';
$sortorder = isset($_GET['sortorder'])? "{$_GET['sortorder']}" : '';
$sql = "select * from {$table} where cat_code = ':cat_code' order by ':sortvalue' ':sortorder';";
$stmt2 = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY) );
$stmt2->execute(array(':cat_code' => $whereCategory,':sortvalue' => $sortvalue, ':sortorder' => $sortorder));
$result = $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
header('Content-type: application/json');
echo json_encode($result);
If I var_dump the variables $where_category,$sortorder, and $sortvalue, they are all what I expect and the correct data that would need to be passed in the query. I've tried the query directly without PDO just substituting in the correct variables and I get back what I want, but apparently I'm not sending the variables correctly with my PDO methods (such as they are).
I'm getting no errors back, but no data returned either.
Any suggestions?
First off, named placeholders doesn't need to be quoted, so ditch those.
Secondly, you cannot bind identifiers (table/columns/DESC/ASC) You could only whitelist those.
Third, don't mix ->query() and ->execute(). Use ->execute() alone:
header('Content-type: application/json');
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//get values from AJAX
if(isset($_GET['cat_code'], $_GET['sortvalue'], $_GET['sortorder'])) {
$whereCategory = $_GET['cat_code'];
$sortvalue = $_GET['sortvalue'];
$sortorder = $_GET['sortorder'];
// super simple filtering
$default_tables = array('table1', 'table2', 'table3');
$default_columns = array('column1', 'column2', 'column3');
in_array(needle, haystack)
if(
in_array($table, $default_tables) &&
in_array($sortvalue, $default_columns) &&
in_array($sortorder, array('ASC', 'DESC'))
) {
// good to go
$sql = "SELECT * FROM $table where cat_code = :cat_code ORDER BY $sortvalue $sortorder";
$stmt2 = $dbh->prepare($sql);
$stmt2->execute(array(':cat_code' => $whereCategory));
echo json_encode($stmt2->fetchAll(PDO::FETCH_ASSOC));
} else {
// did not satisfy condition
}
}
Sidenote: Those default tables and columns are just examples, you'll need to populate and correspond it into yours. You could create your own method/function which creates a map with tables with their corresponding columns if you really want to be sure of it.
Change this -
$result = $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
to this -
$result = $stmt2->fetchAll(PDO::FETCH_ASSOC);
You're trying to run the query again when all you need to do is grab the results.
The query you are running is against a prepared statement which is incorrect, removing the query and assigning the result from the execute statement will work. There's also quite a few other problems in your php. Also using the input directly from the user such as the table (which appears to be undefined in this code snippet), sort order and sort value leaves you open to sql injection.
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//get values from AJAX
$whereCategory = isset($_GET['cat_code'])? $_GET['cat_code'] : '';
$sortvalue = isset($_GET['sortvalue'])? $_GET['sortvalue'] : '';
$sortorder = isset($_GET['sortorder'])? $_GET['sortorder'] : '';
/** you cannot use prepared statements for doing the order by */
$sql = "select * from $table where cat_code = :cat_code order by $sortvalue $sortorder;";
$stmt2 = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY) );
$query = $stmt2->execute(['cat_code' => $whereCategory]);
/** below line isn't needed because above on deals with it */
//$dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
$result = $query->fetchAll();
header('Content-type: application/json');
echo json_encode($result);
try without quotes:
$sql = "select * from {$table} where cat_code = :cat_code order by :sortvalue :sortorder;";
Use Like this
$result = $stmt2->fetchAll(PDO::FETCH_ASSOC);

How to add another column in where clause

I am having issue trying to figure out how to add another column to my where clause not sure how to do it. I need it to have FIRSTNAME and LASTNAME since the existing database has two columns.
<?php
header('Content-Type: application/json');
try {
$dbName = "C:\\inetpub\\wwwroot\\fpdb\\staffing.mdb";
$db = new PDO("odbc:DRIVER={Microsoft Access Driver (*.mdb)};charset=UTF-8; DBQ=$dbName; Uid=; Pwd=;");
}
catch (PDOException $e) {
echo $e->getMessage();
}
$Employee_Name= trim($_POST["Employee_Name"]);
$params = array( ':FIRSTNAME' => $Employee_Name);
$query = $db->prepare("
SELECT * FROM tbl_USERS
WHERE FIRSTNAME=:FIRSTNAME");
$query->execute($params);
$result = $query->fetch(PDO::FETCH_ASSOC);
$EMPLOYEE_NUMBER=trim('EMPLOYEE_NUMBER');
$rc= $result[$EMPLOYEE_NUMBER];
echo json_encode ($rc);
?>
$Employee_Name= trim($_POST["Employee_Name"]);
$params = array( ':FIRSTNAME' => $Employee_Name, ':LASTNAME'=>$Employee_Lastname );
$query = $db->prepare("
SELECT * FROM tbl_USERS
WHERE FIRSTNAME=:FIRSTNAME and LASTNAME=:LASTNAME");
I'm guessing the column names above but generally the right idea

Categories