search not returning query - php

Sorry my english. I'm trying to search mysql database that contains hashtags, but it returns all.
eg Search #NBA returns: #NBA, #NBA2021, #NBAscoreBoard, etc
I've tried every preg_replace on here. eg #(^|\s)#(\w*[a-zA-Z_]+\w*)# But how do I break after the specific search is met?
$_GET["tag"]='#nba'; // $_GET is from a query string
$fulltag = preg_replace("/[^a-zA-Z0-9_]/", '', $_GET["tag"]); //trying to isolate this problem
$sql='SELECT * FROM status WHERE data LIKE "%#'.$fulltag.'%" LIMIT 12';
//
//
//
echo //the result containing the "# $fulltag";

As I said in my comment--just doing two queries with one to test if data = fullTag, and then if that returns nothing, then doing the wildcard search--is probably going to be simpler.
However, if you really want this to be a single query, you could do something like this, wherein you test to see if it is an exact match within a sub-query, then order by whether it's an exact match so that if there is an exact match, it will be the first result.
SELECT *
FROM (
SELECT
data,
CASE
WHEN data = "#NBA"
THEN 1
ELSE 0
END AS is_exact
FROM status
WHERE data LIKE "%#NBA%"
LIMIT 12
) AS matches
ORDER BY is_exact DESC
A separate note: You code right now is very vulnerable to SQL Injection. You should try using parameterized prepared statements instead of manually building your queries. See PDO or MySQLi prepared statements.
Here is an example of the above query using PDO, and this method of using CONCAT to safely add wildcards to your query:
$_GET["tag"]='#nba'; // $_GET is from a query string
$fulltag = preg_replace("/[^a-zA-Z0-9_]/", '', $_GET["tag"]); //trying to isolate this problem
$pdo = new PDO(/* your connection details */);
$sql =
'SELECT *
FROM (
SELECT
data,
CASE
WHEN data = CONCAT("#", :tag1)
THEN 1
ELSE 0
END AS is_exact
FROM status
WHERE data LIKE CONCAT("%#", :tag2, "%")
LIMIT 12
) AS matches
ORDER BY is_exact DESC
';
$stmt = $pdo->prepare($sql);
$stmt->execute([
':tag1' => $fulltag,
':tag2' => $fulltag,
]);
Here's your simpler query using the same, safer approach:
$_GET["tag"]='#nba'; // $_GET is from a query string
$fulltag = preg_replace("/[^a-zA-Z0-9_]/", '', $_GET["tag"]); //trying to isolate this problem
$pdo = new PDO(/* your connection details */);
$sql = 'SELECT * FROM status WHERE data LIKE CONCAT("%#", :fullTag, "%") LIMIT 12';
$stmt = $pdo->prepare($sql);
$stmt->execute([':fullTag' => $fulltag]);

Related

No replacement of question mark in prepared SQL statement

I use PDO in PHP on a MariaDB to filter rows where text field contains $search_terms. However, I only retrieve the rows which contain a question mark. It seems that the content of $search_terms is not replaced in the prepared statement.
$query = $db->prepare('SELECT * FROM notes WHERE text LIKE \'%?%\'');
$query->execute(array($search_terms));
$data['notes'] = $query->fetchAll(PDO::FETCH_ASSOC);
Why ?
Not sure if $search_terms is intended to hold one or more than one search term. Your query implies the former, and if so, then use:
$search_term = "%apple%";
$query = $db->prepare('SELECT * FROM notes WHERE text LIKE ?');
$query->execute($search_term);
$data['notes'] = $query->fetchAll(PDO::FETCH_ASSOC);
Note that we bind the search term with the % wildcards to the statement. The statement just holds a single ? placeholder.

Laravel 5-Execute sql statement in string

I am using Laravel 5.
I need to save some sql statements in a field of a table of the database (these statements are used to get some results).
I want to get these statements in my controller and execute them using Laravel, but the statements are only strings,
Let's suppose the following
$statement = Table::where('ID', 1);
$statement = $statement->STATEMENT;
In $statement I have a string like this
$statement = 'SELECT SUM(VAL) FROM TABLE';
What I need to know is how to execute in the database the statement saved in my string var $statement
I finally want to have something like
$result = 10 (the result of executing 'SELECT SUM(VAL) FROM TABLE', which was in $statement)
Thanks!
This is called raw queries in laravel. For example:
DB::select(DB::raw('select * from users''));
So in your case(if You've already got $statement):
DB::select(DB::raw($statement));

PDO adds the apostrophe to the mySQL query

After years of reading it's time to ask first question :)
My problem is that after migrating the code from mySQLi to PDO we have got a problem as it seems PDO adds the apostrophes to the query.
PHP code goes like that:
$sort = $_GET['sort']; << table column name (mySQL VARCHAR only columns)
....
$query = 'SELECT * FROM table WHERE xxx > 0';
$query .= ' ORDER BY :sort ASC ;';
$qry_result= $db->prepare($query);
$qry_result->execute(array(':sort'=>$sort));
mysqli version went smoothly but now queries (mysql log file) looks like this:
SELECT * FROM table where xxx > 0 ORDER BY 'SORT_VAR_VALUE' ASC;
^ 2 problems ^
So the table is NOT sorted, as sort order (from mySQL point of view) is wrong.
phpinfo() does not get any results for search on "magic" nor "quotes" btw.
Any idea ??
The placeholders in PDO statements are for values only. If you want to add actual SQL to the query you need to do it another way.
First, you should sanitize $sort and surround it with backticks in the query.
$sort = preg_replace('/^[a-zA-Z0-9_]/', '', $sort);
Then you could double quote the query string and PHP will replace $sort with it's value for you:
$query = "SELECT * FROM table WHERE xxx > 0 ORDER BY `$sort` ASC";
Or you could replace it with preg_replace like so:
$query = 'SELECT * FROM table WHERE xxx > 0 ORDER BY `:sort` ASC';
$query = preg_replace('/:sort/', $sort, $query, 1);
I would use the preg_replace method because it allows you to reuse the query if you assign the results from preg_replace to another variable instead of overwriting the original variable.
by default pdo binds values as strings.
To fix this you will want to check that the column is actually a valid name and then add it to the query, you can do it the following way:
function validName($string){
return !preg_match("/[^a-zA-Z0-9\$_\.]/i", $string);
}
if(validName($sort)){
$db->prepare("SELECT * FROM table where xxx > 0 ORDER BY $sort ASC");
}
With PDO it's not possible to bind other things that variables in the WHERE statement. So you have to hard code the names of the columns you order by.
See How do I set ORDER BY params using prepared PDO statement?
or Can PHP PDO Statements accept the table or column name as parameter? for further explanations.

PDO parameterized query not returning anything

I am converting old mysql_query code to PDO parameterized queries. Here's what I have so far. It doesn't seem to return anything. I have tried the same query in phpmyadmin, and in the old code with the same input, and the query returns rows those ways.
public function searchArticle($input)
{
$db = new PDO("mysql:host=localhost;dbname=thecorrectdbname", "root", "supersecretpassword");
$statement = $db->prepare("SELECT * FROM news WHERE headline LIKE '%:title%'
OR content LIKE %:content%'
OR author LIKE '%:author%'
ORDER BY id DESC");
$statement->execute(array('title' =>$query,
'content' =>$query,
'author'=>$query));
$result = $statement->fetchAll();
print_r($result);
if (!$result || $statement->rowCount() <= 0)
{
echo'nothing in this array';
return false;
}
return $result;
}
This returns
Array ( ) nothing in this array
Using the same $db connection I can manage to INSERT data into the DB, so the connection is working.
Two questions.
What am I doing wrong in this code?
Suppose I would get the code working. Is the $result object returned by a PDO prepared statement structurally the same as a mysql_query $result object? If not, how do I convert a PDO resultset to a mysql_query one?
Your replacement variables will get escaped and quoted automatically by PDO, which means you cannot have a variable within quotes.
change the following:
$statement = $db->prepare("SELECT * FROM news WHERE headline LIKE :title
OR content LIKE :content
OR author LIKE :author
ORDER BY id DESC");
$statement->execute(array('title' =>'%'.$query.'%',
'content' =>'%'.$query.'%',
'author'=>'%'.$query.'%'));
You are doing an invalid use of placeholder. Placeholder must be used in the place of whole value.
$statement = $db->prepare("SELECT * FROM news WHERE headline LIKE :title
OR content LIKE :content
OR author LIKE :author
ORDER BY id DESC");
$statement->execute(array('title' =>"%$query%",
'content' =>"%$query%",
'author'=>"%$query%"));

Using PDO in PHP to count all from database and the 'WHERE' is a variable that has to be cleaned

I'm trying to count all of the rows from an item list where the id matches a user input. I am switching all of my code from mysql to PDO as I have learned it is much better.
The code below is what I found to work in my situation.
$id = '0';
$sql="SELECT count(*) FROM item_list WHERE item_id = $id";
$data=$connMembers->query($sql)->fetchcolumn();
echo $data;
However, It is not safe for a live site due to sql injections.
I want to know how can I change it to work whare it sanatizes the user input.
I would prefer using a prepare and execute functions so the variables are kept seperately.
So is there something I can do?
This is where you start binding parameters. I prefer to do it using ? and one array for inputs.
Assuming $connMembers is your PDO object:
$sql="SELECT COUNT(*) FROM item_list WHERE item_id = ?";
$input=array($id); //Input for execute should always be an array
$statement=$connMembers->prepare($sql);
$statement->execute($input);
$data=$statement->fetchObject();
var_dump($data);
To add more variables to your sql, just add another ? to the query and add the variable to your input.
$sql="SELECT COUNT(*) FROM item_list WHERE item_id = ? AND item_name=?";
$input=array($id, $name); //Input for execute should always be an array
$statement=$connMembers->prepare($sql);
$statement->execute($input);
$data=$statement->fetchObject();
var_dump($data);
OR you can use bindParam:
$sql="SELECT COUNT(*) FROM item_list WHERE item_id = :itemID";
$statement=$connMembers->prepare($sql);
$statement->bindParam(':itemID', $id);
/*Here I am binding parameters instead of passing
an array parameter to the execute() */
$statement->execute();
$data=$statement->fetchObject();
var_dump($data);

Categories