PHP, PDO e visualizzazioni errori e/o eccezioni

frankz

Nuovo Utente
27 Dic 2017
8
0
1
64
Qualcuno mi puo' dire come fare ad aprire finestra visualizzando gli errori sql del DB (mysql).
il codice nel file conn.php
PHP:
<?php
session_start();
$_SESSION['dbinuso']="ottica";
    $hostname="localhost";
    $dbname= $_SESSION['dbinuso'];

    $user="root";
    $pass="pippo";
    $dboptions = array(
        PDO::ATTR_PERSISTENT => FALSE,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
    );
    
    try {
        $DBsel= new PDO("mysql:host=$hostname;dbname=$dbname", $user, $pass, $dboptions);
        
    }
    catch (PDOException $ex){
        echo "ERRORE:  ". $ex->getMessage();
        die();
    }
    
?>
mi funziona tutto, tranne se NON viene inserito correttamente il nome del DB, mi compare semplicemente una pagina bianca.

mentre nel seguente caso, dove i dati provengono da un form ( e anche da JS) non segnala nessun errore del DB.
mi spiego :il campo codfisc deve essere univoco (con phpmuadmin, in effetti mi da l'errore)
PHP:
<?php
include 'conn.php';

$cognome = $_POST['cognome'];
$nome = $_POST['nome'];
$codfisc = $_POST['codfisc'];
$indirizzo = $_POST['indirizzo'];
$citta = $_POST['citta'];
$cap = $_POST['cap'];
$tel = $_POST['tel'];
$tipo = $_POST['tipo'];
$email = $_POST['email'];
$piva = $_POST['piva'];
$telcell = $_POST['telcell'];
$pr = $_POST['pr'];
$qualifica = $_POST['qualifica'];
$note = $_POST['note'];

$sql=" INSERT INTO clienti(
        cognome,
        nome,
        codfisc,
        indirizzo,
        citta,
        cap,
        tel,
        tipo,
        email,
        piva,
        telcell,
        pr,
        qualifica,
        note) VALUES (
        :cognome,
        :nome,
        :codfisc,
        :indirizzo,
        :citta,
        :cap,
        :tel,
        :tipo,
        :email,
        :piva,
        :telcell,
        :pr,
        :qualifica,
        :note)";

try {
    $stmt = $DBsel->prepare($sql);
    
        $stmt->bindParam(':cognome',$cognome);
        $stmt->bindParam(':nome',$nome);
        $stmt->bindParam(':codfisc',$codfisc);
        $stmt->bindParam(':indirizzo',$indirizzo);
        $stmt->bindParam(':citta',$citta);
        $stmt->bindParam(':cap',$cap);
        $stmt->bindParam(':tel',$tel);
        $stmt->bindParam(':tipo',$tipo);
        $stmt->bindParam(':email',$email);
        $stmt->bindParam(':piva',$piva);
        $stmt->bindParam(':telcell',$telcell);
        $stmt->bindParam(':pr',$pr);
        $stmt->bindParam(':qualifica',$qualifica);
        $stmt->bindParam(':note',$note);
        
        $stmt->execute();
       // header("location: ../views/errore.html");
} catch (Exception $ex) {
    //printErrorMessage($ex->getMessage());
   // header("location: ../views/errore.html");
    echo "ERRORE:  ". $ex->getMessage();
    die ('ERRORE');
}
il codice JS relativo alle istruzioni sopra è:
Codice:
    $('#fanacli').form('submit');
    window.location.href = '../views/clienti.php';
qualcuno mi puo' aiutare o indicarmi come risolvere il problema?
grazie.
 

macus_adi

Utente Attivo
5 Dic 2017
1.294
85
48
IT/SW
Ciao @frankz, non capisco perchè inserisci il nome del database nella sessione, solitamente si usa un file di configurazione....
$stmt = $DBsel->prepare($sql);

$stmt->bindParam(':cognome',$cognome);
$stmt->bindParam(':nome',$nome);
$stmt->bindParam(':codfisc',$codfisc);
$stmt->bindParam(':indirizzo',$indirizzo);
$stmt->bindParam(':citta',$citta);
$stmt->bindParam(':cap',$cap);
$stmt->bindParam(':tel',$tel);
$stmt->bindParam(':tipo',$tipo);
$stmt->bindParam(':email',$email);
$stmt->bindParam(':piva',$piva);
$stmt->bindParam(':telcell',$telcell);
$stmt->bindParam(':pr',$pr);
$stmt->bindParam(':qualifica',$qualifica);
$stmt->bindParam(':note',$note);

$stmt->execute();
Quando effettui le chiamate in ajax, dovresti prevedere i casi possibili e le relative rispose.... Va bene il preparedstatement, me se hai dei vincoli dovresti gestirli in modo differente....

Altra nota, prevedi una mappatura nel modello, così quando invii i dati (che sia js o no) non devi metterci mano....
Mi spiego...
$('#fanacli').form('submit');
Cosa produce?
Sicuramente valorizzi la variabile POST, credi convenga mappare i dati a mano? Ad ogni modifica del DB e/o della view dovrai ricordarti di inserire i valori mancanti nella insert/update/select.
Secondo me le cose da fare sono :
  1. Creare il modello per recuperare, modificare e inserire i dati
  2. Insert
    1. Prevedere i vincoli e nel caso gestire l'eccezioni, tipo (codfiscale univoco)
      1. Prevedi un metodo che verifica il codice fiscale
      2. Nel caso in cui il codice fiscale risulta già inserito non prosegui con il codice
    2. Mappa il modello dati con la view a modi array
PHP:
$map_insert=['nome'=>'view_name','cognome'=>'my_cognome'....etc]
In questo modo sleghi effettivamente i nomi degli input con i reali campi del DB. Naturalmente nel modello devi prevedere tutte le eccezioni....

Cmq tornando alla tua richiesta.....
PHP:
print_r($DBsel->errorInfo());
http://php.net/manual/en/pdo.errorinfo.php

Spero sia utile, e soprattutto spero si capisca...
 

marino51

Utente Attivo
28 Feb 2013
2.920
164
63
Lombardia
per la tua specifica richiesta, considera che,

un errore non dovrebbe mai essere generato dalla gestione del db in "produzione",
se ciò dovesse mai succedere,

credo sia necessario interrompere quella transazione per evitare inconsistenze nel db stesso

se poi il messaggio di errore arriva all'utente, quasi sicuramente viene perso e non comunicato nei dovuti modi a chi deve provvedere

da queste considerazioni, ti suggerisco di registrare il messaggio di errore nel log di php, modificando il file conn.php con,
PHP:
try { $DBsel= new PDO("mysql:host=$hostname;dbname=$dbname", $user, $pass, $dboptions); }
catch (PDOException $ex) { sql_errors("PDO : ERRORE connessione al db", $ex); }

function sql_errors($sql, $e)
{
    error_log("SQL cmd    : ".$sql, 0);
    error_log("error code : ".$e->getCode(), 0);
    error_log("error info : ".$e->getMessage(), 0);

    die("ERRORE INATTESO, contatta l'amministratore del sistema");
}
ed allo stesso modo puoi usare la funzione che è stata inserita nei successivi script php che includono "conn.php"

PHP:
    $stmt->execute();
}
catch (PDOException $ex) { sql_errors($sql, $ex); }
certo è utile avere anche il contenuto delle variabili che alimentano la query,
puoi ampliare la funzione "sql_errors" affinchè affinchè le possa trattare (magari attraverso un'array)
 

frankz

Nuovo Utente
27 Dic 2017
8
0
1
64
Scuatemi per il ritardo della risposta, ma ero impossibilitato a rispondere.
Il DB lo metto in sessione perche' ogni anno devo svuotare alcune tabelle contabili, matenere lo storico dei clienti. facendo la copia a fine anno, in seguito posso richiamare il DB di qull'anno specifico. Sperando che possa aprire il DB in sola lettura (non ci avevo ancora pensato a questo particolare).
Ho risolto facendo un Submit "normale" e NON con ajax (che ho capito solo il principio).
Per quanto riguarda le MAp hai ragione, ma non le conosco.
Mi puoi dare dei link o libri per approfondire gli argomenti di ajax e Map ?
Grazie.