Reputation: 354
What I am trying to achieve
I am trying to update my database with values filled out in a form by the user.
I've spent a few months now with endless Google searches avoiding asking a question to StackOverflow, and every site has taught me a bit but I havent been able to finish this product.
The issue I am struggling with
On submission, the PDO::execute
does not execute and database is not updated.
Previously I was receiving errors of "Undefined index"
but those errors has been solved by passing the variables correctly. Now I am not getting any errors.
My question
What am I doing wrong? Considering I am not getting any errors in console or anywhere (and error_reporting
is on). The if
statement where I check if it has been executed, always gives nope
so somewhere in the query it's failing.
Also how can I debug this better?
What I've tried (code's been minified to reveal relevant content)
index.php (displaying table with an Update button redirecting me to update.php)
<?php
session_start();
require 'assets/php/database.php';
require 'assets/php/usersession.php';
?>
<!DOCTYPE html>
<html>
<head>
<!-- irrelevant content -->
</head>
<body>
<?php
$sql = "SELECT * FROM utlansliste";
$stmt = $conn->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll();
?>
<table>
<thead>
<th>ID</th>
<th>Brukernavn</th>
<th>Datamaskin</th>
<th>Periferiutstyr</th>
<th>Start dato</th>
<th>Slutt dato</th>
<th>Oppdater tabell</th>
</thead>
<?php
foreach($result as $rows) {
?>
<tr>
<td><?php echo $rows['id']; ?></td>
<td><?php echo $rows['username']; ?></td>
<td><?php echo $rows['hostname']; ?></td>
<td><?php echo $rows['peripherals']; ?></td>
<td><?php echo $rows['start_date']; ?></td>
<td><?php echo $rows['end_date']; ?></td>
<td><a href="update.php?id=<?php echo $rows['id'];?>&hostname=<?php echo $rows['hostname'];?>"><div class="btn btn-primary">Oppdater</div></a></td>
</tr>
<?php
}
?>
</table>
</body>
</html>
update.php (where the user fills out the form and where the execution should happen)
<?php
session_start();
require 'assets/php/database.php';
require 'assets/php/usersession.php';
if(isset($_GET['id'])) {
$id = $_GET['id'];
$hostname = $_GET['hostname'];
global $conn;
$sql = "SELECT * FROM utlansliste WHERE id='$id';";
$stmt = $conn->prepare($sql);
$stmt->execute();
$row = $stmt->fetchAll();
$username = $row[0]['username'];
$peripherals = $row[0]['peripherals'];
$start_date = $row[0]['start_date'];
$end_date = $row[0]['end_date'];
if(isset($_POST['submit'])) {
try {
global $conn;
$sql = "UPDATE utlansliste SET username = ':username', peripherals = ':peripherals', start_date = ':start_date', end_date = ':end_date', WHERE id = ':id'";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":username", $username, PDO::PARAM_STR);
$stmt->bindParam(":peripherals", $peripherals, PDO::PARAM_STR);
$stmt->bindParam(":start_date", $start_date, PDO::PARAM_STR);
$stmt->bindParam(":end_date", $end_date, PDO::PARAM_STR);
$stmt->bindParam(":id", $id, PDO::PARAM_STR);
$stmt->execute();
if ($stmt->execute()) {
echo "gg";
} else {
echo "nope";
}
/*header('Location:index.php');*/
}
catch(PDOException $exception) {
echo "Error: " . $exception->getMessage();
}
}
}
?>
<html>
<head>
<!-- irrelevant content -->
</head>
<body>
<?php include 'assets/php/header.php' ?>
<?php if( !empty($user) ): ?>
<div class="content">
<strong>Oppdater utlånsliste for <?php echo $hostname; ?></strong>
<form name="form" method="POST" action="">
<div class="updatebox" style="text-align:center;">
<label for="username">Brukernavn</label>
<div><input type="text" name="username" value="<?php echo $username;?>" id="username" required/></div>
<label for="peripherals">Periferiutstyr</label>
<div><input type="text" name="peripherals" value="<?php echo $peripherals;?>" id="peripherals"/></div>
<label for="startdate">Låne fra - dato</label>
<div><input data-date-format="YYYY/MM/DD" type="date" name="start_date" value="<?php echo $start_date;?>" id="start_date" required/></div>
<label for="enddate">Låne til - dato</label>
<div><input data-date-format="YYYY/MM/DD" type="date" name="end_date" value="<?php echo $end_date;?>" id="end_date" required/></div>
<input name="id" type="hidden" id="id" value="<?php echo $id;?>"/>
<input name="hostname" type="hidden" value="<?php echo $hostname;?>" id="hostname"/>
<input type="submit" name="submit" value="Submit"/>
</div>
</form>
</div>
<body>
</html>
Additional comments
I've looked into many sites looking for a help and knowledge. These are a few of many more. I am mainly looking for knowledge to learn this secure method of updating a database, so even just a comment helps a ton!
The unofficial PDO manual, (PDODelusions)
Upvotes: 0
Views: 171
Reputation: 33823
The sql was incorrect before - aside from the single quotes around the placeholders there was a comma before the where
clause.
$sql = "UPDATE utlansliste SET
username = :username,
peripherals = :peripherals,
start_date = :start_date,
end_date = :end_date
WHERE id = :id";
Can you confirm that the update statement actually gets called? Try printing the sql before/after the execute
method is called to ensure the program gets to that point
Gone through the PHP quickly and made a few little changes which MIGHT ( or might not ) help.
<?php
try{
session_start();
$id='';
require 'assets/php/database.php';
require 'assets/php/usersession.php';
if( isset( $_GET['id'], $_GET['hostname'] ) ) {
$id = $_GET['id'];
$hostname = $_GET['hostname'];
/*
global $conn;
The `global` keyword is used within functions to allow a variable declared outside the function
to be used within the function... think `scope`
*/
/*
$sql = "SELECT * FROM utlansliste WHERE id='$id';";
As the problem revolves around prepared statements why not use a prepared statement here
and avoid the possibility of sql injection??
*/
$sql='select * from `utlansliste` where id=:id;';
$args=array( ':id' => $id );
$stmt = $conn->prepare($sql);
$res=$stmt->execute( $args );
if( !$res )throw new Exception(' Failed to SELECT records ');
$row = $stmt->fetchAll();
$username = $row[0]['username'];
$peripherals = $row[0]['peripherals'];
$start_date = $row[0]['start_date'];
$end_date = $row[0]['end_date'];
/* make sure that all variables are available... */
if( isset( $_POST['submit'], $username,$peripherals,$start_date,$end_date ) ) {
try {
/* same issue, global is NOT required */
#global $conn;
$sql = "UPDATE utlansliste SET username = :username, peripherals = :peripherals, start_date = :start_date, end_date = :end_date WHERE id = :id";
$stmt = $conn->prepare( $sql );
$stmt->bindParam(":username", $username, PDO::PARAM_STR);
$stmt->bindParam(":peripherals", $peripherals, PDO::PARAM_STR);
$stmt->bindParam(":start_date", $start_date, PDO::PARAM_STR);
$stmt->bindParam(":end_date", $end_date, PDO::PARAM_STR);
$stmt->bindParam(":id", $id, PDO::PARAM_STR);
$result = $stmt->execute();
if ( $result ) {
echo "gg";
} else {
echo "nope";
}
/*header('Location:index.php');*/
}catch(PDOException $exception) {
echo "Error: " . $exception->getMessage();
}
}
}
}catch( Exception $e ){
exit( $e->getMessage() );
}
?>
Incidentally it is not neccessay to use a prepared statement
in the following because there is no user supplied variables and no possibility of sql injection
$sql = "SELECT * FROM utlansliste";
$stmt = $conn->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll();
If there was a where
clause then it might be different... maybe
update
To aid debugging PDO queries I use the following function debugpdo
~ an example is given as to it's usage.
function debugpdo( $sql=false, $args=array() ){
if( $sql && !empty( $args ) ){
$params = array();
$keys = array();
foreach( $args as $placeholder => $value ){
if( is_numeric( $value ) )$params[]=sprintf('set @%s=%d;',str_replace( ':', '', $placeholder ), $value );
else $params[]=sprintf('set @%s="%s";',str_replace( ':', '', $placeholder), str_replace( '"',"'", $value ) );
$keys[]=str_replace(':','@',$placeholder);
}
printf(
"<pre><h1>Copy & Paste this SQL into mySQL GUI Application</h1>%s\n\n%s;</pre>",
implode( PHP_EOL, $params ),
str_replace( array_keys( $args ), $keys, $sql )
);
}
}
$sql = "update `utlansliste` set `username`=:username, `peripherals`=:peripherals, `start_date`=:start_date, `end_date`=:end_date where `id`=:id";
$args = array(
':username' => $username,
':peripherals' => $peripherals,
':start_date' => $start_date,
':end_date' => $end_date,
':id' => $id
);
/* To debug the sql, uncomment this and run... */
exit( debugpdo( $sql, $args ) );
/* code continues... */
$stmt = $conn->prepare( $sql );
$result = $stmt->execute( $args );
Upvotes: 2