Lo que sucede es que un header significa "cabezera", cuando tu servidor envía una información a tu explorador este se compone en cabezera y cuerpo, en este caso no puedes poner parte de la cabezera después del cuerpo:
+----------------+
| CABEZERA |
+----------------+
| CUERPO |
+----------------+
| TERMINO |
+----------------+
En este caso algunos servidores utilizan un buffer de termino pero no le prestes atención a eso, solo necesitas saber que no puedes insertar un header después de haber iniciado con las funciones y la página en si ya que el header se envía una sola ves y después solo te irá mostrando errores.
Que quieres hacer escribiendo
header('index.php'); ?, solo harás que se incluya en la cabezera pero no hará nada más.
Si te da error al enviar la cabezera es porque lo estás enviando después de escribir algo en el explorador.
Me podrian explicar mas o menos como es esto del ob_start y ob_flush.
Significa que no enviará nada al explorador hasta cuando declares ob_end_flush y ahi recién se enviará todo, es para evitar mostrar este tipo de errores cuando algo falla antes de que las cabezeras sean enviadas pero no es la idea hacerlo, es algo así como tapar un oyo con paja.