Lo mejor es hacerlo con Javascript. Te dejo un ejemplo que armé con provincias y ciudades de 2 níveles pero podés agregarle más:
Código HTML:
<script type="text/javascript">
function slctr(texto,valor){
this.texto = texto
this.valor = valor
}
var Chubut=new Array()
Chubut[0] = new slctr("Comodoro Rivadavia Centro",'Comodoro Rivadavia Centro')
Chubut[1] = new slctr("Comodoro Rivadavia Apt",'Aeropuerto de Comodoro Rivadavia')
Chubut[2] = new slctr("Esquel Centro",'Esquel Centro')
Chubut[3] = new slctr("Esquel Apt",'Aeropuerto de Esquel')
Chubut[4] = new slctr("Puerto Madryn Centro",'Puerto Madryn Centro')
Chubut[5] = new slctr("Puerto Madryn Apt",'Aeropuerto de Puerto Madryn')
Chubut[6] = new slctr("Trelew Centro",'Trelew Centro')
Chubut[7] = new slctr("Trelew Apt",'Aeropuerto de Trelew')
var Cordoba=new Array()
Cordoba[0] = new slctr("Córdoba Centro",'Cordoba Centro')
Cordoba[1] = new slctr("Córdoba Apt",'Aeropuerto de Cordoba')
Cordoba[2] = new slctr("Río Cuarto",'Rio Cuarto')
var Mendoza=new Array()
Mendoza[0] = new slctr("Mendoza Centro",'Mendoza Centro')
Mendoza[1] = new slctr("Mendoza Apt",'Aeropuerto de Mendoza')
Mendoza[2] = new slctr("San Rafael Centro",'San Rafael Centro')
Mendoza[3] = new slctr("San Rafael Apt",'Aeropuerto de San Rafael')
function slctryole(cual,donde){
if(cual.selectedIndex != 0){
donde.length=0
cual = eval(cual.value)
for(m=0;m<cual.length;m++){
var nuevaOpcion = new Option(cual[m].texto);
donde.options[m] = nuevaOpcion;
if(cual[m].valor != null){
donde.options[m].value = cual[m].valor
}
else{
donde.options[m].value = cual[m].texto
}
}
}
}
</script>
Y para hacer el llamado:
Código HTML:
<select name="select" onchange="slctryole(this,this.form.select2)">
<option></option>
<option value="Chubut">Chubut</option>
<option value="Cordoba">Córdoba</option>
<option value="Mendoza">Mendoza</option>
</select>
<option></option>
</select>
<select name="select2">
<option></option>
</select>