Hi I am new to PHP and Mysql. I need help with a logon on script I am currently writing. I have the script working fine. But I am wanting to add an additional requirement for logging in.
In the table I have:
user_id | username | password | first_name | department
-------------------------------------------------------
I am currently authenticating users by using just there username and passsword but I want to add another requirement of "department". There are two entries in the department column either "user" or "manager". I want to only allow access to a manager how can I add this in?
The mysql query i am using is:
$query = "SELECT * FROM users WHERE username='".mysql_real_escape_string($uname)."' AND password='".mysql_real_escape_string($passencrypt)."'";
Don't ever save pure passwords in db! You should use hashes or encryption.
Don't use mysql_* functions because they are depracated and will be removed in future. Use mysqli or PDO instead.
Also remember to bind parameters just changing mysql to mysqli doesn't make your scripts secure.
Adding roles as you mentioned it can be solved on 2 ways.
First is simple but not good to extend and second is better but needs more effort.
Add department as tinyint to DB with 1 = user, 2 = manager
PDO solution
$sth = $dbh->prepare('SELECT * FROM users WHERE username=? AND password=md5(?) AND department=?);
$sth->bindParam(1, $user, PDO::PARAM_STR);
$sth->bindParam(2, $pass, PDO::PARAM_STR);
$sth->bindParam(3, $department, PDO::PARAM_INT);
$sth->execute();
Read more about PDO http://www.php.net/manual/en/pdo.construct.php
Second solution is to use roles and resources. Here is good explanation of how to use it: http://framework.zend.com/manual/1.12/en/zend.acl.introduction.html
$query = "SELECT * FROM users WHERE username='".mysql_real_escape_string($uname)."' AND password='".mysql_real_escape_string($passencrypt)."'";
is okay then simply in php you just check
$row = mysql_fetch_array($result);
if($row['department']=="manager"){
//complete login
}else{
//logout
}
You could either check the value of DEPARTMENT in the resultset and take appropriate action, or filter it out of the query altogether. This will do that:
$query = "SELECT * FROM users WHERE department='manager' AND username='".mysql_real_escape_string($uname)."' AND password='".mysql_real_escape_string($passencrypt)."'";
But keep in mind that that means you are not making any distinction between a non-existent user, an incorrect password, or a user who is not a manager.
You just need to add an extra clause to your WHERE
$query = "SELECT * FROM users WHERE username='".mysql_real_escape_string($uname)."' AND password='".mysql_real_escape_string($passencrypt)."' AND delartment = 'manager'";
In this way only member wich have department as manager will be matched by your query
Then I would like to remember you that mysql_ functions are deprecated so i would advise you to switch to mysqli or PDO
you can do this:
if (isset($_POST['manager']))
{
$query = "SELECT * FROM users WHERE username = '$uname' AND password = '$passencrypt'";
}
elseif (isset($_POST['user'])
{...}
of course you will have to replace the three dots within the last pair of braces with whatever you want to do when it is not the manager who signs in.
Related
I have a DB that I created using MYSQL workbench. I was later given access to MyphpAdmin. I was not able to connect to the DB created by Workbench while using MyPhpAdmin.
I then created the same DB using MyPhpAdmin, but now my code, (PHP) cannot locate the DB created by MyPhpAdmin.
I would rather use the DB created by MyPhpAdmin, so what do I need to do to connect to the MyPhpAdmin DB. They are both located on the same server and I am using XAMPP/Apache
Thanks.
Don "Ho"
You can use PDO for that :
$pdo = new PDO('mysql:host=localhost;dbname=mydb;port=3306', 'user', 'pass');
and then use that to make requests :
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND status=?');
$stmt->execute([$email, $status]);
$user = $stmt->fetch();
for fetching multiple rows :
$stmt = $pdo->prepare("SELECT * FROM table WHERE name LIKE ?");
$stmt->execute([$search]);
$data = $stmt->fetchAll();
and if there is no parameter you can just use query :
$stmt = $pdo->query('SELECT name FROM users');
check out the documentation for pdo, there is a lot more functions, like rowCount and so on
I am working on a Symfony 2.7 webapp that uses the FOSUserBundle. Everything works fine so far. Not I would like to add an Admin Backend, that allow to show details about different Users.
For example in a Phone Book App, on should be able to see how many contacts a selected user has created:
$contact_count = $this->contactsCountForUser(5);
...
public function contactsCountForUser($user_id) {
$repo = $this->em->getRepository('AppBundle:Contact');
$qb = $repo->createQueryBuilder('c');
$qb->select('COUNT(c)');
$qb->where('c.user = :userId');
$qb->setParameter('userId', $user_id);
$sql = $qb->getQuery()->getSql();
$count = $qb->getQuery()->getSingleScalarResult();
return $count;
}
This fails, since the following is created as SQL query:
SELECT COUNT(c0_.guid) AS sclr0 FROM contact c0_ WHERE (c0_.user_id = ?) AND (c0_.user_id = '1')
Problem 1:
Why is $qb->where('c.user = :userId') being translated to c0_.user_id = ?? Why isn't 5 beeing used as user_id?
Problem 2:
AND (c0_.user_id = '1') is automatically added to the query. I assume this is done by the FOSUserBundle which limits the query to the current user. Here ID 1 is the ID of the currently logged in user, which is the Admin... Obviously (c0_.user_id = ?) AND (c0_.user_id = '1') can never be true.
So: How do I convince Doctrine and/or the FOSUserBundle, that the admin should be able to execute queries on other users data?
Thanks to the comment of #LBA, I was able to find the source of the problem:
A piece of third-party code add an SQLFilter as UserAware annotation. This webpage describes in detail what is done and how it works.
Maybe this can help others to avoid this kind of "problem" and to figure out what is "wrong" :-)
About Problem 1: Even after solving Problem 2, Problem 1 is still the same. The userId is still translated to ? within the query. However this does not seem to influence the function of the code. As far as I can see everything is working as expected.
I'm creating a PHP Webapplication which uses 8 classes (more to come). I realized that all of those classes have pretty much the same functions to access the database: A get_single, a get_list, an insert, update and delete.
Which database table is addressed and which fields are selected is different for every class of course.
For example:
function get_single($conn) {
$sql = $conn->prepare('SELECT id_person, join_date, img_profile, img_header, firstname, familyname, nationality, mail, password, birthday FROM person WHERE id_person = ?');
$sql->bind_param('i', $this->id);
$sql->execute();
$sql->bind_result($this->id, $this->join_date, $this->profile_img, $this->header_img, $this->firstname, $this->familyname, $this->nationality, $this->mail, $this->password, $this->birthday);
$sql->fetch();
return $this;
}
I asked myself if I could or should write a single function for all the classes, something like this:
function get_single($id, $conn, $query) {
$sql = $conn->prepare($query);
$sql->bind_param('i', $id);
$sql->execute();
$sql->bind_result(/* ??? */);
$sql->fetch();
return /* ??? */ ;
}
... and then call
$foo = new Foo(array('id' => $bar));
$foo = get_single($foo->id, $conn, $qry_single_foo);
This way I could
store all the SQL queries centrally
reduce the overall amount of code
increase readability... maybe?
Or should I have a parent class which those classes inherit from?
Or use a design pattern? Maybe the decorator? (Sorry my knowledge there is quite inexistent)
Now that I realized that it might be easier to do it differently I'm a bit overwhelmed by the possibilities.
Ideas?
Thanks
You can use a web MVC framework or ORM library.
Please check some ORM libraries you can integrate with your application.
ORM
Doctrine
Propel
PHP Activerecord
I'm making a WordPress plugin and I need to update tables for the current database in a query. However, instead of writing the database name into the sql, I need some way to select it in the query so that way it will work no matter what your database's name is. This is the code I currently have:
$stmt = $conn->prepare("UPDATE `wp_plugin_development` . `wp_users` SET `user_pass` = ? WHERE `user_login` = ?") or trigger_error($mysqli->error);
$stmt->bind_param('ss', $user_password[$i], $user_login[$i]);
wp_plugin_development is my current database name, but needs to be replaced with some other way of selecting the database name. I wish I could write something like UPDATE SELECT DATABASE() but that obviously doesn't work. Maybe there's an entirely different way to code this? I still consider myself new to all this, so I'm sorry if I'm missing something obvious. Any help is greatly appreciated.
You don't need the current database name, because the connection is already established with the current database.
You need the tablename! The prefix is set when setting up wordpress. You need the prefix, because every installation is different.
The proper Wordpress way is like this:
global $wpdb;
$table_name = $wpdb->prefix . 'plugin_development';
The prefix is stored (wp_). In WP; you don't use PDO or MySqli directly, you work with the global $wpdb object.
$wpdb->update($table_name, $data, $where, $format = null, $where_format = null);
If you really need the database name, it's stored in $wpdb->dbname;.
Here are examples and the class reference:
https://codex.wordpress.org/Class_Reference/wpdb
I was using another database as the connection method (this was defined in the $conn variable). So I made a new connection to the current database using $wpdb and named it $this_db. Now I don't have to specify the database name in the query and it works like I want it to. For better context, here's the code I added/changed:
$thisServername = $wpdb->dbhost;
$thisUsername = $wpdb->dbuser;
$thisPassword = $wpdb->dbpassword;
$thisDBname = $wpdb->dbname;
$this_db = new mysqli($thisServername, $thisUsername, $thisPassword, $thisDBname);
$stmt = $this_db->prepare("UPDATE `wp_users` SET `user_pass` = ? WHERE `user_login` = ?") or trigger_error($mysqli->error);
$stmt->bind_param('ss', $user_password[$i], $user_login[$i]);
So, for solving this specific issue, this solution works. Sorry I forgot to mention using the external database. That was an important thing I left out of the question. And thank you everyone for your input.
The function database() returns the DB name - http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_database -
so you can run SELECT DATABASE(); first to get the DB name.
Hopefully a simple question.
error_reporting(E_ALL);
ini_set('display_errors', '1');
$c = oci_connect('whatmyusrnameis', 'whatmypwdis', 'host');
if ($c) {
echo 'connection';
}
$s = oci_parse($c, 'select * from mantis_bug_table');
oci_execute($s);
The following results in
Warning oci_execute(): ORA-00942: table or view does not exist
but the connection doesn't result in any errors and the DB table does exist and it is not empty.
Any ideas??? Thank you :).
Typically this has one of four possible problems
You're not connecting to the database you think you are (probably not the case)
You don't have permission to the table (See Justin Cave's answer regarding Grant)
You may need to add the owner to the table name e.g. select * from DB_USER.mantis_bug_table (See Justin Cave's answer regarding SYNONYMs if you don't want qualify the tablename)
The table really doesn't exist perhaps a spelling error
You can diagnose this by running the following
SELECT * FROM ALL_TABLES WHERE UPPER(table_name) = 'MANTIS_BUG_TABLE'
What Oracle user owns the table?
Does the Oracle user that your PHP script connects as have access to this table?
Is there a public or private synonym for the MANTIS_BUG_TABLE table?
If the table is owned by some other user, you could try fully qualifying the table name
$s = oci_parse($c, 'select * from owner_of_table.mantis_bug_table');
If the user your PHP script is using doesn't have access to the table, you'll need a DBA or the owner of the table to
GRANT SELECT ON owner_of_table.mantis_bug_table
TO whatmyusernameis;
If you have access to the table and fully qualifying the table name works but you don't want to have to fully qualify the table name every time, you can create a synonym
CREATE [PUBLIC] SYNONYM mantis_bug_table
FOR owner_of_table.mantis_bug_table
A public synonym allows all users with access to the table to reference it without using a fully qualified name. A private synonym allows just the owner of the synonym (i.e. whatmyusernameis) to reference the table without a fully qualified table name.
You should point scheme in connection string like:
oci_connect('whatmyusrnameis', 'whatmypwdis', 'host/**YOUR_DB**');
Look at http://www.php.net/manual/en/function.oci-connect.php in section connection_string