Visualizzazione risultati 1 fino 11 di 11

Discussione: Check record alfanumerico

  1. #1
    omgprova non è connesso Utente giovane
    Data registrazione
    03-02-2020
    Messaggi
    52

    Predefinito Check record alfanumerico

    salve cerco aiuto mi servirebbe fare un check su un record alfanumerico

    posto l intero codice

    Codice PHP:
    <?php
     
    //dovrei fare il check sul "fir" che ha questo formato
    //xxxx.213124/9873


    //connessione al db
    include("config.php");
     
    //var_dump($_POST);
           //dati ricevuti dalla pagina pagina salva_dati.php

    $om $_POST['omologa'];
    $dataR $_POST['data_arrivo']; 
    $cer $_POST['cer'];
    $fir $_POST['fir'];

    //se inserisco solo numeri interi il check funziona
    // con il formato alfanumerico(qasw.9876/7868) mi dice sempre record presente
    //ho provato ad inserire WHERE fir '[[:alpha:]]{1,}' = $_POST[fir] ma non cambia nulla

    //verifica record se presente
    $verifica "SELECT * FROM liquidi WHERE fir = $_POST[fir]";   
    $result mysqli_query($conn,$verifica);                       
                                                                  
    $check mysqli_num_rows($result);                           


           
    //check : se fir non è presente effettua la query
    if ($check == '0'){
    $carica_dati "INSERT INTO liquidi (omologa, data_arrivo, cer, fir) VALUES ('$om','$dataR','$cer','$fir')";

    if (
    $conn->query($carica_dati) === TRUE
        
    echo 
    '<script>alert("DATI CARICATI")</script>';

        
    }else{
    echo 
    '<script>alert("CARICAMENTO DATI FALLITO - FIR PRESENTE")</script>';}
     
    mysqli_close();
    ?>

    grazie in anticipo a chi potrà aiutarmi
    Ultima modifica di omgprova : 29-11-2020 alle ore 15.20.12

  2. #2
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,880

    Predefinito

    Aiutaci ad aiutarti!
    Dici di avere bisogno di un controllo su un valore alfanumerico, ma non dici esattamente di quale controllo hai bisogno.

    Dal codice mostrato sembra che tu debba effettuare un inserimento solo a condizione che non esista un record in cui la colonna fir valga... qualcosa di non meglio definito che dipende da un parametro dall'emblematico nome fir passato tramite POST.

    Non basta verificare che nella tabella non esistano record con fir = $_POST[fir]? Se no, perché e cosa deve essere verificato esattamente? Che ruolo gioca il formato, e come puoi dire che è "alfanumerico" se negli esempi mostrati sono contenuti caratteri non alfanumerici (il punto "." e la barra "/")?

    I suggerimenti che do più spesso:


  3. #3
    omgprova non è connesso Utente giovane
    Data registrazione
    03-02-2020
    Messaggi
    52

    Predefinito

    Citazione Originalmente inviato da mzanella Visualizza messaggio
    Aiutaci ad aiutarti!
    Dici di avere bisogno di un controllo su un valore alfanumerico, ma non dici esattamente di quale controllo hai bisogno.

    Dal codice mostrato sembra che tu debba effettuare un inserimento solo a condizione che non esista un record in cui la colonna fir valga... qualcosa di non meglio definito che dipende da un parametro dall'emblematico nome fir passato tramite POST.
    si esatto nel momento in cui vado ad inserire tutti i dati ...il "fir" non deve essere già presente ..che è un codice identificativo

    Non basta verificare che nella tabella non esistano record con fir = $_POST[fir]?
    il quel modo mi da sempre record presente...
    esempio....se inserisco
    abcd.1234/1234

    dice che è sempre presente

    mentre se inserisco
    12324
    12325
    il chek funziona
    Se no, perché e cosa deve essere verificato esattamente? Che ruolo gioca il formato, e come puoi dire che è "alfanumerico" se negli esempi mostrati sono contenuti caratteri non alfanumerici (il punto "." e la barra "/")?
    ho sbagliato a specificare il tipo..
    ma il formato è come descritto sopra
    Ultima modifica di omgprova : 29-11-2020 alle ore 20.16.12

  4. #4
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,880

    Predefinito

    Chiaro! Sorge spontanea una domanda: la colonna fir è una chiave della tabella liquidi? Se lo è non hai bisogno di controlli, puoi [cercare di] inserire il record direttamente, e MySQL ti restituirà un errore in caso di chiave duplicata. Più efficiente rispetto a eseguire una prima query solo per accertarsi che la seconda possa andare a buon fine.

    Se non è una chiave non c'è altra scelta. In questo caso, nel codice, saltano all'occhio almeno un paio d'errori:
    • stai mescolando l'interfaccia a oggetti di mysqli con quella procedurale
    • stai confrontando il valore restituito da mysqli_num_rows, che è un intero, con una stringa, è normale che il risultato sia abbastanza imprevedibile

    E naturalmente il codice è vulnerabile a SQL Injection. Prova piuttosto in questo modo:
    Codice PHP:
    <?php
    include "config.php";
    // var_dump($_POST);

    // Reads parameters
    if (!isset($_POST['omologa'], $_POST['data_arrivo'], $_POST['cer'], $_POST['fir'])) {
        die(
    "Missing mandatory parameter.");
    }
    $omologa $_POST['omologa'];
    $data_arrivo $_POST['data_arrivo']; 
    $cer $_POST['cer'];
    $fir $_POST['fir'];

    // Checks whether "fir" is a duplicate
    $query 'SELECT COUNT(*) AS is_present FROM liquidi WHERE fir = ?';
    $stmt mysqli_prepare($conn$query);
    if (!
    $stmt) {
        die(
    "Cannot prepare query: " mysqli_error($conn));
    }
    mysqli_stmt_bind_param($stmt"s"$fir);
    if (!
    myaqli_stmt_execute($stmt)) {
        die(
    "Cannot execute statement: " mysqli_error($conn));
    }
    mysqli_stmt_bind_result($stmt$row);
    mysqli_stmt_close($stmt);

    // var_dump($row);

    if ($row['is_present'] > 0) {
        echo 
    '<script>alert("CARICAMENTO DATI FALLITO - FIR PRESENTE")</script>';
    }
    else {
        
    $query 'INSERT INTO liquidi (omologa, data_arrivo, cer, fir) VALUES (?, ?, ?, ?)';
        
    $stmt mysqli_prepare($conn$query);
        if (!
    $stmt) {
            die(
    "Cannot prepare query: " mysqli_error($conn));
        }
        
    mysqli_stmt_bind_param($stmt"ssss"$omologa$data_arrivo$cer$fir);
        if (!
    myaqli_stmt_execute($stmt)) {
            die(
    "Cannot execute statement: " mysqli_error($conn));
        }
        
    mysqli_stmt_close($stmt);
        echo 
    '<script>alert("DATI CARICATI")</script>';
    }

    mysqli_close();
    ?>

    I suggerimenti che do più spesso:


  5. #5
    omgprova non è connesso Utente giovane
    Data registrazione
    03-02-2020
    Messaggi
    52

    Predefinito

    Citazione Originalmente inviato da mzanella Visualizza messaggio
    Chiaro! Sorge spontanea una domanda: la colonna fir è una chiave della tabella liquidi? Se lo è non hai bisogno di controlli, puoi [cercare di] inserire il record direttamente, e MySQL ti restituirà un errore in caso di chiave duplicata. Più efficiente rispetto a eseguire una prima query solo per accertarsi che la seconda possa andare a buon fine.

    Se non è una chiave non c'è altra scelta. In questo caso, nel codice, saltano all'occhio almeno un paio d'errori:
    • stai mescolando l'interfaccia a oggetti di mysqli con quella procedurale
    • stai confrontando il valore restituito da mysqli_num_rows, che è un intero, con una stringa, è normale che il risultato sia abbastanza imprevedibile

    E naturalmente il codice è vulnerabile a SQL Injection. Prova piuttosto in questo modo:
    Codice PHP:
    <?php
    include "config.php";
    // var_dump($_POST);

    // Reads parameters
    if (!isset($_POST['omologa'], $_POST['data_arrivo'], $_POST['cer'], $_POST['fir'])) {
        die(
    "Missing mandatory parameter.");
    }
    $omologa $_POST['omologa'];
    $data_arrivo $_POST['data_arrivo']; 
    $cer $_POST['cer'];
    $fir $_POST['fir'];

    // Checks whether "fir" is a duplicate
    $query 'SELECT COUNT(*) AS is_present FROM liquidi WHERE fir = ?';
    $stmt mysqli_prepare($conn$query);
    if (!
    $stmt) {
        die(
    "Cannot prepare query: " mysqli_error($conn));
    }
    mysqli_stmt_bind_param($stmt"s"$fir);
    if (!
    myaqli_stmt_execute($stmt)) {
        die(
    "Cannot execute statement: " mysqli_error($conn));
    }
    mysqli_stmt_bind_result($stmt$row);
    mysqli_stmt_close($stmt);

    // var_dump($row);

    if ($row['is_present'] > 0) {
        echo 
    '<script>alert("CARICAMENTO DATI FALLITO - FIR PRESENTE")</script>';
    }
    else {
        
    $query 'INSERT INTO liquidi (omologa, data_arrivo, cer, fir) VALUES (?, ?, ?, ?)';
        
    $stmt mysqli_prepare($conn$query);
        if (!
    $stmt) {
            die(
    "Cannot prepare query: " mysqli_error($conn));
        }
        
    mysqli_stmt_bind_param($stmt"ssss"$omologa$data_arrivo$cer$fir);
        if (!
    myaqli_stmt_execute($stmt)) {
            die(
    "Cannot execute statement: " mysqli_error($conn));
        }
        
    mysqli_stmt_close($stmt);
        echo 
    '<script>alert("DATI CARICATI")</script>';
    }

    mysqli_close();
    ?>
    grazie gentilissimo....ho provato il codice ma non da esito negativo se presente..di conseguenza registra sempre il record...
    poi ti chiedo un altra cosa se puoi...
    spiegarmi i passaggi da
    // Checks whether "fir" is a duplicate
    in giù
    $stmn sta per $result ?


    mysqli_stmt_bind_param($stmt, "s", $fir);

    "s" che funzione ha


    mysqli_stmt_bind_param($stmt, "ssss", $omologa, $data_arrivo, $cer, $fir);
    if (!mysqli_stmt_execute($stmt)) {

    mysqli_stmt_bind_param e _execute(stmt è standard o solo perchè il risultato della query ha quel nome?)
    poi perche la 4 "ssss" perchè sono 4 record?


    scrivere
    mysqli_stmt_bind_param($stmt, "ssss", $omologa, $data_arrivo, $cer, $fir);
    è lo stesso di scrivere ?
    $stmt->msqli_bind_param idem per execute

    edit
    come non detto mysqli_stmt_bind_param è una funzione ma dice che è stata eliminata dopo php 5.4..
    Ultima modifica di omgprova : 29-11-2020 alle ore 21.47.57

  6. #6
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,880

    Predefinito

    grazie gentilissimo....ho provato il codice ma non da esito negativo se presente..di conseguenza registra sempre il record...
    Prova ad abilitare il var_dump($row) togliendo il commento, dovrebbe riportare il numero di righe che contengono il fir indicato nella tabella liquidi. Se così non è c'è un problema a monte.

    spiegarmi i passaggi da [...]
    Codice PHP:
    // Checks whether "fir" is a duplicate
    $query 'SELECT COUNT(*) AS is_present FROM liquidi WHERE fir = ?';
    $stmt mysqli_prepare($conn$query);
    if (!
    $stmt) {
        die(
    "Cannot prepare query: " mysqli_error($conn));
    }
    mysqli_stmt_bind_param($stmt"s"$fir);
    if (!
    myaqli_stmt_execute($stmt)) {
        die(
    "Cannot execute statement: " mysqli_error($conn));
    }
    mysqli_stmt_bind_result($stmt$row);
    mysqli_stmt_close($stmt); 
    Qui viene controllato se esiste già una riga che contiene il fir indicato. Vengono usati i prepared statement di mysqli per evitare attacchi MySQL Injection.
    La prima riga definisce il testo della query: si seleziona il numero di righe nella tabella liquidi in cui fir ha il valore che si intende testare. Il numero di righe viene selezionato tramite la funzione COUNT di SQL. Questo è più efficiente rispetto a selezionare tutte le righe per poi contarle, in quanto viene restituito un singolo numero anziché un insieme di risultati.
    $stmt sta per statement, il tipo di dato al centro dei prepared statement, e viene generato chiamando mysqli_prepare. Naturalmente alla riga seguente vi è un controllo su eventuali errori.
    Tramite la funzione mysqli_stmt_bind_param il valore di $fir viene "inserito" nel segnaposto della query usata per preparare lo statement. La stringa "s" indica che viene usato un solo parametro di tipo stringa. Se le variabili da "inserire" fossero state tre, due stringhe e un intero, il codice sarebbe stato "ssd". Uno dei vantaggi dell'uso di questa funzione è che provvede automaticamente a "sanificare" i parametri passati, evitando SQL Injection.
    Non so dove tu abbia letto che questa funzione sia stata eliminata dopo PHP 5.4, come puoi vedere dalla documentazione non è così. Forse ti confondi con mysqli_bind_param (di cui, per qualche motivo, esiste solo la pagina di documentazione in spagnolo), la quale era un alias successivamente rimosso dal linguaggio.
    Dopo mysqli_stmt_bind_param, lo statement viene eseguito chiamando mysqli_stmt_execute. Nella stessa riga ne viene controllato il valore restituito per identificare la presenza di errori.
    La funzione mysqli_stmt_bind_result serve a leggere il risultato della query e scriverlo nella variabile $row, che viene contestualmente creata e inizializzata.
    Infine, mysqli_stmt_close non fa altro che indicare che l'utilizzo dello statement è terminato, e la memoria può essere liberata.

    Il codice per la query di inserimento è del tutto analogo:
    Codice PHP:
        $query 'INSERT INTO liquidi (omologa, data_arrivo, cer, fir) VALUES (?, ?, ?, ?)';
        
    $stmt mysqli_prepare($conn$query);
        if (!
    $stmt) {
            die(
    "Cannot prepare query: " mysqli_error($conn));
        }
        
    mysqli_stmt_bind_param($stmt"ssss"$omologa$data_arrivo$cer$fir);
        if (!
    myaqli_stmt_execute($stmt)) {
            die(
    "Cannot execute statement: " mysqli_error($conn));
        }
        
    mysqli_stmt_close($stmt); 
    Le uniche differenze significative sono il numero di segnaposto "?" nella query, che diventano quattro (poiché quattro sono i parametri da inserire). Di conseguenza, a mysqli_stmt_bind_param viene passato "ssss" come secondo parametro, perché i valori da inserire sono quattro, e tutti di tipo stringa.
    In questo caso non è presente mysqli_stmt_bind_result, poiché si stratta di un inserimento, quindi non c'è alcun risultato da leggere.

    I suggerimenti che do più spesso:


  7. #7
    omgprova non è connesso Utente giovane
    Data registrazione
    03-02-2020
    Messaggi
    52

    Predefinito

    Citazione Originalmente inviato da mzanella Visualizza messaggio
    Prova ad abilitare il var_dump($row) togliendo il commento, dovrebbe riportare il numero di righe che contengono il fir indicato nella tabella liquidi. Se così non è c'è un problema a monte.
    ecco l esito del var_dump($row)

    NULL
    Notice: Trying to access array offset on value of type null in C:\ on line 29

    Warning: mysqli_close() expects exactly 1 parameter, 0 given in C:\ on line 46

    riga 29
    if ($row['is_present'] > 0) {

    in pratica qualunque numero io metta anche intero me lo carica sempre...
    ho provato 555 e me lo carica piu volte...visto che mi da sempre null l esito del select count

    Codice PHP:
    // Checks whether "fir" is a duplicate
    $query 'SELECT COUNT(*) AS is_present FROM liquidi WHERE fir = ?';
    $stmt mysqli_prepare($conn$query);
    if (!
    $stmt) {
        die(
    "Cannot prepare query: " mysqli_error($conn));
    }
    mysqli_stmt_bind_param($stmt"s"$fir);
    if (!
    myaqli_stmt_execute($stmt)) {
        die(
    "Cannot execute statement: " mysqli_error($conn));
    }
    mysqli_stmt_bind_result($stmt$row);
    mysqli_stmt_close($stmt); 
    Qui viene controllato se esiste già una riga che contiene il fir indicato. Vengono usati i prepared statement di mysqli per evitare attacchi MySQL Injection.
    La prima riga definisce il testo della query: si seleziona il numero di righe nella tabella liquidi in cui fir ha il valore che si intende testare. Il numero di righe viene selezionato tramite la funzione COUNT di SQL. Questo è più efficiente rispetto a selezionare tutte le righe per poi contarle, in quanto viene restituito un singolo numero anziché un insieme di risultati.
    $stmt sta per statement, il tipo di dato al centro dei prepared statement, e viene generato chiamando mysqli_prepare. Naturalmente alla riga seguente vi è un controllo su eventuali errori.
    Tramite la funzione mysqli_stmt_bind_param il valore di $fir viene "inserito" nel segnaposto della query usata per preparare lo statement. La stringa "s" indica che viene usato un solo parametro di tipo stringa. Se le variabili da "inserire" fossero state tre, due stringhe e un intero, il codice sarebbe stato "ssd". Uno dei vantaggi dell'uso di questa funzione è che provvede automaticamente a "sanificare" i parametri passati, evitando SQL Injection.
    Non so dove tu abbia letto che questa funzione sia stata eliminata dopo PHP 5.4, come puoi vedere dalla documentazione non è così. Forse ti confondi con mysqli_bind_param (di cui, per qualche motivo, esiste solo la pagina di documentazione in spagnolo), la quale era un alias successivamente rimosso dal linguaggio.
    Dopo mysqli_stmt_bind_param, lo statement viene eseguito chiamando mysqli_stmt_execute. Nella stessa riga ne viene controllato il valore restituito per identificare la presenza di errori.
    La funzione mysqli_stmt_bind_result serve a leggere il risultato della query e scriverlo nella variabile $row, che viene contestualmente creata e inizializzata.
    Infine, mysqli_stmt_close non fa altro che indicare che l'utilizzo dello statement è terminato, e la memoria può essere liberata.

    Il codice per la query di inserimento è del tutto analogo:
    Codice PHP:
        $query 'INSERT INTO liquidi (omologa, data_arrivo, cer, fir) VALUES (?, ?, ?, ?)';
        
    $stmt mysqli_prepare($conn$query);
        if (!
    $stmt) {
            die(
    "Cannot prepare query: " mysqli_error($conn));
        }
        
    mysqli_stmt_bind_param($stmt"ssss"$omologa$data_arrivo$cer$fir);
        if (!
    myaqli_stmt_execute($stmt)) {
            die(
    "Cannot execute statement: " mysqli_error($conn));
        }
        
    mysqli_stmt_close($stmt); 
    Le uniche differenze significative sono il numero di segnaposto "?" nella query, che diventano quattro (poiché quattro sono i parametri da inserire). Di conseguenza, a mysqli_stmt_bind_param viene passato "ssss" come secondo parametro, perché i valori da inserire sono quattro, e tutti di tipo stringa.
    In questo caso non è presente mysqli_stmt_bind_result, poiché si stratta di un inserimento, quindi non c'è alcun risultato da leggere.
    poi qualcosa l ho letta ..grazie per la spiegazione
    Ultima modifica di omgprova : 30-11-2020 alle ore 12.12.44

  8. #8
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,880

    Predefinito

    ecco l esito del var_dump($row)

    NULL
    Notice: Trying to access array offset on value of type null in C:\ on line 29

    Warning: mysqli_close() expects exactly 1 parameter, 0 given in C:\ on line 46
    Chiaro, c'erano un paio di errori nel mio codice.
    Innanzitutto questa riga
    Codice PHP:
    mysqli_stmt_bind_result($stmt$row); 
    va sostituita con
    Codice PHP:
    $result mysqli_stmt_get_result($stmt);
    $row mysqli_fetch_assoc($result); 
    In pratica avevo erroneamente usato mysqli_stmt_bind_result per "associare" la variabile $row al risultato, in realtà bisogna passare prima per mysqli_stmt_get_result e poi per mysqli_fetch_assoc.

    poi quest'ultima riga
    Codice PHP:
    mysqli_close(); 
    va modificata in
    Codice PHP:
    mysqli_close($conn); 

    I suggerimenti che do più spesso:


  9. #9
    omgprova non è connesso Utente giovane
    Data registrazione
    03-02-2020
    Messaggi
    52

    Predefinito

    Citazione Originalmente inviato da mzanella Visualizza messaggio
    Chiaro, c'erano un paio di errori nel mio codice.
    Innanzitutto questa riga
    Codice PHP:
    mysqli_stmt_bind_result($stmt$row); 
    va sostituita con
    Codice PHP:
    $result mysqli_stmt_get_result($stmt);
    $row mysqli_fetch_assoc($result); 
    In pratica avevo erroneamente usato mysqli_stmt_bind_result per "associare" la variabile $row al risultato, in realtà bisogna passare prima per mysqli_stmt_get_result e poi per mysqli_fetch_assoc.

    poi quest'ultima riga
    Codice PHP:
    mysqli_close(); 
    va modificata in
    Codice PHP:
    mysqli_close($conn); 
    Grazie...funziona tutto...ultima cosa..
    Ma $query per il select
    E $query per insert..
    Come $stmt
    Non vanno in conflitto visto che hanno lo stesso nome....o visto che c è un check la seconda esclude la prima se esitò negativo

  10. #10
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,880

    Predefinito

    Non vanno in conflitto visto che hanno lo stesso nome....o visto che c è un check la seconda esclude la prima se esitò negativo
    La seconda sostituisce la prima.
    In particolare lo statement per la SELECT viene chiuso(mysqli_stmt_close($stmt)) prima che quello di inserimento sia inizializzato, quindi i due non sono mai simultaneamente attivi.
    Lo stesso vale per $query.
    Naturalmente possono essere rinominati in $query_select e $query_insert ($stmt_select, $stmt_insert)per differenziarli e rendere più espliciti i loro ruoli .
    Ultima modifica di mzanella : 30-11-2020 alle ore 14.15.03

    I suggerimenti che do più spesso:


  11. #11
    omgprova non è connesso Utente giovane
    Data registrazione
    03-02-2020
    Messaggi
    52

    Predefinito

    Citazione Originalmente inviato da mzanella Visualizza messaggio
    La seconda sostituisce la prima.
    In particolare lo statement per la SELECT viene chiuso(mysqli_stmt_close($stmt)) prima che quello di inserimento sia inizializzato, quindi i due non sono mai simultaneamente attivi.
    Lo stesso vale per $query.
    Naturalmente possono essere rinominati in $query_select e $query_insert ($stmt_select, $stmt_insert)per differenziarli e rendere più espliciti i loro ruoli .
    Grazie per i chiarimenti

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •