The canonical path of a filesystem path is the absolute, normalised path with .., ., and symbolic-link segments fully resolved. realpath($p) returns it.
To confine dynamic file inclusion to a directory, compute the canonical path of the user-supplied input prefixed with the directory, then check that the result still starts with the target directory prefix:
Naively checking that this string starts with pdir would pass — every prefix character matches — and yet the path clearly escapes the directory. The canonical-path defence resolves it before testing:
prefix
/var/www/htdocs/pages/
realpath()
/etc/passwd
starts-with check
/etc/passwd starts with /var/www/htdocs/pages/? no
Since the resolved path no longer begins with pdir, the check rejects the read. A benign request like ?file=about.php resolves to /var/www/htdocs/pages/about.php, which does start with pdir, so it is allowed.
The point is that realpath() collapses the ../ sequence and resolves any symlinks before the prefix test runs, so the comparison answers the question that matters — “did we land back inside the directory?” — rather than whether the raw user string happened to begin with the right characters.