Apostrophe causing error when entering data into Mysql

Asked

Viewed 2,916 times

3

I’m a beginner in PHP and I’m creating a personal project to consolidate my knowledge until I came across a problem, by entering a name that has an apostrophe this apostrophe makes the INSERT INTO not run causing the data not to be written to the Mysql database.

The query and the rest is all correct because I tested remove the apostrophe and the data were recorded correctly and were displayed on the site correctly, I would like to know how to treat these eventual errors of characters at the time of insertion.

PHP code

<?php require_once "topo-painel.php"; ?>

<?php

$array_erro = array(
    UPLOAD_ERR_OK           => "Sem erro.",
    UPLOAD_ERR_INI_SIZE     => "O arquivo enviado excede o limite definido no PHP.ini .",
    UPLOAD_ERR_FORM_SIZE    => "O arquivo enviado excede o limite definido no formulário.",
    UPLOAD_ERR_PARTIAL      => "O upload do arquivo não terminou ou foi cancelado antes de ser concluido.",
    UPLOAD_ERR_NO_FILE      => "Nenhum arquivo foi enviado.",
    UPLOAD_ERR_NO_TMP_DIR   => "Não foi definida uma pasta temporaria.",
    UPLOAD_ERR_CANT_WRITE   => "Falha ao escrever arquivo em disco",
    UPLOAD_ERR_EXTENSION    => "Uma extensão do PHP interrompeu o upload do arquivo."
);

if ( isset($_POST["cadastrar"]) ) {

    $champ_nome     = $_POST["nome-champ"];
    $champ_desc     = $_POST["desc-champ"];
    $champ_avatar   = $_FILES["avatar-champ"]["name"];

    $adiciona_champ = "INSERT INTO campeoes (champ_nome, champ_descricao, champ_avatar) VALUES ('$champ_nome', '$champ_desc', 'img/campeoes/{$champ_avatar}' )";

    $executa_champ = mysqli_query($conexao, $adiciona_champ);

    $arquivo_temporario = $_FILES["avatar-champ"]["tmp_name"];
    $arquivo = basename( $_FILES["avatar-champ"]["name"] );

    $diretorio = "../img/campeoes";

    if ( move_uploaded_file($arquivo_temporario, $diretorio."/".$arquivo) ) {
        $mensagem = "Arquivo publicado";
    }else {
        $numero_erro = $_FILES["avatar-champ"]["error"];
        $mensagem = $array_erro[$numero_erro];
    }
}

?>

<?php

?>

<?php //require_once "menu-painel.php"; ?>



<div class="col-md-10 col-md-offset-2">
    <div class="container">

        <div class="col-md-4 col-md-offset-3 mtl">
            <form action="adiciona-campeao.php" method="post" enctype="multipart/form-data">
                <div class="form-group">
                    <label for="nome-champ">Nome do campeão</label>
                    <input type="text" class="form-control" id="nome-champ" name="nome-champ" placeholder="Informe o nome do campeão">
                </div>

                <div class="form-group">
                    <label for="desc-champ">Descrição do campeão</label>
                    <input type="text" class="form-control" id="desc-champ" name="desc-champ" placeholder="Informe a descrição do campeão">
                </div>

                <div class="form-group">
                    <label for="avatar-champ">Avatar do campeão</label>
                    <input type="hidden" name="MAX_FILE_SIZE" value="3145728" />
                    <input type="file" name="avatar-champ" value="avatar" id="avatar-champ">
                    <p class="help-block">Tamanho máximo de 3MB</p>
                </div>

                <input type="submit" value="CADASTRAR" name="cadastrar" class="btn btn-outlined btn-white" />
            </form>

            <?php 
if ( isset($mensagem) ) {
    echo $mensagem;
}
            ?>
        </div>

    </div>
</div>

<?php require_once "rodape-painel.php"; ?>
  • You could test with $champ_nome = filter_input(INPUT_POST, 'nome-champ', FILTER_SANITIZE_SPECIAL_CHARS); and return the result obtained? So the parameter taken from the post with this function will be treated. You have several forms besides the FILTER_SANITIZE_SPECIAL_CHARS. Documentation: http://php.net/manual/en/function.filter-input.php

  • Rafael Withoeft Thank you very much, it worked perfectly the name was recorded in the bank as follows Cho&#39;Gath and displayed with the apostrophe on the site Thank you very much again.

  • For nothing! : ), when capturing parameters for $_POST or $_GET, at all times as possible, use filter_input.

  • 1

    @Qmechanic73 Done... thank you :)

  • 1

    vc can use tbm or mysqli_real_escape_string

  • 1

    May not, MUST. the filter input is not the correct solution for this case, but the escape.

  • 1

    @Felipedumont recommend also besides the implementation of filter, the use of Prepared Statement. See: http://php.net/manual/en/mysqli-stmt.bind-param.php or http://php.net/manual/mysqli.prepare.php or http://stackoverflow.com/questions/9629328/how-to-use-mysqli-prepared-statements-in-php

  • 1

    convert to htmlentities for this case and general cases , it is an error. It is right to escape the special and reserved characters of sql.

  • 1

    @Felipedumont I have provided a new, coolest solution for you in the answer. Note the Edit part. As there were many questions about filter_input (with good reason), I decided to edit the answer and provide a more correct solution. Thank you for the remark of Bacco and Daniel;

Show 4 more comments

1 answer

4


EDIT

The most ideal solution would be the use of Prepared Statement, que chamarei de "PS"; Let’s take a look at the example:

We keep your original string provided by the user and then use the PS that will take care of the rest (note that there will be no "Sanitize" of your string, then your apostrophes will appear correctly in the database, but without any risk because it (PS), will take care of security).

$champ_nome     = filter_input(INPUT_POST, 'nome-champ'); //Mantêm a string original
$champ_desc     = filter_input(INPUT_POST, 'desc-champ'); //Mantêm a string original
$champ_avatar   = 'img/campeoes/' . $_FILES["avatar-champ"]["name"];

//Fornecemos ? nos lugares dos valores, que indicarão um "parâmetro";
$adiciona_champ = $sua_conexao->prepare("INSERT INTO campeoes (champ_nome, champ_descricao, champ_avatar) VALUES (?, ?, ?)");

//Bind Params. Tipos: s = string, i = integer, d = double,  b = blob
//No caso são 3 Strings, então o primeiro parâmetro do bind_param receberá 'sss';
//Caso tivesse algum inteiro por exemplo, poderia ser 'ssis'... e assim por diante.
//Cuidado para não trocar a ordem que você forneceu("INSERT INTO campeoes (champ_nome, champ_descricao, champ_avatar)..."); no caso a ordem é: champ_nome, champ_descricao, champ_avatar.

$adiciona_champ->bind_param('sss', $champ_nome, $champ_desc, $champ_avatar);
$adiciona_champ->execute();


//Continuação

Another solution may be the function filter_input (most used to validate and filter information from unsafe sources), which provides the capture of external parameters and may apply specific filters.

Explanation of the documentation:

filter_input - Gets a specific External variable by name and Optionally Filters it

Syntax: filter_input(tipo, variável, filtro(opcional:vide documentação));
To filter special characters you can pass the filter: FILTER_SANITIZE_SPECIAL_CHARS.

Your code applying filter_input;

//Filtrar caracteres especiais
$champ_nome = filter_input(INPUT_POST, 'nome-champ', FILTER_SANITIZE_SPECIAL_CHARS);
//Filtrar caracteres especiais
$champ_desc = filter_input(INPUT_POST, 'desc-champ', FILTER_SANITIZE_SPECIAL_CHARS);

The ideal complement for the continuation of the code would be the use of Prepared Statement and not the direct concatenation in the SQL String.

References/Complements:

Documentation
Filter Types
PHP Prepared Statement

If you need anything else, or would like me to add more information to the answer, please let us know.

Browser other questions tagged

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