Php 7: Uncaught PDOException: SQLSTATE [3D000]: Invalid catalog name: 1046 No database selected in

0

I have been learning from Php in an online course that many may know, taught by Informational Pills. In this topic of connection to BBDDs with classes POO and PDO I have an error that took days without being able to resolve.

This small toy program is about a search engine that goes to a database to request the information of some products depending on the country parameter. There are four files in this small program:

index.php

<?php
require ('devuelve_productos.php');

$pais = $_GET["buscar"];

$productos = new DevuelveProductos(); #Aquí iniciamos todo, es como darle al botón del start

$array_productos = $productos->get_productos($pais);
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Conexion con clases POO</title>
</head>
<body>

<?php 

    foreach($array_productos as $elemento){?>

        <table>
            <tr>
                <td><?php echo $elemento ['CÓDIGOARTÍCULO']?> </td>
                <td><?php echo $elemento ['NOMBREARTÍCULO']?> </td>
                <td><?php echo $elemento ['SECCIÓN']?> </td>
                <td><?php echo $elemento ['PRECIO']?> </td>
                <td><?php echo $elemento ['FECHA']?> </td>
                <td><?php echo $elemento ['IMPORTADO']?> </td>
                <td><?php echo $elemento ['PAÍSDEORIGEN']?> </td>
            </tr>
        </table>
        <br><br><?php
    };
?>

returns_products.php

<?php 

require 'conexion.php';

class DevuelveProductos extends Conexion{

    public function DevuelveProductos(){

        parent::__construct(); #Aquí está llamando al cosntructor de la clase padre (o sea del archivo conexion). En conclusión, está conectando a la BBDD
    }

    public function get_productos($dato){

        $sql = 'SELECT * FROM PRODUCTOS WHERE PAÍSDEORIGEN = "' . $dato . '"';

        $sentencia = $this->conexion_db->prepare($sql);

        $sentencia->execute(array());

        $resultado = $sentencia->fetchAll(PDO::FETCH_ASSOC);

        $sentencia->closeCursor();

        $this->conexion_db = null;

        return $resultado;


    }
}
?>

conexion.php

<?php

class Conexion{

    protected $conexion_db;

    public function Conexion(){

        try {

            $this->conexion_db = new PDO('mysql:host = localhost, db_name =pruebas', 'root', '');

            $this->conexion_db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);

            $this->conexion_db->exec('SET CHARACTER SET utf8');

            return $this->conexion_db;

        } catch (Exception $e) {

            echo "Error: " . $e->getMessage() . " en la línea: " . $e->getLine();

        }finally{



        }

    }
}
?>

form_search_pays.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Formulario de búsqueda</title>
</head>
<body>
    <form action="index.php" method="get">
        <label for="buscar">Introduzca país: <input type="text" name="buscar"></label>
        <input type="submit" name="enviando" value="¡Dale!">
    </form>
</body>
</html>

When the main file is run (form_search_paises.php), it sends a call to index.php so that it returns the results of the search.

when I run the file search_ form_paises.php and I put the country I want to search for, I get this error:

  

Fatal error: Uncaught PDOException: SQLSTATE [3D000]: Invalid catalog   name: 1046 No database selected in C: \ xampp \ htdocs \ Course   PHP \ BBDD \ Conexion_BBDD_clases_poo \ using_pdo \ returns_products.php: 18   Stack trace: # 0 C: \ xampp \ htdocs \ Course   PHP \ BBDD \ Conexion_BBDD_clases_poo \ using_pdo \ returns_products.php (18):   PDOStatement-> execute (Array) # 1 C: \ xampp \ htdocs \ Course   PHP \ BBDD \ Conexion_BBDD_clases_poo \ using_pdo \ index.php (8):   ReturnsProducts-> get_products ('Espa \ xC3 \ xB1a') # 2 {main} thrown in   C: \ xampp \ htdocs \ Course   PHP \ BBDD \ Conexion_BBDD_clases_poo \ using_pdo \ returns_products.php on   line 18

I have reviewed MILLIONS of times line 18, and as far as I can see there is nothing wrong, I have reviewed MILLIONS of times the name of the database and it is also correct, I would like to know if someone can help me with this problem please.

Thank you very much in advance

    
asked by YouthProgrammer 29.03.2018 в 08:09
source

2 answers

0

As the partners have already commented on their answers, you are passing the connection data in the wrong way.

But you also have an error in the get_productos method: you pass an empty array in execute . And that code is highly vulnerable to SQL injection, it is a serious security problem.

Correcting the connection

As you can see, I'm going to use a variable $arrOptions to set a suitable configuration to the connection object that will be created. With that array, it is not necessary to make more configurations, once the object has been created. Also, in PDO you must always deactivate PDO::ATTR_EMULATE_PREPARES , otherwise, the driver will emulate certain queries and you could have a SQL injection 1 .

/*Array con todo lo necesario para la configuración*/
    $arrOptions = array(
        PDO::ATTR_EMULATE_PREPARES => FALSE, 
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 
        PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"
    );

    try {

        # Intentar la conexión 
        $this->conexion_db = new PDO('mysql:dbname=pruebas;host=localhost', 'root', '', $arrOptions);
        return $this->conexion_db;
        //Resto de tu código ...

Correcting the query in get_productos

public function get_productos($dato){
    $sql = 'SELECT * FROM PRODUCTOS WHERE PAÍSDEORIGEN = ?';
    $sentencia = $this->conexion_db->prepare($sql);
    $sentencia->execute(array($dato));
    $resultado = $sentencia->fetchAll(PDO::FETCH_ASSOC);
    $sentencia->closeCursor();
    $this->conexion_db = null;
    return $resultado;
}

Basically what has been done has been:

  • Change the SQL statement, removing the data you passed directly and changing it to a placeholder ? . Executing a sentence like you have in your code is a very serious hole ... you can sneak anything.
  • Pass variable $dato in an array in execute . That way, we neutralize any malicious attack.

As a suggestion, I would never put accents on names of columns or tables in the database. I say it for this column: PAÍSDEORIGEN .

I hope it serves you.

1 This has been extensively explained and demonstrated in my answer to the question: How to avoid SQL injection in PHP?

    
answered by 29.03.2018 / 12:41
source
0

It seems that there is an error in the constructor of PDO , try modifying it like this:

$this->conexion_db = new PDO('mysql:host=localhost;dbname=pruebas', 'root', '');

I changed db_name by dbname , I removed the spaces and changed the comma that you had put after 'localhost' by ;

    
answered by 29.03.2018 в 08:25