I have two MySQL tables. The first one is for the user's credentials i.e. username, password, business_id (system generated). The second one has the user's profile for multiple entities e.g. business name, location, profile_id and business id (system genrated - the same number for the business_id).
The user can edit the details of their business details i.e. their details in the second table. The business id would be say 'abcdef' and profile id would be say 1234567, if they have a second business profile it would be say 1235879.
In order to edit each profile I would have to have the following URL
Edit Business Profile
For the second one it would be
Edit Business Profile
In turn when the a href is clicked the url in the browser would be edit_profile.php?id=1234567 and for the second one would be edit_profile.php?id=1235879
Would it be possible that instead of having edit_profile.php?id=1234567 and edit_profile.php?id=1235879 in the URL I would have edit_profile.php?id=1234567 and for the second one would be edit_profile.php
I don't want the User to see the id i.e. have only edit_profile.php
Ideally, I would like to use a PHP solution, please.
Yes, it is possible, but not exactly what are you trying to do
Solution #1
Intoduction
First of all, it should work only on users who are currently logged in and are trying to see their profile. The final results to reach is to not display ID in URL if ID is equal to current logged user's ID. It is more common than Solution #2 but if you want to hide all IDs, skip this solution.
Pluses:
There is not too much to change, just add a few more lines for checking current user ID
You can still use <a></a> tags for Edit Business Profile links.
Minuses:
Only current logged user's ID will be hidden in the URL
So what to do...
You probably use sessions to let users remain logged in even if they refreshed the page. You are on the right path, but you should add at least one more element to $_SESSION (Profile identification, so we can call it as profile_id for example).
Assume you are using this login formula:
function check_login($username, $password)
{
// query to find user with these inputs (encrypted password, prepared statements, etc)
if($query->num_rows > 0) // user exists
{
// fetch your query
// ...
session_start();
// set the session probably user is logged
// some return on success (probably redirect)
}
else
{
// some return on false
}
}
Now you should add one more $_SESSION element to save your current profile_id value:
session_start();
// ...
$_SESSION['profile_id'] = $result->profile_id; // <--- THIS IMPLEMENT
// some return on success (probably redirect)
1/2 is done!
Half of the problem is already finished, now all you need to do is compare $_GET input with $_SESSION.
Again, assuming your edit_profile.php file looks like this:
if(isset($_GET['id']) && !empty(trim($_GET['id'])))
{
$profile_id = intval($_GET['id']);
// ...
}
else
{
// probably an error profile id is not defined
}
// rest of the code ...
So now instead of error profile id is not defined we can assign to $profile_id variable index profile_id of superglobal $_SESSION:
else
{
$profile_id = intval($_SESSION['profile_id']);
}
Notice that I am assuming you have condition to reject access to this script, if user is not logged (some condition at the start).
Now your code should work but maybe you are asking the question what if user knows his ID and types it into URL?
So you have two choices:
Let it be as it is
Add condition to check if $_GET['id'] equals to $_SESSION['profile_id'] then redirect to edit_profile.php
Final thoughts...
Maybe if you are generating the list of the users, where the user can edit the others' users profiles including himself's, you want to remove id parameter of the edit_profile.php URL if the user's ID is equal to current ID in fetch loop. You can inspire by this simple function:
function generate_profile_edit_url($id)
{
session_start(); // for the case, you don't have started session yet
return 'Edit Business Profile';
}
Just in every fetch iteration you will use this function, like in the example below:
// ...
echo generate_profile_edit_url($result->profile_id);
// ...
Solution #2
Introduction
This solution will reach to the editing user's profile without any ID parameter in URL. It is designed for situation where user has rights to edit someone else's profile (for example, a moderator or an admin) and you still don't want to have the users' ID in the URL.
Pluses:
No ID parameter in URL needed for all users
Minuses:
you have to change every profile link to little form using POST action without JavaScript knowledge
no more <a></a> links for profile edit, again without JavaScript knowledge
users are still able to get their id if they want to
So what to do...
Firstly, we need to change edit_profile.php file. We have to recieve $_POST data containing target's profile_id.
Like in Solution #1, assume your edit_profile.php looks like:
if(isSet($_GET['id']) && !empty(trim($_GET['id'])))
{
$profile_id = intval($_GET['id']);
// ...
}
else
{
// probably an error profile id is not defined
}
// rest of the code ...
Most of the changes will be just replacing $_GET with $_POST:
if(isSet($_POST['profile_id']) && !empty(trim($_POST['profile_id'])))
{
$profile_id = intval($_POST['profile_id']);
// ...
}
else
{
// probably an error profile id is not defined
}
// rest of the code ...
For this file, it is enough.
Now there is some more work to do if you have a placed profile links in different files. But we can make it easier using one simple function like this:
function get_profile_edit_button($profile_id)
{
$html = '<form action="edit_profile" method="POST">';
$html .= '<input type="hidden" name="profile_id" value="' . intval($profile_id) . '">';
$html .= '<input type="submit" value="Edit Business profile">';
$html .= '</form>';
return $html;
}
The last thing is replace current edit profile links with this function. For example you have fetch loop of users:
// ...
echo 'Edit Business Profile';
// ...
So you will replace this string with your function get_profile_edit_button():
// ...
echo get_profile_edit_button($result->profile_id);
// ...
Final thoughts...
As I mentioned in minuses, profiles' ids cannot be totally hidden. If someone opened Source code of your page, he can see profile_id in hidden form type:
<input type="hidden" name="profile_id" value="1234567">
It is only on you what solution you prefer, but I can recommend you Solution #1. There is nothing bad about having IDs in URL. Stack Overflow has it too as you can see it on questions, answers, comments and users.
Useful resources:
PHP Session Security
PHP form token usage and handling
When logging in, try saving the user ID and business ID inside session.
As for example..
$logged_in = some_logic_stuffs();
if($logged_in){
session_start();
$_SESSION['user_id'] = SOME_ID_FETCHED_FROM_LOGIN_LOGIC;
$_SESSION['business_id'] = SOME_ID_FETCHED_FROM_LOGIN_LOGIC;
}
Now, when user goes to edit_profile.php, do
session_start();
$business_id = $_SESSION['business_id'];
$user_id = $_SESSION['business_id'];
For the login logic, try reading this tutorial:
http://www.formget.com/login-form-in-php/
If the user can edit multiple business profiles, the $_SESSION solutions would not work. You would need to disguise what gets sent to the address bar:
You would need to change your code to POST the data rather than sending it as a GET request.
To do this you could either use JavaScript to fake a form post on the link click, or wrap your link in a form tag and set method="POST".
POST sends the data "behind the scenes" rather than exposing it in the browser. I should add that this would still be visible to anyone wanting to discover your IDs, but it would hide it from the casual user at least.
If you really wanted security, #BobBrown's suggestion to tokenise would be a great way forward. You may find, however, that just hiding the ID from display on-screen is enough. Just make sure your user management system will restrict who can edit a particular business.
Try this
<?php
session_start();
include('dbconnect.php');
if(isset($_SESSION['username']))
{
$username = $_SESSION['username'];
$userid = $_SESSION['id'];
}
else
{
$_SESSION['id'] = "";
$_SESSION['username'] = "";
}
if($username <> "")
{
$username = 'username';
$userid = 'id';
}
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 900))
{
// last request was more than 30 minutes ago
session_unset(); // unset $_SESSION variable for the run-time
session_destroy(); // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp
?>
then
<?php
#if the form is set (meaning that the information was submitted then define what the parameters are for each
if(isset($_REQUEST['username']) == TRUE)
{
$username = $_REQUEST['username'];
$password = $_REQUEST['password'];
#make sure there are no blank fields
if($username == "" OR $password == "")
{
echo '<p class="text-danger">Please enter a Username and Password</p>';
}
else
{
$userid = finduser($username, $password);
if($userid > 0)
{
loginuser($userid);
}
else
{
echo '<p class="lead text-danger">The Username and/or Password enter is incorrect</p><br />';
}
}
}
?>
after that then this
<?php
if(isset($_SESSION['username']))
{
if($_SESSION['username'] <> "")
{
//do something
}
else{
//form or something else
?>
<form>form goes here</form>
<p> or something else you want</p>
<?php
}
}
?>
Start your PHP with session_start(); then when the user logs in make a session value for the ID:
$_SESSION['profile-id'] = 1235879; //Select it from database
after in your edit_profile.php do that:
if (!isset($id)) {
$id = $_SESSION['profile-id'];
}
And then edit the $id.
Store the id in session on the first page:
$_SESSION['id'] = 12345;
And on edit_profile.php you can get the value by:
$id = $_SESSION['id'];
And start the session on every page by session_start();
Easiest and simplest way to handle your situation if you want to use Id or any information in URL and pass it through URL
then you can have a scret combination with your values like below
Firt you have to encode the value with your secret stuff for example
$sshhh="ITSMY_SECRET_VALUECODE";
$encrypted_id = base64_encode($your_value . $sshhh);
Then pass it (encrpyted_id) in URL
for example href="all-jvouchers.php?id=<?= $encrypted_id; ?>
and while getting value use below code to get back your value
$sshhh="ITSMY_SECRET_VALUECODE";
$decrypted_id_raw = base64_decode($_GET['id']);
$decrypted_id = preg_replace(sprintf('/%s/', $sshhh), '', $decrypted_id_raw);
Use $decrypted_id wherever and however you want to securely
Related
I would like to implement multiple user login show like gmail login. See below image:
Current I'm using COOKIE to get the USERID. But it only give me the last USERID. not all.
Here is PHP to set COOKIE:
setcookie("cookielogin[userLoginRemembered]", $dataLoginQuery['USERID'] , $time + (60*60*24*7));
What I want is, to show all user ever logged in and display it using COOKIE.
Is it possible?
Because you only store last logged user id into cookie, and it overrides old value
Cookie only stores raw text, so if you want to store a list (array), you have to serialize it (by your own way or using serialize() function). This
sample code below uses PHP's serialize():
$lastLoggedUserId = '123';
if (!isset($_COOKIE['cookie_key_for_logged_users'])) {
$cookieLoggedUserIds = [$lastLoggedUserId];
} else {
// unserialize
$cookieLoggedUserIds = (array) unserialize($_COOKIE['cookie_key_for_logged_users']);
$cookieLoggedUserIds[] = $lastLoggedUserId;
}
// just to make sure no duplicated user id to be stored
$cookieLoggedUserIds = array_unique($cookieLoggedUserIds);
setcookie('cookie_key_for_logged_users', serialize($cookieLoggedUserIds));
print_r(unserialize($_COOKIE['cookie_key_for_logged_users']));
I've not tested this code, but it's easy to test and tweak.
You need to append the information in the cookie.
There is no append for cookies so what we need to do is read it's current value, add current string and write a new cookie.
$currentvalue = $_COOKIE["cookielogin[userLoginRemembered]"];
If(strpos($currentvalue, $dataLoginQuery['USERID']) !== false){
Echo "username exist in cookie already";
}else{
setcookie("cookielogin[userLoginRemembered]", $currentvalue .",". $dataLoginQuery['USERID'] , $time + (60*60*24*7));
//Here I set the value of cookie as current value and dataloginquery.
}
Output:
Var_dump(explode(",", $_COOKIE["cookielogin[userLoginRemembered]"]));
// Dumps the array of usernames that is comma separated.
While I refresh my browser the entries of the registration form goes into the Database every time i press REFRESH, Professor told me to resolve this problem with the help of LAST_INSERT_ID().
I am able to get the last_insert_id from the database but doesn't know what would I do further with that ID.
Please help..
enter image description here
The recommended way is to use the Post/Redirect/Get pattern.
There are other ways to achieve what you desire here.
I am not sure what your professor is asking to do with the last insert id. Maybe he is referring to something like this,
if(isset($_SESSION['last_insert_id'])){ // At the beggining
//redirect to a another location
}
// Code for insertion goes here
$_SESSION['last_insert_id'] = $last_insert_id; // Get and store the insertion id as a session
I think you are using the same page to Save the Data, If it is So, then follow the following method :
<?php
if(isset($_POST[userName]))
{
// Put your Registration Operation Code Here
header('Location: ./Registrationform.php');
}
?>
After DataBase Insertion it redirects to the same page. Now Refresh is made with the GET Method not by the POST Method. So, you can eliminate the duplicate entries by this way.
As per your requirement I used the Last Inserted ID for the Validation before Inserting Records in the Database.
<?php
session_start();
if(isset($_POST[userID]))
{
$flag = false;
if(isset($_SESSION['last_insert_id']))
{
if($_SESSION['last_insert_id'] == $_POST[userID])
{
$flag = false;
header('Location: ./Registrationform.php');
}
else
{
$flag = true;
$_SESSION['last_insert_id'] = $_POST[userID];
}
}
if($flag == true)
{
// Put your Registration Operation Code Here
}
}
?>
I'm aware that this topic has been covered before here on Stack, and I have looked at some answers, but I'm still a bit stuck, being fairly new to PHP. Every page on my website requires a login, and so users are redirected to a login page on page load. At the top of each page then I have:
<?
require("log.php");
include_once("config.php");
include_once("functions.php");
?>
This redirects the user to log.php (with new code added):
<?
session_name("MyLogin");
session_start();
if(isset($_SESSION['url']))
$url = $_SESSION['url']; // holds url for last page visited.
else
$url = "index.php"; // default page for
if($_GET['action'] == "login") {
$conn = mysql_connect("localhost","",""); // your MySQL connection data
$db = mysql_select_db(""); //put your database name in here
$name = $_POST['user'];
$q_user = mysql_query("SELECT * FROM users WHERE login='$name'");
if (!$q_user) {
die(mysql_error());
}
if(mysql_num_rows($q_user) == 1) {
$query = mysql_query("SELECT * FROM users WHERE login='$name'");
$data = mysql_fetch_array($query);
if($_POST['pwd'] == $data['password']) {
$_SESSION["name"] = $name;
header("Location: http://monthlymixup.com/$url"); // success page. put the URL you want
exit;
} else {
header("Location: login.php?login=failed&cause=".urlencode('Wrong Password'));
exit;
}
} else {
header("Location: login.php?login=failed&cause=".urlencode('Invalid User'));
exit;
}
}
// if the session is not registered
if(session_is_registered("name") == false) {
header("Location: login.php");
}
?>
The login form is contained in login.php. The code for login.pho relevant to the PHP/log.php is:
<?
session_start();
if($_GET['login'] == "failed") {
print $_GET['cause'];
}
?>
and
<form name="login_form" id="form" method="post" action="log.php?action=login">
The answer that I came across stated that I should add:
session_start(); // starts the session
$_SESSION['url'] = $_SERVER['REQUEST_URI'];
to the top of each page, which I did, at the top of the page (above "require("log.php");"), and then add:
if(isset($_SESSION['url']))
$url = $_SESSION['url']; // holds url for last page visited.
else
$url = "index.php"; // default page for
to my login page, and use the following URL for redirect on successful login:
header("Location: http://example.com/$url"); // perform correct redirect.
I am not 100% where the code which stores the referring URL should go, at the top of log.php or login.php.
I have tried adding it to both, but the login page is just looping once I have entered the username and password.
I wonder if someone could help me get this working?
Thanks,
Nick
It appears that I don't have the privilege to comment on your post, so I'll do the best that I can to answer. I apologize for all of the scenarios, I'm just doing the best I can to answer on a whim.
SCENARIO 1:
If you've truly not selected a database in your code, as demonstrated here, could that potentially be your issue? Please do note, that the code below, is the code you've posted.
$db = mysql_select_db(""); //put your database name in here
SCENARIO 2:
The code below is not something I've ever used in anything I've built, might I suggest that you try replacing that line of code with the line below it?
if(session_is_registered("name") == false) { // Current
if(isset($_SESSION['name']) == false) { // Potential Replacement
SCENARIO 3:
If you're logic for the following, exists on the login.php file as well... That could potentially be your problem. Upon visiting your site, I noticed your form appears on login.php, yet your logic is posting to log.php. I'm hoping this bit of code can help rule out that "jump", as login.php might be saving itself and overwriting the $_SESSION variable you've established
session_start(); // starts the session
$_SESSION['url'] = $_SERVER['REQUEST_URI'];
If it's too complex to take it out of the login.php file, if you even have it there, I've put together some code that you can use to create "internal" breadcrumbs, so you can go 2 pages back in your history.
if(!isset($_SESSION['internal_breadcrumbs']))
$_SESSION['internal_breadcrumbs'] = array();
$_SESSION['internal_breadcrumbs'][] = $_SERVER['REQUEST_URI'];
$max_breadcrumbs = 5;
while(count($_SESSION['internal_breadcrumbs']) > $max_breadcrumbs)
array_shift($_SESSION['internal_breadcrumbs']);
That will create an array with a max of $max_breadcrumbs elements, with your most recent page at the end, like the following
Array
(
[internal_breadcrumbs] => Array
(
[0] => /other_page.php
[1] => /other_page.php
[2] => /other_page.php
[3] => /user_page.php <-- desired page
[4] => /login.php <-- most recent page
)
)
So now... you can setup your url to be something more like the following...
// I'm doing - 2 to accommodate for zero indexing, to get 1 from the current page
if(isset($_SESSION['internal_breadcrumbs']))
$url = $_SESSION['internal_breadcrumbs'][count($_SESSION['internal_breadcrumbs']) - 2];
else
$url = "index.php"; // default page for
All the best, and I certainly hope this has helped in some way.
IN SCENARIO 4
From the client test the login/password which ajax XMLHttpRequest with javascript code to a dedicated script for validation (do it on mode https for secure)
If response is right send the login password to your script server.
Stips : Encoding password is better secure !
Using header() function it's a bad idea.
Manual specification say ;
Remember that header() must be called before any actual output is
sent, either by normal HTML tags, blank lines in a file, or from PHP.
It is a very common error to read code with include, or require,
functions, or another file access function, and have spaces or empty
lines that are output before header() is called. The same problem
exists when using a single PHP/HTML file.
So in your case, i suggest that to use cookies with an ID generate only for the session, at the first connection its generate, and the duration of the cookie maybe for only from 2 to 10 minutes.
Regenerate cookie each time the loging.PHP is called !
Have a nice day
I've been searching about deleting db entries in Codeigniter and I finally created a solution that I think is secure. I would really appreciate any feedback! I'm not sure if I'm doing this right..
Advantages:
Uses POST request
ID of entry to be deleted is
validated
Uses CSRF protection (automatically
generated by Codeigniter)
In my example I'm deleting user submitted links (a DB table row contains a link title, link URL, an link description).
HTML: Database entires are contained within a form. Each entry has a form button with the respective link id in the id attribute.
<?php echo form_open('profile/remove_link'); ?>
<?php echo form_hidden('link_id', ''); //value will be populated via jquery ?>
<ul id="user_links">
<?php foreach($query as $row): ?>
<li><?php echo $row->link_title; ?></li>
<li><?php echo auto_link($row->link_url, 'url', TRUE); ?></li>
<li><?php echo $row->link_description; ?></li>
<button type="submit" class="remove" id="<?php echo $row->link_id ?>" value="remove">Remove Link</button>
<?php endforeach; ?>
</ul>
</form>
JQUERY: When user clicks on the remove button, the respective link id is added to the the hidden text input named link_id.
$(document).ready(function(){
$('.remove').click(function() {
var link_to_remove = $(this).attr("id");
$("input[name=link_id]").val(link_to_remove);
});
});
Upon clicking a remove button, it sends the id of link to be removed to controller profile and function remove_link
function remove_link()
{
$this->load->model('Profile_model');
$links_data['query'] = $this->Profile_model->links_read(); //get links from db to add in view
//Validation
$this->form_validation->set_rules('link_id', 'Link ID', 'trim|required|xss_clean|max_length[11]|numeric'); //validate link id
if ($this->form_validation->run() == FALSE) //if validation rules fail
{
$this->load->view('profile/edit_links_view', $links_data);
}
else //success
{
$link_id = $this->input->post('link_id'); //get id of link to be deleted
$seg = 'user_links'; //used to redirect back to user links page
$this->Profile_model->links_delete($link_id, $seg); //send link id to model function
}
}
MODEL
function links_delete($link_id, $seg)
{
$this->db->where('user_id', $this->tank_auth->get_user_id());
$this->db->where('link_id', $link_id);
$this->db->delete('user_links');
redirect("/profile/$seg/");
}
If the ids are unique integers in your database, you could remove these rules:
trim|xss_clean|numeric
And add this one:
is_natural_no_zero
Returns FALSE if the form element contains anything other than a natural number, but not zero: 1, 2, 3, etc.
The numeric rule allows some characters you probably don't want, like decimals and negative. Here's the source (one line):
return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);
If for some reason you are echo'ing the input back in your HTML output before validating, or are just paranoid, then by all means: xss_clean it up. Otherwise it's not really needed, as I don't think there's any possible method of XSS attacks that only use a number.
Reference:
https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29
http://ha.ckers.org/xss.html
Also, you might want to add a LIMIT 1 clause to your query, and definitely make sure to return a value (probably TRUE/FALSE) from your model so you know whether or not the query was successful, so you can give feedback to the user instead of assuming everything went well.
The only thing that I see wrong is that you don't validate who can and can't delete records. That's the only issue you should focus on. Permissions to check if the person sending the request of deletion is allowed to perform such operations. Other than that it's just a matter of preference.
I would suggest rewriting controller and model a bit to make the flow more logical and provide better performance:
controller:
function remove_link()
{
if ($this->input->post('link_id'))
{
//Validation
$this->form_validation->set_rules('link_id', 'Link ID', 'is_natural_no_zero');
if ($this->form_validation->run())
{
$seg = 'user_links'; //do you really need to assign it to variable ??
$this->load->model('Profile_model');
if ($this->Profile_model->links_delete($this->input->post('link_id')) //send link id to model function
{
redirect('/profile/user_links'); // redirect user in controller and only when model returns true
}else{
// inform user about error somehow, eg. by setting session flashdata and redirecting back to /profile/user_links
}
}
} // else statement here was a mistake as in case of form_validation failure nothing happened
$this->load->model('Profile_model');
$links_data['query'] = $this->Profile_model->links_read(); //get links from db to add in view
$this->load->view('profile/edit_links_view', $links_data);
}
model:
function links_delete($link_id)
{
$this->db->where('user_id', $this->tank_auth->get_user_id())
->where('link_id', $link_id)
->delete('user_links'); // you can chain methods without writing always $this->db->
return $this->db->affected_rows(); // returns 1 ( == true) if successfuly deleted
}
And as a side note in your jQuery code I suggest using $('#some_id') instead of $('input[name=XXXX]') - it saves some javascript code execution thus is faster
To practice PHP and MySQL development, I am attempting to create the user registration system for an online chess game.
What are the best practices for:
How I should handle the (likely) possibility that when a user tries to register, the username he has chosen is already in use, particularly when it comes to function return values? Should I make a separate SELECT query before the INSERT query?
How to handle varying page titles?($gPageTitle = '...'; require_once 'bgsheader.php'; is rather ugly)
(An excerpt of the code I have written so far is in the history.)
Do a separate SELECT to check whether the username is already in use before attempting to INSERT.
More importantly, I would suggest something like the following structure for the script you're writing. It has a strong separation of presentation logic (e.g. HTML) from your other processing (e.g. validation, database, business logic.) This is one important aspect of the model-view-controller paradigm and is generally considered a best-practice.
<?php
// The default state of the form is incomplete with no errors.
$title = "Registration";
$form_completed = false;
$errors = array();
// If the user is submitting the form ..
if ($_POST) {
// Validate the input.
// This includes checking if the username is taken.
$errors = validate_registration_form($_POST);
// If there are no errors.
if (!count($errors)) {
// Add the user.
add_user($_POST['username'], $_POST['password']);
// The user has completed.
$form_completed = true;
// Optionally you could redirect to another page here.
} else {
// Update the page title.
$title = "Registration, again!"
}
}
?>
<html>
<head>
<title>Great Site: <?= $title ?></title>
<body>
<?php if ($form_complete): ?>
<p>Thanks for registering!</p>
<?php else: ?>
<?php if (count($errors)): ?>
<ul>
<?php foreach ($errors as $error): ?>
<li><?= $error ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<form method="post">
Username: <input type="text" name="username">
Password: <input type="password" name="password">
<input type="submit">
</form>
<?php endif; ?>
</body>
</html>
Well, one thing you can do instead of repeating code down near the bottom is this:
if( $result === true ) {
$gPageTitle = 'Registration successful';
$response = <p>You have successfully registered as ' . htmlspecialchars( $username ) . ' on this site.</p>';
} elseif( $result == 'exists' ) {
$gPageTitle = 'Username already taken';
$response = '<p>Someone is already using the username you have chosen. Please try using another one instead.</p>';
} else {
trigger_error('This should never happen');
}
require_once 'bgsheader.php';
echo $response;
require_once 'bgsfooter.php';
Also, you can return false rather than the string 'exists' in the function, not that it makes much difference.
Checking the error number isn't bad, I'm sure that's why it's an included feature. If you really wanted to do something different, you could check if there already is a user by that name by selecting the username. If no result exists, then insert the user, otherwise, give the error.
One thing I like to do with error handling on forms is save all the error strings into an array like $error['username'], $error['email'], etc., and then have it run through the error checking on each input individually to set all the error strings, and then have a function that does something like this:
function error($field)
{
global $error;
if(isset($error[$field]))
{
echo $error[$field];
}
}
and then call that after each field in the form to give error reporting on the form. Of course, the form page must submit to itself, but you could have all the error checking logic in a separate file and do an include if $_POST['whatever'] is set. If your form is formatted in a table or whatever, you could even do something like echo '<tr><td class="error">' . $error[$field] . '</td></tr>, and automatically insert another row directly below the field to hold the error if there is one.
Also, always remember to filter your inputs, even if it should be filtered automatically. Never pass post info directly into a DB without checking it out. I'd also suggest using the specific superglobal variable for the action, like $_POST rather than $_REQUEST, because $_REQUEST contains $_GET, $_POST, and $_COOKIE variables, and someone could feasibly do something strange like submit to the page with ?username=whatever after the page, and then you have both $_POST['username'] and $_GET['username'], and I'm not sure how $_REQUEST would handle that. Probably would make there be a $_REQUEST['username'][0] and $_REQUEST['username'][1].
Also, a bit about the page titles. Don't know if you have it set up like this but you can do something like this in your header:
$pageTitle = "My Website";
if(isset($gPageTitle))
{
$pageTitle .= "- $gPageTitle";
}
echo "<title>$pageTitle</title>";
Which would make the page load normally with "My Website" as the title, and append "- Username already exists" or whatever for "My Website - Username already exists" as the title when $gPageTitle is set.
I think the answer from Mr. Neigyl would require a separate trip to the database, which is not a good idea because it would only add performance overhead to yuor app.
I am not a PHP guru, but I know my way around it, although I don't recall the === operator. == I remember.
You could pass the function call directly into the IF statement.
if (addUser($username, $passwd));
I don't see anything wrong with using the $gPageTitle variable, but you will probably have to declare it "global" first and then use namespaces so you can actually access it within the "header.php" because "header.php" will not know how to address this page's variables.
Although I personally don't like messing with namespaces and I would rather call a function from the "header.php" and pass the page title into it
display_title($pgTitle);
or
display_title("Registration Successfull");
or
$header->display_title("Registration Successfull")
if you like OO style better
Let me know if that helps. :)
You should get into forms and allow your page to redirect to another page where you have there the 'insert username to database'.
Suppose the username entered is in a post variable such as $_POST['username'].
Have your database check where that username exist:
$res = mysql_query("SELECT * FROM table WHERE username='$_POST['username']'") or die(mysql_error());
if(mysql_num_rows($res) > 0) {
echo "Username exists.";
// more code to handle username exist
} else {
// ok here.
}
What is basically done is we check if your table already contains an existing username. mysql_num_rows($res) will return 0 if no username exist.