These aren't actually SSI's. These are inclusions which effectively assemble the parts from smaller parts. SSI's are interpreted during the serve, while the includes are interpreted during the request. The virtual() function can be used to create actual SSI's if for whatever reason you need them.
I do not recommend simply using a flat path unless its taken well into control. Inclusions and requires are always based off of the executing file's working directory, regardless of the depth of the files used for including. For this reason, only your first example is the proper usable one.
You can get around this by setting include paths (using set_include_path and get_include_path to append). This lets you search a directory for these paths and then include. It is based on order it is found.
If you like the relative, always go relative to this file. So in that second example, it would be
require_once __DIR__ . '/../includes/header.php';, or dirname(__FILE__) if you're on an older version of PHP. Unless there is a particular need for it, don't use a regular require or include, always use the _once function to avoid stomping created variables, and avoid fatal errors on already declared functions, constants, classes, etc. Prior to this, we would use a defined() check, but that is no longer necessary. Also, you'll very rarely need an actual include; mostly you are constructing out of other pieces, so these are typically required.