What is your registration process, and why wouldn't a user specify the (unique) username they want to use in the first step? Seems like you are making this harder for the user, which will create a bad User eXperience (UX), and take more code and queries?
Some comments about the posted code -
- Don't put external, unknown, dynamic values directly into an sql query statement. Use a prepared query instead. If you switch to use the much simpler PDO database extension, prepared queries are very simple. Not so much with the mysqli extension, which requires you to learn almost two different extensions since the non-prepared and prepared programming interfaces are complete different.
- Don't try to SELECT data to decide if you are going to INSERT new values, e.g. the username and email. Those columns MUST be defined as unique indexes, so that the database will enforce unique values. You should just attempt to insert the data, then detect if a duplicate index error occurred. If you get a duplicate error, you would then execute a SELECT query to find which of those column(s) contain duplicates. You would setup message(s) for the user telling them which values are already in use and to enter new value(s).
- You only need one set of error handling for queries and except for inserting/updating duplicate or out of range values (see item #2 in this list), you should not tell the visitor anything specific about an error that has occurred, since a they cannot do anything to fix things like sql syntax errors. To do this, simply use exceptions for database statement 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.) You would then remove all the existing database error handling logic, since it will no longer get executed upon an error (execution transfers to the nearest correct type of exception handler, or to php if there is none.) The exception to this rule is when inserting/updating user data. In this case your code would catch the exception, detect if the error number is for something that the user can correct, then setup a message for the user telling them what was wrong with the data that they submitted.
- Don't use a loop to fetch data from a query that will at most match one row of data. Just directly fetch the row of data.
- Don't copy variables to other variables for nothing. Just use the original variables.