ls -ltrR .
questo comando Linux/Unix mostra, per ogni cartella, l'elenco dei file presenti e la relativa dimensione
-l è il formato lungo
-R è ricorsivo
-tr ordina (inversamente)
L'output è qualcosa così
-rw-r--r-- 1 root wheel 16 Apr 4 19:32 pkg-plist
-rw-r--r-- 1 root wheel 326 Apr 5 13:02 pkg-descr
-rw-r--r-- 1 root wheel 367 Apr 5 13:22 Makefile
-rw-r--r-- 1 root wheel 161 Apr 5 13:37 distinfo
L'output viene "pipato" (col |) verso awk, che in prima battuta prende la quinta colonna output (awk '{print \$5})
Come puoi vedere la quinta colonna è composta proprio dalle dimensioni, cioè
16,326,367 e 161 nell'esempio.
Queste righe vengono inviate, di nuovo, ad awk (sempre un programma eseguibile) il quale fa una sorta di ciclo e poi ne sputa fuori il risultato, cioè la dimensione (sum) della dimensione dei file.
Questo output viene "intercettato" da PHP dentro $io
$io = popen("ls -ltrR {$path} |awk '{print \$5}'|awk 'BEGIN{sum=0} {sum=sum+\$1} END {print sum}'", 'r');
A quel punto viene letto in formato stringa (fgets) fino a un massimo di 80 caratteri (perchè 80? boh mica l'ho fatto io, ovviamente è eccessivo, intval potrebbe facilmente andare in errore con una eventuale stringa così lunga).
In sostanza l'output da lavorare sarà qualcosa del tipo "123456789012" (in stringa), da convertire in testo.
Chiaramente, nel tuo caso, fino a 80 caratteri vengono letti (cioè una dimensione tipo
12345678901234567890123456789012345678901234567890123456789012345678901234567890 che mi pare leggermente eccessiva)
Infine viene convertito in intero, e messo in $size
$size = intval(fgets($io, 80));
E' una tecnica molto diffusa: intercettare l'output di un comando eseguibile ed interpretarlo (in questo caso male, non c'è verifica degli errori etc).
Usando un altro programma avresti potuto ottenere direttamente il dato
Get directory size, ignoring .zfs and :$DATA
30/04/2021 17:00:44 Scan dir <</tmp/>>
Free 0 217.127.645.184 202.22 GB <</tmp/>>
=============================================
Dir 0 3.994.805.780 69 0.003 <</tmp/>>
=============================================
3.994.805.780 69 0.003 sec (3.72 GB)
0.003 seconds (all OK)
O magari con altre tecniche (du, tree e chi più ne ha ne metta).
Se ti chiedi perchè ls non scriva il totale della dimensione dei file, almeno come opzione, ti assicuro che stai colpendo nel segno uno dei grandi misteri dell'informatica, che non ho mai capito