LIKE COUNT 1 but dont count in the db - mysql

I was told to try and make a new post and explain better.
I have a upload function on my webpage. And i want to block certain titles from a database called filter. But it dont work.
The php side looks like this.
$DB->query("SELECT COUNT(*) FROM filter WHERE '". $Properties['Title'] ."' LIKE CONCAT('%', filter, '%')");
if($DB->record_count() != 0) {
$Err = '<b>you cant upload this!</b>';
include(SERVER_ROOT . '/sections/upload/upload.php');
die();
$Properties['Title'] contains this in my test: The.White.Tiger.Test.Dawe.avi
The.White.Tiger. is blocked in the database filter. and if run this query in SQL
SELECT COUNT(*) FROM filter WHERE '". The.White.Tiger.Test.Dawe.avi ."' LIKE CONCAT('%', filter, '%')
I get count 1
So the php side SHOULD deny upload because it has 1 entry on it.. But it dosnt? Is something wrong with the code?
I have now tried these in php witch gave 500 Internal Server error
SELECT id FROM filter WHERE 'filter' LIKE CONCAT('%', '" . $Properties['Title'] . "', '%')
if($DB->record_count() != 0) {
$Err = '<b>You cant upload!</b>';
include(SERVER_ROOT . '/sections/upload/upload.php');
die();
}
}
SELECT COUNT(*) as 'count' FROM filter WHERE 'filter' LIKE CONCAT('%', '" . $Properties['Title'] . "', '%')
if($DB->record_count() != 0) {
$Err = '<b>You cant upload!</b>';
include(SERVER_ROOT . '/sections/upload/upload.php');
die();
}
}
SELECT COUNT(*) as count FROM filter WHERE 'filter' LIKE CONCAT('%', '" . $Properties['Title'] . "', '%')
if($DB->record_count() != 0) {
$Err = '<b>You cant upload!</b>';
include(SERVER_ROOT . '/sections/upload/upload.php');
die();
}
}
All off the above gave 500 internal server error

As I can see from a query you want to find existsing records with title like user (or someone else) entered.
Here you have two errors:
Wrong WHERE clause. After WHERE comes name of a table field, not value
filter in CONCAT is what? What's it value?
Suppose title column name in your table filter is column_title.
And you are looking for already existing title The.White.Tiger.Test.Dawe.avi in a table filter.
The query should be like this:
SELECT COUNT(*) as count FROM filter WHERE 'column_title' LIKE CONCAT('%', 'The.White.Tiger.Test.Dawe.avi', '%')
After query you have to check value of count and compare it to 1. If it's equals or more than 1 - you already have this title. Else - title is not in the table and you can perform adding or something else.
UPDATE:
As I see your real table structure - you should replace column_title to filter:
SELECT COUNT(*) as count FROM filter WHERE 'filter' LIKE CONCAT('%', 'The.White.Tiger.Test.Dawe.avi', '%')

Related

Writing mysql query with two variable conditions with prepare statement and bind param [duplicate]

I need to change this query to use a prepared statement. Is it possible?
The query:
$sql = "SELECT id, title, content, priority, date, delivery FROM tasks " . $op . " " . $title . " " . $content . " " . $priority . " " . $date . " " . $delivery . " ORDER BY " . $orderField . " " . $order . " " . $pagination . "";
Before the query, there's code to check the POST variables and change the content of variables in the query.
//For $op makes an INNER JOIN with or without IN clause depending on the content of a $_POST variable
$op = "INNER JOIN ... WHERE opID IN ('"$.opID."')";
//Or
$op = "INNER JOIN ... ";
//For $title (depends of $op):
$title = "WHERE title LIKE'%".$_POST["title"]."%'";
//Or
$title = "AND title LIKE'%".$_POST["title"]."%'";
//For $content:
$content = "AND content LIKE '%".$_POST["content"]."%'";
//For $priority just a switch:
$priority = "AND priority = DEPENDING_CASE";
//For $date and $delivery another switch
$d = date("Y-m-d", strtotime($_POST["date"]));
$date = "AND date >= '$d' 00:00:00 AND date <= '$d' 23:59:59";
//Or $date = "AND date >= '$d' 00:00:00";
//Or $date = "AND date <= '$d' 23:59:59";
//For $orderField
$orderField = $_POST["column"];
//For $order
$order= $_POST["order"];
//For $pagination
$pagination = "LIMIT ".$offset.",". $recordsPerPage;
How I could do this query using prepared statement?
The query could be more static but this means to make different prepared statements and execute it depending of $_POST checks.
It depends on many variables because this query show results in a table that contains search fields and column to order.
A full example of query would be like this (depending of $_POST checks):
SELECT id, title, content, priority, date, delivery FROM tasks INNER JOIN op ON task.op = op.opId WHERE op IN (4851,8965,78562) AND title LIKE '%PHT%' AND content LIKE '%%' AND priority = '2' ORDER BY date DESC LIMIT 0, 10
An excellent question. And thank you for moving to prepared statements. It seems that after all those years of struggle, the idea finally is starting to take over.
Disclaimer: there will be links to my own site because I am helping people with PHP for 20+ years and got an obsession with writing articles about most common issues.
Yes, it's perfectly possible. Check out my article, How to create a search filter for mysqli for the fully functional example.
For the WHERE part, all you need is to create two separate arrays - one containing query conditions with placeholders and one containing actual values for these placeholders, i.e:
WHERE clause
$conditions = [];
$parameters = [];
if (!empty($_POST["content"])) {
$conditions[] = 'content LIKE ?';
$parameters[] = '%'.$_POST['content ']."%";
}
and so on, for all search conditions.
Then you could implode all the conditions using AND string as a glue, and get a first-class WHERE clause:
if ($conditions)
{
$where .= " WHERE ".implode(" AND ", $conditions);
}
The routine is the same for all search conditions, but it will be a bit different for the IN() clause.
IN() clause
is a bit different as you will need more placeholders and more values to be added:
if (!empty($_POST["opID"])) {
$in = str_repeat('?,', count($array) - 1) . '?';
$conditions[] = "opID IN ($in)";
$parameters = array_merge($parameters, $_POST["opID"]);
}
this code will add as many ? placeholders to the IN() clause as many elements in the $_POST["opID"] and will add all those values to the $parameters array. The explanation can be found in the adjacent article in the same section on my site.
After you are done with WHERE clause, you can move to the rest of your query
ORDER BY clause
You cannot parameterize the order by clause, because field names and SQL keywords cannot be represented by a placeholder. And to tackle with this problem I beg you to use a whitelisting function I wrote for this exact purpose. With it you can make your ORDER BY clause 100% safe but perfectly flexible. All you need is to predefine an array with field names allowed in the order by clause:
$sortColumns = ["title","content","priority"]; // add your own
and then get safe values using this handy function:
$orderField = white_list($_POST["column"], $sortColumns, "Invalid column name");
$order = white_list($_POST["order"], ["ASC","DESC"], "Invalid ORDER BY direction");
this is a smart function, that covers three different scenarios
in case no values were provided (i.e. $_POST["column"] is empty) the first value from the white list will be used, so it serves as a default value
in case a correct value provided, it will be used in the query
in case an incorrect value is provided, then an error will be thrown.
LIMIT clause
LIMIT values are perfectly parameterized so you can just add them to the $parameters array:
$limit = "LIMIT ?, ?";
$parameters[] = $offset;
$parameters[] = $recordsPerPage;
The final assembly
In the end, your query will be something like this
$sql = "SELECT id, title, content, priority, date, delivery
FROM tasks INNER JOIN ... $where ORDER BY `$orderField` $order $limit";
And it can be executed using the following code
$stmt = $mysqli->prepare($sql);
$stmt->bind_param(str_repeat("s", count($parameters)), ...$parameters);
$stmt->execute();
$data = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
where $data is a conventional array contains all the rows returned by the query.

Like statment not returning correct values

Im having a little problem finding a query to do what I want.
Im using Jquerys autocomplete to search for job ID.
Currently the code I'm using is:
$keyword = "%" . (int) $_GET['term'];
$sql = $DB->prepare("SELECT JID, SiteName FROM jobs WHERE CID = :cid AND `JID` LIKE :term ORDER BY JID DESC LIMIT 6");
when the code runs it only returns IDs 1 and 11
I want is so any ID beginning with 1 is displayed eg
1,10,11,12,13,14,15 ... 100 etc
Any ideas how I solve this?
change that
$keyword = "%" . (int) $_GET['term'];
to
$keyword = (int) $_GET['term']. "%" ;
you are cheking numbers which ends by 1 , like that you will check numbers wich starts by 1.
this would be better thought if you using pdo
$keyword = (int) $_GET['term'];
$params = array("$keyword%");
$sql = $DB->prepare(...........);
$sql->execute($params);

MYSQL query with variables that may not be set

I have a PHP file which is taking in seven variables like so:
$name=$_REQUEST['membername'];
$email=$_REQUEST['email'];
$dob=$_REQUEST['dob'];
$gender=$_REQUEST['gender'];
$phone=$_REQUEST['phone'];
$county=$_REQUEST['county'];
$IP=$_REQUEST['IP'];
Some of these will not be set. What I want to do is construct a query which will search the members table such that if only $email and $dob are set it will only search by $email and $dob, ignoring the others. Or if only $phone, $name, and $gender are set, it will search those three columns only.
Is there an easier method than constructing a big block of if isset functions covering all possible permutations?
If you don't want to search on a field, pass NULL for the parameter and structure your WHERE clause something like...
WHERE
( (#parameter1 IS NULL) OR (column1 = #parameter1) )
AND
( (#parameter2 IS NULL) OR (column2 = #parameter2) )
I don't spend much time in MYSQL so the syntax is probably a bit off but you get the idea.
Presuming that you use parameters to push values into the query...
SELECT *
FROM MyTable
WHERE name = COALESCE(#p1, name)
OR email = COALESCE(#p2, email)
OR dob = COALESCE(#p3, dob)
...
...
If you construct a query string in PHP you can, instead, take another tack:
function AddWhere(&$where, $dbFieldName, $fieldValue)
{
if ($fieldValue <> "")
{
if (strlen($fieldName) > 0)
$fieldName .= " AND ";
$fieldname .= '(' + $dbFieldName + ' = \'' + $fieldValue + '\')'
}
}
Then, when you're retrived the variables, build a SQL statement thusly
$whereClause = ''
AddWhere($whereClause, 'name', $name)
AddWhere($whereClause, 'email', $email)
AddWhere($whereClause, 'dob', $dob)
...
IF (strlen($whereClause) > 0)
{
$sql = 'SELECT * FROM MyTable WHERE ' + $whereClause
... etc
}
(I'm not great at PHP, so the syntax may be somewhat screwed up).

php codeigniter MySQL search query

I want to create a search query on MySQL database that will consist of 5 different strings typed in from user. I want to query 5 different table columns with these strings.
When I for example have input fields like:
first name, last name, address, post number, city.
How should I query the database that I dont always get all the rows.
My query is something like this:
SELECT user_id, username
from users
where
a like %?% AND
b like %?% AND
c like %?% AND
d like %?% AND
e like %?%;
When I exchange the AND for OR I always get all the results which makes sense, and when I use AND I get only the exact matches...
Is there any function or statement that would help me with this?
EDIT
The code I use is:
$sql = "select users.user_id, first_name
from users
inner join user_normal_aos
on users.user_id = user_normal_aos.user_id
inner join normal_areas_of_expertise
on user_normal_aos.normal_areas_of_expertise_id = normal_areas_of_expertise.normal_areas_of_expertise_id
where
users.first_name like ? AND
users.kanzlei like ? AND
normal_areas_of_expertise.normal_aoe like ? AND
users.postcode like ? AND
users.city like ?";
$query = $this->db->query($sql,
array(
'%'.$lawyer_name.'%',
'%'.$kanzlei.'%',
'%'.$area_of_expertise.'%',
'%'.$post_code.'%',
'%'.$city.'%')
);
For example use PHP to adjust your query based on what fields you have entered.
$where = array();
$replacements = array();
/* you can also compare if string is not null or not empty...
this is just example using isset */
if (isset($lawyer_name)) {
$where[] = 'users.first_name like ?';
$replacements[] = '%'.$lawyer_name.'%';
}
/* repeat this if again for all your fields .... */
$sql = "..... where ".implode(' AND ', $where);
$query = $this->db->query($sql,
$replacements
);

MySQL REGEXP Search

I have made a search engine which works well, but I want it to disregard symbols in the database entries.
e.g. I search for A*B-C
In the database I have a column that contains ABC.
I would like it to bring back this record even thought it has symbols in.
How would I do this?
Hi, I tried that but it does not work.
Here is my code:
$query = '%' . rawurlencode($queryRaw) . '%' ;
$queryClean = ereg_replace("[^A-Za-z0-9]", "%", $query) ;
$result = $dbh->prepare("SELECT supplier_details.id as supid, name, languages.languages, countries.country
FROM supplier_details, languages, countries
WHERE languageRef = languages.id
AND countryRef = countries.id
AND (name LIKE ? OR name LIKE ?)
LIMIT 50") ;
$result->bindParam(1, $query, PDO::PARAM_INT) ;
$result->bindParam(2, $queryClean, PDO::PARAM_INT) ;
$result->execute() ;
select *
from tbl
where clmn like '%A%B%C%'