4

I am trying to use symbolic links on Windows 7 from within PHP. I am running XAMPP with Apache 2.4.10 and PHP 5.5.15 from a regular user account (non-admin). As suggested in Symlink is not working in my local machine I setup the correct permissions to for my user to create symlinks. This works fine, I am able to create symlinks (mklink ...) from the command line without elevation. PHP's symlink() function does not throw any permission (code 1314) errors.

When running PHP from the command line or by loading it through CGI everything works as expected:

  • symlink() is able to create symbolic links (absolute and relative
    target paths)
  • is_link() returns true for symbolic links
  • filetype() returns 'link' for symbolic links

However, when I run PHP as an apache module, I run into all kinds of trouble:

  • symlink() is only able to create symbolic links, when target is a valid absolute path (using relative paths will throw: Warning: symlink(): Could not fetch file information(error 2))
  • is_link() returns false for symbolic links
  • filetype() returns 'file' / 'dir' for symbolic links

This seems to be related to PHP symlink() fails on Windows 7, but that bug was fixed in PHP 5.4 and I am using 5.5. Also PHP is reporting error code 2, not 3.

In addition to my main question ("How to make this work?"), I am looking for answers to the following questions:

  1. Is this another bug in PHP (or Apache?)?

  2. What is the difference between loading PHP as a module and through CGI and how could that relate to this matter?

And after reading about thread safety in PHP:

  1. Can thread safety have anything to do with that?

I can tell that mod_php is loaded as thread-safe version ("phpt5ts.dll") right now.

Here's part of httpd.conf for loading as module (default xampp settings):

LoadFile "G:/xampp/php/php5ts.dll"
LoadFile "G:/xampp/php/libpq.dll"
LoadModule php5_module "G:/xampp/php/php5apache2_4.dll"

<FilesMatch "\.php$">
   SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch "\.phps$">
    SetHandler application/x-httpd-php-source
</FilesMatch>

And here's the php-cgi settings:

<FilesMatch "\.php$">
    SetHandler application/x-httpd-php-cgi
</FilesMatch>
<IfModule actions_module>
    Action application/x-httpd-php-cgi "/php-cgi/php-cgi.exe"
</IfModule>
Community
  • 1
  • 1
wolfgangwalther
  • 1,226
  • 7
  • 15

1 Answers1

1

symlink() is only able to create symbolic links, when target is a valid absolute path (using relative paths will throw: Warning: symlink(): Could not fetch file information(error 2))

This is due to the following bug in PHP:

is_link() returns false for symbolic links

I have noticed the same thing, at least under my current setup. When PHP is run as an Apache module instead of via CGI, the is_link function always returns false for any symlink. My setup is:

  • Windows 7 x64
  • XAMPP 1.8.3
  • PHP 5.5.11

What is the difference between loading PHP as a module and through CGI and how could that relate to this matter?

The advantage of running PHP through CGI is, that each PHP process can be run under a different user instead of only the user that Apache runs under. This is useful for productive server environments, so that each website does not need to have the same access rights. However, running PHP via CGI is also much, much slower. Running it as a module is always the fastest option.

Running PHP via FastCGI alleviates the performance downside for the most part, but it's still a little bit slower than running it as a module.

As to why these problems with is_link (and filetype) occur when running PHP as a module, I don't know.

fritzmg
  • 2,494
  • 3
  • 21
  • 51