I'm running a function that checks whether or not an user has already submitted a question. I've narrowed the problem down to my function which runs a query code. For some reason it is not working. The function does work when the part that involved AND user_requester... is not there. I'm sure it's some sort of syntax error but I don't get a response from the error reporting. Here is the code below:
function question_exists ($question, $user_id) {
$question = sanitize($question);
$query = mysql_query("SELECT COUNT(`primary_id`) FROM `requests` WHERE
`question_asked`= '$question' AND `user_requester` = $user_id");
return (mysql_result($query, 0) == 1) ? true : false;
}
Clarification: I want to prevent an user from submitting the same question twice. That is the purpose of adding the AND section to the where clause in the query. When I do add the AND section, everything goes to pieces and the user can submit the same question anyways.
I would try doing all steps separately so you can test the result of each operation individually. Your return line is handling a lot of things and so it's hard to tell where you problem is. Something like this...
function question_exists( $question, $user_id )
{
$question = sanitize( $question );
$user_id = (int) $user_id; // additional sanitization in case you didn't do it already.
$sql = "SELECT COUNT(`primary_id`) FROM `requests` WHERE
`question_asked`= '$question' AND `user_requester` = $user_id";
$result = mysql_query( $sql );
if ( !$result ) {
// Note: this would be better sent to an error handling function, this is just for simplicity's sake.
echo 'Mysql query error: ' . mysql_error();
exit;
}
$row = mysql_fetch_row ( $result );
if ( $row ) {
return true;
} else {
// temporary debug code
echo "unknown error</ br>\n";
echo "sql: " . $sql . "</ br>\n";
echo "<pre>";
var_dump( $row );
echo "</pre>";
exit();
// real code for after problem is solved
return false;
}
}
If this still doesn't help and you haven't already, dump your $question and $user_id vars to make sure that you are receiving them and your sanitize function isn't doing something incorrectly. Note, I have not run this code so there may be syntax errors.
What kind of error reporting are you referring to? A query failing will not trigger any PHP errors/warnings. You'd need somethign like
$query = mysql_query(...) or die(mysql_error());
to see what really happened.
$query = mysql_query("SELECT COUNT(`primary_id`) FROM `requests` WHERE
`question_asked`= '$question' AND `user_requester` = {$user_id}");
Add curly braces to your variable in the query.
Related
I can't seem to echo all of my data with assoc and exit();. I looked up other questions similar and found this:
if(isset($_POST['postuserid'])){
$uid = $_POST['postuserid'];
$ssql = "SELECT * FROM foodid WHERE postid=$uid";
$rresult = mysqli_query($db,$ssql);
while ($lrow = mysqli_fetch_assoc($rresult)){
if($lrow !== FALSE) {
echo $lrow['userid'];
exit();
}
}
}
}
No success. I also tried putting exit() outside each bracket and I still get the same result. I only fetch one data at a time. I know that using exit() causes this, but is there a way to fetch all data with it?
There are multiple solutions, I will display the more commonly used methods:
$ssql = "SELECT * FROM foodid WHERE postid=$uid";
$rresult = mysqli_query($db,$ssql);
if($rresult){
$data = mysqli_fetch_all($rresult, MYSQLI_ASSOC);
die(json_encode(mysqli_fetch_all($rresult, MYSQLI_ASSOC)));
} else {
header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
// Do your error logging.
die();
}
Or without the fetch_all incase you want to alter some of the data:
$ssql = "SELECT * FROM foodid WHERE postid=$uid";
$rresult = mysqli_query($db,$ssql);
while ($lrow = mysqli_fetch_assoc($rresult)){
$ret[] = $lrow;
}
die(json_encode($ret));
Note:
Keep in mind that you wide open to mysql injection attacks, resolved
if you would be using prepared
statements.
In the second example I did not diagnose if the query was successful. It is a bad practise not to do so.
I'm trying to take a query string param such as ?table=products and have mysql return all the rows for the "products" table in mysql. I tried running the code below in my browser, but I just get a blank white page. I know the mysql server/username/pass information is correct, I've tested the query in mysql and it works fine.
I guess I have two question:
What am I doing wrong?
How come I can't see any error messages when php has an issue?
e.g. code:
<?php
// Get query string parameter value
$keys = array_keys($_GET);
$key = $keys[0];
$value = $_GET[$key];
// Setup connection to mysql database
$serverName = "localhost";
$username = "root";
$password = "password";
$dbname = "webserver";
$conn = new mysqli($serverName, $username, $password, $dbname);
// SQL query
$sql = "SELECT * FROM $value";
$result = $conn->query($sql);
// Print results
echo $result;
?>
Follow the instuctions on below link to enable php.ini errors
How do I get PHP errors to display?
VULNERABLE IMPLEMENTATION WARNING
The above comments clearly mention the side effects of this implementation.
Since knowing the actual bug is a developer's right! Continue reading the answer keeping the safety of software and its users in mind.
You are trying to print $result which is not valid since its an object.
You can do the following instead:
$response = array();
$sql = "SELECT * FROM $value";
$result = $conn->query($sql);
// Print results
if ($result) {
while($row = $result->fetch_array(MYSQL_ASSOC)) {
$response[] = $row;
}
}
echo json_encode($response);
What am I doing wrong?
Sadly, pretty much everything.
// Get query string parameter value
$keys = array_keys($_GET);
$key = $keys[0];
$value = $_GET[$key];
You are dereferencing a named value based on its position. And its totally unnecessary. Consider:
$value=$_GET['table'];
...
$conn = new mysqli($serverName, $username, $password, $dbname);
Where is your error checking to see if $conn was initialized?
$result = $conn->query($sql);
again, no error checking.
echo $result;
$result here is a mysqli_result object. You need to call some methods on it to get the data out.
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
var_export($row);
}
How come I can't see any error messages when php has an issue?
Have you tested that the default handlers produce output in your browser? You're not overriding the config in php.ini in the code you've shown us. Did you check your logs?
ini_set('diplay_error', 1);
error_reporting(E_ALL);
I just get a blank white page
Would it be so hard to put
print "finished";
at the end of the code? Then you'd at least know if the code executed.
The main issue you have right now is you need to get the results
while ($row = $result->fetch_assoc()) {
//do something with row
}
See ( for mysqli->query method )
http://php.net/manual/en/mysqli.query.php
false on failure and mysqli_query() will return a mysqli_result object on success
See ( for the result objects definition )
http://php.net/manual/en/class.mysqli-result.php
Now as others mentioned I would never just concatenate user data into your query. Imagine a hacker knows the name of a valid table, not hard considering your sending it through the request. All they would have to do is send a value like this:
$value = 'real_table; DROP DATABASE';
And your query becomes.
$sql = "SELECT * FROM real_table; DROP DATABASE";
I won't say that this would actually work as there are ( maybe ) some restrictions on running multiple queries in a single request,user permissions etc... That might save your bacon, but I certainly wouldn't risk it.
So you have 2 choices.
Use a white list of tables
Query the DB for the schema
The first one is easy to do, make a list of tables
$whitelist = [
'table1',
'table2'
];
Then compare your user input
$safeTable = false;
if( false !== ($index = array_search($table, $whitelist))) {
$safeTable = $whitelist[$index];
}else{
//log error and
exit();
}
// SQL query
$sql = "SELECT * FROM $safeTable";
$result = $conn->query($sql);
For the second one,
$schema = $conn->query('SELECT `TABLE_NAME` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` LIKE "database"');
$whitelist = [];
while ($row = $result->fetch_assoc()) {
$whitelist[] = $row['TABLE_NAME'];
}
$safeTable = false;
if( false !== ($index = array_search($table, $whitelist))) {
$safeTable = $whitelist[$index];
}else{
//log error and
exit();
}
// SQL query
$sql = "SELECT * FROM $safeTable";
$result = $conn->query($sql);
This will return a list of all the tables in that database, from which you can build an array and then compare. The nice thing about the second one is that if you add a table then you don't have to change the code, which may or may not be a good thing. You have to have a user with permission to read from information_schema database. And you have to do an additional query.
-note- I am not directly using the users input, I'm using their input to find my data. It's less prone to breaking when there is a coder error. Consider this:
///all my codes are broken;
--if(!in_array($_GET['table'], $whitelist))) {
-- //log error and
-- exit();
--}
// SQL query
$sql = "SELECT * FROM {$_GET['table']}";
$result = $conn->query($sql);
Against this:
$safeTable = false;
// all my codes are broken
-- if( false !== ($index = array_search($_GET['table'], $whitelist))) {
-- $safeTable = $whitelist[$index];
-- }else{
-- //log error and
-- exit();
-- }
// SQL query
$sql = "SELECT * FROM $safeTable"; //$safeTable is undefined or false;
$result = $conn->query($sql);
Were using our code for inclusion, instead of exclusion. So if it breaks, it's never included. The other way, if it breaks it's never excluded. Which is not a situation we want to be even remotely possible.
I hope that helps you understand some of the pitfalls. The #1 rule for SQL (or anything on the web), is Never Trust the User. Never put their data into your SQL.
I am trying to select a table within my database with a GET Method.
Now when I hardcode the value of the variable in there (the table name) it works as expected and it returns the values in an array.
But when I try to determine the table name through a variable, I get the following error:
Fatal error: Call to a member function fetch_array() on a non-object in
Now I have tried the var_dump($result); but that returns bool(false).
Now the variable does carry a value, because when I echo it back to the screen it gives the value I would expect.
So why does not return the value when making the query for my table search???
$result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = ". $series); //This where a change needs to happen
var_dump($result);
$posts = array();
while($row = $result->fetch_array())
{
$ID=$row['ID'];
$sermonTitle=$row['sermonTitle'];
$sermonSpeaker=$row['sermonSpeaker'];
$sermonSeries=$row['sermonSeries'];
$sermonDate=$row['sermonDate'];
$linkToImage=$row['linkToImage'];
$linkToAudioFile=$row['linkToAudioFile'];
$posts []= array (
'ID'=> $ID,
'sermonTitle'=> $sermonTitle,
'sermonSpeaker'=> $sermonSpeaker,
'sermonSeries'=> $sermonSeries,
'sermonDate'=> $sermonDate,
'linkToImage'=> $linkToImage,
'linkToAudioFile'=> $linkToAudioFile
);
}
$response['posts'] = $posts;
var_dump($posts);
PS I have read about the depreciation in mysql style and that I know have to use mysqli writing. I am running PHP Version 5.2.6-1+lenny16
If the $series is a string you need to put quotes around the variable..
Try...
$result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = '". $series ."'");
Hope it helps.
Now I have tried the var_dump($result); but that returns bool(false).
Because your query failed.
Try:
if( ! $result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = ". $series); ) {
echo "An error has occurred: \n" . var_export($mysqli->error_list, TRUE);
} else {
//do stuff
}
The central question seems to me: Where does $series come from? Where does that variable ever get initialized?
If you're passing this in from the web form, two things: either use $_GET or $_POST (whatever action you use in your form). And then you have to sanitize what comes from there, in order to not be vulnerable to SQL injection attacks. Prepared statements are your friend in this case; they help harden your script against this kind of attacks.
try this
$result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = '$series' ");
$result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = ". $series); //This where a change needs to happen
You should be using Prepared Statements if the variable: $series is user defined.
$result->prepare("SELECT * FROM PodcastSermons WHERE `sermonSeries`=?");
$result->bind_param('s', $series);
$result->execute();
Also, Print_r($result); to check if your initial $result to see if it has been populated; Furthermore, in your SQL Query is sermonSeries properly matched to your SQL Table?
Update:
while($row = $result->fetch_array())
{
Try Modifying this to:
while($row = $result->fetch_array(MYSQLI_ASSOC))
{
http://uk1.php.net/manual/en/mysqli-result.fetch-array.php
your query simply fails. check var_dump($series); before executing.
i assume it might be a string and you just don't quote it?
just a tip: first build a string with your commandtext before
calling $mysqli->query. and use that string (like $mysqli->query($cmd);
dump that string :) might open your eyes ;)
that way you can extract it and execute it directly against the database (f.e. phpmyadmin).
My goal is to display the profile of a user. I have this function:
function get_profile($un) {
if($registerquery = $this->conn->query("SELECT * FROM table WHERE usr = '".$un."' ")){
return $profile = mysql_fetch_array($registerquery);
}
}
Then the display snippet:
<?php $profile = $mysql->get_profile($un);
foreach($profile as $key => $value){
echo "<span>".$key.': '.$value."</span><br />";
}
?>
But I get: "Warning: Invalid argument supplied for foreach() in..."
Help pls???
You need to see if the result was a success or not
if (gettype($result) == "boolean") {
$output = array('success' => ($result ? 1 : 0));
}
And you need to cycle through it if it's a resource type...
if (gettype($result) == "resource") {
if (mysql_num_rows($result) != 0 ) {
while ($row = mysql_fetch_assoc($result)) {
$output[] =$row;
}
}
}
I chopped up some real code that does basically everything pretty awful for you because I can't release it, sorry.
Check the result of get_profile, as it will return null if the query failed. You can't loop over null.
Be very very careful here. You are passing a raw string into the query function without escaping it and without using a parameterized query. Use mysql_escape_string around $un in your query. Your code flaw is called a sql injection attack.
Someone could pass their username as this
myusername'; update users set password = '';
And blank all passwords, thereby allowing themselves to access any account. Other similar shady attacks are equally likely.. you can basically do anything to a database with sql injection attacks.
I Agree with Anthony Forloney. The following code is just returning TRUE or FALSE depending on wether loading the $profile variable worked:
return $profile = mysql_fetch_array($registerquery);
You don't need $profile. You can eliminate it as such:
return mysql_fetch_array($registerquery);
The function will return the array and then when you call the function later you can load it's return value into $profile as you do with the following:
$profile = $mysql->get_profile($un);
Try this:
function get_profile($un) {
if($result = $this->conn->query("SELECT * FROM table WHERE usr = '".$un."' ")){
return $result->fetchArray(MYSQLI_ASSOC);
}
return array();
}
You're mixing MySQLi and MySQL functions and you can't do that. And, the last line of this code will return an empty array if the query does not work, rather than return null.
It is probably empty ($profile). Print the value of "count($profile)"
I have found that the easiest way to loop through mysql results is to use a while loop:
$select = "SELECT * FROM MyTable";
$result = mysql_query($select);
while ($profile = mysql_fetch_array($result)) {
$name = $profile['name'];
...
}
function procLogin($username,$password){
$query = "SELECT *
FROM members
WHERE login = '".mysql_escape_string($username)."'
AND passwd = '".mysql_escape_string($password)."'";
$result = mysql_query($query);
//$values = array();
while($row = mysql_fetch_array($result))
{
return 'gg';
return(array($row['member_id']));
}
}
Not able to get the userlevel field.... nor anything....
Not sure exactly what your question is, but one problem is that you're returning from within this while loop:
while($row = mysql_fetch_array($result))
{
return 'gg';
return(array($row['member_id']));
}
In fact, you're returning twice from within the loop... so the procLogin() function will always return a value of "gg", unless something goes wrong with your SQL query.
In general, you should avoid return statements within any loop, as it creates confusion and can lead to unexpected results.
return(array($row['member_id']));
Looks wrong - it should be:
return($row['member_id']);
You shouldn't need to define the array in the return like that.
You also use mysql_fetch_array () which returns as a numerical index - the function you probably want is mysql_fetch_assoc which is much nicer to work with as it returns the values with the keys as the column name rather than a numerical index.
Here's it again with a few tidy ups:
function procLogin($username,$password){
$query = "SELECT *
FROM members
WHERE login = '".mysql_escape_string($username)."'
AND passwd = '".mysql_escape_string($password)."'";
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
if ($row['member_id'] > 0)
{
return ($row['member_id']);
}
else
{
return false;
}
}
I'm thinking, based on your comments about the userlevel, that you want to return the entire array rather than just the member_id ? Here's a slight edit to Meep3D's answer above:
function procLogin($username,$password){
$query = "SELECT *
FROM members
WHERE login = '".mysql_escape_string($username)."'
AND passwd = '".mysql_escape_string($password)."'";
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
if (mysql_num_rows($result) > 0)
{
$row = mysql_fetch_assoc($result);
return $row;
}
else
{
return false;
}
}
This should return an array of all your table columns, if you are looking for the userlevel, presumably you should be able to access it something like:
$loginInfo = procLogin("theband","password1");
//if ($loginInfo) or something similar here
$level = $loginInfo['userlevel'];
So are you getting anything returned? That is to say, is it actually going into the while loop?
I'd use a mysql_error() function call straight after the mysql_query call to see if anything went wrong there.
Maybe there was no connection made, for example.
Are you still having issues? If so try something like:
echo $query;
after you define the query, then copy+paste that into phpmyadmin to check if there are any valid returns from the database.
After that try placing:
if (mysql_error())
{
trigger_error ("MySQL Error: ". mysql_error(), E_USER_ERROR);
}
Just after you call mysql_query. This should trigger an error if there is one giving you details of what went wrong.