ho sempre fatto il semplice collegamento di mysql_connect
, mysql_pconnect
:Sostituzione mysql_ * funzioni con DOP e le istruzioni preparate
$db = mysql_pconnect('*host*', '*user*', '*pass*');
if (!$db) {
echo("<strong>Error:</strong> Could not connect to the database!");
exit;
}
mysql_select_db('*database*');
Durante l'utilizzo di questo ho sempre usato il metodo semplice per sfuggire tutti i dati prima di prendere una interrogazione, sia che si tratti INSERT
, SELECT
, UPDATE
o DELETE
utilizzando mysql_real_escape_string
$name = $_POST['name'];
$name = mysql_real_escape_string($name);
$sql = mysql_query("SELECT * FROM `users` WHERE (`name` = '$name')") or die(mysql_error());
Ora ho capito questo è sicuro, in una certa misura!
Sfugge a personaggi pericolosi; tuttavia, è ancora vulnerabile ad altri attacchi che possono contenere caratteri sicuri, ma possono essere dannosi per la visualizzazione di dati o, in alcuni casi, per la modifica o l'eliminazione di dati maliziosi.
Così, ho cercato un po 'e ho trovato informazioni su PDO, MySQLi e istruzioni preparate. Sì, potrei essere in ritardo con il gioco ma ho letto molti, molti tutorial (tizag, W3C, blog, ricerche Google) là fuori e nessuno li ha menzionati. Sembra molto strano il motivo per cui, come solo la fuga di input da parte dell'utente non è davvero sicuro e non è una buona pratica per non dire altro. Sì, sono consapevole che potresti usare Regex per affrontarlo, ma sono sicuro che non è abbastanza?
È a mio avviso che l'utilizzo di istruzioni PDO/preparato è un modo molto più sicuro di archiviare e recuperare i dati da un database quando le variabili sono fornite dall'input dell'utente. L'unico problema è che il passaggio (specialmente dopo essere rimasto bloccato nei miei modi/abitudini di codifica precedente) è un po 'difficile.
questo momento ho capito che per la connessione al database utilizzando il mio DOP userei
$hostname = '*host*';
$username = '*user*';
$password = '*pass*';
$database = '*database*'
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
if ($dbh) {
echo 'Connected to database';
} else {
echo 'Could not connect to database';
}
Ora, i nomi di funzione sono diversi in modo non sarà più il mio mysql_query
, mysql_fetch_array
, mysql_num_rows
ecc lavoro. Quindi devo leggere/ricordare un carico di nuovi, ma è qui che mi sto confondendo.
Se volevo inserire dati da un modulo di iscrizione/registrazione, come potrei fare, ma soprattutto come procedere in modo sicuro? Presumo che questo è dove arrivano le dichiarazioni preparate, ma usandole questo elimina la necessità di utilizzare qualcosa come mysql_real_escape_string
? So che mysql_real_escape_string
richiede che tu sia connesso a un database tramite mysql_connect
/mysql_pconnect
, quindi ora non stiamo usando nessuno di questi non produrrà solo un errore?
Ho visto diversi modi per avvicinarsi al metodo PDO, ad esempio, ho visto :variable
e ?
come quelli che penso siano noti come segnaposto (scusate se è sbagliato).
Ma penso che questo è più o meno l'idea di ciò che dovrebbe essere fatto per andare a prendere un utente da un database
$user_id = $_GET['id']; // For example from a URL query string
$stmt = $dbh->prepare("SELECT * FROM `users` WHERE `id` = :user_id");
$stmt->bindParam(':user_id', $user_id, PDO::PARAM_INT);
Ma poi mi sono bloccato su un paio di cose, se la variabile non era un numero ed era una stringa di testo, devi dare una lunghezza dopo PDO:PARAM_STR
se non sbaglio. Ma come puoi dare una lunghezza impostata se non sei sicuro del valore dato dai dati inseriti dall'utente, può variare ogni volta? Ad ogni modo, per quanto ne so per visualizzare i dati che poi fare
$stmt->execute();
$result = $stmt->fetchAll();
// Either
foreach($result as $row) {
echo $row['user_id'].'<br />';
echo $row['user_name'].'<br />';
echo $row['user_email'];
}
// Or
foreach($result as $row) {
$user_id = $row['user_id'];
$user_name = $row['user_name'];
$user_email = $row['user_email'];
}
echo("".$user_id."<br />".$user_name."<br />".$user_email."");
Ora, è questo tutto al sicuro?
Se ho ragione, sarebbe l'inserimento di dati sia lo stesso per esempio:
$username = $_POST['username'];
$email = $_POST['email'];
$stmt = $dbh->prepare("INSERT INTO `users` (username, email)
VALUES (:username, :email)");
$stmt->bindParam(':username, $username, PDO::PARAM_STR, ?_LENGTH_?);
$stmt->bindParam(':email, $email, PDO::PARAM_STR, ?_LENGTH_?);
$stmt->execute();
Sarebbe
che il lavoro, ed è che sicura troppo? Se è giusto quale valore inserirò per lo ?_LENGTH_?
? Ho completamente sbagliato tutto questo?
UPDATE
Le risposte che ho avuto finora sono stati estremamente utili, non è possibile grazie ragazzi abbastanza! Tutti hanno un +1 per aprire gli occhi a qualcosa di un po 'diverso. È difficile scegliere la risposta migliore, ma credo che il Col. Shrapnel se lo meriti dato che tutto è praticamente coperto, persino andando in altri array con librerie personalizzate di cui non ero a conoscenza!
Ma grazie a tutti voi :)
Forse la lunghezza dei campi "nome utente" e "email"? Per esempio. se username è varchar (32), il parametro length dovrebbe essere 32. – deejayy