Use prepare statement at a constant value?

Asked

Viewed 56 times

3

$type = 'post';
$stmtPG = $conn->prepare("SELECT count(*) FROM myTable WHERE entry_type = :type");
$stmtPG->bindParam(':type', $type);
$stmtPG->execute();
$total = $stmtPG->fetchColumn();
$total_paginas = ceil($total/$maximo);

A while ago I saw in a stackoverflow question here that a guy said that you don’t need to prepare constant values, I had also googled about prepared statement, but I didn’t get it right.

As that code should be?

Edit:

$stmtPG = $conn->query("SELECT count(*) FROM myTable WHERE entry_type = 'post'");
$total = $stmtPG->fetchColumn();
$total_paginas = ceil($total/$maximo);
  • Basically a constant is a value that does not change, if you know what is the initial value of it does not have why to escape it, now if its value is dynamic (comes from the user input) is necessary as well as all other inputs. Remember, never trust your customer’s data

3 answers

2


Prepared Statement

In short: you will be preparandoyour query protected to prevent attacks such as sql Injection and will also gain more performance in the execution of the consultation.

We must always protect the data that comes from front, that is, that are sent by the user. In your case, the variable that is part of the query is already directly in the code, so it is not necessary to perform the preparation (unless the variable value is malicious. Which developer would do this?).

In that case, your query could look like this:

$type = 'post';
$stmtPG = $conn->query("SELECT count(*) FROM myTable WHERE entry_type = " .$type);    
$total = $stmtPG->fetchColumn();
$total_paginas = ceil($total/$maximo);

If the variable value $type came from outside, for example, a POST = $_POST['tipo'], to preparação consultation would be of utmost importance.

Here I leave some references for study:

Sql Injection

How an SQL Injection happens?

How to prevent SQL code injection into my PHP code?

Article about Prepared Statements

  • With the code you showed me is appearing an error saying that the column post does not exist. In my case post is the value of the column entry_type. I tried to do it differently here, look at my question Dit.

  • 1

    Avoiding SQL Injection is one of the advantages of using Prepared Statement, but it is not only for this it serves, it also increases the performance of repeated queries

  • @Susi edited the answer, take a look.

  • @Guilhermecostamilam really, I forgot to add that information.

  • @Jorgematheus A doubt, what is the need to put a variable in the value of entry_type = '$type'?

  • 1

    @Susi, I put as variable because in your example the value is stored in the variable, but could put directly in the query.

Show 1 more comment

1

Assuming you know what it is SQL Injection

First you need to understand one thing, Prepared Statement has two features:

  • Escaping values (if well used)
  • Optimize Repeated Searches

So you should use it whenever possible, not necessarily for the first but for the second. Now if you will pass the values by bindParam depends on whether you know what that value is, and not whether or not the value is a constant

For example imagine that you have a class that does some pagination queries:

class Paginacao {
    private $itensPorPagina;

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

    public function buscarPorNome($nome) {
        $stmtPG = $conn->prepare("SELECT * FROM usuarios WHERE nome = :nome LIMIT $this->itensPorPagina");
        $stmtPG->bindParam(':nome', $name, PDO::PARAM_STR);

        //...
    }

    public function buscarPorTelefone($telefone) {
        $stmtPG = $conn->prepare("SELECT * FROM usuarios WHERE telefone = :telefone LIMIT $this->itensPorPagina");
        $stmtPG->bindParam(':telefone', $telefone, PDO::PARAM_STR);

        //...
    }
}

Then you’d use it that way

$paginacao = new Paginacao(25);

$paginacao->buscarPorNome($_GET["nome"]);

Note that itensPorPagina is not a constant, but who defines its value is the programmer at the time of instantiating the class Paginacao

You don’t need to pass the itensPorPagina for bindValue because you know that its value is only an integer of value 25, the fact that it is a constant has nothing to do with

Now if it was a variable that came from the user, like the name and phone, then yes, you need to go through bindParam to avoid SQL Injection

Completion

You do not need to pass variables as a parameter in SQL statements if you know what their value is. Only pass what is doubtful (user entries)

  • But because you used a named paramter in value of nome? ":name". From what I understood the value of nome wouldn’t come from the user, so I don’t know why you put it on bindParam. PS: I don’t usually use the bindParam and even less in a function then I might be talking nonsense.

  • On the contrary, name will come from the user input, updated the question, see if it became clearer

1

It must be borne in mind that Prepared Statements do not serve solely to prevent SQL Injection, the other great advantage is that SGBD caches the Statement so you don’t need to rebuild an equal query.

That said, I would use bindParam even if the value is a constant because the:

SELECT count(*) FROM myTable WHERE entry_type = 'post';
SELECT count(*) FROM myTable WHERE entry_type = 'page';

Theoretically they would be compiled twice by the server, where a Prepared Statement would only be compiled once and the client would only send the parameters to the server.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.