I am converting PHP code from mysql_ to mysqli_. My DB connection is in a separate file, named "conn.inc" in a parent folder of my regular code. The code in it is ::
function GetDBConn($host="localhost", $user="mydb", $pass="mypass", $db="mydb") {
return $dbconn = #mysqli_connect($host, $user, $pass, $db);
mysqli_close($dbconn);
}
In my code files, I have
include_once ("../conn.inc"); .
I have code like -
$AuditInsertQ = mysqli_query(GetDBConn(),"INSERT INTO audit (userid, notes) VALUES (\"".$userid."\", \"".$notes."\")") or die("Error inserting row to Audit: ".mysqli_error($dbconn));
When I run the code, I get a message that ::
PHP Notice: Undefined variable: dbconn in C:\...
All of the examples I have seen have the DB connection in the same file as the code it was referencing. How do I reference the DB connection when it is in a different file; I thought the "include_once" was the way...?
There is so much wrong in this code I don't even know where to start.
no need for mysqli_error() at all
no need for a function like GetDBConn()
mysqli_close() right after connect makes no sense. Thanks to return operator, it never gets called though
die() is harmful
# operator is harmful
the file extension for conn.inc is harmful
the way you are adding variables to your query is most harmful of them all
I know it's hard to find a good tutorial. Internet is full of crappy outdated information. I am writing good tutorials, but Google don't know they are good and don't show them to you. Well at least I can give it to you here in my answer.
Three things you must understand about modern mysqli
mysqli can report its errors automatically, no need for mysqli_error()
a connection must be made only once, it means there is no use for a function like this
no variable should be added to the query directly. You have to use prepared statements with placeholders for the purpose.
In order to fix your code,
please read this post. It doesn't explain why you should use prepared statements but take my word for it
then read my tutorial on how to connect with mysqi properly
rename your file to conn.php or anyone will be able to see your database credentals
Then rewrite your code to
include_once ("../conn.php");
$stmt = $mysqli->prepare("INSERT INTO audit (userid, notes) VALUES (?,?)");
$stmt->bind_param("ss", $userid,$notes);
$stmt->execute();
For the explanation on what is going on in this code please see my tutorial on how to run an INSERT query with mysqli
In you function GetDBConn it return a mysql resource, not define a $dbconn variable for you.
Use something like mysqli_query($dbconn = GetDBConn(),"INSERT INTO audit ....
Note
function GetDBConn($host="localhost", $user="mydb", $pass="mypass", $db="mydb") {
return $dbconn = #mysqli_connect($host, $user, $pass, $db);
mysqli_close($dbconn);
}
$dbconn is only avaliable in the function, it cannot be accessed outside the function, so define it here is useless.
mysqli_close($dbconn); will never reached.
Related
I have a small problem. I'm trying to make a simple register/login system with sessions and I got this error:
Fatal error: Call to a member function query() on a non-object in C:\xampp\htdocs\members\includes\login.inc.php on line 9
This is the relevant line of code:
$result = $conn->query($sql);
The first time I tried it was working.
The rest of the code:
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$email = $_POST['email'];
$password = md5($_POST['password']);
$sql = "SELECT email, password FROM member WHERE email = '$email' AND password = '$password'";
$result = $conn->query($sql);
I also have db.php, which is used to connect the MYSQL and everything inside it is fine.
I cannot understand why, the first time I tried it was working I guess and now this kind of error.
I'm also having the db.php which is used to connect the MYSQL and everything inside is fine.. could someone explain me why I keep facing this error ?
I'm going to speculate. I'm speculating that you have a separate file (probably called db.php) which "handles" the setting up of the database connection. I'm further going to speculate that you've a chain of files which are require() (or include())'d into your web app.
I've seen this more times than I care to recall. It's a very old fashioned way of separating code into logical chunks inside PHP - which needs to be left in the past.
I'm speculating that you were previously defining $conn in another script which was included (or required) before this code. A global variable, which had was dependency later in the code execution. Invisible to the file it was declared in.
That's the problem. The quick/hack fix is to rename $conn or the restore the original declaration of it and make sure it's global and make sure it is included before this code is ran.
The proper fix (IMHO) is to look at using a framework (Laravel, Lumen, CodeIgniter, Yii, there are many - take your pick) and read up on the topics of dependency injection, autoloading and namespacing. Think about why global variable declarations make for unmaintainable code.
If you're really reluctant to go with a full framework, at the very least have a look at some database-abstraction libraries like doctrine (and it's sub-library dbal) which can easily be auto-loaded into your project via composer.
As Sascha already pointed out, $conn might be either not defined at all, or it's not an object (hence the error message).
From the code sample you have provided, it's actually a bit hard to tell what kind of connection object you might be using, but I think it's save to say that in your case it might be either PDO or mysqli.
For the sake of simplicity, let's stick with mysqli. A working code sample based on mysqli would look like this (shortened example taken from the docs cited above):
$conn = new mysqli("localhost", "my_user", "my_password", "world");
$result = $conn->query($sql);
Though you really should go for so-called prepared statements, as your code right now is prone to SQL injection as wally already stated.
I would have linked wally's answer and provide you with a link to the PHP docs relating to prepared statements, but apparently, my lack of reputation points don't allow me to, so just do a quick Google search for PHP & prepared statements.
The database connection file has to be added at the beginning of the file.
The present format is easy.
<?php $mysqli = new mysqli("localhost", "Userid", "password", "database name"); if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error; }
?>
At the beginningļ¼
require 'db.php';
$conn = new db();
I am attempting to create new tables every time I post to this method, but for some reason I can not figure out why it dies.
<?php
$host = "127.0.0.1";
$username = 'cotten3128';
$pwd = 'pwd';
$database = "student_cotten3128";
$pin = $_REQUEST['pinSent'];
$words = $_REQUEST['resultSent'];
$tableName = $pin;
$db = new mysqli($host, $username, $pwd, $database);
if ($sql = $db->prepare("CREATE TABLE $pin (id INT(11) AUTO_INCREMENT);")) {
$sql->execute();
$sql->close();
}else{
echo $mysql->error;
die('Could not create table');
}
for($i=0;$i<count($words);$i++){
if($sql = $db->prepare("INSERT INTO ".$pin.$words[$i].";")) {
$sql->execute();
$sql->close();
}else{
echo $mysql->error;
die("Could not add data to table");
}
}
mysqli_close();
?>
Any help or insight would be greatly appreciated.
The intention of my post is to help you finding the issue by yourself. As you did not added much information I assume my post is helpful for you.
Based on the code you have shared I guess you mean one of your called die() functions is executed.
Wrong function call
As Jay Blancherd mentioned mysql_close is the wrong function. You rather have to use mysqli_close as you created a mysqli instance.
Beside of that mysql_* is deprecated and should not be used anymore.
Debugging Steps
Not only for this case but in general you should ask yourself:
Is there an error message available? (Frontend output, error log file, ...)
YES:
What's the message about?
Is it an error you can search for? E.g. via a search engine or the corresponding documentation?
Look up in the bug tracker (if available), by the software developer of the software you are using, and if it has not been reported yet report the issue.
NO: (if none error message available OR you cannot search for it as it is a custom error message)
Search in the files of the software you are using for the error message and start a core-debugging.
STILL NO SOLUTION?:
Ask on stackoverflow.com e.g. and tell your issue and the steps you have performed to find and fix the bug. Post only as much code as necessary plus use a proper format.
Debugging in your case:
In order to narrow down the scope. Which of the die() is executed? Depending on that echo the query to execute just before it actually is executed. Then copy the SQL query to an SQL editor and look at it syntax. After that you probably know the problem already.
I am trying my best to object orientate my login scripts and checks for my website. As such, I have created a function that is called named "attempt_login". This function uses a database connection via the "mysqli_connect" function provided by a outside php file that is included and returns the $link variable.
However, when in my "attempt_login" the "mysqli_stmt_prepare" function is reached. It always returns false, and as such, the if statement never runs.
mysql_connect.php
require_once '../conf.php';
$link = mysqli_connect($mysql_server,$mysql_user,$mysql_pass,$mysql_db);
if(mysqli_connect_error())
{
//Fail
echo mysqli_connect_error();
}else{
//Success
}
return $link;
And the code from the "attempt_login" that fails:
$link = require_once 'functions/mysql/mysql_connect.php';
print_r($link);
$stmt = mysqli_stmt_init($link);
echo mysqli_stmt_error($stmt);
echo mysqli_error();
//This if statement always fails.
if(mysqli_stmt_prepare($stmt,"SELECT member_salt FROM members WHERE username=?" ) )
{
mysqli_stmt_bind_param($stmt,'s',$login_details['username']);
mysqli_stmt_execute($stmt);
$member_salt = NULL;
mysqli_stmt_bind_result($stmt,$member_salt);
mysqli_stmt_close($stmt);
}
And calling the function is pretty simple.
attempt_login($login_details);
I have tried many ways to do this, but it seems to only work when it is not within a function. Which defeats the purpose of me trying to have it in a function. If I move the error output to after the if statment, it will print:
No Database Selected
Even though one clearly is set in the link. I also can do a print_r($link); and it does print proper data for the mysql server.
It also has the same issue with procedural and object orientated mysqli styles, and fails as well with "mysqli_prepare".
I do have mysql working on the site, but any attempts to run anything within a function fails.
I have searched for several hours on trying to find a answer, but was unable to locate anything. I look forward to hearing from you! Many thanks in advance.
~Travis
I'd say then you haven't selected a database.
Either $mysql_db isn't set in ../conf.php or there is a typo or $mysql_db isn't visible in mysql_connect.php.
You don't seem to be passing $stmt to your function, I would advise your read this on scopes.
I'm stuck on this problem and all error examples are using $stmt->error or something which I don't understand. I write in procedural style not OOP. My insert fails so I'm curious to debug it please...
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_USER_PASSWORD, DB_NAME) or die(DB_CONNECT_ERROR);
if (!$stmt = mysqli_prepare($dbc, $query)) die('SEL:mysqli_prepare');
call_user_func_array('mysqli_stmt_bind_param', array_merge(array($stmt, 'sssssssssssssssssssssbsssss')), $idb);
mysqli_stmt_execute($stmt);
if (!mysqli_stmt_affected_rows($stmt)) {
// Failed to insert
} else {
// Success
}
My insert fails... how can I see what the reason was? Please and thank you in advance! I'm also just learning prepared statements so if I did something wrong please advise... The code makes it down to the // FAILED TO INSERT line and when checking cpanel the query did fail (there was nothing in the DB).
If you want to write your own example using the style of programming I used above and show me how to check if an insert failed that's cool too. Once I see how you do yours I can change my code. :)
Use mysqli_stmt_error() and mysqli_stmt_errno() to retrieve the error information:
mysqli_stmt_execute($stmt);
printf("Error #%d: %s.\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
Note
I would recommend you to use
if(mysqli_stmt_affected_rows($stmt) == 0)
instead of relying on the ugly autocast feature of PHP
if(!mysqli_stmt_affected_rows($stmt))
If you echo the stmt, and try it directly in SQL, that's probably your easiest method.
To try in SQL, either use the command line if you can, or download phpmyadmin, really easy to install, and run the query in there.
new here and really green to programming, so go easy..
I discovered I have an INSERT that is failing because of a duplicate record error. I figured it out by running the query in a MySQL console with literals, where err#1062 popped up.
What I want to understand is why mysql_error() or mysql_errno() didn't catch this error in my PHP script.
Below is a generic setup of what I've done. I have a form that submits to a php file that calls data_insert()
function data_insert($var1, $var2, $var3, $var4){
$db = db_connect();
$query = "INSERT INTO exampletable (id, id_2, id_3, id_4)
VALUES ('$var1', '$var2', '$var3', '$var4')";
$result = $db->query($query);
if (!$result)
{
echo ('Database Error:' . mysql_error());
}
else
{
echo "Data added to db";
}
}
The DB connection:
function db_connect()
{
$result = new MySQLi('localhost', 'root', 'root', 'dbname');
if (!$result)
throw new Exception('Could not connect to database server');
else
return $result;
}
Result I'm getting is:
Database Error:
PHP echos "Database Error:" because the INSERT fails, but no subsequent MySQL error info is echoed. Honestly, I'm not exactly sure what I'm supposed to see, but through reading some other SO questions, I've double-checked my php.ini file for error handling and E_ALL and display_errors is set appropriately (although not sure if it matters in this case).
Is there something in my logic that I'm not understanding, like the scope of the link resource mysql_error() takes?
Thanks for your help, I'm hoping this is something embarrassingly obvious.
I know the above is missing XSS and security precautions and uniform exception handling. Baby steps though. It's simplified here for discussion's sake.
You're using mysqli (note the i) for your DB operations, but are calling mysql_error (no i). They're two completely different interfaces, and do not share internal states at at all. DB handles/results from one are not usable in the other.
Try mysqli_error() instead (note the I).
As far as I can tell, you appear to be using the MySQLi class for connecting and queries, but you're trying to access MySQL error message. MySQLi and MySQL aren't the same, so errors in one will not show in the other. You should look up error handling for MySQLi, not MySQL.
You are confusing two seperate methods for connecting to a mySQL DB.
mysql_error() will only work on queries that are run through mysql_query().
As you are using mysqli, you must use mysqli_error()