I looked at your code, but I don't see a problem. What are the full contents of redirect.php? Is it possible you are including the wrong redirect.php? There could also be some sort of syntax issue. I'm not sure what is going on. Are you possibly using Opcache? There are times that Opcache gets a file stuck in cache, and it doesn't read changes. If you are using opcache, you should either turn it off for development purposes, or learn how to clear the cache. I've seen that cause major confusion plenty of times, where people had code that should work, but doesn't and they can't figure out why.
This has nothing to do with your problem but since I looked at your code, I figured I'd refactor it for you.
function loginSuccess($username, $password) {
global $cn;
$sql = "SELECT COUNT(*) as countOf FROM admin WHERE username=:username AND password=:password";
$stmt = $cn->prepare($sql);
$stmt->bindValue(":username", $username);
$stmt->bindValue(":password", $password);
$stmt->execute();
$countOf = $stmt->fetchColumn();
return ($countOf > 0);
}
I fixed your spelling. The word is spelled "success".
Use PHP community standards for naming your functions, methods and variables. The standard is to use camelcase.
See https://www.php-fig.org/psr/psr-12/ for this and more standards you should conform your code to
Writing code to these standards has many benefits including the avoidance of bugs where you mix up case, as php variables are case sensitive, better readability, and support for tools that can be integrated into the best PHP code editors to maintain standards and reformat your code
It's also easier for others to read
Don't use underscores, except in special circumstances. Use camelCase to differentiate words. Some people will use an _ as the first character of a name to indicate private/protected variables in OOP, but I'd avoid them entirely. Underscores are used to name certain special PHP method names, like __construct for example.
Your query does not need to return anything from the database other than a count of rows that match your criteria. Just use COUNT(*) for that, and this will always return a result that will either be 0 or something > 0
Have your function return a boolean, so it's clear that it's true/false.
Ideally you would use return ($countOf == 1) however, I don't know if you guarantee uniqueness for usernames in your database. You should do that, with a Unique constraint on username, as this would insure that it's impossible to insert more than one row in your admin table with the same username.
Not preventing the insertion of multiple admin rows with the same username can lead to terrible bugs in your system.
If you do have a unique constraint on username in your admin table, then change the code to return ($countOf == 1).
This is also semantics, but the name of your function "loginSuccess" isn't a great name. The function, despite your name does not indicate "login success". All it indicates is that you verified the existence of a row. The concept of a "login" is more complicated and typically involves setting up some session variables and regenerating the session, if you are using sessions generically (for unauthenticated users).
A better name for this function would be: function canAuthenticate() or isAuthenticated().