Tja, in PHP werden Strings eben initialisiert.
Das geschieht in Delphi nicht, aus performancegründen, denn wenn man SetLength verwendet, sollte man danach auch die reservierten Dinge initialisieren, bzw. gleich mit den gewünschten Werten füllen und bei Letzerem wäre eine vorherige automatische Initialisierung nur unnötiger Overhead.
Und wenn jemand es eben nichts befüllt/initialisiert, dann soll man sich auch nicht wundern, wenn etwas unerwartetes darin erscheint.
Genauso wie bei nichtinitialisierten lokalen Variablen.
Wenn man das SetLenght hoch genug wählt, dann kann ich euch garantieren, was sich in dem String befinden wird.
Bei kurzen Strings und wird ein Speicherblock vom Delphi-Memory-Manager verwendet und jenachdem ob und für was dieser Speicherblock vorher verwendet wurde, befindet sich doch auch schon "irgendwas" drin.
Wird der String aber größer, als der größte verwaltete Block des MM, wird direkt bei Windows ein Speicherbereich extra für diesen String bestellt und da Windows sowas immer mit 0 initialisiert, wird der String auch auch nur vielen #0 bestehen.
PS:
DupeString und
StringOfChar