0

I'm working on a basic ticketing system, where a user registers, logs in and creates tickets etc. Today I setup a very basic routing system, where my index page uses a switches and cases to redirect the users:

<?php 
require '../logic/session_message.php';

$request = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

switch($request) {

    case '/':
    require '../views/my_tickets.php';
    break;

    case '/login':
    require '../views/login.php';
    break;

    case '/register':
    require '../views/register.php';
    break;

    case '/register_user':
    require '../logic/register_user.php';
    break;


    case '/ticket_page':
    require '../views/ticket_page.php';
    break;
    
    case '/auth_login':
    require '../logic/auth_login.php';
    break;

    case '/my_tickets':
    require '../views/my_tickets.php';
    break;

    case '/select_tickets':
    require '../logic/select_tickets.php';
    break;

    case '/get_ticket_details':
    require '../logic/get_ticket_details.php';
    break;

    case '/create_ticket':
    require '../views/create_ticket.php';
    break;

    case '/insert_ticket':
    require '../logic/insert_ticket.php';
    break;

    case '/insert_comment':
    require '../logic/insert_comment.php';
    break;

    case '/logout':
    require '../logic/logout.php';
    break;

    //I need to setup a proper 404 view
    default:
    http_response_code(404);
    require '../views/404.php';
    echo "Page not found!";
    break;



}

This has worked fine. However, I wanted to turn it into a function. I've tried two. The first one:

<?php



function router($request) {     

    $view_routes = ['/login', '/register', '/my_tickets', '/create_ticket', '/ticket_page'];

    $logic_routes = ['/auth_login', '/get_ticket_details', '/insert_comment', '/insert_ticket', '/logout', 
    '/register_user', '/select_tickets', '/session_message'] ;

    if (in_array($request, $view_routes)) {
        require '..'.'/'.'views'.$request.'.php';
        // require '..'.'/'.'views'.$request.'.php';
        // exit;
        

    } elseif(in_array($request, $logic_routes)) {

        require '..'.'/'.'logic'.$request.'.php';
        // exit;


    } else {

        http_response_code(404);
        require '../views/404.php';
        echo 'page not found!';


    }





}

The second one:

function routing($request) {

    $view_routes = ['/login', '/register', '/my_tickets', '/create_ticket', '/ticket_page'];

    $logic_routes = ['/auth_login', '/get_ticket_details', '/insert_comment', '/insert_ticket', '/logout', 
    '/register_user', '/select_tickets', '/session_message'] ;


    if (in_array($request, $view_routes)) {

        switch($request) {
            case $request:
            require '..'.'/'.'views'.$request.'.php';
            break;


        }
    }elseif(in_array($request, $logic_routes)) {

        switch($request) {
            case $request:
            require '..'.'/'.'logic'.$request.'.php';
            break;    


        }

        
        


    }






}

Both functions are working fine, apart from the error handling. So for example, a user will login from here on the login page:

`require('../views/partials/login_header.php');
// require('../logic/session_message.php');

?>


<div class="login-form-container">
    <h2>Login</h2>
    <?php if(!empty($error_msg)) {
        echo '<label for="error">'. $error_msg . '</label>';

    } ?>
    <form action="/auth_login" method="post">
        <label for="email">Email</label>
        <input type="email" name="email" id="email">
        <label for="password">Password</label>
        <input type="password" name="password" id="password">
        <input type="submit" value="Login">
    </form>







</div>

The request will be authenticated through here:

<?php

require('config.php');
// require('session_message.php');
require('../logic/session_message.php');




if($_SERVER['REQUEST_METHOD'] == "POST") {

    $log_email = $_POST['email'];
    $log_pass = $_POST['password'];


    if(empty($log_email) || empty($log_pass)) {

        $_SESSION['error_msg'] = "Email and password is required";
        header('Location: /login');
        exit();

    } else {

        try {

            $login = $conn->prepare("SELECT user_id, email, password FROM users WHERE email = :email");
            $login->bindParam("email", $log_email);
            $login->execute();

            $user = $login->fetch(PDO::FETCH_ASSOC);
            if($user && password_verify($log_pass, $user['password'])) {
                $_SESSION['user_id'] = $user['user_id'];
                $_SESSION['login'] = $log_email;
                header('Location: /my_tickets');
                exit();


            } else {

                $_SESSION['error_msg'] = "Incorrect email or password.";
                header('Location: /login');
                exit();

            }


 
        }catch (PDOException $e) {
            die("Failed to login: " . $e->getMessage());
            header('Location: /login');
            exit();

        }





    }







}

Session messages are handled through here:

<?php

session_start();
$error_msg = "";

if(isset($_SESSION['error_msg'])) {
    $error_msg = $_SESSION['error_msg'];
    unset($_SESSION['error_msg']);
}

If the user does not enter an email address, the request is redirected back to the login page and an error displays. However, with the two functions, the request is redirected, but no error message displays.

I don't understand why it works with the original switch and case, but not with either functions? Does anyone have any feedback please? I'm sure this could be improved via a class etc, however, I'm very new to PHP and I do not fully understand Object-oriented programming yet.

I tried this to log any errors and also made sure it wasn't trying to start another session:

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

$error_msg = "";

if (isset($_SESSION['error_msg']) && !empty($_SESSION['error_msg'])) {
    $error_msg = $_SESSION['error_msg'];
    error_log("Session error message retrieved: " . $error_msg); 
    unset($_SESSION['error_msg']);
} else {
    error_log("No session error message found."); 
}

I'm using the PHP dev server. The error messages seem to be captured, as this was a message from the terminal, but it's not displaying the message:

[Tue Aug 27 20:43:20 2024] Session error message retrieved: Email and password is required

13
  • I'm curious to know why you would implement a router. The normal practice in PHP is to let the web server do the routing, so each page loads a top-level PHP file with a name matching the URL. I'm not saying it's wrong, but it seems unusual, and error-prone. Commented Aug 27, 2024 at 20:34
  • Simplify your mapping. 3v4l.org/v7c7A Commented Aug 27, 2024 at 20:37
  • 1
    @TimRoberts Hi Tim, it's my second month using PHP, so I'm still learning. Having models, controllers and views seem to be common practice, so I was trying to implement something similar, albeit in a simple form. Commented Aug 27, 2024 at 20:52
  • 2
    It's common when you're using a framework that implements the routing for you. If not, the usual way is to just let the webserver do it. Commented Aug 27, 2024 at 20:59
  • 1
    For anyone curious, I've managed to solve it. The problem was, I wasn't declaring the $error_msg variable as global within the functions, so it wasn't accessible, whereas the switch-case wouldn't have been isolated in a function. I've declared $error_msg as global on my two functions and they seem to be working. It's also working on @MarkusZeller script as well. As it's declared as global, I only need to call my session_message file once in the index file. Thank you for everyone's input. As I said, it's month two, so I'm still learning. Commented Aug 28, 2024 at 15:33

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.