O,
it is really the bottom line where the question kicks in.. But you may want the other info afterwards like how I connected and so on to avoid misunderstandings. :)
$con = mysql_connect('localhost', 'root', '******');
if(!$con) {
die('Could not establish connection: ' . mysql_error);
}
mysql_select_db('hunkusersystem');
function user_login($username, $password) {
//Avoid SQL-injections.
$username = mysql_real_escape_string($username);
$password = md5($password);
//Match user and password
$sql = mysql_query("SELECT * FROM usersystem WHERE username = '$username' AND password = '$password' LIMIT 1", **$con**);
My question is - in the very last block of code, I can not use the resource id.. Why is that? Is it because the mysql_select_db would be "cleared"? So you stand with correct connection but no database? If I would use several connections, should I define the connection in the mysql_select_db(); ?
Thank you very much for your help :)
Greets from Swe.
It's a scope issue; the function user_login can't see $con, because it's not been passed in as a parameter or declared as a global variable.
(Please don't declare it as a global variable; it's very bad practice)
Try:
function user_login($username, $password, $con) {
The variable $con is defined in the global scope and not in the local scope of the function.
If you want to use it there, you can use:
function user_login($username, $password) {
global $con;
However, you'd better pass the variable to the function as a parameter.
The best solution would be to move to PDO / mysqli with prepared statements and use dependency injection but that's outside of the scope of your question.
Related
I am working on a login script with prepared statements in PHP procedural mysqli syntax. Here is my current code:
<?php
include "/ssincludes/functions.php";
$host = HOST;
$username = USER;
$password = PASSWORD;
$db_name = DATABASE;
$table = TABLEU;
//These includes and constants are fine I checked them all
$con = mysqli_connect($host, $username, $password, $db_name);
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$myusername='test';
$mypassword='password1';
$sql="SELECT * FROM $table WHERE user_name=? and password=?";
$result=mysqli_prepare($con, $sql);
mysqli_stmt_bind_param($result, 'ss', $myusername, $mypassword);
mysqli_execute($result);
mysqli_stmt_fetch($result);
$row_cnt = mysqli_num_rows($result);
echo $row_cnt;
?>
The error returned is: Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, object given
I thought I took out all instances of OO PHP in my script? Also I understand that this may mean my query is incorrect so I ran it on MySQL in the database and all seems to be fine there:
So I am lost as to what the problem could be. I read many similar posts (maybe I'm missing one that is exactly similar to mine) and none seem to handle the problem. I appreciate your time and help.
P.S. I understand the security issues with plain text passwords and using "password1". I plan to use better security practices as I build this but I just want to get prepared statements down first.
You should use
mysqli_stmt_execute
mysqli_stmt_num_rows
Instead of the mysqli_execute and mysqli_num_rows.
This question already has answers here:
Reference: What is variable scope, which variables are accessible from where and what are "undefined variable" errors?
(3 answers)
Closed 9 years ago.
This is code is made to return the name of a chosen $ID from the database,
#DB Informations (username/password)
require('/path/to/db_informations.php');
# This function return the 'name of the $ID from the db
function getName($ID){
$link = new PDO($dsn, $user, $pwd);
$query = "SELECT `name` FROM `tables` WHERE `id`=$ID";
$smt = $link->prepare($query);
$smt->execute();
$name = $smt->fetch(PDO::FETCH_ASSOC);
return $name['name'];
}
# db_informations contain the credentials to connect the database. ($dsn, $user, $pwd)
Mmh require(/path/to/db_informations.php') is not working inside the function even if I put `require();' function in the body. I do not understand my mistake, can you please explain me:
Why the /path/to/file is not included by PHP? and How to?
Your DB variables are not in scope of your getName() function. You need, at bare minimum:
function getName(...) {
global $dsn, $user, $pwd;
...
}
In the greater picture, you should NOT be using global variables, nor should you be creating a DB connection in every function call. Connect to the database ONCE in your db setup file, then simply re-use that connection for the rest of the DB operations in your script.
This is a variable scope issue.
$dsn, $user, $pwd are global variables and not defined within the getName() function scope.
The quickest way to resolve this is to use global.
function getName($ID) {
global $dsn, $user, $pwd;
// code...
}
However, I do not recommend using global (they are evil). The better thing to do would be to define your database object (PDO) at the global scope and pass it around to your functions/classes. This is called dependency injection.
This question already has answers here:
Reference: What is variable scope, which variables are accessible from where and what are "undefined variable" errors?
(3 answers)
Closed 2 years ago.
I have a file that corrals my re-usable functions into one file (functions.php). It's include_once()'d on every page that needs it. I'm getting an error when my custom functions are trying to access a MySQL connection outside their own scope. The source is a bit like this:
<?php
// functions.php
$connect = mysql_connect("localhost", "user", "pass") or die("MySQL said: ".mysql_error());
mysql_select_db("database", $connect) or die("MySQL said: ".mysql_error()); // no error
/* ... */
function getmotd($user) {
$query = "SELECT cid FROM `users`
WHERE id = ".$user;
$query = mysql_query($query, $connect); // error occurs here, $connect is not a valid MySQL link-resource
/* ... */
}
?>
Why can't my function access variables declared above it's scope? I can get a successful connection by reproducing $connect's declaration within the function.
Any insight into how I can work around this or what I'm doing wrong here?
You can't access $connect because it is outside the scope of the function; that is, PHP can only see the variables within the function when it's inside it. You could use the global keyword to let PHP know the variable is outside the function's scope as Kemal suggests, but I think a better course of action is to pass the connection into the function. This will give you better encapsulation. If you learn to write your functions (and later classes) with passing in the resources and data you need (a practice known as "dependency injection"), you'll find you have cleaner and more maintainable code. Here's the example:
function getmotd($db, $user) {
$query = "SELECT cid FROM users WHERE id = " . (int)$user;
$result = mysql_query($query, $db);
/.../
}
$connect = mysql_connect(...);
mysql_select_db(...);
$motd = getmotd($connect, $user);
Hope this helps.
Use the global keyword.
Example
function getmotd($user) {
global $connect;
$query = "SELECT cid FROM `users`
WHERE id = ".$user;
$query = mysql_query($query, $connect); // error occurs here, $connect is not a valid MySQL link-resource
/* ... */
}
You can also do it like this
function getmotd($user) {
$query = "SELECT cid FROM `users`
WHERE id = ".$user;
$query = mysql_query($query, $GLOBALS['connect']); // error occurs here, $connect is not a valid MySQL link-resource
/* ... */
}
If you want to make re-usable codes, you'd probably be better off with OOP. Create a class for the database, and add some properties for the database info, and access them from the functions by using the this keyword.
I'm setting up a blog type page for my business. Brand new to MySQL and PHP. Set up this login system. For some reason have no idea why the login is dropping. Suppose to check for errors then return 'good' through php if the email and password is right. If php returns good then it's suppose to redirect to the blog page.
Been dealing with this for a few months need desperate help please. Thank you.
Here is the php code that goes along with the jquery.
Link to test site is here.
test.toddprod.com/login
Would really appreciated the help.
Thanks
<?php
#fake mysql connection first
DEFINE ('DB_USER','usernamegoeshere');
DEFINE ('DB_PASSWORD','passwordhere');
DEFINE ('DB_HOST','hostnamehere');
DEFINE ('DB_NAME','andtheotherthinghere');
$dbc = mysql_connect (DB_HOST, DB_USER, DB_PASSWORD) or die ('Could not connect to MySQL');
$db = mysql_select_db(DB_NAME, $dbc) or die('Could not select database.'.mysql_error());
$e = $_POST['email'];
$pass = $_POST['pass'];
$q = 'SELECT user_id from toddprod where email="'.$e.'" and pass= SHA1("'.$pass.'")';
$r = mysql_query($db, $q);
if( mysql_num_rows($r)==1 ){
setcookie ( 'user_id', $r);
setcookie ( 'email', '$e');
setcookie ( 'logged-in', 'true');
echo 'good';
}
else if (mysql_num_rows($r)==0) {
echo 'Your '.$e.' with password '.$pass;
};
mysql_close ($db);
?>
Umm there's a number of things I see wrong here...
First of all your query should be sanitized...
$email = mysql_real_escape_string ($_POST['email']); // escape the email
$pass = SHA1(mysql_real_escape_string ($_POST['pass'])); // escape and encrypt the pass
// now you can put it into the query safely
$query = "SELECT user_id from toddprod where email = '$email' and pass = '$pass' ";
Next you're executing the query wrong, the mysql_query function takes two arguments, the query and the database connection. You're passing the wrong arguments, you're passing the query and the result of the mysql_select_db function which is just a boolean value. So you have to $dbc not $db into that query, and even then you're passing the arguments in the wrong order. The query goes first, than the connection. So it should be...
$result = mysql_query($query, $dbc);
Next you're trying to set the return value from the mysql_query function as your cookie but that value is a resource, not the userid that you need. You have to actually read the value from the resource like this.
$row = mysql_fetch_array($result);
$userid = $row["user_id"];
setcookie('user_id', $userid);
Moving on... when you're setting the email cookie, you have the variable in single quotes, so the cookie will actually contain $e and not the actual email because single quotes store strings litterly (without parsing the variables). So you should either use double quotes, or no quotes at all. So either one of the following is fine...
setcookie('email', "$e");
setcookie('email', $e);
Last but not least, you should not have the semicolon at the end of your if-statement, and you again you need to pass the connection not the database-selection result into the mysql_close function, so it should be
mysql_close($dbc);
There, hope this gets you somewhere, try out these changes and if the problem persists i'd be happy to help you further.
Here are links that will help you out:
http://www.php.net/manual/en/function.mysql-query.php
http://www.php.net/manual/en/function.mysql-fetch-array.php
http://www.php.net/manual/en/function.mysql-real-escape-string.php
Edit:
Here, I have fixed the code according to the problems I found. Try it out, I could not test it so it might have some small syntax errors here and there, but it should give you something to compare with. Also for the future, I would suggest that you name your variables semantically/properly so it's easier for others to pickup and it will also keep you from getting confused like you were passing $db instead of $dbc into a few of your functions.
<?php
// keep the function names in lowercase, no reason, just looks better to me
define('DB_USER', 'usernamegoeshere');
define('DB_PASSWORD', 'passwordhere');
define('DB_HOST', 'hostnamehere');
define('DB_NAME', 'andtheotherthinghere');
// connect to the mysql server
$conn = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD) or die ('Could not connect to MySQL');
// select the database, you don't need to store the result, it just returns true or false
mysql_select_db(DB_NAME, $conn) or die('Could not select database.' .mysql_error());
// escape the input
$email = mysql_real_escape_string($_POST['email']);
$pass = sha1(mysql_real_escape_string($_POST['pass']));
// create the query
$query = "SELECT user_id FROM toddprod WHERE email = '$email' AND pass = '$pass'";
// execute the query
$result = mysql_query($query, $conn);
$usercount = mysql_num_rows($result);
if($usercount == 1){
// read the results and get the user_id
$row = mysql_fetch_array($result);
$userid = $row['user_id'];
// set the cookies
setcookie('user_id', $userid);
setcookie('email', $email);
setcookie('logged-in', 'true');
// echo success message
echo 'good';
}elseif($usercount == 0) {
echo "You're $email with password $pass";
}
mysql_close($conn);
?>
First things first, you MUST sanitise user input with mysql_real_escape_string():
$e = mysql_real_escape_string ($_POST['email']);
$pass = mysql_real_escape_string ($_POST['pass']);
Read up a bit on SQL injection, you'll be very glad you did.
As for the main problem, could you provide a bit more context? How are you checking to see if the user is logged in?
When you open a MySQL connection with mysql_connect(), it returns a link identifier. But what if you want to get that link identifier again later in the script? (for example: A plug-in, that needs to open a new database connection, and still access the old one.)
I'm looking for a way to return a link identifier to the last connection opened by mysql_connect(). Is there a function that does this?
Even though the explanation of Anti Veeranna is correct, there is a very straight-forward way to do what you want. The docs for mysql_connect() state that this function has a 4th parameter $new_link , which is false by default. If you call mysql_connect() again with the same parameters, which is probably the case, it would not create a new connection, but instead would return the resource identifier of the old one.
Any time ;)
No, there isn't. You have to record link identifiers yourself. You could define link identifier as a class property, so that you can easily access it from your methods and don't have to worry about passing it as a variable over and over again.
Thanks to everyone for the replies.
I ended up opening my own connection, and when my plug-in was done, the last line reopens the initial connection so the rest of the main script can use the database it expects. It's sloppy, I know, but it doesn't seem like there's a better option in this case. :/
Update:: I've submitted this as a feature request on php.net. The link is: http://bugs.php.net/bug.php?id=49400
You have to store your handle in a var.
$link = mysql_connect($host, $login, $pass);
And you can reuse $link along your script, before a new HTTP request.
You either have to store the link identifier yourself as mentioned in other answers OR you can simply omit it, the mysql_* functions can reuse the existing handle
mysql_query help explains it like this:
resource mysql_query ( string $query [, resource $link_identifier ] )
link_identifier
The MySQL connection. If the link identifier is not specified, the last link opened by mysql_connect() is assumed.
I would not use that reuse behaviour myself though, unless you are completely sure that your application (or any plugins, etc) are not opening any new connections to other databases.
Use mysql_pconnect, that will do what you want.
First, when connecting, the function would first try to find a (persistent) link that's already open with the same host, username and password. If one is found, an identifier for it will be returned instead of opening a new connection.
You could also use a static or singleton class to handle connection pooling for you.
<?php
class dbConnectionPooler
{
static var $connections = array();
private static function createConnection($host, $username, $password, $db) {
$connection = mysql_pconnect($host, $username, $password);
if (FALSE !== $connection) {
$result = mysql_select_db($db, $connection);
if (FALSE !== $result) {
self::$connections[self::getConnectionHash($host, $username, $password, $db)] = $connection;
return $connection;
}
}
}
private static function getConnectionHash($host, $username, $password, $db) {
return md5($host. $username. $password. $db); // use your favourite hashing function here
}
public static function getConnection($host, $username, $password, $db) {
$connectionHash = self::getConnectionHash($host, $username, $password, $db);
if (array_key_exists($connectionHash, self::$connections)) {
return self::$connections[$connectionHash];
} else {
return self::createConnection($host, $username, $password, $db);
}
return false;
}
}
$connection = dbConnectionPooler::getConnection("dbhost", "dbuser", "dbpassword", "mydb");
?>