PHP PDO prepare query issue - php

The below works as long as the two fields are selected. If neither are selected it works, however my issue is when only one of the fields is selected, it doesn't work. It throws the unbound parameters issue.
I've tried setting a false value of 0 to both of the variables, however that won't work because then the query would be select from where = 0.
Ideas?
public static function searchProfile($status, $fundamt)
{
$database = DatabaseFactory::getFactory()->getConnection();
$sql = "SELECT profile_id, profile_name, profile_url, finance_fundingtype, finance_equitypercent, finance_loanrate, finance_loanlength, finance_fundingamount, info_tradingstatus, info_elevatorpitch, info_patentable, info_industry, info_industry1, info_industry2, info_industry3, info_industry4, seeker_logo_url FROM profile_seeker WHERE profile_status = '1' ";
if ($status) {
$sql .= "AND info_tradingstatus IN (:status) ";
}
if ($fundamt) {
$sql .= "AND finance_fundingamount <= :fundamt ";
}
$query = $database->prepare($sql);
$query->execute(array(':status' => $status, ':fundamt' => $fundamt));
$profiles = array();
$profiles[$profile->profile_id] = new stdClass();
$profiles[$profile->profile_id]->profile_id = $profile->profile_id;
$profiles[$profile->profile_id]->profile_name = $profile->profile_name;
$profiles[$profile->profile_id]->profile_url = $profile->profile_url;
$profiles[$profile->profile_id]->finance_fundingtype = $profile->finance_fundingtype;
$profiles[$profile->profile_id]->finance_equitypercent = $profile->finance_equitypercent;
$profiles[$profile->profile_id]->finance_loanrate = $profile->finance_loanrate;
$profiles[$profile->profile_id]->finance_loanlength = $profile->finance_loanlength;
$profiles[$profile->profile_id]->finance_fundingamount = $profile->finance_fundingamount;
$profiles[$profile->profile_id]->info_tradingstatus = $profile->info_tradingstatus;
$profiles[$profile->profile_id]->info_elevatorpitch = $profile->info_elevatorpitch;
$profiles[$profile->profile_id]->info_patentable = $profile->info_patentable;
$profiles[$profile->profile_id]->info_industry = $profile->info_industry;
$profiles[$profile->profile_id]->info_industry1 = $profile->info_industry1;
$profiles[$profile->profile_id]->info_industry2 = $profile->info_industry2;
$profiles[$profile->profile_id]->info_industry3 = $profile->info_industry3;
$profiles[$profile->profile_id]->info_industry4 = $profile->info_industry4;
$profiles[$profile->profile_id]->seeker_logo_url = $profile->seeker_logo_url;
}
return $profiles;

You could try to check if the variables are set and that they hold a value that is not 0 and this has a string length longer than 0:
if (isset($status) && $status !== 0 && strlen($status) > 0) {
$sql .= "AND info_tradingstatus IN (:status) ";
}
if (isset($fundamt) && $fundamt!== 0 && strlen($fundamt) > 0) {
$sql .= "AND finance_fundingamount <= :fundamt ";
}
You could also try to bind the parameters manually:
$query = $database->prepare($sql);
if (isset($status) && $status !== 0 && strlen($status) > 0) {
$query ->bindParam(':status',$status);
}
if (isset($fundamt) && $status !== 0 && strlen($fundamt) > 0) {
$query ->bindParam(':fundamt',$fundamt);
}
$query->execute();

Your binding error comes because you forgot to use the same if exists statement on your bindings.
Change this...
if ($status) {
$sql .= "AND info_tradingstatus IN (:status) ";
}
if ($fundamt) {
$sql .= "AND finance_fundingamount <= :fundamt ";
}
and
$profiles[$profile->profile_id]->finance_fundingamount = $profile->finance_fundingamount;
$profiles[$profile->profile_id]->info_tradingstatus = $profile->info_tradingstatus;
To this...
if (isset($status) && $status != '') {
$sql .= "AND info_tradingstatus IN (:status) ";
}
if (isste($fundamt) && $fundamt != '') {
$sql .= "AND finance_fundingamount <= :fundamt ";
}
and
if (isset($status) && $status != '') {
$profiles[$profile->profile_id]->finance_fundingamount = $profile->finance_fundingamount;
}
if (isste($fundamt) && $fundamt != '') {
$profiles[$profile->profile_id]->info_tradingstatus = $profile->info_tradingstatus;
}
This will stop the binding if one or both of the text boxes are empty.

Related

Count all products with search function

I’ve been trying to call a function and it just doesn’t seem to work.
So, this is function count_all_products_q. This is needed for pagination.
function count_all_products_q($options=[]) {
global $db;
$visible = $options['visible'] ?? false;
$search_statement = isset($_POST['search']) ? $_POST['search'] : '';
if ($search_statement == '') {
$search_statement = isset($_GET['search']) ? $_GET['search'] : '';
}
$search = h(db_escape($db, $search_statement));
$sql = "SELECT COUNT(id) FROM products ";
if ($search != '') {
$search = h(db_escape($db, $search_statement));
$sql .= "WHERE (`prod_name` LIKE '%".$search."%') ";
}
if($visible) {
$sql .= "AND visible = true ";
}
$sql .= "ORDER BY position ASC";
$result = mysqli_query($db, $sql);
confirm_result_set($result);
$row = mysqli_fetch_row($result);
mysqli_free_result($result);
//[0] - I want only one number.
$count = $row[0];
return $count;
}
search.php
$products_count = count_all_products_q(['visible' => $visible]);
//if count is nothing ('') redirect to....
if($products_count == '') {
redirect_to(url_for('/index.php'));
}
This part doesn’t work if($products_count == '') when I click search by mistake, instead of redirection, I have Database query failed (search.php?search=).
Am I missing something, did I do something wrong? Thanks for your attention!
UPDATE2 everything works!
search.php
$visible = $visible ?? true;
$search_statement = isset($_POST['search']) ? $_POST['search'] : '';
if ($search_statement == '') {
$search_statement = isset($_GET['search']) ? $_GET['search'] : '';
}
$search = h(db_escape($db, $search_statement));
if($search == '') {
redirect_to(url_for('/index.php'));
}
$products_count = count_all_products_q(['visible' => $visible]);
You have problem with the code where you are concatenating "WHERE" condition.
if($visible) then "WHERE" which is wrong and will give query error if this condition fails. Also $options['visible'] ?? false; this code may cause issue depending on the version on PHP. You can change your conditions like this to make it work in all scenarios.Followed by rest of the logic.
$sql = "SELECT COUNT(id) FROM products WHERE 1 ";
if($visible) {
$sql .= "AND visible = true ";
}
if ($search != '') {
$search = h(db_escape($db, $search_statement));
$sql .= "AND (prod_name LIKE '%".$search."%') ";
}
In case there is no visible is false ans search has text your query will be broken
In this case you should
if($visible) {
$sql .= "WHERE visible = true ";
}
if ($search != '') {
$search = h(db_escape($db, $search_statement));
$sql .= $visible ? 'AND ' : 'WHERE';
$sql .= " (`prod_name` LIKE '%".$search."%') ";
}
Not tested but I hope you can see your problem.
Print your query with echo $sql or with echo $this->db->query()
Run directly in mysql and check why it is getting failed.
May you have generate wrong query.

how to Search Result Record Paging

This code is working fine for searching with POST method, how to pagination search results?
I have attach images. First image searching with this field:
Searching result in which I want paging:
<? php
include('connection.php');
if (isset($_POST['search'])) {
$fields = array('EJAMAATID', 'GNAME', 'MOBNO', 'EMAILID', 'DNNO', 'GCNTRYID', 'PINCODE', 'GCITYID', 'DNTYPE');`search field`
$conditions = array();
foreach($fields as $field) {
if (isset($_POST[$field]) && $_POST[$field] != '') {
$conditions[] = "`$field` LIKE '%".mysql_real_escape_string($_POST[$field]). "%'";`condition`
}
}
$query = "SELECT * FROM donation ";
$orderby = "ORDER BY DNDATE desc";
$datebetween = "AND DNDATE >='$start' AND DNDATE<='$end'";
if (count($conditions) > 0) {
$yakin5 = implode(' AND ', $conditions);
$query. = "WHERE ".$yakin5.$datebetween.$orderby;
}
}
$jo = (isset($query)) ? $query : '';
$don4 = mysql_query($jo);
while ($roww = mysql_fetch_array($don4)) {
}
?>

Issue in using arrays as parameters of method of PHP custom class

To explain my issue, here is a simple code at first:
public function sql($data) {
if (is_array($data)) {
$cells = $data['cells'];
$from = $data['from'];
$where = $data['where'];
$joins = $data['joins'];
$order_by = $data['order_by'];
$o_type = $data['order_by_type'];
$limit = $data['limit'];
/*****************************/
if ($cells == '') { $cells = "*"; }
if ($where != '') { $where = "where ".$where; }
if ($oredr_by != '') { $order_by = "order by ".$order_by." ".$o_type; }
if ($limit != '') { $limit = "limit ".$limit; }
//
$sql = "select ".$cells." from ".$from." ".$joins." ".$where." ".$order_by." ".$limit;
$run = mysqli_query($_SESSION['con'], $sql);
}else{
$run = mysqli_query($_SESSION['con'], $data);
}
}
When I start using this method, I pass a multidimensional array as a parameter, like this:
$sql = $class->sql([ "from" => "table", "order_by" => "id", "order_by_type" => "asc" ]);
/* This will generate and run this query: select * from table order by id asc */
// Notice that I've only used 3 keys, not the all above.
In Apache server, it works OK perfectly when I just use some of the keys of array, but in XAMPP it doesn't because it says that I have to pass all the parameters (cells, from, where, joins, ...) even if they are empty.
Please help me to resolve this, and thanks.
You can use isset to check if an array key is present, then get it's value like.
public function sql($data) {
if (is_array($data)) {
$cells = '';
if(isset($data['cells']) {
$cells = $data['cells'];
}
....
/*****************************/
if ($cells == '') { $cells = "*"; }
if ($where != '') { $where = "where ".$where; }
if ($oredrby != '') { $orderby = "order by ".$orderby." ".$od_type; }
if ($limit != '') { $limit = "limit ".$limit; }
$sql = "select ".$cells." from ".$table." ".$joins." ".$where." ".$orderby." ".$limit;
$run = mysqli_query($_SESSION['con'], $sql);
}else{
$run = mysqli_query($_SESSION['con'], $data);
}
}
Or simply just do error_reporting(1) before calling this function or in your index.php.
The problem is this.
$arr = ["a"];
echo $arr["b"];
You will get an error notice.
Notice: Undefined index: b
If you want to avoid this use it in this way.
$arr = ["a"];
$arr = ["b"] = "";
echo $arr["b"];
Change $from to $table, you have not $table variable
$from = $data['from'];
to
$table = $data['from'];
Also you have spelling mistake biggest spelling mistake which is very difficult to find.orderby and oredrby

Filter MYSQL query with form options

I have a form with multiple inputs which are my filters.
This is my code (not all of it, just the part I want to fix):
$req_resumo = '';
$req_status = '';
$req_usuario = '';
$n_req = 0;
$parametros = "";
// Checks which fields are filled and increases the number of filters for future usage
if (isset($_POST['usuario']) && $_POST['usuario'] != "") {
$req_usuario = $_POST['usuario'];
$n_req++;
}
if (isset($_POST['resumo']) && $_POST['resumo'] != "") {
$req_resumo = $_POST['resumo'];
$n_req++;
}
if (isset($_POST['status']) && $_POST['status'] != "") {
$req_status = $_POST['status'];
$n_req++;
}
// Then (there is some code between these parts)
if ($n_req > 0 && $funcao != 'usuario') $parametros.= " where ";
if ($req_usuario != "") {
$parametros.= " usuario = '$req_usuario' ";
if ($n_req > 1) $parametros.= " and ";
}
if ($req_resumo != "") {
$parametros.= " resumo = '$req_resumo' ";
if ($n_req > 1 && ($req_status != "") || ($req_data_inicial != "")) $parametros.= " and ";
}
if ($req_status != "") {
$parametros.= " status = '$req_status' ";
}
// This will create the query and add the parameters string at the end.
$tot = mysqli_query($con, "SELECT * FROM solicitacoes $parametros");
This code looks ugly, and even for me (begginer), it doesn't feels right, does not sounds like the way of coding.
So, is there any better and easier way of building this code?
Give this a try. From my testing locally (without db) looked right.
$n_req = 0;
$_POST['usuario'] = 'test';
$_POST['resumo'] = 'test2';
$_POST['status'] = 'test3';
if (!empty($_POST['usuario'])) {
$req_usuario = $_POST['usuario'];
$where[] = " usuario = ? ";
$params[] = $req_usuario;
$n_req++;
}
if (!empty($_POST['resumo'])) {
$req_resumo = $_POST['resumo'];
$where[] = " resumo = ? ";
$params[] = $req_resumo;
$n_req++;
}
if (!empty($_POST['status'])) {
$req_status = $_POST['status'];
$where[] = " status = ? ";
$params[] = $req_status;
$n_req++;
}
$sql_where = !empty($where) ? ' where ' . implode(' and ', $where) : '';
echo $sql_where;
$tot = mysqli_prepare($con, "SELECT * FROM solicitacoes $sql_where");
if(!empty($params)) {
//foreach($params as $param) {
// mysqli_stmt_bind_param($tot, "s", $param);
//echo $param;
//}
$params = array_merge(array($tot),
array(str_repeat('s', count($params))),
array_values($params));
print_r($params);
call_user_func_array('mysqli_stmt_bind_param', $params);
// adapated from https://stackoverflow.com/questions/793471/use-one-bind-param-with-variable-number-of-input-vars and http://www.pontikis.net/blog/dynamically-bind_param-array-mysqli may need to be altered
}
echo "SELECT * FROM solicitacoes $sql_where";
mysqli_execute($tot);
If all three values are populated your query should be
SELECT * FROM solicitacoes where usuario = ? and resumo = ? and status = ?
The ? are populated with the values by the driver later in the process. This prevents the user(s) from adding in malicious code to manipulate the SQLs processing.
https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_1:_Prepared_Statements_.28Parameterized_Queries.29
How can I prevent SQL injection in PHP?
I also didn't see where $funcao was set..
You can comment out the mysqli functions and decomment out the echo lines to see what the code does. That is how I confirmed queries were being built as expected.
$predicates = array();
if ($_POST['usuario'] != "") {
$predicates[] = "usuario = '{$_POST["usuario"]}'";
}
if ($_POST['resumo'] != "") {
$predicates[] = "resumo = '{$_POST["resumo"]}'"
}
if ($_POST['status'] != "") {
$predicates[] = "status = '{$_POST["status"]}'"
}
if (count($predicates) == 0) {
// handle case when nothing specified in POST
} else {
$tot = mysqli_query($con, "SELECT * FROM solicitacoes WHERE "
. implode(" and ", $predicates) );
}
I may not have all your logic exactly as required ... but the ideas are there. Use implode() to insert and between the predicates of your WHERE clause (it'll figure out how many are needed, if any). Also, since it is your HTML form that is submitting the POST, you can be certain that at least some value is being passed for each POST variable (so isset() is not required).

Infinite scrolling

I am trying to add some "Infinite Scrolling" to my product pages. However, i can't get it working at all, so i have nothing.
The page currently works, but it just outputs all of the products. I can't get the infinite scrolling scripts i found working, as my query is not always the same.
This is the code that builds my query, using GETs:
$kategori_q = "";
if ($kategori !== "") {
if ($hkat !== "") {
$ukator = "";
$underkategorier = sqlSelect("SELECT * FROM underkategorier WHERE fk_hkategori = '$kategori'");
while ($row = sqlFetch($underkategorier)) {
$ukator .= " fk_ukategori = '".$row['underkategori_id']."' OR";
}
$kategori_q = rtrim($ukator, "OR");
$kategori_q = "WHERE ($kategori_q)";
}
else {
$kategori_q = "WHERE fk_ukategori = '$kategori'";
}
}
$query = "SELECT * FROM annoncer $kategori_q ORDER BY annonce_id DESC";
$soeg = "";
if (isset($_GET['soeg'])) {
$soeg = $_GET['soeg'];
if (substr_count($query, "WHERE") == 1) {
$soeg = " AND (overskrift LIKE '%$soeg%' OR beskrivelse LIKE '%$soeg%')";
}
else {
$soeg = " WHERE (overskrift LIKE '%$soeg%' OR beskrivelse LIKE '%$soeg%')";
}
}
$query = "SELECT * FROM annoncer $kategori_q $soeg ORDER BY annonce_id DESC";
$q = sqlSelect($query);

Categories