I am new to PHP and MySQL, and I am having a bit of bother with the SELECT query. I am having some issues with this PHP/SQL variable:
$dbPassword = mysql_query("SELECT UserData.Password FROM UserData WHERE UserData.EmailAddress = '.$loginEmail.'");
What would be the correct way to select a value from a row where the "EmailAddress" is the same as another value in an Apache MySQL server?
All help will be appreciated.
Note that $dbPassword would be a resultset object, not a scalar.
You'd need to "fetch" rows from the resulset.
An example is provided in the documentation http://www.php.net/manual/en/function.mysql-query.php
You also have an issue with PHP string concatenation.
If you did this in two separate steps, you could echo (or printf or vardump) the string containing your SQL statement, before you execute it.
Also note that including "unsafe" values in the SQL statement makes your code vulnerable to SQL injection. Little Bobby Tables
$sql = "SELECT UserData.Password FROM UserData WHERE UserData.EmailAddress = '"
. mysql_real_escape_string($loginEmail) . "'";
vardump($sql);
$res = mysql_query($sql);
(The vardump isn't required; it's just there for debugging, a way for us to see the contents of the string that is about to be sent to the database. (When we're debugging a problem, it helps us determine whether the problem is in the SQL text, or whether it's a problem in the database.
We'll want to test whether the call to mysql_query actually returned a resultset, or whether it returned an error. Once we've verified it's a valid resultset object, we can fetch rows from the resultset. (There's a variety of functions to perform that operation.)
Note: The red box in the documentation that says the mysql extension is deprecated. New code should use either the mysqli or PDO extension.
Related
I often use the function rowCount of PDO like this for example:
$sql = $dataBase->prepare('SELECT email, firstname, lastname
FROM pr__user
WHERE id = :id');
$sql->execute(array('id' => $_SESSION['user_id']));
$rowCount = $sql->rowCount();
It al the time worked fine but I saw in the PHP manual:
If the last SQL statement executed by the associated PDOStatement was
a SELECT statement, some databases may return the number of rows
returned by that statement. However, this behaviour is not guaranteed
for all databases and should not be relied on for portable
applications.
http://php.net/manual/en/pdostatement.rowcount.php
It works fine with MySQL and MariaDB so I kept on using it. As I use it an application I wish portable, should I modify my code?
I never ask for the row count. Querying always returns an array of result rows (in some format), I can simply ask how many rows in the array -- such as with PHP's count(..) function.
What you're missing is that PDO is an interface to many different databases, not just MySQL. They make no guarantees that the function will return the same sort of values on completely different back-ends.
This is what "for portable applications" means: If you want your code to run universally on an arbitrary database you may need to avoid using that function. If that's not the case, you're not writing generic library code, you can depend on MySQL's particular behaviour.
Just be sure to test whatever you're doing to ensure that assumption is reasonable.
Rather, it's just pointless and superfluous. You are bloating your code for no reason.
From your example it is evident that you are going to use the data selected (otherwise there is no point in selecting email). So it means that you can use that data instead of row count all the way. Assuming the next operator would be fetch(), you can omit rowCount()
$sql = $dataBase->prepare('SELECT email, firstname, lastname
FROM pr__user
WHERE id = :id');
$sql->execute(array('id' => $_SESSION['user_id']));
$user = $sql->fetch();
if ($user) { ...
and from now on you can use $user in the every single condition where $rowCount has been used. Simply because you don't actually need a count here, but rather a boolean flag for which purpose an array would serve as good as an integer.
Even in a case when you don't need email but only to know whether a user exists, you can simply select just 1 scalar value and then fetch it - so your code remains uniform.
I have been trying to run my stored procedure using mysql unsuccessful for quite sometime. whenever I use the code below
$link_id = DbConnection::getInstance('mycon')->connectMysql();
$table_count = mysql_query("SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'mycon' AND table_name LIKE 'table_%' ")
while($row = mysql_fetch_array($table_count)){
$table = $row["TABLE_NAME"];
$excute = mysql_query("dummy_2('$table')") or die(mysql_error());
$result = mysql_fetch_assoc($excute);
var_dump($result);
}
it gives an error saying
Commands out of sync; you can't run this command now
so when I searched the internet, it said that I need to use MYSQL PDO.. Therefore can anyone convert my above statement to mysql pdo.. since i got no clue about PDO whatsoever
When you query something from the MySQL database the result is presented as a result set. Actually some queries might have multiple result sets associated. But there can be only one active list of results sets per connection. I.e. you, your script somehow has to close all currently active result sets before you can issue another query.
If e.g. your stored function uses multiple SELECTs the function has multiple result sets and you have to iterate/close/drop them all.
http://dev.mysql.com/doc/refman/5.1/en/stored-routines-syntax.html:
MySQL supports a very useful extension that enables the use of regular SELECT statements (that is, without using cursors or local variables) inside a stored procedure. The result set of such a query is simply sent directly to the client. Multiple SELECT statements generate multiple result sets, so the client must use a MySQL client library that supports multiple result sets.
The old, deprecated mysql_* functions do not support multiple result sets - you simply can't iterate/drop them.
The mysqli_* extension does: see http://docs.php.net/mysqli.next-result
And so does PDO: see http://docs.php.net/pdostatement.nextrowset.php
I have this code:
<?php
$table = $_GET ["table"];
$query = "SELECT 1 FROM $table";
$st = $pdo->prepare($query);
$st->execute();
This is not the real code, but it is an example to get the idea.
If I make:
hacked.php?table=users;DROP TABLE users;
It will work, cause it is not correctly escaped.
However, if I want to update information like this:
hacked.php?table=users; UPDATE users SET name="abc" WHERE name="def";
It will not work, cause since it is escaped, pdo will convert the query to
SELECT 1 FROM users; UPDATE users SET name=\"abc\" WHERE name=\"def\";
and obviously it fails.
Is there anyway to make this query works?
EDIT 1
We have one guy in our team only devoted to check my code and hacked it. So I want to be ready if this can be in some way accomplished.
EDIT 2
I was already read this: Are PDO prepared statements sufficient to prevent SQL injection? but it really did not answered my question. However it gave me a way to go through. And the solution of #duskwuff was the same I came to. So, for the admins, if this should be removed or marked as a duplicate is ok. But I insist that this can be helpful for someone to know how pdo prepared can be hacked.
It will not work, cause since it is escaped, pdo will convert the query to
SELECT 1 FROM users; UPDATE users SET name=\"abc\" WHERE name=\"def\";
This is incorrect! PDO does not perform escaping on text that is interpolated into queries, as it has no awareness of what text was interpolated. What you're seeing is the result of PHP's deprecated magic_quotes feature adding backslashes to the content of request variables (like $_GET and $_POST). Even if this is enabled, it can be trivially avoided in a query like this one by using non-quoted constructs such as:
SELECT 1 FROM users; UPDATE users SET name = CHAR(97,98,99) WHERE name = CHAR(100,101,102)
(CHAR() is a MySQL function which constructs a string from a list of character code values. If you're using some other database, an equivalent function probably exists.)
Interpolating unescaped content directly into a query is never safe. Don't do it.
I think you are asking the wrong question. If you have code that is even remotely similar to this, then you have a huge problem with the way you're writing code... and probably with the way you're conceptualizing the problem that you need to solve, or you're working from a very bad design.
If, for some reason, you have a need for anything about the design of your database to be passed in on a URL query string or an http post, and if, for some reason, you think executing an unescaped query is the approach you need... then whatever you're doing, you're doing it wrong.
If, by some remote chance, you actually have a need to pass the name of a table to a web page, then the very least you must do is compare the input value to some kind of static structure to see if the input value is in the list... and then use the value from the list, or from something static, never from the input.
Simplistically something as primitive as the following would be a far superior approach, though arguably it is a bad design if table names, column names, or any database internals ever need to go out into browser-land.
$table = $_GET ["table"];
IF ($table == "users")
{
$query = "SELECT 1 FROM users;"
}
ELSEIF ($table == "points")
{
$query = "SELECT 1 FROM points;"
}
...
I have a weird problem.
I have a table which has a title field.
I am inserting values into this title field using mysql_real_escape_string. Inserting is working fine for values with single quotes.
Some other place I am doing a select using title filed in the where clause as below
SELECT * FROM table WHERE title=mysql_real_escape_string(Girish's Photo);
This query is returning empty result set even when I inserted Girish's Photo.
---- Editing to put some code
$photo_title=mysql_real_escape_string($_POST[photo_title]);<br/>
$sql = "INSERT INTO photos values($id,'$photo_title');<br/>
using this from a form I have inserted Girish's Photo into photo_title. It worked fine.
...
..
..
Then at some other place in PHP
$title="Girish's Photo";
$sql = "SELECT photo_id,photo_title FROM photos WHERE photo_title ='" . mysql_real_escape_string($title)."'" ;
But this query is returning empty result set.
Using phpMyAdmin, if I try to run the above query .. the result is empty. If I browse the table I see value Girish\'s Photo
Now if I run the query on phpMyAdmin replacing where clause with where photo_title='Girish\''s Photo' I am getting the record.
$data = "Girish's Photo";
$query = "SELECT * FROM table WHERE title='".mysql_real_escape_string($data)."'";
mysql_real_escape_string() is a PHP-function, which should be used as follow:
"SELECT * FROM table WHERE title='".mysql_real_escape_string("Girish's Photo")."'";
However, this is bad practice.
Okay so you're going to want to use PDO for all queries. Primarily for the following reasons:
mysql_* is being deprecated.
It's not safe from SQL Injection.
PDO is capable of accessing numerous database engines making it much more flexible without changing the API.
Please take a look at this post to get a look at how to issue a SELECT using PDO.
Parameterized SELECT queries via PDO?
I had a similar problem recently which I solved by using htmlentites() instead of mysql_real_escape_string() check it out in the manual or w3 schools
EDIT: this is a valid answer because he's using mysql_real_escape_string() in the wrong context in the first place. if you read the question, he's escaping a FILENAME and therefore he's not at risk of injection. If you're going to downvote at least say why..
The value in your database should not contain backslashes. That's why your query doesn't match. Girish's Photo does not match Girish\'s Photo. Sounds like you are a victim of magic quotes. Read the manual and get rid of them.
$qry1 = "DELETE FROM
si_topics
WHERE
topic_id = '". $_GET['topic'] ."'
DELETE FROM
si_posts
WHERE
topic_id = '". $_GET['topic'] ."'";
$mysqlqry1 = mysql_query($qry1);
if($mysqlqry1){
echo 'Topic deleted from database!';
} else {
echo 'Mysql query failed!';
}
This gives the message Mysql query failed!, why?
Greetings
You are missing a semicolon between your two delete statements.
Also, multiple queries are not supported in mysql_query.
From the documentation:
mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server that's associated with the specified link_identifier.`
You can not run multiple queries in mysql_query() function in once.
Try mysqli::multi_query instead to run multiple queries. queries can be separated by ;
Quoting from the manual (my emphasis)
mysql_query() sends a unique query (multiple queries are not supported)
If you want to execute several SQL statements in a single query, you need to use mysqli and multi-query, and each statement needs to be separated by a semi-colon (;)
Because:
you're sending one query with invalid syntax, and
even if you'd added the semicolon between queries (how else is the MySQL server supposed to know where your second query starts?!?), PHP's old library doesn't support that here.
Use mysqli.multi_query() instead.
You should also either use prepared statements or at the very least sanitise your inputs, as your code has a huge SQL Injection vulnerability (how are people still writing PHP like this?!? what are they teaching in these "schools"?! aghh!)
PHP does not allow running 2 queries in one go.
You need to split your queries in 2 variables and run them one by one.
http://php.net/manual/en/function.mysql-query.php
The documentation explains:
mysql_query() sends a unique query
(multiple queries are not supported)
to the currently active database on
the server that's associated with the
specified link_identifier.
The standard MySQL separator semicolon ( ; ) will not work here.
If you wish to specify multiple delete conditions across several tables, then you can use JOIN syntax for the DELETE statement, however this might be inefficient - but that way, the query will fit within mysql_query();
Someone already mentioned mysqli and multi_query function, thumbs up for that :)
On the other hand, your code is extremely prone to SQL injection attacks, always clean your $_POST and $_GET input before using it in the query directly!
Add mysql_error ($link) after 'echo 'Mysql query failed!';' line
That will explain the problem.