Pages system PHP/SQL
I think it overall is good, but there's some minor changes that could still quicken this script, namely using fetchAll and foreach instead of fetch and while

using fetchAll will get the values quicker then fetch on every single row. also foreach will prevent you from having to check if you have results, it just won't run if there are not.

also, you prepare the statement multiple times in the huge loop, instead of preparing it outside of the loop and execute() it multiple times

function update_menu(&amp;$pdo, $filepath){
    $qry = "SELECT * FROM pages WHERE top = 1";
    $exec = $pdo-&gt;query($qry)-&gt;fetchAll(PDO::FETCH_ASSOC);
    $qryChild = $pdo-&gt;prepare("SELECT * FROM pages WHERE parent = ?");
    $string = '&lt;ul&gt;' . "\n";
    foreach($exec as $row)){
        $string.= "&lt;li&gt;&lt;a href='?page=".$row['id']."'&gt;".$row['title'].'&lt;/a&gt;' . "\n";
        $qryChild-&gt;execute($row['id']);
        $childs = $qryChild-&gt;fetchAll(PDO::FETCH_ASSOC);
        $i=0;
        foreach($childs as $child){
            if($i==0){
                $string.='&lt;ul&gt;' . "\n";
            }
            $string.="&lt;li&gt;&lt;a href='?page=".$child['id']."'&gt;".$child['title'].'&lt;/a&gt;' . "\n";
            $i++;
        }
    if($i != 0) $string.='&lt;/ul&gt;' . "\n";
    $string.='&lt;/li&gt;' . "\n";
    }
$string.='&lt;/ul&gt;' . "\n";
file_put_contents($filepath, $string);


also, adding some "\n" will give some better readability to you html code