Unknown error when submitting form - Kevin Yank/Tom Bulter PHP/MySQL Novice to Ninja 6th Edition

I’ve been learning PDO via Kevin Yank/Tom Butler’s Php/MySQL Novice to Ninja 6th. I have had success with it thus far and been able to input data via form. But I have been trying everything to make this form submit but it just won’t work. I wish I could see an error when I submit, but all I get is a blank page.

<?

if (isset($_POST['user'])) {

        $user = $_POST['user'];   
        $user['date'] = new DateTime();
        
        save($pdo, 'users', 'id', $user); 

        echo('<script>alert("Successfully.")</script>');
        
}

$gp = findById($pdo, 'users', 'id', $id);
	
?>

<form action="<? $_SERVER['PHP_SELF']; ?>" method="post">
<input type="hidden" name="user[id]" value="<?=$gp['id'] ?? ''?>" />
  <p>Make Admin:</p>
      <select name="user[admin]">
      <option value="1">Yes</option>
        <option value="" selected="selected">No</option>
      </select>
    <p>Full Name:</p>
      <input type="text" name="user[name]" value="<?=$gp['name'] ?? ''?>" />
    <p>Username:</p>
      <input type="text" name="user[username]" value="<?=$gp['username'] ?? ''?>" />
      <p>Email Address:</p>
      <input type="email" name="user[email]" value="<?=$gp['email'] ?? ''?>" />
    
      <input type="submit" value="Submit" name="submit" />
  
</form>

They created a univeral function called save which is what I use to save the form. When I remove this link $user = $_POST[‘user’]; the form submits but it’s blank. When I add it back, the form produces a blank page. I use the exact same format for another form and it worked so I am really confused where the problem is coming from.

This is the save function;

function save($pdo, $table, $primaryKey, $record) {
    try {
        if ($record[$primaryKey] == '') {
            $record[$primaryKey] = null;
        }
        insert($pdo, $table, $record);
    }
    catch (PDOException $e) {
        update($pdo, $table, $primaryKey, $record);
   } 
}

Turn on error reporting. If the code you are trying is only what you posted, you have a Fatal Error.

I assume you have $id defined and values from the user DB table are populating the form??? Otherwise findById() and all $gp lines would be throwing errors. Other than that, placing print_r() within your POST condition prints out fine so the form is submitting values.

if(isset($_POST['user'])) {

	echo "<pre>";
	print_r($_POST['user']);	
	echo "</pre>";
Array
(
    [id] => 1
    [admin] => 1
    [name] => me
    [username] => bigme
    [email] => me@mail.ccom
)

Someone’s short-tags bit them on the rear here methinks…?

2 Likes

There are other forms that use the same short-tags and they all work fine. Can you explain further pls?

That’s what I want to find out how to do that. It’s not stated in the book.

Yep. $id is defined and when I edit a user, it’s data populates the fields. But when I hit submit, I get a blank page. When I change this line $user =$_POST[‘user’] to anything else eg. $user = ‘’ and submit, a new row is added to the db with only the date and new id populated, everything else is blank even though the print_r shows that the values are been sent.

This code is filled with gotcha’s. It might work under perfect conditions, but won’t tell you why it has failed if anything has gone wrong. Using short opening tags results in non-portable code and has resulted in a huge amount of wasted time, simply, spend the time typing the three extra php characters. It’s apparently not trimming and validating input data before using it. It either missed echoing the form’s action attribute or the = got lost somewhere, however, since using the raw $_SERVER['PHP_SELF'] is not safe, it’s fortunate that the echo is missing. By passing the id being edited through the form, and having no apparent user permission system, will allow anyone to edit the data for any user. There are at least a half a dozen different errors that can occur for an INSERT query, so the code should NOT unconditionally perform an UPDATE query for any insert error, only if the data already exists (and for this case there’s a single, atomic query that won’t suffer from a race condition that should be used instead), and in fact if the current operation is specifically to edit existing data, the code shouldn’t even be attempting to run an insert query.

Your book should have covered setting php’s error_reporting and display_errors settings, in the php.ini on your system, so that php would help you by reporting and displaying all the errors it detects. At the point of starting using database code, is should have covered using exceptions for database statement errors and when to catch and handle them in your code, for ‘recoverable’ errors only.

As to what the current issue is, it would take having all the relevant code, less any database connection credentials, in order to specifically help. (I suspect that since the code is dependent on exceptions being used for the database statements, that the reason the UPDATE logic isn’t being executed is because the setting needed to set the error mode to exceptions isn’t being used.)

1 Like

Yes the book did discuss how to display errors but that was only for when you failed to connect to the database. It doesn’t show you how to display errors if you submit a form and something goes wrong.

I have the book so I took a look thinking how to set error reporting would be in there. Apparently not. Tom starts from the position you already have your dev set up.

Chapter 14
For our purposes, however, the server is up and running, and you’re
ready to write your first PHP script.

So, OP, while we all are happy to help and turning on error reporting is a trivial task, did you even try to help yourself and google how to turn it on? If you want to be a programmer, making an attempt at solving the problems you encounter is one of the basic skills you will need to develop. This includes googling for an answer before you ask a help forum for answers. I am going to refrain from telling you how to turn it on since it is such a trivial task that you could find the answer to in two seconds on google.

I am familiar with this book. It will teach you many things but it does go from novice level to ninja quite fast so you will need to pay close attention as you follow along. Feel free to come back if you get stuck after you have tried to find the answer yourself. @TomButler, one of the authors, has been known to show up here once in awhile.

Since the book has left out the dev setup, allow me to guide you. If you are on Windows, install Laragon. It will set up a local dev for you and is the best WAMP for windows for many reasons.

Hahahaha, I appreciate that. And I wish it was that trivia for some of us. When I was on php 5.6 I just added a few lines to my sql statement ie;

if (mysql_query($sql)) { echo('<script>alert("Page updated successfully.")</script>'); } else exit('<p>Error fetching data: ' . mysql_error() . '</p>');

And this would spew out any errors you face when submitting to the db. I don’t even know where to begin when it comes to PDO. Drummin was able to help with the print_r() but if he hadn’t shown exactly where to type that command within my codes, it wouldn’t have produced the results above. So that’s why it’s best to just ask questions relating to your problem. Had it been a generic issue not a specific one like this, I would know what to search for.

I don’t know about anyone else, but I just shudder when I see mysql_* code. LOL! :cold_face:

I don’t know where your skill level is, but since you mentioned PDO I have a better and faster place for you to start before you get into the book. Start with this PDO tutorial. It will get right to the meat of things without any fluff.

1 Like

Thanks. Am actually following the book quite nicely. Already on Chapter 10, going on 11. I just hit a stumbling block which WASN’T addressed in the book as you rightly said. Now if I could just get someone to show me the equivalent of mysql_error() and how to implement it in the code above, that would be great and I can continue with the book.

I will check out that site when I do complete the book. Thanks.

The tutorial is actually a quick read and will give you the answer you are looking for for PDO errors. I would really suggest you take 15 minutes to look it over first.

Ok. Will do. Thanks alot. Preciate it. I hope I don’t have to hit you up again regarding something from the book :grinning:

Oh, you probably will and that’s OK. We are here to help.

1 Like

Another issue with the posted code is that it repopulates the form fields with the initial values upon an error, losing any typing the user did. It is a simple logic statement to only get the initial data if the form has never been submitted.

The code is trying to use exceptions for errors for queries, i.e the try/catch logic. This is not just an A B substitution. This requires a setting to be made in the connection code, then ONLY catch the exception in your code for user ‘recoverable’ errors, such as when inserting/updating duplicate or out of range values, in which case the catch logic must test the error number and execute appropriate logic. For all other query-cases and all other query errors, just let php catch and handle the exception, where php will use its error related settings to control what happens with the actual error information (database statement errors will ‘automatically’ get displayed/logged the same as php errors.)

Should I assume all user[keys] found in POST match fields in the user table? You have a field called admin? Is the field type INTEGER? How is that being handled in the query? And a field called date as you are also passing this with user? I don’t think it’s good to use a reserved word as a field name. Maybe like created_date or modified_date… Hey maybe I am just not understanding how your insert() and update() functions are written.

At the very least I would check that the ID is being passed as it is required for the update query and go directly to the update() function. Something like this.


if($_SERVER["REQUEST_METHOD"] == "POST" && !empty($_POST['user']) && !empty($_POST['user']['id')):

	$user = $_POST['user'];   
	$user['date'] = new DateTime();
	update($pdo, 'users', 'id', $user);
	
endif;

Oh Ma Gosh! So I checked the columns in the db against the field names and I realized that admin isn’t in the db. I changed it to what’s in the db and it worked. So basically mysql wasn’t finding admin in the db and so it wasn’t submitting the form. Previously echo mysql_error would have displayed an error stating column ‘admin’ doesn’t exist. But with this, I didn’t get anything. I wonder how this could have been fixed?

By having error handling that is correctly written and actually helps you.

When learning, developing, and debugging code/query(ies), you would like to display all the php and database statement error information, so that you get immediate feedback as to any problems. When putting code onto a live/public server, you would like to log all the error information, so that if a legitimate visitor does something that you didn’t anticipate or a hacker attempts/succeeds in breaking in, you will know what has occurred and can fix it.

For database statements, if you use exceptions for errors and in most cases let php catch and handle the exception, meaning don’t put any try/catch logic in your code, php will ‘automatically’ display/log the actual error information, the same as displaying/logging php errors, via an uncaught exception error.

For the PDO extension, the connection always uses an exception for an error. When you make the connection you would set the error mode to exceptions so that all the other database statements - query, prepare, and execute, will also use exceptions for errors.

The current code’s database exception handling is wrong and should simply be removed for now. If the INSERT query is failing, the code isn’t testing what sql error number occurred, so it isn’t reporting errors that are due to programming mistakes. If you get to the point of needing to detect if duplicate user data was attempted to be inserted, someone can show how to write the try/catch logic to detect this and to re-throw the PDO exception for all other error numbers.