PHP Front Controller Flow Confusion - Switch statement only tested once - php

I am new to php and confused on the flow of this. It seems to me that switch($action) would need to be evaluated more than once when the $action variable gets a new value. But I don't see the switch($action) being evaluated but just once. I used admin_menu.php as an example. What if the user picks <p>Product Manager</p> from admin_menu.php? I don't see where index.php is called afterwards, so I don't see how the new value will be tested since switch($action) has already ran.
localhost ch21_ex2 # cat index.php
<?php
// Start session management and include necessary functions
session_start();
require_once('model/database.php');
require_once('model/admin_db.php');
// Get the action to perform
if (isset($_POST['action'])) {
$action = $_POST['action'];
} else if (isset($_GET['action'])) {
$action = $_GET['action'];
} else {
$action = 'show_admin_menu';
}
// If the user isn't logged in, force the user to login
if (!isset($_SESSION['is_valid_admin'])) {
$action = 'login';
}
// Perform the specified action
switch($action) {
case 'login':
$email = $_POST['email'];
$password = $_POST['password'];
if (is_valid_admin_login($email, $password)) {
$_SESSION['is_valid_admin'] = true;
include('view/admin_menu.php');
} else {
$login_message = 'You must login to view this page.';
include('view/login.php');
}
break;
case 'show_admin_menu':
include('view/admin_menu.php');
break;
case 'show_product_manager':
include('view/product_manager.php');
break;
case 'show_order_manager':
include('view/order_manager.php');
break;
case 'logout':
$_SESSION = array(); // Clear all session data from memory
session_destroy(); // Clean up the session ID
$login_message = 'You have been logged out.';
include('view/login.php');
break;
}
?>localhost ch21_ex2 # firefox 'view/admin_menu.php'
localhost ch21_ex2 # cat 'view/admin_menu.php'
<?php
require_once('util/secure_conn.php'); // require a secure connection
require_once('util/valid_admin.php'); // require a valid admin user
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My Guitar Shop</title>
<link rel="stylesheet" type="text/css" href="main.css"/>
</head>
<body>
<div id="page">
<div id="header">
<h1>My Guitar Shop</h1>
</div>
<div id="main">
<h1>Admin Menu</h1>
<p>Product Manager</p>
<p>Order Manager</p>
<p>Logout</p>
</div><!-- end main -->
</div><!-- end page -->
</body>
</html>

I just now see the answer....index.php is being called again with: index.php?action=show_order_manager in <p>Order Manager</p>

Related

Why doesn't login provide me a session_id()?

I'm building a simple login system.
Registration is working with password_default:
So, now the login. This is my login class:
<?php
include("../Controllers/DatabaseController.php");
class LoginModel extends DatabaseController
{
protected $dbconn;
public function __construct()
{
$this->dbconn = DatabaseController::instance();
}
public function Login()
{
$db = $this->dbconn->pdo;
try {
$username = $_POST['username'];
$passwordAttempt = $_POST['user_password'];
//Retrieve the user account information for the given username.
$sql = "SELECT * FROM user WHERE username = :username";
$stmt = $db->prepare($sql);
//Bind value.
$stmt->bindParam(':username', $username);
//Execute.
$stmt->execute();
//Fetch row.
$user = $stmt->fetch(PDO::FETCH_ASSOC);
//If $row is FALSE.
if ($user === false) {
//Could not find a user with that username!
?>
<script type="text/javascript">
alert("username not found!");
window.location.href = "../Views/login.php";
</script>
<?php
} else {
//User account found. Check to see if the given password matches the
//password hash that we stored in our users table..
$validPassword = password_verify($passwordAttempt, $user['user_password']);
//If $validPassword is TRUE, the login has been successful.
if ($validPassword) {
//Provide the user with a login session.
$_SESSION['id'] = $user['id'];
$_SESSION['logged_in'] = time();
//Redirect to our protected page, which we called home, to see if we are provided a session.php
?>
<script type="text/javascript">
alert("You're logged in!");
window.location.href = "../index.php";
</script>
<?php
header('Location: home.php');
exit;
} else {
//$validPassword was FALSE. Passwords do not match.
?>
<script type="text/javascript">
alert("Password is incorrect!");
window.location.href = "../Views/login.php";
</script>
<?php
}
}
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
}
}
Now I know, it isn't proper OOP, but I'm learning.
When I press login, passwords do match:
But when redirecting to home.php, it seems the log in didn't provide me with a session_id...
Home.php:
<?php
/**
* Start the session.
*/
session_start();
/**
* Check if the user is logged in.
*/
if(!isset($_SESSION['id']) || !isset($_SESSION['logged_in'])){
//User not logged in. Redirect them back to the login.php page.
?>
<script type="text/javascript">
alert("You're not logged in!" );
</script>
<?php
exit;
}
/**
* Print out something that only logged in users can see.
*/
echo 'Congratulations! You are logged in!';
I hope somebody has a solution, because I don't see one unfortunately.
For completion my partial login.php:
<?php
include "../Models/LoginModel.php";
$login = new LoginModel();
?>
<?php
if (isset($_POST["submit"])) {
$login->Login();
}
?>
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<title>Title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="../style-registration.css">
</head>
<body>
<?php
include 'header.php';
?>
<div class="signup-form">
<form action="" method="post">
And my partial header.php:
<?php
session_start();
?>
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<title>Scores Website</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="../style-index.css">
</head>
<body>
<nav class="navbar navbar-expand-xl bg-light">
Try to end with that kind of structure :
<?php
include "../Models/LoginModel.php";
session_start();
if ($_POST) {
//execute login method
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
//set title, meta, call needed css files
</head>
<body>
//your form etc...
//end with javascript calls
</body>
</html>
In this order everything should works as expected.

Php switch-case with functions doesn't work

Why does the first logic work
<!DOCTYPE html>
<html>
<head>
<title>Installation Script</title>
</head>
<?php
$step = (isset($_GET['step']) && $_GET['step'] != '') ? $_GET['step'] : '';
switch($step){
case '1':
step_1();
break;
case '2':
step_2();
break;
case '3':
step_3();
break;
default:
step_1();
}
?>
<body>
<?php
function step_1(){
some php code for the below form
?>
form (html code)
<?php
}
function step_2(){
some php code for the below form
?>
form (html code)
<?php
}
function step_3(){
some php code for the below form
?>
form (html code)
<?php
}
?></body>
</html>
but the second doesn't?
<?php
$result='';
$step = (isset($_GET['step']) && $_GET['step'] != '') ? $_GET['step'] : '';
switch($step){
case '1':
step_1();
break;
case '2':
step_2();
break;
case '3':
step_3();
break;
default:
step_1();
}
function step_1(){
$result='';
some php code for the $result form in this function
$result.='html form';
}
function step_2(){
$result='';
some php code for the $result form in this function
$result.='html form';
}
function step_3(){
$result='';
some php code for the $result form in this function
$result.='html form';
}
?><!DOCTYPE html>
<html>
<head>
<meta charset="utf8" />
<title>Install</title>
</head>
<body>
<div id="wrapper">
<header id="header">
<h1>Installer</h1>
</header>
<section>
<?php print $result; ?>
</section>
<footer id="footer">
</footer>
</div>
</body>
</html>
It's ok,that i shouldn't use an installer like this, i won't, but i only have this code to show you my problem. In my opinion,the second example's structure is more logical than the first one, but it doesn't work. Can you help me? Or where to find some information about this?

Having problems with function defined in other file

My page won't load at all, browser says its redirecting in a way that is not loading. As the title suggests I think the issue is with one of the php files I include with require_once(). Let me just show you:
thumbnail.php:
<?php
if(!function_exists("makethumbnail"))
{
//die("right before function definition");
function makethumbnail($src,$new_name,$new_width,$new_height)
{
die("inside makethumbnail");
$si = imagecreatefromjpeg($src);
$w = imagesx($si);
$h = imagesy($si);
$vi = imagecreatetruecolor($new_width,$new_height);
imagecopyresampled($vi,$si,0,0,0,0,$new_width,$new_height,$w,$h);
imagejpeg($vi,$new_name);
}
}
?>
checksession.php:
<?php
session_start();
$session_name = "forces";
$com=0;
if(!function_exists("logout"))
{
function logout()
{
$_SESSION = array();
session_destroy();
header('Location:http://cs4.sunyocc.edu/~j.d.dancks/index.php');
}
}
if(!isset($_SESSION['time']) || !isset($_SESSION['nick']))
{
$com=2;
logout();
}
else if($_SESSION['time'] < time())
{
$com=3;
logout();
}
//redirect back to main whatever ignore this line
?>
index.php:
<?php
require_once("shopsite/thumbnail.php");
require_once("shopsite/checksession.php");
die("made it past the require_once");
$con = mysql_connect('localhost','jddancks','csc255');
mysql_select_db('test',$con);
$q = mysql_query("select prod_name,image_name,type1,type2 from Product",$con) or die("its the mysql");
$row = mysql_fetch_assoc($q);
$totalRows_Recordset1 = mysql_num_rows($q);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Welcome to the shopsite</title>
<script type="text/javascript" src="shopsite/lib/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="shopsite/lib/jquery.jcarousel.min.js"></script>
<link rel="stylesheet" type="text/css" href="shopsite/skins/ie7/skin.css" />
<script type="text/javascript">
JQuery(document).ready(function() {
JQuery('#mycarousel').jcarousel({
itemLoadCallback:itemLoadCallbackFunction,
start:1,
auto:3,
animation:"slow",
wrap:"both"
});
});
</script>
</head>
<body>
<?php
session_start();
if(isset($_SESSION['nick']))
{
echo "<p>Welcome, ".$_SESSION['nick']."</p>";
}
die("Made it past the first php");
?>
<h1>Welcome to the one-stop shop for your every need!</h1>
<div class="jcarousel-ie7">
<p>Browse Items:</p>
<div class="jcarousel-container">
<div class="jcarousel-clip">
<ul id="mycarousel" class="jcarousel-skin-ie7">
<?php
$cnt=1;
do
{
$i=$row['image_name'];
$name=preg_split("/.jpg/",$i);
$name = "shopsite/thumb/".$name[0]."-index.jpg";
if(!file_exists($name))
{
makethumbnail("shopsite/images/".$row['image_name'],$name,50,50);
}
echo " <li class=\"jcarousel-item-".$cnt."\"><img src=\"".$name."\" /></li>\n";
$cnt=$cnt+1;
if($cnt>12) die("cnt larger than 12");
}
while($row = mysql_fetch_assoc($q));
?>
</ul>
</div>
<div disabled="disabled" class="jcarousel-prev jcarousel-prev-disabled"></div>
<div class="jcarousel-next"></div>
</div>
</div>
</body>
</html>
<?php mysql_free_result($row);
mysql_close($con); ?>
I want to insert images into a jquery carousel so a visitor can browse items they may want to purchase. I've never used jcarousel so I don't know if what I have works, I'm pretty sure thats not the problem. I guess its just one of those things you need a second pair of eyes for. The die statements in thumbnail.php make me believe that is the culprit, but it won't make it to the first line of the function, which is really confusing. I don't know how the php preporcessor works, other than its client-side.

php redirect when wrong password

is this right the code will redirect a person to the login page when they try to access it using without going into the login page
<?php
$pass = 'password';
?>
<html>
<head>
<title></title>
</head>
<body>
<?php
if ( $_POST["pass"] == $pass){
?>
Congrats you have log in!
<?php
}else{
header("Location: http://signin.com/");
}
?>
</body>
</html>
i ended up having a "Server error
The website encountered an error while retrieving http://www.test.com It may be down for maintenance or configured incorrectly."
You can't call header after you've already outputted some HTML. Do your password checks & redirect. above the HTML
Eg:
<?php
$pass = 'password';
if ( $_POST["pass"] != $pass){
header("Location: http://signin.com/");
exit;
}
?>
<html>
<head>
<title></title>
</head>
....
So the HTML will only show if they're successful.
You can't send a header() after any output to the user:
<?php
$pass = 'password';
if ( $_POST["pass"] == $pass)
{
?>
<html>
<head>
<title></title>
</head>
<body>
Congrats you have log in!
</body>
</html>
<?php
}
else
{
header("Location: http://signin.com/");
}
?>
Something like this would work better:
<?php
$pass = 'password';
if ($_POST["pass"] != $pass){
header("Location: http://signin.com/");
exit;
}
?>
<html>
<head>
<title></title>
</head>
<body>
Congrats you have log in!
</body>
</html>
You need to check if the user is logged in. If not, redirect and exit. If so, display the message.
Put ob_start(); at the top and ob_end_flush(); and that might fix it.
You can't output html before make a redirect with header. Code all logic before:
<?php
$pass = 'password';
if ($_POST["pass"] == $pass)
{
$message = "Congrats you have log in!";
}
else
{
header("Location: http://signin.com/");
}
?>
<html>
<head>
<title></title>
</head>
<body>
<?php echo $message; ?>
</body>

PHP - loading static class sends headers

I have a simple page in HTML/CSS/PHP that connects to MySQL DB.
"index.php" is loaded and "mainPage::showSectionLogin($_SESSION['login'])" shows logging form
<?php session_start(); ?>
<?php require_once 'clMainPage.php'; ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
<HEAD>
<?php mainPage::setSectionHEAD() ?>
<LINK rel="stylesheet" type="text/css" href="style.css">
</HEAD>
<BODY>
<DIV id="sidebar">
<?php mainPage::showSectionLogin($_SESSION['login']) ?>
<?php mainPage::showSidebarMenu($_SESSION['login']) ?>
</DIV>
<DIV id="main">
<?php mainPage::showActualNews(5) ?>
</DIV>
</BODY>
</HTML>
"login.php" is executed after the logging form was filled
<?php session_start(); ?>
<?php require_once 'clMainPage.php'; ?>
<?php
if($_SERVER["REQUEST_METHOD"] == "POST") {
$dblink = mainPage::openDBconn();
$result = mainPage::checkIfUserCanLogIn($dblink, $_POST['inpLogin'], $_POST['inpPassw']);
if (mysql_num_rows($result) == 1) {
$row = mysql_fetch_array($result);
mainPage::logUserIn($row['login'], $row['passw']);
}
else
{
die("error checking user: there is no such user in a database");
}
mainPage::closeDBconn($dblink);
header("refresh:1;url=index.php");
} ?>
I don't inderstand why, during logging in, "header("refresh:1;url=index.php");" (line:18) says that "require_once 'clMainPage.php';" in file "login.php" (line:2) sends headers. How is it possible that "require_once 'clMainPage.php';", that is a class declaratin containing only static functions, actually sends headers?
There is white space after your closing php tag on line 1, that's what sends the headers
<?php
session_start();
require_once 'clMainPage.php';
if($_SERVER["REQUEST_METHOD"] == "POST") {
Do you have any whitespace / output before / after your < ?php. This is often the cause.
What does 'clMainPage.php' contain?

Categories