PHP redirect works in Chrome, but not other browsers
SO I am trying to learn MVC using a book. I'm still at a very basic level , so please keep that in mind if you're kind enough to answer.
This is part of my app layout:
Now I have a simple login form
<form method="post" action="index.php">
<input type="text" name="action" value="login" style="display: none">
<label for="email">Email</label>
<input type="email" required="required" name="email" id="email" placeholder="Enter Your Email" />
<br />
<label for="password">Password</label>
<input type="password" required="required" name="password" id="password" placeholder="Enter Your Password" />
<button type="submit" name="submit">Login</button>
</form>
Pay attention to the first field name="action" value="login"
as the redirect depends on that particular field.
MODEL
users_db.php
function login($email, $pword)
{
$sql = "SELECT * FROM users WHERE email = :email AND pword = :pword ";
$stmnt = $db->prepare($sql);
$stmnt->bindValue(':email', $email);
$stmnt->bindValue(':pword', $pword);
$stmnt->execute();
if ($stmnt->rowCount() > 0) {
return $stmnt->fetchAll();
} else {
return null;
}
}
Directory - users
index.php as a controller. Below is a partial excerpt of the "controller" and the problem arises.
require_once('../config/db.php');
require_once('../model/users_db.php');
if(isset($_POST['action'])) {
$action = $_POST['action'];
if ($action == 'login') {
$email = htmlspecialchars($_POST['email']);
$pword = htmlspecialchars($_POST['password']);
$users = login($email, $pword);
if (is_array($users)) {
foreach ($users as $user) {
session_start();
$_SESSION['firstname'] = $user['firstname'];
$_SESSION['lastname'] = $user['lastname'];
$_SESSION['username'] = $user['username'];
$_SESSION['email'] = $user['email'];
$_SESSION['userType'] = $user['userType'];
$_SESSION['userID'] = $user['userID'];
header('Location:welcome.php');
die();
}
APP FLOW / STEPS
- User enters email and password in the form.
- Information about the form is passed to index.php to a "controller" which includes the email, pword. and the hidden value of the input field
- Inside the index.php file, the controller checks if the value of the hidden input field
action
for the login is set, which it is. - If login is set, it calls the login function from the users_db model, which queries the db and returns all information about the user.
- Assuming correct email and password, type enterd, index.php will redirect the user to the welcome page and
exit()
Works great in Chrome, but all other browsers redirect to 404 index.php not found error. This is rather strange to me, it would be highly appreciated if anyone can contribute to the cause of the error above?
source to share
try it
error_reporting(E_ALL | E_WARNING | E_NOTICE);
ini_set('display_errors', TRUE);
flush();
header("Location: http://www.website.com/");
echo '<script>window.location.replace("http://www.example.com")</script>';
die('should have redirected by now');
PHP redirects use header codes to tell the browser about the redirect. But if your PHP code echoes (even a warning) before that header location, some browsers won't redirect.
In the above code, it clears everything and sends the location of the header. It also tells the browser to redirect using javascript, so it will work, even the php header redirect doesn't work.
Hope it helps
source to share
There are several problems with this code besides the redirection. The reason the function header
doesn't work is because the title must have an absolute URL, for example http://www.example.com/replace.php
, in addition, there Location:
must be a space between the title and the value, for example:
header('Location: http://www.example.com/replace.php')
...
Note that to set the response header with a function, header
you should not send the previous headers , if you have anything less than the space that is returned before the function is called header
, it will not work.
Now tell us about other problems this code has:
1 - The function session_start()
must be called at the top of the page before you start working with the $ _SESSION supergelobal.
2 - You call die()
in the foreach loop, that is, your code will go through the array only once and then the code will stop. Move the call die()
outside of the loop.
3 - Validate the input with a function filter_val
( http://php.net/manual/ro/function.filter-input.php ) ~ I'm talking mainly about email, but I think you can apply it to other inputs as well.
4 - Do not store password in plain text, use the password hashing API that PHP offers ( https://www.sitepoint.com/hashing-passwords-php-5-5-password-hashing-api/ )
source to share
Maybe another solution:
users_db.php
function login($email, $pword)
{
$sql = "SELECT * FROM users WHERE email = :email AND pword = :pword LIMIT 1";
$stmnt = $db->prepare($sql);
$stmnt->bindValue(':email', $email);
$stmnt->bindValue(':pword', $pword);
$stmnt->execute();
if ($stmnt->rowCount() > 0) {
return $stmnt->fetchAll();
} else {
return null;
}
}
index.php
require_once('../config/db.php');
require_once('../model/users_db.php');
if(isset($_POST['action'])) {
$action = $_POST['action'];
if ($action == 'login') {
$email = htmlspecialchars($_POST['email']);
$pword = htmlspecialchars($_POST['password']);
$user = login($email, $pword);
if ($user != null) {
session_start();
$_SESSION['firstname'] = $user['firstname'];
$_SESSION['lastname'] = $user['lastname'];
$_SESSION['username'] = $user['username'];
$_SESSION['email'] = $user['email'];
$_SESSION['userType'] = $user['userType'];
$_SESSION['userID'] = $user['userID'];
header('Location: welcome.php');
echo '<script>window.location.replace("http://www.example.com")</script>';
die();
}
}
}
source to share