I have to following code:
session_start();
if(isset($_SESSION['Username']))
{
//User has selected auto sign-in re-fill session variables.
$mysqli = new mysqli('****','****','****','****');
if($mysqli->errno)
{
//Error connecting
}
else
{
//No error connecting to database
$stmt = $mysqli->prepare("SELECT Expires FROM Subscribers WHERE UName=?");
$stmt->bind_param('s', $_SESSION['Username']);
$stmt->execute();
$stmt->bind_result($Expires);
$stmt->store_result();
while($row = $stmt->fetch())
{
if($Expires < time())
{
//Deny user
$pageToShow = "Payment";
}
else
{
//Accept
$pageToShow = "Content";
}
}
}
}
else
{ ... }
I am getting the error Fatal error: Call to a member function bind_param() on a non-object in /home/content/42/7401242/html/****/wp-content/themes/****/archive.php on line 15
I just had an error like this about 30min ago on a different page, and I had for gotten the FROM from the sql query, but I have read, re-read, re-checked, every single letter of the code, over and over. I am about to pull all of my hair out...
What am I doing wrong?
That's simple.
You're not handling errors.
And not even asking how to do that.
In your other question they showed you error itself instead of showing you the way how can you see the error yourself.
In the present question the answer is "check your query" which is not too helpful too.
Instead of asking other people to find typos in your queries, you have to ask mysqli to do that. That's way more efficient, especially because there could be another mistake, not in the query but somewhere else.
So, you have to check every database interaction result and translate it into PHP error.
$sql = "SELECT Expires FROM Subscribers WHERE UName=?";
$stmt = $mysqli->prepare($sql) or trigger_error($mysqli->error);
...
$stmt->execute() or trigger_error($mysqli->error);
so, you will immediately know what's going wrong.
The error tells you that your SQL query is returning an empty result.
two things you must do:
check that you are connected to the database properly and that you
have the permissions to access the data in the database
check your query and see if it returns any results in your SQL
database.
Related
I have a button in a webapp that allows users to request a specially formatted number. When a user click this button 2 scripts run. The first that is fully functional, looks at a number table finds the largest number and increments it by 1. (This is not the Primary Key) the second script which is partially working gets the current date and runs a SQL query to get which period that date falls in. (Periods in this case not always equaling a full month) I know this script is at least partially working because I can access the $datetoday variable called in that script file. However it is not returning the requested data from the periods table. Anyone that could help me identify what I am doing wrong?
<?php
include 'dbh.inc.php';
$datetoday = date("Ymd");
$sql = "SELECT p_num FROM periods where '$datetoday' BETWEEN p_start AND p_end";
$stmt = mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../quote.php?quotes=failed_to_write");
exit();
} else {
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_assoc($result);
$pnum = $row;
mysqli_stmt_close($stmt);
}
If it helps any one I published my code to https://github.com/cwilson-vts/Quote-Appliction
So first off, I do not use msqli and never learned it. However, I believe I get the gist of what you want to do. I use PDO because I FEEL that it is easier to use, easier to read and it's also what I learned starting off. It's kinda like Apple vs. Samsung... no one product is exactly wrong or right. And each have their advantages and disadvantages. What I'm about to provide you will be in PDO form so I hope that you will be able to use this. And if you can't then no worries.
I want to first address one major thing that I saw and that is you interlacing variables directly into a mysql statement. This is not considered standard practice and is not safe due to sql injections. For reference, I would like you to read these sites:
http://php.net/manual/en/security.database.sql-injection.php
http://php.net/manual/en/pdo.prepared-statements.php
Next, I'm noticing you're using datetime as a variable name. I advise against this as this is reserved in most programming languages and can be tricky. So instead, I am going to change it something that won't be sensitive to it such as $now = "hello world data";
Also I'm not seeing where you would print the result? Or did you just not include that?
Another thing to consider: is your datetime variable the same format as what you are storing in your db? Because if not, you will return 0 results every time. Also make sure it is the right time zone too. Because that will really screw with you. And I will show you that in the code below too.
So now on to the actual code! I will be providing you with everything from the db connection code to the sql execution.
DB CONNECTION FILE:
<?php
$host = '127.0.0.1';
$user = 'root';
$pw = '';
$db = 'test'; // your db name here (replace 'test' with whatever your db name is)
try {
// this is the variable will call on later in the main file
$conn = new PDO("mysql:host=$host;dbname=$db;", $user, $pw);
} catch (PDOException $e) {
// kills the page and returns mysql error
die("Connection failed: " . $e->getMessage());
}
?>
The data file:
<?php
// calls on the db connection file
require 'dbconfig.php';
// set default date (can be whatever you need compared to your web server's timezone). For this example we will assume the web server is operating on EST.
date_default_timezone('US/Eastern');
$now = date("Ymd");
// check that the $now var is set
if(isset($now)) {
$query = $conn->prepare("SELECT p_num FROM periods WHERE p_start BETWEEN p_start AND :now AND p_end BETWEEN p_end AND :now");
$query->bindValue(':now', $now);
if($query->execute()) {
$data = $query->fetchAll(PDO::FETCH_ASSOC);
print_r($data); // checking that data is successfully being retrieved (only a troubleshooting method...you would remove this once you confirm it works)
} else {
// redirect as needed and print a user message
die("Something went wrong!");
}
$query->closeCursor();
}
?>
Another thing I want to mention is that make sure you follow due process with troubleshooting. If it's not working and I'm not getting any errors, I usually start at the querying level first. I check to make sure my query is executing properly. To do that, I go into my db and execute it manually. If that's working, then I want to check that I am actually receiving a value to the variable I'm declaring. As you can see, I check to make sure the $now variable is set. If it's not, that block of code won't even run. PHP can be rather tricky and finicky about this so make sure you check that. If you aren't sure what the variable is being set too, echo or print it with simply doing echo $now
If you have further questions please let me know. I hope this helps you!
I think I know what I was doing wrong, somebody with more PHP smarts than me will have to say for sure. In my above code I was using mysqli_stmt_store_result I believe that was clearing my variable before I intended. I changed that and reworked my query to be more simple.
<?php
include 'dbh.inc.php';
$datetoday = date("Ymd");
$sql = "SELECT p_num FROM periods WHERE p_start <= $datetoday order by p_num desc limit 1";
$stmt = mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../quote.php?quotes=failed_to_write");
exit();
} else {
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
while( $row = mysqli_fetch_assoc($result)) {
$pnum = $row['p_num'];
echo $pnum;
}
mysqli_stmt_close($stmt);
}
Thanks to #rhuntington and #nick for trying to help. Sorry I am such an idiot.
So I'm trying to write a temp way to login to the admin panel using an if else statement while I read up on PDO. If someone could tell me where the error lies here it would be much appreciated.
I've updated my code after looking around a little bit, but I still have the issue of nothing showing up where my code belongs and pulling the information it should.
<?php
$admin = $_SESSION['admin_login'];
$con=mysql_connect("$server","$user","$pass");
if
(!$con)
{
die('Could not Connect' .mysql_error());
}
mysql_select_db($webdb, $con);
$result=mysql_query("SELECT * FROM permissions WHERE username= '$admin' ");
$row = mysql_fetch_assoc($result);
if ($row['permissions']=="3")
{
echo 'Admin Panel';
}
elseif ($row['permissions']=="1")
{
echo 'include acp_error.php';
}
?>
Is what I've updated to; Does anyone see any issue here?
mysql_query returns a statement HANDLE, not the value(s)/row(s) you're trying to select. YOu need to FETCH a row of data to be able to get the values you need to compare.
$result = mysql_query(...) or die(mysql_error());
$row = mysql_fetch_assoc($result);
if ($row['somefield'] == 3) {
...
}
Please note that things like
"$webdb"
are pointless cargo-cult programming. A simple
$webdb
is all that's needed for such things. There is not point in creating a new string, whose sole contents are the contents of a variable - just use the variable itself.
As well, note that you're vulnerable to SQL injection via that $_SESSION value you're using in the query. If that's a text value, and contains user-supplied data, your server is trivial to pwn.
I'm having a problem with the a mysqli query I'm calling from a php script. I've rewritten it many times and keep getting the error: "mysqli num_rows Commands out of sync; you can't run this command now" This is the first attempt to access the database from this page. I was previously binding the parameters and then calling: $checkAcct->num_rows() and getting the same problem. I also tried what someone suggested in a different post on this site:
do { $checkAcct->use_result(); } while( $checkAcct->next_result() );
but this didn't work either and I got the same error. After I make sure a user with these details isn't in the db I execute another query to insert the user's info into the site but the error message I get pertains to this query here. Let me know if it would help to see the other query also.
Below is the code I'm trying to use:
$checkAcct = $dbConn->stmt_init();
$existingAcct = array();
if ($checkAcct->prepare("select usrName, eAddy from usr where usrName = ? OR eAddy = ?"))
{
$checkAcct->bind_param("ss", $usr, $eml);
$checkAcct->execute();
$checkAcct->bind_result($result);
while($checkAcct->fetch())
{
$existingAcct[] = $result;
}
if ($existingAcct[0] != 0)
{
if ($usr == $inputs['usrName'] && $eml == $inputs['eAddy'])
{
$acctSetupErrors[] = "Someone with your username and email address already exists. Please use the forgot password form to reset your password";
} else if ($eml == $inputs['eAddy']) {
$acctSetupErrors[] = "Someone with your email address already exists. Please use the forgot password form to reset your password or setup an account with a different email address";
} else {
$acctSetupErrors[] = "Someone with your username already exists. Please choose a different username";
}
}
$checkAcct->free_result();
$checkAcct->close();
Edit
Alright. I tried your way and it didn't work either so I went hunting for any previous db calls. I found the offending query in a db call in an include file linked higher up in the script. Funny, it's never caused problems anywhere else but now I freed the result and it works well. Thanks for your help with this. I don't have enough points to upvote you for suggesting it must be somewhere above in the code.
Can you change the above code like this and see what you are getting
$checkAcct = $dbConn->stmt_init();
$existingAcct = array();
if ($checkAcct->prepare("select usrName, eAddy from usr where usrName = ? OR eAddy = ?"))
{
$checkAcct->bind_param("ss", $usr, $eml);
$checkAcct->execute();
$checkAcct->store_result();
printf("Number of rows: %d.\n", $stmt->num_rows);
$checkAcct->free_result();
$checkAcct->close();
}
And could you make sure prepare buffer is cleared before you use it again. I hope there is some other query which is executed prior to this statement is still active in mysqli prepare statement buffer.
I have a code which kinda works, but not really i can't figure out why, what im trying to do is check inside the database if the URL is already there, if it is let the user know, if its not the go ahead and add it.
The code also makes sure that the field is not empty. However it seems like it checks to see if the url is already there, but if its not adding to the database anymore. Also the duplicate check seems like sometimes it works sometimes it doesn't so its kinda buggy. Any pointers would be great. Thank you.
if(isset($_GET['site_url']) ){
$url= $_GET['site_url'];
$dupe = mysql_query("SELECT * FROM $tbl_name WHERE URL='$url'");
$num_rows = mysql_num_rows($dupe);
if ($num_rows) {
echo 'Error! Already on our database!';
}
else {
$insertSite_sql = "INSERT INTO $tbl_name (URL) VALUES('$url')";
echo $url;
echo ' added to the database!';
}
}
else {
echo 'Error! Please fill all fileds!';
}
Instead of checking on the PHP side, you should make the field in MySQL UNIQUE. This way there is uniqueness checking on the database level (which will probably be much more efficient).
ALTER TABLE tbl ADD UNIQUE(URL);
Take note here that when a duplicate is INSERTed MySQL will complain. You should listen for errors returned by MySQL. With your current functions you should check if mysql_query() returns false and examine mysql_error(). However, you should really be using PDO. That way you can do:
try {
$db = new PDO('mysql:host=localhost;db=dbname', $user, $pass);
$stmt = $db->query('INSERT INTO tbl (URL) VALUES (:url)');
$stmt->execute(array(':url' => $url));
} catch (PDOException $e) {
if($e->getCode() == 1169) { //This is the code for a duplicate
// Handle duplicate
echo 'Error! Already in our database!';
}
}
Also, it is very important that you have a PRIMARY KEY in your table. You should really add one. There are a lot of reasons for it. You could do that with:
ALTER TABLE tbl ADD Id INT;
ALTER TABLE tbl ADD PRIMARY KEY(Id);
You should take PhpMyCoder's advice on the UNIQUE field type.
Also, you're not printing any errors.
Make sure you have or die (mysql_error()); at the end of your mysql_* function(s) to print errors.
You also shouldn't even be using mysql_* functions. Take a look at PDO or MySQLi instead.
You're also not executing the insert query...
Try this code:
if(isset($_GET['site_url']) ){
$url= $_GET['site_url'];
$dupe = mysql_query("SELECT * FROM $tbl_name WHERE URL='$url'") or die (mysql_error());
$num_rows = mysql_num_rows($dupe);
if ($num_rows > 0) {
echo 'Error! Already on our database!';
}
else {
$insertSite_sql = "INSERT INTO $tbl_name (URL) VALUES('$url')";
mysql_query($insertSite_sql) or die (mysql_error());
echo $url;
echo ' added to the database!';
}
}
else {
echo 'Error! Please fill all fileds!';
}
As PhpMyCoder said, you should add a unique index to the table.
To add to his answer, here is how you can do what you want to do with only one query.
After you add the unique index, if you try to "INSERT INTO" and it result in a duplicate, MySQL will produce an error.
You can use mysql_errno() to find out if there was a duplicate entry and tell the user.
e.g.
$sql = "INSERT INTO $tbl_name (URL) VALUES('$url')";
$result = mysql_query($sql);
if($result === false) {
if(mysql_errno() == $duplicate_key_error) {
echo 'Error! Already in our database!';
} else {
echo 'An error has occurred. MySQL said: ' . mysql_error();
}
}
mysql_error() will return the mysql error in plain english.
mysql_errno() returns just the numeric error code. So set $duplicate_key_error to whatever the code is (I don't know it off the top of my head) and you are all set.
Also note that you don't want to print any specific system errors to users in production. You don't want hackers to get all kinds of information about your server. You would only be printing MySQL errors in testing or in non-public programs.
ALSO! Important, the mysql functions are deprecated. If you go to any of their pages ( e.g. http://php.net/manual/en/function.mysql-errno.php) you will see recommendations for better alternatives. You would probably want to use PDO.
Anyone who wants to edit my answer to change mysql to PDO or add the PDO version, go ahead.
<?php
include 'connect.php';
include 'header.php';
$page = "signup.php";
// receive the invite code:
$code = $_POST['code'];
$sql = "SELECT codes FROM invites WHERE codes='$code'";
// check the table for matching codes
$result = mysql_query($sql);
// check if the request returned 1 or 0 rows from the database
if (mysql_query($result)) {
// end any previously defined sessions.
session_start();session_unset();session_destroy();
// start a new session
session_start();
// define the session variable.
// this allows us to check if it's set later and is required for
// the script to run properly.
$code = $_POST["code"];
mysql_query("DELETE FROM invites WHERE codes='$code'");
header('Location: '.$page);
exit;
} else {
echo "Invite invalid. Please try again later.";
echo $code;
}
include 'footer.php';
?>
I am trying to implement an invite system to a webpage I am working on. However when trying to evaluate if there is a row containing the invite code I keep either getting nothing or this warning. The warning in this case but if I change the if state to ==1, it allows everyone regardless of code and ==0 does throws different errors.
if (mysql_query($result)) {
Try mysql_num_rows there.
There are a few things wrong here.
1) SQL Injection vulnerabilities, don't ever pass a superglobal $_POST or $_GET or any other user-supplied variable directly inside your query!
Use at minimum mysql_real_escape_string() to the variable before letting it into the query, or better look into parametrized queries, it's the best way to avoid SQL vulnerabilities
2)
$result = mysql_query($sql);
// check if the request returned 1 or 0 rows from the database
if (mysql_query($result)) ....
This doesn't check if request returns 1 or 0 rows, you should use mysql_num_rows() here instead
if(mysql_num_rows() == 1) //or whatever you need to check
3)
session_start();session_unset();session_destroy();
// start a new session
session_start();
session_start() should be called before anything in your page. Don't know why this redundancy of calling, unsetting, destroying, recalling it here. If you want another id, just use session_regenerate_id();
And as already said by other, use some error reporting in your query, something like
$result = mysql_query($sql) or die(mysql_error())
to actually see what's failed, where and why.
Problem is your query. First of all check your statement and use this :
$result = mysql_query($sql) or die(mysql_error());
instead of this
$result = mysql_query($sql);
So, you can see are there any error at your SQL query .