How do you get PHP, Symlinks and __FILE__ to work together nicely?










40















On localhost. I have the following directory structure:



/share/www/trunk/wp-content/plugins/otherfolders



/share/www/portfolio/wp-content/symlink



Where symlink is a symbolic link to /trunk/.../plugins/. Basically, this is because I need to test multiple WordPress installs and set them up, but I don't want to have to move plugins around and copy and paste them everywhere.



However, sometimes I need to crawl up the directory tree to include a config file:



 $root = dirname(dirname(dirname(dirname(__FILE__))));
if (file_exists($root.'/wp-load.php'))
// WP 2.6
require_once($root.'/wp-load.php');



The folder always resolves to:



/share/www/trunk



Even when the plugin is being executed and included in



/share/www/portfolio/.



Is it possible in PHP to include files in the share/www/portfolio directory from a script executing in a symlink to the /share/www/trunk/.../plugins directory?



While this problem only happens on my test server, I'd like to have a safely distributable solution so crawling up an extra level is not an option.










share|improve this question
























  • Do you know where the script where you're doing the FILE business is relative to the entry point? What does $_SERVER['SCRIPT_FILENAME'] equate to in the context of your example?

    – Shabbyrobe
    Jul 22 '10 at 2:30











  • Bingo. I know exactly how many directories up I need to crawl. I just needed to have the right base directory. Post the answer and the bounty is yours.

    – Aaron Harun
    Jul 22 '10 at 4:13











  • An other idea would be to use hard links instead of symlinks. Or is there a reason why you need symlinks (like other mountpoint, etc.)?

    – JochenJung
    Jul 22 '10 at 20:26











  • Another option is to remove the symlink and instead mount the directory (mount -o bind target link). You get a behavior similar to a symlink and __FILE__ resolves correctly. It's a hack and certainly not always an option, but may be a viable alternative in some use-cases. Also, don't forget to add it to the fstab file, or else it will disappear after rebooting.

    – Michael Osl
    Jul 21 '14 at 14:27
















40















On localhost. I have the following directory structure:



/share/www/trunk/wp-content/plugins/otherfolders



/share/www/portfolio/wp-content/symlink



Where symlink is a symbolic link to /trunk/.../plugins/. Basically, this is because I need to test multiple WordPress installs and set them up, but I don't want to have to move plugins around and copy and paste them everywhere.



However, sometimes I need to crawl up the directory tree to include a config file:



 $root = dirname(dirname(dirname(dirname(__FILE__))));
if (file_exists($root.'/wp-load.php'))
// WP 2.6
require_once($root.'/wp-load.php');



The folder always resolves to:



/share/www/trunk



Even when the plugin is being executed and included in



/share/www/portfolio/.



Is it possible in PHP to include files in the share/www/portfolio directory from a script executing in a symlink to the /share/www/trunk/.../plugins directory?



While this problem only happens on my test server, I'd like to have a safely distributable solution so crawling up an extra level is not an option.










share|improve this question
























  • Do you know where the script where you're doing the FILE business is relative to the entry point? What does $_SERVER['SCRIPT_FILENAME'] equate to in the context of your example?

    – Shabbyrobe
    Jul 22 '10 at 2:30











  • Bingo. I know exactly how many directories up I need to crawl. I just needed to have the right base directory. Post the answer and the bounty is yours.

    – Aaron Harun
    Jul 22 '10 at 4:13











  • An other idea would be to use hard links instead of symlinks. Or is there a reason why you need symlinks (like other mountpoint, etc.)?

    – JochenJung
    Jul 22 '10 at 20:26











  • Another option is to remove the symlink and instead mount the directory (mount -o bind target link). You get a behavior similar to a symlink and __FILE__ resolves correctly. It's a hack and certainly not always an option, but may be a viable alternative in some use-cases. Also, don't forget to add it to the fstab file, or else it will disappear after rebooting.

    – Michael Osl
    Jul 21 '14 at 14:27














40












40








40


10






On localhost. I have the following directory structure:



/share/www/trunk/wp-content/plugins/otherfolders



/share/www/portfolio/wp-content/symlink



Where symlink is a symbolic link to /trunk/.../plugins/. Basically, this is because I need to test multiple WordPress installs and set them up, but I don't want to have to move plugins around and copy and paste them everywhere.



However, sometimes I need to crawl up the directory tree to include a config file:



 $root = dirname(dirname(dirname(dirname(__FILE__))));
if (file_exists($root.'/wp-load.php'))
// WP 2.6
require_once($root.'/wp-load.php');



The folder always resolves to:



/share/www/trunk



Even when the plugin is being executed and included in



/share/www/portfolio/.



Is it possible in PHP to include files in the share/www/portfolio directory from a script executing in a symlink to the /share/www/trunk/.../plugins directory?



While this problem only happens on my test server, I'd like to have a safely distributable solution so crawling up an extra level is not an option.










share|improve this question
















On localhost. I have the following directory structure:



/share/www/trunk/wp-content/plugins/otherfolders



/share/www/portfolio/wp-content/symlink



Where symlink is a symbolic link to /trunk/.../plugins/. Basically, this is because I need to test multiple WordPress installs and set them up, but I don't want to have to move plugins around and copy and paste them everywhere.



However, sometimes I need to crawl up the directory tree to include a config file:



 $root = dirname(dirname(dirname(dirname(__FILE__))));
if (file_exists($root.'/wp-load.php'))
// WP 2.6
require_once($root.'/wp-load.php');



The folder always resolves to:



/share/www/trunk



Even when the plugin is being executed and included in



/share/www/portfolio/.



Is it possible in PHP to include files in the share/www/portfolio directory from a script executing in a symlink to the /share/www/trunk/.../plugins directory?



While this problem only happens on my test server, I'd like to have a safely distributable solution so crawling up an extra level is not an option.







php linux symlink






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jun 9 '16 at 15:40







Aaron Harun

















asked Jul 11 '10 at 3:42









Aaron HarunAaron Harun

16.9k83861




16.9k83861












  • Do you know where the script where you're doing the FILE business is relative to the entry point? What does $_SERVER['SCRIPT_FILENAME'] equate to in the context of your example?

    – Shabbyrobe
    Jul 22 '10 at 2:30











  • Bingo. I know exactly how many directories up I need to crawl. I just needed to have the right base directory. Post the answer and the bounty is yours.

    – Aaron Harun
    Jul 22 '10 at 4:13











  • An other idea would be to use hard links instead of symlinks. Or is there a reason why you need symlinks (like other mountpoint, etc.)?

    – JochenJung
    Jul 22 '10 at 20:26











  • Another option is to remove the symlink and instead mount the directory (mount -o bind target link). You get a behavior similar to a symlink and __FILE__ resolves correctly. It's a hack and certainly not always an option, but may be a viable alternative in some use-cases. Also, don't forget to add it to the fstab file, or else it will disappear after rebooting.

    – Michael Osl
    Jul 21 '14 at 14:27


















  • Do you know where the script where you're doing the FILE business is relative to the entry point? What does $_SERVER['SCRIPT_FILENAME'] equate to in the context of your example?

    – Shabbyrobe
    Jul 22 '10 at 2:30











  • Bingo. I know exactly how many directories up I need to crawl. I just needed to have the right base directory. Post the answer and the bounty is yours.

    – Aaron Harun
    Jul 22 '10 at 4:13











  • An other idea would be to use hard links instead of symlinks. Or is there a reason why you need symlinks (like other mountpoint, etc.)?

    – JochenJung
    Jul 22 '10 at 20:26











  • Another option is to remove the symlink and instead mount the directory (mount -o bind target link). You get a behavior similar to a symlink and __FILE__ resolves correctly. It's a hack and certainly not always an option, but may be a viable alternative in some use-cases. Also, don't forget to add it to the fstab file, or else it will disappear after rebooting.

    – Michael Osl
    Jul 21 '14 at 14:27

















Do you know where the script where you're doing the FILE business is relative to the entry point? What does $_SERVER['SCRIPT_FILENAME'] equate to in the context of your example?

– Shabbyrobe
Jul 22 '10 at 2:30





Do you know where the script where you're doing the FILE business is relative to the entry point? What does $_SERVER['SCRIPT_FILENAME'] equate to in the context of your example?

– Shabbyrobe
Jul 22 '10 at 2:30













Bingo. I know exactly how many directories up I need to crawl. I just needed to have the right base directory. Post the answer and the bounty is yours.

– Aaron Harun
Jul 22 '10 at 4:13





Bingo. I know exactly how many directories up I need to crawl. I just needed to have the right base directory. Post the answer and the bounty is yours.

– Aaron Harun
Jul 22 '10 at 4:13













An other idea would be to use hard links instead of symlinks. Or is there a reason why you need symlinks (like other mountpoint, etc.)?

– JochenJung
Jul 22 '10 at 20:26





An other idea would be to use hard links instead of symlinks. Or is there a reason why you need symlinks (like other mountpoint, etc.)?

– JochenJung
Jul 22 '10 at 20:26













Another option is to remove the symlink and instead mount the directory (mount -o bind target link). You get a behavior similar to a symlink and __FILE__ resolves correctly. It's a hack and certainly not always an option, but may be a viable alternative in some use-cases. Also, don't forget to add it to the fstab file, or else it will disappear after rebooting.

– Michael Osl
Jul 21 '14 at 14:27






Another option is to remove the symlink and instead mount the directory (mount -o bind target link). You get a behavior similar to a symlink and __FILE__ resolves correctly. It's a hack and certainly not always an option, but may be a viable alternative in some use-cases. Also, don't forget to add it to the fstab file, or else it will disappear after rebooting.

– Michael Osl
Jul 21 '14 at 14:27













6 Answers
6






active

oldest

votes


















31





+50









The problem that I see with your code is that __FILE__ resolves symlinks automatically.



From the PHP Manual on Magic Constants




... Since PHP 4.0.2, __FILE__ always contains an absolute path with symlinks resolved ...




You can try using $_SERVER["SCRIPT_FILENAME"] instead.



$root = realpath(dirname(dirname(dirname(dirname($_SERVER["SCRIPT_FILENAME"])))));
if (file_exists($root.'/wp-load.php'))
// WP 2.6
require_once($root.'/wp-load.php');



Note that I added the realpath() function to the root directory. Depending on your setup, you may or may not need it.



EDIT: Use $_SERVER["SCRIPT_FILENAME"] instead of $_SERVER["PHP_SELF"] for the file system path.






share|improve this answer

























  • PHP_SELF only gives the value of the current processing file. The end result needs to be an absolute path not a URI.

    – Aaron Harun
    Jul 22 '10 at 14:48











  • My bad... I was originally testing from the CLI. How about using $_SERVER["SCRIPT_FILENAME"] instead? That worked in my environment. If that doesn't work what about prepending $_SERVER["DOCUMENT_ROOT"] to $_SERVER["PHP_SELF"]?

    – pferate
    Jul 22 '10 at 16:21











  • The following is the bug to your problem: bugs.php.net/bug.php?id=46260 Sadly, PHP won't change in this manner, which is a bug in my opinion.

    – Thorsten Schöning
    Jul 12 '15 at 19:42











  • Unfortunately, $_SERVER["SCRIPT_FILENAME"] doesn't work if the script you are executing this is included from another file. It's set to the original script that executed. This makes sense since the $_SERVER variable seems to be set up when the first script and doesn't change for any included scripts unlike magic constants.

    – user193130
    Sep 20 '17 at 18:46












  • This is as good a workaround as it gets, but, unfortunately, we have to silently ignore the very invalidating warning then right from the manual: "There is no guarantee that every web server will provide any of these; servers may omit some, or provide others not listed here."

    – Sz.
    Nov 13 '18 at 1:13



















2














You can use this code snippet to get a path where symlinks are not resolved.
If you don't have bash available, there's probably a different command you can use, but it works on linux enviroments.



I do think it's a malpractice that php resolves symlinks in FILE, since there's no way to get the path with symlinks. Otherwise we could easily get it using realpath.



Oh well.



<?php
$output = array();
exec('pwd', &$output);
define('__LINK__', $output[0].substr(__FILE__, strpos(__FILE__, DIRECTORY_SEPARATOR)));
?>





share|improve this answer


















  • 1





    'pwd' returns value depends on current working dir; To work propertly you should change working directiry first: cd /var/www/wp-content/themes/twenty_twelve/ && php script.php

    – AndreyP
    Jun 7 '16 at 16:57











  • I removed the &, and $output[0] worked for me.

    – Mr Goobri
    Sep 1 '16 at 10:23


















2














In some case its possible to change working dir and use getenv('PWD'):



$root = dirname(dirname(dirname(getenv('PWD'))));
if (file_exists($root.'/wp-load.php'))
// WP 2.6
require_once($root.'/wp-load.php');



And change working directory before run this code:



cd /var/www/wp-content/themes/twenty_twelve/ && php script.php





share|improve this answer






























    1














    The PHP interpreter resolves symlinks before it processes them. You can do this yourself with the readlink function. PHP resolves the links because it's more efficient for *_once functions and code caches like APC, Xcache etc.



    What you propably need is another way to find where a particular installation stores it's files. I'd recommend using $_SERVER['DOCUMENT_ROOT']/wp-content/wp-load.php assuming /share/www/portfolio is the document root.






    share|improve this answer























    • The document root is unfortunately /share/www/

      – Aaron Harun
      Jul 20 '10 at 14:30


















    1














    Here is the solution to that issue: https://github.com/logical-and/symlink-detective



    $root = dirname(dirname(dirname(dirname(__FILE__))));
    if (file_exists(SymlinkDetective::detectPath($root.'/wp-load.php')))
    // WP 2.6
    require_once(SymlinkDetective::detectPath($root.'/wp-load.php'));



    or you can try that



    try 
    $root = dirname(dirname(dirname(dirname(__FILE__))));
    require_once SymlinkDetective::detectPath($root.'/wp-load.php', '',
    false /* this would throw an exception if file doesn't exists */);

    catch (Exception $e)
    // nothing to do if file doesn't exists






    share|improve this answer


















    • 1





      I really don't understand why you removing my answer. I wrote solution for the issue, I gave examples on how it can be used, I wrote that answer. Try to do the same, instead of removing my post or let me know at least why? Isn't my information useful?

      – And
      Dec 1 '16 at 10:12


















    0














    If I were trying to solve this, I'd split __FILE__ along the path bits and create a SplFileInfo for each along the way, test with isDir and isLink, then try to determine how to handle reconstruction of the path once it's known to be different than expected so you can pull from the right directory. (If you're more of a procedural type, there's is_dir and is_link.)



    That being said, I think you've already disqualified this solution. Maybe the tools are smart enough to do it for you. Try comparing the result of getRealPath to getPath? getRealPath expressly says that it resolves symlinks, while getPath doesn't expressly say that.



    Even then, this sniffing might not be safe on client sites, depending on who the host is. I've seen some pretty creative shared hosting filesystem setups. You could add a check to php_uname and pull out the hostname of the machine, and if it isn't your dev box, don't do the extra work.






    share|improve this answer


















    • 1





      Unfortunately, getRealPath and getPath all output the /trunk/ directory.

      – Aaron Harun
      Jul 11 '10 at 20:22











    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3221771%2fhow-do-you-get-php-symlinks-and-file-to-work-together-nicely%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    6 Answers
    6






    active

    oldest

    votes








    6 Answers
    6






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    31





    +50









    The problem that I see with your code is that __FILE__ resolves symlinks automatically.



    From the PHP Manual on Magic Constants




    ... Since PHP 4.0.2, __FILE__ always contains an absolute path with symlinks resolved ...




    You can try using $_SERVER["SCRIPT_FILENAME"] instead.



    $root = realpath(dirname(dirname(dirname(dirname($_SERVER["SCRIPT_FILENAME"])))));
    if (file_exists($root.'/wp-load.php'))
    // WP 2.6
    require_once($root.'/wp-load.php');



    Note that I added the realpath() function to the root directory. Depending on your setup, you may or may not need it.



    EDIT: Use $_SERVER["SCRIPT_FILENAME"] instead of $_SERVER["PHP_SELF"] for the file system path.






    share|improve this answer

























    • PHP_SELF only gives the value of the current processing file. The end result needs to be an absolute path not a URI.

      – Aaron Harun
      Jul 22 '10 at 14:48











    • My bad... I was originally testing from the CLI. How about using $_SERVER["SCRIPT_FILENAME"] instead? That worked in my environment. If that doesn't work what about prepending $_SERVER["DOCUMENT_ROOT"] to $_SERVER["PHP_SELF"]?

      – pferate
      Jul 22 '10 at 16:21











    • The following is the bug to your problem: bugs.php.net/bug.php?id=46260 Sadly, PHP won't change in this manner, which is a bug in my opinion.

      – Thorsten Schöning
      Jul 12 '15 at 19:42











    • Unfortunately, $_SERVER["SCRIPT_FILENAME"] doesn't work if the script you are executing this is included from another file. It's set to the original script that executed. This makes sense since the $_SERVER variable seems to be set up when the first script and doesn't change for any included scripts unlike magic constants.

      – user193130
      Sep 20 '17 at 18:46












    • This is as good a workaround as it gets, but, unfortunately, we have to silently ignore the very invalidating warning then right from the manual: "There is no guarantee that every web server will provide any of these; servers may omit some, or provide others not listed here."

      – Sz.
      Nov 13 '18 at 1:13
















    31





    +50









    The problem that I see with your code is that __FILE__ resolves symlinks automatically.



    From the PHP Manual on Magic Constants




    ... Since PHP 4.0.2, __FILE__ always contains an absolute path with symlinks resolved ...




    You can try using $_SERVER["SCRIPT_FILENAME"] instead.



    $root = realpath(dirname(dirname(dirname(dirname($_SERVER["SCRIPT_FILENAME"])))));
    if (file_exists($root.'/wp-load.php'))
    // WP 2.6
    require_once($root.'/wp-load.php');



    Note that I added the realpath() function to the root directory. Depending on your setup, you may or may not need it.



    EDIT: Use $_SERVER["SCRIPT_FILENAME"] instead of $_SERVER["PHP_SELF"] for the file system path.






    share|improve this answer

























    • PHP_SELF only gives the value of the current processing file. The end result needs to be an absolute path not a URI.

      – Aaron Harun
      Jul 22 '10 at 14:48











    • My bad... I was originally testing from the CLI. How about using $_SERVER["SCRIPT_FILENAME"] instead? That worked in my environment. If that doesn't work what about prepending $_SERVER["DOCUMENT_ROOT"] to $_SERVER["PHP_SELF"]?

      – pferate
      Jul 22 '10 at 16:21











    • The following is the bug to your problem: bugs.php.net/bug.php?id=46260 Sadly, PHP won't change in this manner, which is a bug in my opinion.

      – Thorsten Schöning
      Jul 12 '15 at 19:42











    • Unfortunately, $_SERVER["SCRIPT_FILENAME"] doesn't work if the script you are executing this is included from another file. It's set to the original script that executed. This makes sense since the $_SERVER variable seems to be set up when the first script and doesn't change for any included scripts unlike magic constants.

      – user193130
      Sep 20 '17 at 18:46












    • This is as good a workaround as it gets, but, unfortunately, we have to silently ignore the very invalidating warning then right from the manual: "There is no guarantee that every web server will provide any of these; servers may omit some, or provide others not listed here."

      – Sz.
      Nov 13 '18 at 1:13














    31





    +50







    31





    +50



    31




    +50





    The problem that I see with your code is that __FILE__ resolves symlinks automatically.



    From the PHP Manual on Magic Constants




    ... Since PHP 4.0.2, __FILE__ always contains an absolute path with symlinks resolved ...




    You can try using $_SERVER["SCRIPT_FILENAME"] instead.



    $root = realpath(dirname(dirname(dirname(dirname($_SERVER["SCRIPT_FILENAME"])))));
    if (file_exists($root.'/wp-load.php'))
    // WP 2.6
    require_once($root.'/wp-load.php');



    Note that I added the realpath() function to the root directory. Depending on your setup, you may or may not need it.



    EDIT: Use $_SERVER["SCRIPT_FILENAME"] instead of $_SERVER["PHP_SELF"] for the file system path.






    share|improve this answer















    The problem that I see with your code is that __FILE__ resolves symlinks automatically.



    From the PHP Manual on Magic Constants




    ... Since PHP 4.0.2, __FILE__ always contains an absolute path with symlinks resolved ...




    You can try using $_SERVER["SCRIPT_FILENAME"] instead.



    $root = realpath(dirname(dirname(dirname(dirname($_SERVER["SCRIPT_FILENAME"])))));
    if (file_exists($root.'/wp-load.php'))
    // WP 2.6
    require_once($root.'/wp-load.php');



    Note that I added the realpath() function to the root directory. Depending on your setup, you may or may not need it.



    EDIT: Use $_SERVER["SCRIPT_FILENAME"] instead of $_SERVER["PHP_SELF"] for the file system path.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jul 23 '10 at 0:44

























    answered Jul 21 '10 at 23:11









    pferatepferate

    1,73611218




    1,73611218












    • PHP_SELF only gives the value of the current processing file. The end result needs to be an absolute path not a URI.

      – Aaron Harun
      Jul 22 '10 at 14:48











    • My bad... I was originally testing from the CLI. How about using $_SERVER["SCRIPT_FILENAME"] instead? That worked in my environment. If that doesn't work what about prepending $_SERVER["DOCUMENT_ROOT"] to $_SERVER["PHP_SELF"]?

      – pferate
      Jul 22 '10 at 16:21











    • The following is the bug to your problem: bugs.php.net/bug.php?id=46260 Sadly, PHP won't change in this manner, which is a bug in my opinion.

      – Thorsten Schöning
      Jul 12 '15 at 19:42











    • Unfortunately, $_SERVER["SCRIPT_FILENAME"] doesn't work if the script you are executing this is included from another file. It's set to the original script that executed. This makes sense since the $_SERVER variable seems to be set up when the first script and doesn't change for any included scripts unlike magic constants.

      – user193130
      Sep 20 '17 at 18:46












    • This is as good a workaround as it gets, but, unfortunately, we have to silently ignore the very invalidating warning then right from the manual: "There is no guarantee that every web server will provide any of these; servers may omit some, or provide others not listed here."

      – Sz.
      Nov 13 '18 at 1:13


















    • PHP_SELF only gives the value of the current processing file. The end result needs to be an absolute path not a URI.

      – Aaron Harun
      Jul 22 '10 at 14:48











    • My bad... I was originally testing from the CLI. How about using $_SERVER["SCRIPT_FILENAME"] instead? That worked in my environment. If that doesn't work what about prepending $_SERVER["DOCUMENT_ROOT"] to $_SERVER["PHP_SELF"]?

      – pferate
      Jul 22 '10 at 16:21











    • The following is the bug to your problem: bugs.php.net/bug.php?id=46260 Sadly, PHP won't change in this manner, which is a bug in my opinion.

      – Thorsten Schöning
      Jul 12 '15 at 19:42











    • Unfortunately, $_SERVER["SCRIPT_FILENAME"] doesn't work if the script you are executing this is included from another file. It's set to the original script that executed. This makes sense since the $_SERVER variable seems to be set up when the first script and doesn't change for any included scripts unlike magic constants.

      – user193130
      Sep 20 '17 at 18:46












    • This is as good a workaround as it gets, but, unfortunately, we have to silently ignore the very invalidating warning then right from the manual: "There is no guarantee that every web server will provide any of these; servers may omit some, or provide others not listed here."

      – Sz.
      Nov 13 '18 at 1:13

















    PHP_SELF only gives the value of the current processing file. The end result needs to be an absolute path not a URI.

    – Aaron Harun
    Jul 22 '10 at 14:48





    PHP_SELF only gives the value of the current processing file. The end result needs to be an absolute path not a URI.

    – Aaron Harun
    Jul 22 '10 at 14:48













    My bad... I was originally testing from the CLI. How about using $_SERVER["SCRIPT_FILENAME"] instead? That worked in my environment. If that doesn't work what about prepending $_SERVER["DOCUMENT_ROOT"] to $_SERVER["PHP_SELF"]?

    – pferate
    Jul 22 '10 at 16:21





    My bad... I was originally testing from the CLI. How about using $_SERVER["SCRIPT_FILENAME"] instead? That worked in my environment. If that doesn't work what about prepending $_SERVER["DOCUMENT_ROOT"] to $_SERVER["PHP_SELF"]?

    – pferate
    Jul 22 '10 at 16:21













    The following is the bug to your problem: bugs.php.net/bug.php?id=46260 Sadly, PHP won't change in this manner, which is a bug in my opinion.

    – Thorsten Schöning
    Jul 12 '15 at 19:42





    The following is the bug to your problem: bugs.php.net/bug.php?id=46260 Sadly, PHP won't change in this manner, which is a bug in my opinion.

    – Thorsten Schöning
    Jul 12 '15 at 19:42













    Unfortunately, $_SERVER["SCRIPT_FILENAME"] doesn't work if the script you are executing this is included from another file. It's set to the original script that executed. This makes sense since the $_SERVER variable seems to be set up when the first script and doesn't change for any included scripts unlike magic constants.

    – user193130
    Sep 20 '17 at 18:46






    Unfortunately, $_SERVER["SCRIPT_FILENAME"] doesn't work if the script you are executing this is included from another file. It's set to the original script that executed. This makes sense since the $_SERVER variable seems to be set up when the first script and doesn't change for any included scripts unlike magic constants.

    – user193130
    Sep 20 '17 at 18:46














    This is as good a workaround as it gets, but, unfortunately, we have to silently ignore the very invalidating warning then right from the manual: "There is no guarantee that every web server will provide any of these; servers may omit some, or provide others not listed here."

    – Sz.
    Nov 13 '18 at 1:13






    This is as good a workaround as it gets, but, unfortunately, we have to silently ignore the very invalidating warning then right from the manual: "There is no guarantee that every web server will provide any of these; servers may omit some, or provide others not listed here."

    – Sz.
    Nov 13 '18 at 1:13














    2














    You can use this code snippet to get a path where symlinks are not resolved.
    If you don't have bash available, there's probably a different command you can use, but it works on linux enviroments.



    I do think it's a malpractice that php resolves symlinks in FILE, since there's no way to get the path with symlinks. Otherwise we could easily get it using realpath.



    Oh well.



    <?php
    $output = array();
    exec('pwd', &$output);
    define('__LINK__', $output[0].substr(__FILE__, strpos(__FILE__, DIRECTORY_SEPARATOR)));
    ?>





    share|improve this answer


















    • 1





      'pwd' returns value depends on current working dir; To work propertly you should change working directiry first: cd /var/www/wp-content/themes/twenty_twelve/ && php script.php

      – AndreyP
      Jun 7 '16 at 16:57











    • I removed the &, and $output[0] worked for me.

      – Mr Goobri
      Sep 1 '16 at 10:23















    2














    You can use this code snippet to get a path where symlinks are not resolved.
    If you don't have bash available, there's probably a different command you can use, but it works on linux enviroments.



    I do think it's a malpractice that php resolves symlinks in FILE, since there's no way to get the path with symlinks. Otherwise we could easily get it using realpath.



    Oh well.



    <?php
    $output = array();
    exec('pwd', &$output);
    define('__LINK__', $output[0].substr(__FILE__, strpos(__FILE__, DIRECTORY_SEPARATOR)));
    ?>





    share|improve this answer


















    • 1





      'pwd' returns value depends on current working dir; To work propertly you should change working directiry first: cd /var/www/wp-content/themes/twenty_twelve/ && php script.php

      – AndreyP
      Jun 7 '16 at 16:57











    • I removed the &, and $output[0] worked for me.

      – Mr Goobri
      Sep 1 '16 at 10:23













    2












    2








    2







    You can use this code snippet to get a path where symlinks are not resolved.
    If you don't have bash available, there's probably a different command you can use, but it works on linux enviroments.



    I do think it's a malpractice that php resolves symlinks in FILE, since there's no way to get the path with symlinks. Otherwise we could easily get it using realpath.



    Oh well.



    <?php
    $output = array();
    exec('pwd', &$output);
    define('__LINK__', $output[0].substr(__FILE__, strpos(__FILE__, DIRECTORY_SEPARATOR)));
    ?>





    share|improve this answer













    You can use this code snippet to get a path where symlinks are not resolved.
    If you don't have bash available, there's probably a different command you can use, but it works on linux enviroments.



    I do think it's a malpractice that php resolves symlinks in FILE, since there's no way to get the path with symlinks. Otherwise we could easily get it using realpath.



    Oh well.



    <?php
    $output = array();
    exec('pwd', &$output);
    define('__LINK__', $output[0].substr(__FILE__, strpos(__FILE__, DIRECTORY_SEPARATOR)));
    ?>






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Dec 22 '11 at 14:10









    DagDag

    875




    875







    • 1





      'pwd' returns value depends on current working dir; To work propertly you should change working directiry first: cd /var/www/wp-content/themes/twenty_twelve/ && php script.php

      – AndreyP
      Jun 7 '16 at 16:57











    • I removed the &, and $output[0] worked for me.

      – Mr Goobri
      Sep 1 '16 at 10:23












    • 1





      'pwd' returns value depends on current working dir; To work propertly you should change working directiry first: cd /var/www/wp-content/themes/twenty_twelve/ && php script.php

      – AndreyP
      Jun 7 '16 at 16:57











    • I removed the &, and $output[0] worked for me.

      – Mr Goobri
      Sep 1 '16 at 10:23







    1




    1





    'pwd' returns value depends on current working dir; To work propertly you should change working directiry first: cd /var/www/wp-content/themes/twenty_twelve/ && php script.php

    – AndreyP
    Jun 7 '16 at 16:57





    'pwd' returns value depends on current working dir; To work propertly you should change working directiry first: cd /var/www/wp-content/themes/twenty_twelve/ && php script.php

    – AndreyP
    Jun 7 '16 at 16:57













    I removed the &, and $output[0] worked for me.

    – Mr Goobri
    Sep 1 '16 at 10:23





    I removed the &, and $output[0] worked for me.

    – Mr Goobri
    Sep 1 '16 at 10:23











    2














    In some case its possible to change working dir and use getenv('PWD'):



    $root = dirname(dirname(dirname(getenv('PWD'))));
    if (file_exists($root.'/wp-load.php'))
    // WP 2.6
    require_once($root.'/wp-load.php');



    And change working directory before run this code:



    cd /var/www/wp-content/themes/twenty_twelve/ && php script.php





    share|improve this answer



























      2














      In some case its possible to change working dir and use getenv('PWD'):



      $root = dirname(dirname(dirname(getenv('PWD'))));
      if (file_exists($root.'/wp-load.php'))
      // WP 2.6
      require_once($root.'/wp-load.php');



      And change working directory before run this code:



      cd /var/www/wp-content/themes/twenty_twelve/ && php script.php





      share|improve this answer

























        2












        2








        2







        In some case its possible to change working dir and use getenv('PWD'):



        $root = dirname(dirname(dirname(getenv('PWD'))));
        if (file_exists($root.'/wp-load.php'))
        // WP 2.6
        require_once($root.'/wp-load.php');



        And change working directory before run this code:



        cd /var/www/wp-content/themes/twenty_twelve/ && php script.php





        share|improve this answer













        In some case its possible to change working dir and use getenv('PWD'):



        $root = dirname(dirname(dirname(getenv('PWD'))));
        if (file_exists($root.'/wp-load.php'))
        // WP 2.6
        require_once($root.'/wp-load.php');



        And change working directory before run this code:



        cd /var/www/wp-content/themes/twenty_twelve/ && php script.php






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jun 7 '16 at 17:06









        AndreyPAndreyP

        1,07911113




        1,07911113





















            1














            The PHP interpreter resolves symlinks before it processes them. You can do this yourself with the readlink function. PHP resolves the links because it's more efficient for *_once functions and code caches like APC, Xcache etc.



            What you propably need is another way to find where a particular installation stores it's files. I'd recommend using $_SERVER['DOCUMENT_ROOT']/wp-content/wp-load.php assuming /share/www/portfolio is the document root.






            share|improve this answer























            • The document root is unfortunately /share/www/

              – Aaron Harun
              Jul 20 '10 at 14:30















            1














            The PHP interpreter resolves symlinks before it processes them. You can do this yourself with the readlink function. PHP resolves the links because it's more efficient for *_once functions and code caches like APC, Xcache etc.



            What you propably need is another way to find where a particular installation stores it's files. I'd recommend using $_SERVER['DOCUMENT_ROOT']/wp-content/wp-load.php assuming /share/www/portfolio is the document root.






            share|improve this answer























            • The document root is unfortunately /share/www/

              – Aaron Harun
              Jul 20 '10 at 14:30













            1












            1








            1







            The PHP interpreter resolves symlinks before it processes them. You can do this yourself with the readlink function. PHP resolves the links because it's more efficient for *_once functions and code caches like APC, Xcache etc.



            What you propably need is another way to find where a particular installation stores it's files. I'd recommend using $_SERVER['DOCUMENT_ROOT']/wp-content/wp-load.php assuming /share/www/portfolio is the document root.






            share|improve this answer













            The PHP interpreter resolves symlinks before it processes them. You can do this yourself with the readlink function. PHP resolves the links because it's more efficient for *_once functions and code caches like APC, Xcache etc.



            What you propably need is another way to find where a particular installation stores it's files. I'd recommend using $_SERVER['DOCUMENT_ROOT']/wp-content/wp-load.php assuming /share/www/portfolio is the document root.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jul 19 '10 at 15:31









            jmzjmz

            4,8361826




            4,8361826












            • The document root is unfortunately /share/www/

              – Aaron Harun
              Jul 20 '10 at 14:30

















            • The document root is unfortunately /share/www/

              – Aaron Harun
              Jul 20 '10 at 14:30
















            The document root is unfortunately /share/www/

            – Aaron Harun
            Jul 20 '10 at 14:30





            The document root is unfortunately /share/www/

            – Aaron Harun
            Jul 20 '10 at 14:30











            1














            Here is the solution to that issue: https://github.com/logical-and/symlink-detective



            $root = dirname(dirname(dirname(dirname(__FILE__))));
            if (file_exists(SymlinkDetective::detectPath($root.'/wp-load.php')))
            // WP 2.6
            require_once(SymlinkDetective::detectPath($root.'/wp-load.php'));



            or you can try that



            try 
            $root = dirname(dirname(dirname(dirname(__FILE__))));
            require_once SymlinkDetective::detectPath($root.'/wp-load.php', '',
            false /* this would throw an exception if file doesn't exists */);

            catch (Exception $e)
            // nothing to do if file doesn't exists






            share|improve this answer


















            • 1





              I really don't understand why you removing my answer. I wrote solution for the issue, I gave examples on how it can be used, I wrote that answer. Try to do the same, instead of removing my post or let me know at least why? Isn't my information useful?

              – And
              Dec 1 '16 at 10:12















            1














            Here is the solution to that issue: https://github.com/logical-and/symlink-detective



            $root = dirname(dirname(dirname(dirname(__FILE__))));
            if (file_exists(SymlinkDetective::detectPath($root.'/wp-load.php')))
            // WP 2.6
            require_once(SymlinkDetective::detectPath($root.'/wp-load.php'));



            or you can try that



            try 
            $root = dirname(dirname(dirname(dirname(__FILE__))));
            require_once SymlinkDetective::detectPath($root.'/wp-load.php', '',
            false /* this would throw an exception if file doesn't exists */);

            catch (Exception $e)
            // nothing to do if file doesn't exists






            share|improve this answer


















            • 1





              I really don't understand why you removing my answer. I wrote solution for the issue, I gave examples on how it can be used, I wrote that answer. Try to do the same, instead of removing my post or let me know at least why? Isn't my information useful?

              – And
              Dec 1 '16 at 10:12













            1












            1








            1







            Here is the solution to that issue: https://github.com/logical-and/symlink-detective



            $root = dirname(dirname(dirname(dirname(__FILE__))));
            if (file_exists(SymlinkDetective::detectPath($root.'/wp-load.php')))
            // WP 2.6
            require_once(SymlinkDetective::detectPath($root.'/wp-load.php'));



            or you can try that



            try 
            $root = dirname(dirname(dirname(dirname(__FILE__))));
            require_once SymlinkDetective::detectPath($root.'/wp-load.php', '',
            false /* this would throw an exception if file doesn't exists */);

            catch (Exception $e)
            // nothing to do if file doesn't exists






            share|improve this answer













            Here is the solution to that issue: https://github.com/logical-and/symlink-detective



            $root = dirname(dirname(dirname(dirname(__FILE__))));
            if (file_exists(SymlinkDetective::detectPath($root.'/wp-load.php')))
            // WP 2.6
            require_once(SymlinkDetective::detectPath($root.'/wp-load.php'));



            or you can try that



            try 
            $root = dirname(dirname(dirname(dirname(__FILE__))));
            require_once SymlinkDetective::detectPath($root.'/wp-load.php', '',
            false /* this would throw an exception if file doesn't exists */);

            catch (Exception $e)
            // nothing to do if file doesn't exists







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 30 '16 at 10:05









            AndAnd

            625




            625







            • 1





              I really don't understand why you removing my answer. I wrote solution for the issue, I gave examples on how it can be used, I wrote that answer. Try to do the same, instead of removing my post or let me know at least why? Isn't my information useful?

              – And
              Dec 1 '16 at 10:12












            • 1





              I really don't understand why you removing my answer. I wrote solution for the issue, I gave examples on how it can be used, I wrote that answer. Try to do the same, instead of removing my post or let me know at least why? Isn't my information useful?

              – And
              Dec 1 '16 at 10:12







            1




            1





            I really don't understand why you removing my answer. I wrote solution for the issue, I gave examples on how it can be used, I wrote that answer. Try to do the same, instead of removing my post or let me know at least why? Isn't my information useful?

            – And
            Dec 1 '16 at 10:12





            I really don't understand why you removing my answer. I wrote solution for the issue, I gave examples on how it can be used, I wrote that answer. Try to do the same, instead of removing my post or let me know at least why? Isn't my information useful?

            – And
            Dec 1 '16 at 10:12











            0














            If I were trying to solve this, I'd split __FILE__ along the path bits and create a SplFileInfo for each along the way, test with isDir and isLink, then try to determine how to handle reconstruction of the path once it's known to be different than expected so you can pull from the right directory. (If you're more of a procedural type, there's is_dir and is_link.)



            That being said, I think you've already disqualified this solution. Maybe the tools are smart enough to do it for you. Try comparing the result of getRealPath to getPath? getRealPath expressly says that it resolves symlinks, while getPath doesn't expressly say that.



            Even then, this sniffing might not be safe on client sites, depending on who the host is. I've seen some pretty creative shared hosting filesystem setups. You could add a check to php_uname and pull out the hostname of the machine, and if it isn't your dev box, don't do the extra work.






            share|improve this answer


















            • 1





              Unfortunately, getRealPath and getPath all output the /trunk/ directory.

              – Aaron Harun
              Jul 11 '10 at 20:22















            0














            If I were trying to solve this, I'd split __FILE__ along the path bits and create a SplFileInfo for each along the way, test with isDir and isLink, then try to determine how to handle reconstruction of the path once it's known to be different than expected so you can pull from the right directory. (If you're more of a procedural type, there's is_dir and is_link.)



            That being said, I think you've already disqualified this solution. Maybe the tools are smart enough to do it for you. Try comparing the result of getRealPath to getPath? getRealPath expressly says that it resolves symlinks, while getPath doesn't expressly say that.



            Even then, this sniffing might not be safe on client sites, depending on who the host is. I've seen some pretty creative shared hosting filesystem setups. You could add a check to php_uname and pull out the hostname of the machine, and if it isn't your dev box, don't do the extra work.






            share|improve this answer


















            • 1





              Unfortunately, getRealPath and getPath all output the /trunk/ directory.

              – Aaron Harun
              Jul 11 '10 at 20:22













            0












            0








            0







            If I were trying to solve this, I'd split __FILE__ along the path bits and create a SplFileInfo for each along the way, test with isDir and isLink, then try to determine how to handle reconstruction of the path once it's known to be different than expected so you can pull from the right directory. (If you're more of a procedural type, there's is_dir and is_link.)



            That being said, I think you've already disqualified this solution. Maybe the tools are smart enough to do it for you. Try comparing the result of getRealPath to getPath? getRealPath expressly says that it resolves symlinks, while getPath doesn't expressly say that.



            Even then, this sniffing might not be safe on client sites, depending on who the host is. I've seen some pretty creative shared hosting filesystem setups. You could add a check to php_uname and pull out the hostname of the machine, and if it isn't your dev box, don't do the extra work.






            share|improve this answer













            If I were trying to solve this, I'd split __FILE__ along the path bits and create a SplFileInfo for each along the way, test with isDir and isLink, then try to determine how to handle reconstruction of the path once it's known to be different than expected so you can pull from the right directory. (If you're more of a procedural type, there's is_dir and is_link.)



            That being said, I think you've already disqualified this solution. Maybe the tools are smart enough to do it for you. Try comparing the result of getRealPath to getPath? getRealPath expressly says that it resolves symlinks, while getPath doesn't expressly say that.



            Even then, this sniffing might not be safe on client sites, depending on who the host is. I've seen some pretty creative shared hosting filesystem setups. You could add a check to php_uname and pull out the hostname of the machine, and if it isn't your dev box, don't do the extra work.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jul 11 '10 at 5:09









            CharlesCharles

            45.8k1287125




            45.8k1287125







            • 1





              Unfortunately, getRealPath and getPath all output the /trunk/ directory.

              – Aaron Harun
              Jul 11 '10 at 20:22












            • 1





              Unfortunately, getRealPath and getPath all output the /trunk/ directory.

              – Aaron Harun
              Jul 11 '10 at 20:22







            1




            1





            Unfortunately, getRealPath and getPath all output the /trunk/ directory.

            – Aaron Harun
            Jul 11 '10 at 20:22





            Unfortunately, getRealPath and getPath all output the /trunk/ directory.

            – Aaron Harun
            Jul 11 '10 at 20:22

















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3221771%2fhow-do-you-get-php-symlinks-and-file-to-work-together-nicely%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            27

            Top Tejano songwriter Luis Silva dead of heart attack at 64

            Category:Rhetoric