Object of class Conn could not be converted to string in

2

The following error is presented to me when designing queries to the database, I enclose the source code:

Validations.php:

<?php 

session_start();
if(isset($_SESSION['usuario'])){
header('Location: vistas/home.php');
}

if($_SERVER['REQUEST_METHOD'] == 'POST'){
  $usuario = $_POST['username'];
  $password = $_POST['contrasena'];

require 'config/conn.php';

$sql = "SELECT * FROM usuario WHERE username = :username AND password = :contrasena";
$consulta = $conexion-> prepare($sql);
$consulta = execute(array('usuario' => $usuario, 'contrasena' => $password));

$resultado = $consulta ->fetch();

if($resultado !== false){
    $_SESSION['usuario'] = $usuario;
    header('Location: vistas/home.php');
}else{
    header('Location: index.php');
}
}
?>

Connection text:

<?php

class Conn
{

//Atributos de la base de datos
private $dbname;
private $host;
private $user;
private $pass;
private $port;
private $conexion;

//Métodos
public function __construct()
{
    $this->dbname = "scrum";
    $this->host = "localhost";
    $this->user = "postgres";
    $this->pass = "1234";
    $this->port = "5432";

    try{
        $this->conexion = new PDO("pgsql:host=".$this->host.
                            ";port=".$this->port.
                            ";dbname=".$this->dbname.
                            ";user=".$this->user.
                            ";password=".$this->pass);
        }catch(Exception $e)
        {
            echo "Tienes el siguiente error:", $e->getMessage();
        }
}



}

?>
    
asked by Cristian Camilo Cadavid Escarr 26.11.2018 в 04:22
source

2 answers

2

I understand that you want to make your class Conn a wrapper (wrapper) of your PDO class, which I think is perfect, because that way every time you need to connect you do not have to be passing the credentials. Also, if you connect wherever you use the database and offer to change the password for example, you will not have to start looking in the code where you connected to do it, but you change it in your package nothing else.

The problem is that for the class to have all the functionalities of PDO it is necessary to make it extend PDO. This will be done by simply writing the class like this:

class Conn extends PDO {

By doing that, your class will already have all the PDO methods.

But, the class needs some small improvements:

  • you must call the constructor of the parent class, which is PDO
  • We are also going to establish some important configurations that will save you future headaches: establish an adequate coding, turn off the emulated preparations and correctly establish the handling of exceptions

The class would then be like this:

<?php
class Conn extends PDO
{

    //Atributos de la base de datos
    private $dbname;
    private $host;
    private $user;
    private $pass;
    private $port;

    //Métodos
    public function __construct()
    {
        $this->dbname = "scrum";
        $this->host = "localhost";
        $this->user = "postgres";
        $this->pass = "1234";
        $this->port = "5432";
        $charset="utf8";
        $dsn="pgsql:host=$this->host;port=$this->port;dbname=$this->dbname;charset=$charset";
        $options = array(
            PDO::ATTR_EMULATE_PREPARES => FALSE,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
        );

        try{
            parent::__construct($dsn, $this->user, $this->pass, $options);
        }catch(Exception $e)
        {
            echo "Tienes el siguiente error:", $e->getMessage();
        }
    }
}
?>

Now to use it, you just have to include the file and create a new instance of Conn :

require 'config/conn.php';
$conexion=new Conn();
$sql = "SELECT * FROM usuario WHERE username = :username AND password = :contrasena";
$consulta = $conexion-> prepare($sql);
$consulta = execute(array(':username' => $usuario, ':contrasena' => $password));
//Reste del código

Since Conn extends from PDO , you will now have available in $conexion all methods of class PDO .

I hope it will be useful for you. If something does not work or you have doubts, you can express it in comments.

Note: The array of execute was wrong, I have corrected it.

    
answered by 26.11.2018 / 12:52
source
0

I see that you have two problems.

First, you're assuming that by including the Conn class a $conn object that is a PDO instance is magically generated. Actually the only thing that happens is that you can do something with the Conn class.

Suppose you do then:

$conexion = new Conn();

Now connection is an instance of the Conn class, so you can now occupy its instance methods.

Now comes the second problem. Even if you implement the above, $conexion has no such thing as a prepare method. Actually you should do it with something like:

require 'config/conn.php';
$conexion = new Conn();
$sql = "SELECT ... ";

$consulta = $conexion->conexion->prepare($sql);

Because it is the instance property conexion that constitutes a PDO instance, and not the instance of Conn itself.

One way to save this syntax (connection-> connection) is indicated by A. Cedano. Another common way is to use a getter that encapsulates the use of the instance variable ( EDIT : I had put public class instead of public function to the methods.) A shame Thank you Cristian Camilo Cadavid Escarr for notifying me)

class Conn {

  protected $conexion;

  public function __construct() {
       $this->conexion = new PDO(...);
  }

  public function getConexion() {
       return $this->conexion;
  }

}

And then instantiate it and use the getter to encapsulate the property:

require 'config/conn.php';
$conn = new Conn();
$conexion = $conn->getConexion();
$sql = "SELECT ... ";

$consulta = $conexion->prepare($sql);

In this way your property $conexion can be protected, which nobody uses directly, but must call it with the getter. With this encapsulation the declaration of the class and its subsequent use are decoupled and tomorrow you are free to rename $conexion as $misuperconexionqueyosolamentesecomosellama and it would not matter, the user does not use it directly but through the getter ..

There are other ways to implement the same. If you want to save the step of instantiating the class, you can make the instance itself a static property of the class, and therefore can be accessed from a static method. If the instance does not exist, create it. Then it returns the property $conexion .

class Conn {

   protected $conexion;
   protected static $instance;

   public class __construct() {
       $this->conexion = new PDO(...);
   }

   public static function getConexion() {
       if(!self::$instance) {
            self::$instance = new static();
       }
       return self::$instance->conexion;
   }
}

So you could do:

require 'config/conn.php';
$conexion = Conn::getConexion();

$sql = "SELECT ... ";
$consulta = $conexion->prepare($sql);

This last example is using the Singleton pattern that, at this point, does not have many admirers to say.

Returning to the first problem, there is clearly a part of the code that you are not showing us . Nothing of the code that you hit (and from which we have responded) would generate that error.

    
answered by 26.11.2018 в 13:16