I have a this query:
$query="select * from news where news_id = (select max(news_id) from news where news_id< $id)";
for execute I use class. in this class
public function query($query)
{
$this->_query = filter_var($query, FILTER_SANITIZE_STRING);
$stmt = $this->_prepareQuery();
$stmt->execute();
$results = $this->_dynamicBindResults($stmt);
return $results;
}
Is there any way that < signal is not filtered?
Unfortunately, the whole idea is wrong. FILTER_SANITIZE_STRING won't help even slightest. Let alone it just breaks your SQL.
To protect SQL from injection you must use prepared statements. So instead of adding a variable directly to the query, add a question mark. And then put this variable into execute like this
public function query($query, $params)
{
$stmt = $this->mysqli->prepare();
$types = $types ?: str_repeat("s", count($params));
$stmt->bind_param($types, ...$params);
$stmt->execute();
return $stmt->get_result();
}
then just use it this way
$query="select * from news where news_id = (select max(news_id) from news where news_id<?)";
$data = $db->query($query, [$id])->fetch_all(MYSQLI_ASSOC)
Related
I am trying to make a search key feature. But I am not getting any result with the following query.
public function SearchKey($key,$userid)
{
$key = mysqli_real_escape_string($this->db, $key);
$userid = mysqli_real_escape_string($this->db, $userid);
$query = mysqli_query($this->db,"SELECT * FROM posts WHERE
MATCH(theKey) AGAINST('$key' IN NATURAL LANGUAGE MODE)
AND uid = '$userid' ORDER BY sgq_id LIMIT 5") or die(mysqli_error($this->db));
while($row=mysqli_fetch_array($query)) {
$data[]=$row;
}
if(!empty($data)) {
return $data;
}
}
Then fetch,
$search = $Data->SearchKey($key, $userid);
if($search){
foreach($search as $data){
echo $data['theKey'];
}
}
For example if I search OK005 then I can not get any results. I tried Full-text Search functions https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
Anyone can help me here, what I am missing ?
You're using single quotes to pass your variables. These will not be expanded in your query. You're better off using a prepared statement, and use parameter/value bindings to pass the variables. This will also solve the problem of SQL injection that your code appears to be vulnerable to.
You can try something like:
// Replace comment with appropriate connection data.
$pdo = new PDO(/* your DSN etc. */);
// Your query.
$sql =
'SELECT * FROM posts WHERE ' .
'MATCH(theKey) AGAINST(? IN NATURAL LANGUAGE MODE) ' .
'AND uid = ? ORDER BY sgq_id LIMIT 5';
// Create prepared statement from query.
$statement = $pdo->prepare($sql);
// Bind the values and enforce data type.
$statement->bindValue(1, $key, PDO::PARAM_STR);
$statement->bindValue(2, $userid, PDO::PARAM_INT);
// Run query.
$statement->execute();
// Get query results.
$rows = $statement->fetchAll();
// Your magic ...
I am using PDO prepared statements to execute two queries:
SELECT count(*) FROM vocabulary WHERE `type` = :type AND `lesson` = :lesson;
SELECT * FROM vocabulary WHERE `type` = :type AND `lesson` = :lesson limit 100;
The first query to get the count works as expected and i get the row count.
$stmt = $this->connection->prepare($sql);
foreach ($params as $key => $value)
$stmt->bindValue(":" . $key, $value, PDO::PARAM_STR);
$stmt->execute();
$count = $stmt->fetchColumn();
$sql .= " limit $limit;";
$sql = str_replace("count(*)", $columns, $sql);
$stmt = $this->connection->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_CLASS, $class);
But when executing the second query i get:
SQLSTATE[HY093]: Invalid parameter number: no parameters were bound
Therefore, I would like to know, if I have multiple queries where the parameters are exactly the same ,if I need to bind the same parameters again using
foreach ($params as $key => $value)
$stmt->bindValue(":" . $key, $value, PDO::PARAM_STR);
or if there is a way to bind parameters only once.
If I have multiple queries where the parameters are exactly the same, do I need to bind the same parameters again using
Yes, of course.
Parameters are bound to each query, not to PDO or a database globally.
On a side note, with PDO you don't have to bind variables explicitly, so there is a solution to your "problem": just don't bind at all but send your data directly into execute() as it shown in the Dharman's excellent answer
There is no need to modify your SQL like this. Your code basically comes down to this:
$stmt = $this->connection->prepare('SELECT count(*) FROM vocabulary WHERE `type` = :type AND `lesson` = :lesson');
$stmt->execute($params);
$count = $stmt->fetchColumn();
$stmt = $this->connection->prepare('SELECT * FROM vocabulary WHERE `type` = :type AND `lesson` = :lesson limit 100');
$stmt->execute($params);
$result = $stmt->fetchAll(PDO::FETCH_CLASS, $class);
Lets say I have the following variable:
$where = "where `hats`='red'";
I want to inject this variable into a PDO statement. What is the proper way of doing this?
Is it like so?:
$sql = "select * from `clothing` :where";
$stm = $this->app->db->prepare($sql);
$stm->bindParam(':where', $where);
$stm->execute();
Any help would be greatly appreciated.
You can only bind values, not keywords, object names or syntactic elements. E.g., if you're always querying according to hats, you could bind the 'red' value:
$color = 'red';
$sql = "select * from `clothing` where hats = :color";
$stm = $this->app->db->prepare($sql);
$stm->bindParam(':color', $color);
$stm->execute();
If your where clause is really that dynamic, you'd have to resort to string manipulation (and face the risk of SQL injection, unfortunately):
$where = "where `hats`='red'";
$sql = "select * from `clothing` $where";
$stm = $this->app->db->prepare($sql);
$stm->execute();
// create a new PDO object by name $PDO in your connection file
In your function
function nameOfFunction($var,$value)
{
global $PDO;
$st=$PDO->prepare('SELECT * from clothing WHERE ? = ?');
$rs=$st->execute(array($var,$val));
return $st->fetchAll();
}
I hope it will work. It will return the array, Traverse it as you like
Here's the query below,
public function getSearchResult($searchString){
$stmt = $this->conn->prepare("SELECT t.* FROM company t WHERE t.company_name like ? ");
$stmt->bind_param("i", "%".$searchString."%");
$stmt->execute();
$tasks = $stmt->get_result();
$stmt->close();
return $tasks;
}
Error I am getting is
Fatal error: Cannot pass parameter 2 by reference in
I guess I am doing the like param incorrectly (as it works for where = condition). I am pretty new to slim, any help?
You have to form the string before you can use it in bind_param()
public function getSearchResult($searchString){
$search = '%'. $searchString . '%';
$stmt = $this->conn->prepare("SELECT t.* FROM company t WHERE t.company_name like ? ");
$stmt->bind_param("s", $search);
$stmt->execute();
$tasks = $stmt->get_result();
$stmt->close();
return $tasks;
}
In addition it looks like you're passing a string, not an integer, make sure you set the type to "s"
You need to set where your i variable goes.
$stmt = $this->conn->prepare("SELECT t.* FROM company t WHERE t.company_name LIKE :i ");
$stmt->bind_param(":i", "%$searchString%", PDO::PARAM_STR);
Here is an example in php.net
<?php
public function getSearchResult($searchString){
$stmt = $this->conn->prepare("SELECT t.* FROM company t WHERE t.company_name like ? ");
$stmt->bind_param("s", "%$searchString%",PDO::PARAM_STR);
$stmt->execute();
$tasks = $stmt->get_result();
$stmt->close();
return $tasks;
}
Search string in where condition so it would be s and add PDO::PARAM_STR
These are my PDO add, edit, delete ,select functions for my MVC pattern implementation.
I need to know if this implementation is correct using PDO.
These are Model Class functions:
public function getStudentById($id){
$stmt = $this->db->con->query("SELECT * FROM student WHERE id = '$id'");
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result;
}
public function addStudent($arrData){
$sql = " INSERT INTO student (name,age,address)".
" VALUES ('$arrData[name]','$arrData[age]','$arrData[address]')";
$stmt = $this->db->con->prepare($sql);
$stmt->execute();
return $this->db->con->lastInsertId();
}
public function editStudent($arrData){
$sql = " UPDATE student SET ".
" name='$arrData[name]',age='$arrData[age]',address='$arrData[address]'".
" WHERE id=$arrData[id] ";
$stmt = $this->db->con->prepare($sql);
$stmt->execute();
return $this->db->con->lastInsertId();
}
public function deleteStudent($id){
$stmt = $this->db->con->query("DELETE FROM student WHERE id = '$id'");
}
Correct or not, you can do it easier and safer. One of the main advantages of PDO is the support of parametrized queries, where you only write placeholders and let PDO insert the values. This will help protecting against SQL-injection, because PDO will do the correct formatting for you.
$sql = 'SELECT * FROM student WHERE id = ?';
$statement = $db->prepare($sql);
$statement->bindValue(1, $id, PDO::PARAM_INT); // or PDO::PARAM_STR
$statement->execute();