W pętli "przelatujesz" folder plik po pliku funkcją copy, a następnie tworzysz w nowej lokalizacji foldery które istnieją w tym i również przelatujesz je funkcją copy.
Pisane z palca na szybko, ale na szybkim teście zdało egzamin:
function copyDirToDir($source, $destination)
{
$scan = scandir($source);
$countScan = count($scan);
//przelotka po folderach i plikach
for($i=2; $i<$countScan; $i++)
{
//nazwa pliku/folderu wraz z pełną ścieżką
$fileWithDir = $source.'/'.$scan[$i];
//jeśli folder - tworzymy w docelowej lokalizacji i
//kopiujemy jego zawartość funkcja rekurencyjna
{
mkdir($destination.'/'.$scan[$i]);
copyDirToDir($fileWithDir, $destination.'/'.$scan[$i]);
}
else
{
//nie przenosimy samego siebie
if($scan[$i] == 'copyDirToDir.php')
break;
//przenieś na miejsce docelowe
if(copy($fileWithDir, $destination.'/'.$scan[$i])) {
}
else
{
}
}
}
}
Wyświetlane jest | lub : po wykonaniu, gdyż odpalam funkcję w shellu.
Wrzuć sobie co potrzebujesz w ich miejsce

(np. jakąś zmienną która policzy Ci ilość plików czy coś tam

)