This question already has answers here:
PHP PDO prepared statement -- MySQL LIKE query
(3 answers)
Closed 6 years ago.
As you can see in the title, I have a table that I want to take use of in a website I have.
This is how the MySQL statement looks like now: SELECT * FROM bth_nav WHERE name LIKE (?) OR owner LIKE (?);
On my website I want to either search for name or owner. Right now I can only search for name but not owner. This is why I'm asking for help, I've tried to rewrite the statement but however I do it i can only search for one of them.
Thanks in advance.
The answer will be a little more complicated then you would expect.
I see question marks in your query, this way I can assume you're using prepared statements (which is good!).
Your old statement was using 1 value (for the name), and now you want to use 2.
You have some options for this to work.
The easiest one would be that you bind the value twice, but that's not the nicest way.
A better way would be to name your parameters, like this:
SELECT * FROM bth_nav WHERE name LIKE (:nameOwner) OR owner LIKE (:nameOwner);
Hence that I use the same name for both parameters here. Now you can bind the value to the named parameter with bindValue, and you need do this only once.
Related
This question already has answers here:
Combine PHP prepared statments with LIKE
(8 answers)
How do I create a PDO parameterized query with a LIKE statement?
(9 answers)
Closed 1 year ago.
I am creating a bot and the user can enter name of a movie and results should show up by searching inside a SQL table and find the right movies name so I used prepared statements in PDO but I want to when a user type the incomplete name of a movie it shows up so I want it to be case insensitive and also find matches.
I am using mysql dirver.
before this the SQL query was like this
also noting this is a string inside a PHP script
"SELECT * FROM movies WHERE name = :name LIMIT 5"
but then I thought to use the way that I explained to you above and I know it isn't case insensitive.
"SELECT * FROM movies WHERE name LIKE :name" . "'%' LIMIT 5"
but I don't think this will work properly and fine so how should I write this query to work as I explained at the beginning?
Should use different keywords like REGEXP ?
Let me assume that you are using MySQL (based on the regexp reference).
You can then use:
WHERE name LIKE CONCAT(:name, '%')
In other databases you can use the standard string concatenation operator, ||.
Note: This is often handled at the application level, so :name is given the '%' in the application. Then your original code works.
A similar approach would work for a regular expression, but the logic would be:
WHERE name LIKE CONCAT('^', :name)
This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 8 years ago.
It's a little relative to the question I asked here
(PDO adds the apostrophe to the mySQL query) but this time column name is a parameter.
Not working PDO example would be like this:
"UPDATE tbl SET :COL1 = NOT :COL1;"
sure solution like this:
"UPDATE tbl SET $COL1 = NOT $COL1;" // works (but it's not PDO)
but why
"UPDATE tbl SET $COL1 = NOT :COL1;" // does not ??
while
"UPDATE tbl SET $COL1 = :VAL_COL1;" // is ok if I first get and negate COL1 value...
In a prepared statement, a parameter is a constant value that will be passed into the query without affecting how the query will be run. This allows the database to "prepare" the query ahead of time and figure out how it will be executed even without knowing the exact values that will be used.
Using this definition, a query like this does not have any parameters, and so the PDO and non-PDO versions of the query will look the same. Your working (first) example is as good as you're going to get. In fact, I'd claim that your first example actually is the PDO version.
To use a non-database example, a prepared statement is very much like a function in a programming language such as PHP. A function accepts parameters and uses their values, but (in normal circumstances) the parameters are not lines of code that will be run. The same code is run regardless of what the parameter values are - the function code itself is not changed by the parameters.
No. You cannot bind table names or column names as parameters. You can only bind values as parameters.
See more here: Can PHP PDO Statements accept the table or column name as parameter?
This question already has answers here:
Get table column names in MySQL?
(19 answers)
Closed 9 years ago.
As I am still learning PHP and MySQL, I would like to know if it is possible to query a table without knowing it's name. Knowing the table I am querying and the column I would like to retrieve, I can write something like
$book_title=$row['book_title'];
Then I can use the resulting variable later in the script. In each case, each book category table will have a column of interest with a different name. I have several tables on which I am running queries. I am able to query any table by using a variable that always evaluates to the correct table name, because all the input from users corresponds to the tables in the database, so the $_POST super global will always carry a correct table name. The problem is for me to have a
$variable=$row['column'];
in cases where I do not know a column name before hand even though I know the table name.
My queries are simple, and look like
query="select * FROM $book_categories WHERE id=$id";
$row = mysqli_fetch_array ($result);
$variable=$row['?'];
The question mark say, I do not know what column to expect, as it's name could be anything from the tables in the database!
Since I have several tables, the query will zero on a table, but the column names in each table varies so I would like to be able to use one query that can give me an entry from such a column.
I hope my question is clear and that I am not asking for the impossible. If it's ambiguous, I care to elucidate (hope so).
I'm not sure what you mean, but it is possible to reference specifc columns by typing index (starting with 0) something like this: $row[0], $row[1] where 0 indicates the first column, and 1 indicates the second column from the returned recordset.
Example:
If you have a select-statement like this:
SELECT title, author FROM books
You could reference these two columns with $row[0], $row[1]
If you try to get the value of $row[2] you will get an unassigned value because there are only two columns (0 and 1) from the recordset.
If you have a select-statement like this:
SELECT * FROM book_categories
and the recordset returns three columns, then you could access these with $row[0], $row[1] and $row[2]. $row[3] does not exist because there are only three columns (0,1 and 2)
Since you are learning maybe we could take some time to explain why this is possible but many people (including myself) would say this is bad -- or at least dangerous
Why you can
Your SQL query is basically a text string you send to the DB server, which decode that string trying to interpret it as SQL in order to execute the query.
Since all you send to the DB server is text string, you could build that string however you want. Such as using string interpolation as you did:
select * FROM $book_categories WHERE id=$id
That way, you could replace any part of your query by the content of a variable. You could even go further:
$query FROM $book_categories WHERE id=$id
Where $query could by SELECT * or DELETE.
And, why not initializing all those variables from a form:
$book_categories = $_POST['book_categories'];
$id = $_POST['id'];
$query = $_POST['query'];
Great, no? Well, no...
Why you shouldn't
The problem here is "could you trust those variables to only contain acceptable values?". That is, what would append if $book_categories somehow resolve to one table you didn't want to (say myTableContainigSecretData)? And what if $id resolve to some specially crafted value like 1; DELETE * FROM myImportantTable;?
In these conditions, your query:
select * FROM $book_categories WHERE id=$id
Will become as received by the DB server:
select * FROM myTableContainigSecretData WHERE id=1; DELETE * FROM myImportantTable;
Probably not what you want.
What I've tried to demonstrate here is called SQL injection. This is a very common bug in web application.
How to prevent that?
The best way to prevent SQL injection is to use prepared statement to replace some placeholders in your query by values properly shielded against SQL injection. There was an example posted a few minutes ago as a response to an other question: https://stackoverflow.com/a/18035404/2363712
The "problem" regarding your initial question is that will replace values not table or columns identifiers.
If you really want to replace table/columns identifiers (or other non-value part of your query) by variables contents, you will have to check yourself the content of each of these variables in order to prevent SQL injection. This is quite feasible. But that's some work...
This question already has answers here:
How to select two columns as one?
(2 answers)
Closed 8 years ago.
I want to make a "search engine" with people in php. I have two columns. The first is with first_name and the secon is with last name i use this sql syntax:
SELECT *
FROM users
WHERE first_name OR last_name LIKE '$search_term%'
I wand the sql to search for first name and for last name the same time with out having one column with first_name and last_name together. Please Help !!!!
it should be
SELECT *
FROM users
WHERE first_name LIKE '$search_term%' AND
last_name LIKE '$search_term%'
But the query above performs full table scan because it doesn't use index. For better performance, search about FULL TEXT SEARCH.
As a sidenote, the query is vulnerable with SQL Injection if the value(s) of the variables came from the outside. Please take a look at the article below to learn how to prevent from it. By using PreparedStatements you can get rid of using single quotes around values.
How to prevent SQL injection in PHP?
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
PDO Prepared Statements
I'm using the mysqli extension in PHP and I'm wondering, is there possibly any way to see a prepared query as it will be executed on the server, e.g. The query is something like this
select * from table1 where id = ? and name = ?
but I want to see the query after the values are filled in, like this:
select * from table1 where id = 20 and name = "John"
Turn on mysql query logging and it will log all queries to a text file for you to review.
Duplicate of PDO Prepared Statements
Short answer: no. A prepared query will never be converted to the query you expect. It's executed directly by the database server. You can use mysql's query log or PDO's undocumented function debugDumpParams, but both are just approximations.
See it where?
If it's your code you have the query and you have the prepared parameters, log them separately or replace in the original query string.
If the binding will fail you will get an error, otherwise you should expect the same values to be "filled" in as you specified them.
Its the way most of the times I am debugging mysql quires:
$q = "select * from table1 where id = ".$id." and name = ".$name;
echo $q;
The output generates all variables assigned to the query.
Hope I understood you exactly, what you wanted.