There really is no way other than the "hard" ways, but there are a couple of them - which are relevant to the answer.
The first is oldest of old school - at each step, generate a hidden field for each input value of previous steps. The big advantage to this (that no one seems to care about any more) is that this will work independent of cookies or Javascript. The down side is, navigate away from the page, it's all lost.
The second as you are doing is to establish session variables and carry them. This is inherently cookie dependent.
The third, and the one I'd use, is to store the data at each step in a temporary (or permanent) location such as a database and key it to login data. The advantages are multiple: it will allow the user to come back at a later time and complete it; it gives you data you can review for incomplete submissions; it frees up your programming (i.e., instead of checking for a bunch of session variables you just check against the database;) it makes it more portable.
That would certainly work if a user was trying to access the 2nd page of a form section, but that wouldn't work if they came into the form section on page 3 or 4 or whatever.
But it will. Using the database model, you can read the temporary storage fields and group them by "step number". If someone hits page 3 and the required data for 1 and 2 aren't filled out,
$goback=null;
foreach ($field_in_this_step as $required) {
if (! isset($_SESSION[$required]) or empty($_SESSION[$required])) { // or $row, or whatever
$goback=1;
break;
}
if ($goback) {
//go to step whatever
}
So in any case, you'd use one of the three methods above and figure out how and where you're going to store data so you can check against previous steps - this could be a global array at the top of the program or a more solid solution as below.
I wouldn't redirect though, it's an easy solution but makes for sloppy GUI's - that is, a true redirect back to page 1 leaves all field values unpopulated. To counteract that you'll have to add all kinds of extra programming to pull values from the database, or session variables, or . . . it's just better if you engineer it so it just outputs a different state from the same program.