Önerim; takımları 2 kez çekerek 2 ayrı diziye atın. Önce çektiğiniz takımları karmak için shuffle(); fonksiyonunu kullanarak takımları rasgele sıralayın. Karma işlemi bittikten sonra iç içe döngü kullanın. Aşağıda basit bir örnekle belirteyim.

$takimlar = shuffle(dizi halinde veritabanında çekilmiş takımlar); // veritabanındaki takımlar
$rakipler = shuffle(dizi halinde veritabanında çekilmiş takımlar); // veritabanındaki takımlar

foreach($takimlar as $takim){

 // Rakip takım için döngü
 foreach($rakipler as $rakip){
    if($takim!=$rakip){
     $tarih = // maç tarihi
     $evsahibi = $takim;
     $rakiptakim = $rakip;
      // Veritabanına maçı kaydedeceğiniz sorgu.
    }
 }
 
}
Aklıma daha basit bir yöntem gelmedi. Yazdığım kodları denemedim de. Hata varsa düzeltirsiniz çalışırsa bilgilendirirseniz sevinirim. Tarih olayıyla ilgili önerimde şöyle; şimdiki tarihe sürekli +7 gün(veya kaç gün aralıklarla maç yapılacaksa) ekleterek ilerleyebilirsiniz.


@PhYtOnX
Edit: Aşağıya çalışan bir yapı koyuyorum. Bunu localde çalıştırıp, deneyip geliştirin isterseniz.

<?php
$teams = array("Galatasaray", "Fenerbahçe", "Beşiktaş", "Trabzon");
shuffle($teams);
$takimlar = $teams;
shuffle($teams);
$rakipler = $teams;
    foreach($takimlar as $takim){
        echo "<br>======[".$takim."]======<br>";
        foreach($rakipler as $rakip){
            if($takim != $rakip){
                echo $takim." vs ".$rakip."<br>";
            }
        }
        echo "=========================";
    }
?>