Riuppo questo 3D..
io ho creato questa soluzione, basata su cicli while. Il pregio è che se tutto fila liscio, crea correttamente tutte le giornate. Il difetto è che, essendo basato su cicli while, va facilmente in loop. Con 4 squadre riesco a creare un calendario (al limite, se vedo che tira per le lunghe, dò un reload). Con 8 è quasi impossibile, al massimo sono arrivato a 6 giornate su 7. Poi arriva il tempo limite di 30 secondi di php..
A me serviva un calendario per 6 squadre e già cosi mi va bene. )

Codice PHP:
<?php
    error_reporting
(E_ALL);
    
    
$squadre=array("Napoli","Roma","Lazio","Sampdoria");
    
$tot_squadre=count($squadre);
    
$tot_giornate=$tot_squadre-1;
    
$tot_partite_giornata=$tot_squadre/2;

    
$partite_giocate=array();
    
$partite_questa_giornata=array();
    
$giornata_corrente=1;
    
    function 
get_campionato(){
        global 
$tot_giornate;
        
$tot_giornate_estratte=0;
        while (
$tot_giornate_estratte $tot_giornate){
            
get_giornata();
            
$tot_giornate_estratte++;
        }
    }
    
    function 
check_partita($squadra_a$squadra_b){//true se la partita è presente, false se non c'è
        
global $partite_giocate;
        if(!
in_array($squadra_a."-".$squadra_b,$partite_giocate)){
            if(!
in_array($squadra_b."-".$squadra_a,$partite_giocate)){
                return 
false;
            }
            else{
                return 
true;
            }
        }
        else{
            return 
true;
        }
    }
    
    function 
get_giornata(){
        global 
$tot_partite_giornata$partite_giocate$partite_questa_giornata,$giornata_corrente;
        
$partite_questa_giornata=array();
        while (
count($partite_questa_giornata) < $tot_partite_giornata){
            do {
                   
$tmp_partita=get_partita();
            } while (
$tmp_partita==false);
            
$partite_questa_giornata[]=$tmp_partita;
            
$partite_giocate[]=$tmp_partita;
        }
        echo 
"Giornata $giornata_corrente:
"
;
        while(list(
$chiave,$valore) = each($partite_questa_giornata)){
            
$chiave++;
            echo 
"$chiave$valore
"
;
        }
        
$giornata_corrente++;
        echo 
"


"
;
    }
    
    function 
in_array_giornata($squadra){
        global 
$partite_questa_giornata;
        while(list(
$chiave,$valore) = each($partite_questa_giornata)){
            
$due_squadre=explode("-",$valore);
            if(
in_array($squadra,$due_squadre)){
                
reset($partite_questa_giornata);
                return 
true;
            }
        }
        
reset($partite_questa_giornata);
        return 
false;
    }
    
    function 
get_partita(){
        global 
$partite_questa_giornata,$squadre;
        
srand((float) microtime() * 10000000);
        
$valorecasuale array_rand($squadre,2);
        
$valorecasuale0 $squadre[$valorecasuale[0]];
        
$valorecasuale1 $squadre[$valorecasuale[1]];
        if(
count($partite_questa_giornata)>0){
            if(!
in_array_giornata($valorecasuale0)){
                if(!
in_array_giornata($valorecasuale1)){
                    if(!
check_partita($valorecasuale0,$valorecasuale1)){
                        return 
$valorecasuale0."-".$valorecasuale1;
                    }
                    else{
                        return 
false;
                    }
                }
                else{
                    return 
false;
                }
            }
            else{
                return 
false;
            }
        }
        else{
            return 
$valorecasuale0."-".$valorecasuale1;
        }
    }
    
    
get_campionato();
            
?>