4

I'm trying to make a signup / sign-in form in PHP, but I have trouble logging out. I keep getting the following error.

Fatal error: Uncaught ArgumentCountError: Too few arguments to function USER::__construct(), 0 passed in C:\xampp\htdocs\recepten\logout.php on line 4 and exactly 1 expected in C:\xampp\htdocs\recepten\class.user.php:6 Stack trace: #0 C:\xampp\htdocs\recepten\logout.php(4): USER->__construct() #1 {main} thrown in C:\xampp\htdocs\recepten\class.user.php on line 6

Can somebody advise me on what I'm doing what and how to fix the problem?

This is my line of code for the logout script:

<?php
session_start();
require_once 'class.user.php';
$user = new USER();

if(!$user->is_logged_in())
{
    $user->redirect('indexlogin.php');
}

if($user->is_logged_in()!="")
{
    $user->logout(); 
    $user->redirect('indexlogin.php');
}
?>

This is my code for the call-user script:

<?php
class USER
{
    private $db;

    function __construct($DB_con)
    {
        $this->db = $DB_con;
    }

    public function register($fname,$lname,$uname,$umail,$upass)
    {
       try
       {
           $new_password = password_hash($upass, PASSWORD_DEFAULT);

           $stmt = $this->db->prepare("INSERT INTO users(user_name,user_email,user_pass) 
                                                       VALUES(:uname, :umail, :upass)");

           $stmt->bindparam(":uname", $uname);
           $stmt->bindparam(":umail", $umail);
           $stmt->bindparam(":upass", $new_password);            
           $stmt->execute(); 

           return $stmt; 
       }
       catch(PDOException $e)
       {
           echo $e->getMessage();
       }    
    }

    public function login($uname,$umail,$upass)
    {
       try
       {
          $stmt = $this->db->prepare("SELECT * FROM users WHERE user_name=:uname OR user_email=:umail LIMIT 1");
          $stmt->execute(array(':uname'=>$uname, ':umail'=>$umail));
          $userRow=$stmt->fetch(PDO::FETCH_ASSOC);
          if($stmt->rowCount() > 0)
          {
             if(password_verify($upass, $userRow['user_pass']))
             {
                $_SESSION['user_session'] = $userRow['user_id'];
                return true;
             }
             else
             {
                return false;
             }
          }
       }
       catch(PDOException $e)
       {
           echo $e->getMessage();
       }
   }

   public function is_loggedin()
   {
      if(isset($_SESSION['user_session']))
      {
         return true;
      }
   }

   public function redirect($url)
   {
       header("Location: $url");
   }

  public function logout()
  {
      session_destroy();
      $_SESSION['user_session'] = true;
  }
}
?>

It would be nice if someone could help!

BladeMight
  • 2,670
  • 2
  • 21
  • 35
jacob
  • 49
  • 3
  • 8
    `function __construct($DB_con)` and `$user = new USER();` – Sindhara Mar 10 '19 at 20:30
  • 3
    The above is the problem, but kudos for using a clean and secure registration / login system. It's surprisingly rare :) – Obsidian Age Mar 10 '19 at 20:32
  • That logout function is hideous. Can't write to session after having called session_destroy. – Ultimater Mar 10 '19 at 20:33
  • 4
    You're not passing the db connection to USER. –  Mar 10 '19 at 20:34
  • @kuh-chan I did paste the following line with an AND as you suggested, but now I get the following error. Parse error: syntax error, unexpected 'AND' (T_LOGICAL_AND), expecting ';' or '{' in C:\xampp\htdocs\recepten\class.user.php on line 6 – jacob Mar 10 '19 at 20:44
  • 2
    @jacob `kuh-chan` meant that the problem is in those lines, not to copy-paste text. – BladeMight Mar 10 '19 at 21:03

3 Answers3

3

In class.user.php you have a:

function __construct($DB_con)
{
  $this->db = $DB_con;
}

and when you use it in logout.php:

$user = new USER();

You have to pass the $DB_con to __constructor, or create a __constructor that has no arguments, and add another function to initialize the DB:

function __construct()
{
} 
public function initDB($DB_con)
{
  $this->db = $DB_con;
}

and then you can use it like that:

$YourDB = whatever_get_DB();
$user = new USER();
// And when you need:
$user.initDB($YourDB);

or without this only:

$YourDB = whatever_get_DB();
$user = new USER($YourDB);
BladeMight
  • 2,670
  • 2
  • 21
  • 35
  • I did try to add another function, now I dont have the error message on call.user.php But only on Logout.php. Which give me the following error: Fatal error: Uncaught Error: Call to undefined method USER::is_logged_in() in C:\xampp\htdocs\recepten\logout.php:6 Stack trace: #0 {main} thrown in C:\xampp\htdocs\recepten\logout.php on line 6 – jacob Mar 10 '19 at 20:53
  • @jacob Your function defined not `is_logged_in` but `is_loggedin`, change the name in the `class.user.php` or in `logout.php` on lines 6&11. – BladeMight Mar 10 '19 at 21:00
  • thanks but I have the following problem when trying to sign in, when logging out finally worked. Notice: Undefined variable: fname in C:\xampp\htdocs\recepten\Sign_up.php on line 46 Notice: Undefined variable: lname in C:\xampp\htdocs\recepten\Sign_up.php on line 46 Fatal error: Uncaught Error: Call to a member function prepare() on null in C:\xampp\htdocs\recepten\class.user.php:20 Stack trace: #0 C:\xampp\htdocs\recepten\Sign_up.php(46): USER->register(NULL, NULL, 'johan22', 'johan@live.nl', 'joohaann') #1 {main} thrown in C:\xampp\htdocs\recepten\class.user.php on line 20 – jacob Mar 10 '19 at 21:16
  • The error message clearly describes it: 1. you have used undefined variables `fname` and `lname` in `sign_up.php` on line 46. 2. Your `$this->db` is NULL, it means you didn't pass the DB to constructor or `initDB`, you need to initialize DB first. Thats why it saying that NULL has no `prepare` function. – BladeMight Mar 11 '19 at 09:24
1

Your have to pass DB connection to USER constructor.

Mariyo
  • 486
  • 7
  • 15
  • A PDO database connection to be more precise. – Ultimater Mar 10 '19 at 20:34
  • 1
    Without typehint in constructor it Can be whatever what uses simillar api as PDO and throws PDOException in some case – Mariyo Mar 10 '19 at 20:39
  • Which would be the same case even if type hinting assuming it extends it. – Ultimater Mar 10 '19 at 20:41
  • Note really, i can write my DB class without extending Pdo and use same method naming and throw PDOException, but it will not be same case, because it wont be Pdo – Mariyo Mar 10 '19 at 20:48
  • 1
    If it looks like a duck, walks like a duck, and quacks like a duck... https://en.wikipedia.org/wiki/Duck_typing – Ultimater Mar 10 '19 at 20:54
  • 1
    Yeah, in this meaning duck is db connector, but we cannot say if its Pdo connector or MyCustomDb connector without typehint – Mariyo Mar 10 '19 at 21:00
  • What would a custom adapter add by being used exactly the same way as PDO? Write useless logs? I'd just dump such a custom adapter in favor of PDO because such an adapter would be a joke. – Ultimater Mar 10 '19 at 21:13
  • I do not want to say anything about customization, its still question about precision you advised, which is from my point of view wrong. I tried to provided silly example, where I want to show you were wrong. – Mariyo Mar 11 '19 at 08:39
0

The thrown error is pretty clear. You are missing an argument in your constructor, expected 1 got 0 arguments.

So, basically when you instantiate a class new ClassName(), the constructor arguments are placed in the brackets.

//               v Arguments of the constructor goes here 
$user = new USER( );

In your case, you are missing the arguments which the class constructor needs, ($DB).

Ikhlak S.
  • 8,578
  • 10
  • 57
  • 77
  • yes I tried to fill the missing argument but, this error keeps coming when signin or sign up. Fatal error: Uncaught Error: Call to a member function prepare() on null in C:\xampp\htdocs\recepten\class.user.php:40 Stack trace: #0 C:\xampp\htdocs\recepten\indexlogin.php(15): USER->login('johan22', 'johan22', 'johan12345') #1 {main} thrown in C:\xampp\htdocs\recepten\class.user.php on line 40 – jacob Mar 10 '19 at 21:45
  • @jacob The argument you passing to constructor is null... Maybe you are not connecting to the database... What does your $DB look like, the $DB you pass to the constructor – Ikhlak S. Mar 10 '19 at 21:57
  • setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e) { echo $e->getMessage(); } include_once 'class.user.php'; $user = new USER($DB_con); – jacob Mar 10 '19 at 22:00
  • @jacob Seems your connection syntax is good. You can start debugging in the constructor. Can you do a `print_r($this->db);` there and check if it is not null – Ikhlak S. Mar 10 '19 at 22:19