Tach!
require ...b.shtml
Der Interpreter sucht hier quasi nach dem fehlenden ";" findet aber das Dateiende ($end) und kann garnicht erst meckern, dass ...b.shtml gar kein String ist.
Nein, die Erklärung passt nicht. Die "unexpected $end"-Fehlermeldung[1] würde nur dann kommen, wenn nach der require-Zeile kein Code mehr käme. Der Parser sucht nicht nach bestimmten Dingen sondern er parst einfach vor sich hin und schaut, ob das was da auftaucht, im gerade aktuellen Kontext sinnvoll ist oder nicht. Das fehlende Semikolon würde er nicht bemerken, stattdessen das irgendwas kommt, was nicht darf. Der Parser weiß auch gar nicht, wann konkret das Semikolon kommen muss, denn hier in dem Fall man kann den zu inkludierenden Dateinamen ja auch mit einem beliebig komplexen Ausdruck zusammenbauen. Aus diesem Grund sind Parser-Meldungen meist auch etwas wenig hilfreich, weil nicht da steht, wo der der Programmierer was vergessen hat, sondern irgendwo später, dass da was nicht stehen darf. Nach der Programmlogik ist vielleicht ganz richtig, was da steht, nur irgendwo vorher ist eben was falsch.
[1] In PHP4 heißt das endlich weniger irritierend "unexpected end of file".
dedlfix.