2

I'm having this error when I try to insert data in my database. I've searched the reasons of this error and I think my codes are right and I'm not supposed to get the error. My codes are these:

config.php

<?php
class DatabaseConnection{
    public function __construct(){
        try{
        $pdo = new PDO('mysql:host=localhost;dbname=test','root',''); //'mysql:host=host;dbname=dbname','mysqluser','mysqlpassword'
        }
        catch (PDOException $e){
            exit('Database error');
        }   
    }
}
?>

functions.php

<?php

require "config.php";

class LoginRegister{
    function __construct(){
        $database= new DatabaseConnection();
    }

    public function registerUser($username,$password,$name,$email){

        global $pdo; //THIS IS THE LINE WITH ERROR
        $query=$pdo->prepare("SELECT id FROM usuarios WHERE nombre_usuario=? AND correo_e=?");
        $query->execute(array($username,$email));
        $num=$query->rowCount();

        if($num==0){
            $query = $pdo->prepare("INSERT INTO usuarios(nombre_usuario,nombre_real,password,correo_e) VALUES (?,?,?,?)");
            $query->execute(array($username,$password,$name,$email));
            return true;
        }else{
            return print "Username or E_mail in use";
        }
    }
}
?>

register.php

<?php

require_once "functions.php";
$user = new LoginRegister();
?>

...HTML CODE...

<?php
if($_SERVER['REQUEST_METHOD'] == 'POST'){
    $username=$_POST['nombre_usuario'];
    $password=$_POST['password'];
    $name=$_POST['nombre_real'];
    $email=$_POST['correo_e'];

    if(empty($username) or empty($password) or empty($name) or empty($email)){
        echo "Error... Field must not be empty";
    }else{
        $register = $user->registerUser($username,$password,$name,$email);
        if($register){
            echo "Register done <a href='login.php'>Click here</a> for login";
        }else{
            echo "Username or E_mail in use";
        }
    }
}
?>

...HTML CODE...

As you can see, I declared the variable $pdo inside the registerUser functions, besides the variables that contain the name, username, password and email are parameters of the same function.

I know this is a several times duplicated question but I cannot solve this error with the solutions in the other ones.

He_slp13
  • 67
  • 5

3 Answers3

1

There are several problems with your code.

Two were explained in the other answer, which will make your code work (eventually it all was spoiled), but it's still wrong approach, which will connect to database as many times as many objects you have.

Change DatabaseConnection class this way

class DatabaseConnection{
    public $pdo;
    public function __construct(){
        $user = 'root';
        $pass = '';
        $dsn  = 'mysql:charset=utf8;dbname=test;host=localhost;charset=utf8';
        $opt  = array(
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        );
        $this->pdo = new PDO($dsn, 'root', '', $opt);
    }
}

Change LoginRegister constructor this way

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

And make register.php this way

require_once "functions.php";
$db = new DatabaseConnection();
$user = new LoginRegister($db->pdo);

and then in LoginRegister use $this->db instead of $pdo all the way.

The main idea to make $db connection an external service for the application class. Otherwise it will be all the same as despised global, but just in another form.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
0

I'm sorry but I must say hat horrible code. You are making all the worst mistakes. First NEVER use global, just never do it. Google it for an explanation why. Now the variables you create in your constructors only have scope there so they are never avaliable in your other class or method. That is why $pdo is not a PDO object it is just a local var with null value. Try this:

class DatabaseConnection{
    private $pdo;

    public function __construct(){
        try{
        $this->pdo = new PDO('mysql:host=localhost;dbname=test','root',''); //'mysql:host=host;dbname=dbname','mysqluser','mysqlpassword'
        }
        catch (PDOException $e){
            exit('Database error');
        }   
    }

    public function getPdo()
    {
        return $this->pdo;
}

class LoginRegister{
    private $database;

    function __construct(){
        $this->database= new DatabaseConnection();
    }

    public function registerUser($username,$password,$name,$email){

        $pdo = $this->database->getPdo();
        $query=$pdo->prepare("SELECT id FROM usuarios WHERE nombre_usuario=? AND correo_e=?");

Now this is still horrible but at least it will work. You really must read up on object oriented programming from a good book, one that also teaches you about design patterns and SOLID, DRY and other best practices.

David Soussan
  • 2,698
  • 1
  • 16
  • 19
  • You just reinvented global here, actually. – Your Common Sense Oct 02 '15 at 04:29
  • 1
    @ Your Common Sense Oh have I, really. I have not done so at all. Those class vars are still private in their classes and that means they are NOT global. Thanks for the mark down by the way. – David Soussan Oct 02 '15 at 04:33
  • 2
    @ Your Common Sense I said it was horrible code but I'm not going to write it all for him as it should be with Dependency Injection of the PDO class etc. And I'm not going to give a whole lesson in OOPs here now am I. StackExchange is about solving the immediate problem and pointing the questioner in the right direction, not scoring points and showing off with clever symantics. – David Soussan Oct 02 '15 at 04:36
  • Thank you for your time. Of course I didn't expect you to solve the error for me, I was just looking for a little help. It's ok your comment, I'm quite new in OOP and I have lots of things to learn. I'll wor more my OOP skills – He_slp13 Oct 02 '15 at 05:02
  • My comments above were directed to ' Your Common Sense' not yourself. That is what @ before the screen name means here. He has been happy to mark us down and also to adopt our work. I see he has even deleted the little credit he gave Rasclatt and I for our efforts. – David Soussan Oct 02 '15 at 05:56
0

Here I have used php singleton PDO connection with mysql. Hope this will be help

<?php

class DB {
protected static $instance;
protected function __construct() {
if(empty(self::$instance)) {
        try {
            self::$instance = new PDO("mysql:host=localhost;dbname=techprojects", 'root', '');
            self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
        } catch(PDOException $error) {
            echo $error->getMessage();
        }
    }

}
public static function getInstance() {
    if(empty(self::$instance)) {
        try {
            new DB();
            //var_dump(self::$instance);
        } catch(PDOException $error) {
            echo $error->getMessage();
        }
    }
    //var_dump(self::$instance);
    return self::$instance;
}

private function __clone() {
    // Stopping Clonning of Object
}

private function __wakeup() {
    // Stopping unserialize of object
}
}
?>
<?php
try {
$db = DB::getInstance();
$db1 = DB::getInstance();
$sqlExample = 'SELECT * FROM keywords';
$stm = $db->prepare($sqlExample);
$stm->execute();
$result = $stm->fetchAll(PDO::FETCH_ASSOC);

var_dump($db);
var_dump($db1);
echo "<pre>";
print_r($result);
echo "</pre>";

} catch (Exception $e) {
print $e->getMessage();

}
 ?>