Your database design MUST enforce uniqueness to prevent duplicate data. If there are multiple concurrent requests for the same room, date, and time, only one request should succeed in inserting data. By trying to first SELECT the data, all the concurrent requests will find that the data doesn’t exist and will still run the insert query.
To handle this properly, define a composite unique index consisting of the three - type_salle, reservation_date, and periode columns, then simply attempt to insert the data. The query that wins this concurrent race will run without any error and successfully insert the data. The query(ies) that fail will return a duplicate index error. You would have error handling for the insert query that tests for a duplicate index error number, in order to set up and display a message for the user that the submitted data already exists.
The rest of this code has some problems that will result in improper operation, a poor user experience, and in more code than is necessary -
- Each header() redirect needs an exit statement to stop program execution. For example, if there is a logged in user, but their rank is less than 1, all the code will still run and attempt to insert the submitted data.
- You should only store the user’s id in the session variable to indicate who the logged in user is. You should query on each page request to get any other user information, such as the username and rank, so that any changes made to those values will take effect on the very next page request.
- The only redirect you should have is upon successful completion of the post method form processing code, to the exact same url of the current page, to cause a get request for that page. You should have navigation links to allow the visitor to goto other pages on the site. All the other redirects are more work and take more code to accomplish a task. You also have an error in the url in the last header() redirect, that will go away when you make this change to the code.
- The post method form processing code should first detect that a post method form was submitted, then trim and validate all inputs, storing validation error messages in an array using the field name as the array index, then only use the form data if there are no validation errors. You would display the contents of this array at the appropriate location in the html document when you re-display the form.
- Don’t copy variables to other variables for no reason. This is just a waste of typing.
- Don’t use $_REQUEST variables. Use the correct $_GET, $_POST, or $_COOKIE variables that you expect the data to be in.
- Don’t put external, unknown, dynamic values directly into sql query statements. Use a prepared query with ? place-holders in the sql query for each value, then supply the values when the query finally gets executed.
- You should switch to the much simpler and more consistent PDO extension.
- You should have error handling for each statement that can fail. For database statements, the easiest way of adding error handling, without adding logic at each statement that can fail - connection, query, prepare, and execute, is to use exceptions for errors and in most cases 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.) The exception to this rule is when inserting/updating user submitted duplicate or out of range values. In this case, your code should catch the exception and test if the error number is for something your code is designed to handle. For all other error numbers, just re-throw the exception and let php handle it.
- The form and form processing code should be on the same page. This will eliminate the header() redirects, allow multiple errors to be detected and displayed at the same time, and simplify all the code. This will also allow you to re-populate the form fields when you re-display the form, so that the user doesn’t need to keep re-entering or selecting the same data over and over.
- You should store a user id in the rooms table, rather than a complete name. At the point of executing the insert query, all the information about the person reserving the room should have been entered into a user(s) table, resulting in a user id for that person. This will help prevent confusion over different people with the same name or over firstname/lastname ambiguity, will result in the least amount of storage space, and result in the fastest queries.