1

I have a very simple PHP file that is part of a unit test with PHPUnit, and I am getting an issue where require() reports back that it is unable to open the stream because no such file exists, but yet, on the next line tests if the file_exists and this returns true?

<?php
$inc1 = $_SERVER['DOCUMENT_ROOT'].'/vendor/autoload.php';
require $inc1;
if (file_exists($inc1)){
    echo "yes";
}else
{
    echo "no";
}

What could be causing this behavior and for this to not work?

The exact error being returned by the console is:

Warning: require(/vendor/autoload.php): failed to open stream: No such file or directory in /Users/REDACTED/Documents/Github/XXX/tests/inc/emailSendTest.php on line 3

Fatal error: require(): Failed opening required '/vendor/autoload.php' (include_path='.:') in /Users/REDACTED/Documents/Github/XXX/tests/inc/emailSendTest.php on line 3
jx34tech
  • 21
  • 7
  • What happens if you put the require inside the `if(file_exists($inc1))` statement? – Dawson Irvine Dec 15 '20 at 04:31
  • @DawsonIrvine If I put the require inside the file_exists test, it goes from returning yes, to returning no, which I think is really odd behaviour – jx34tech Dec 15 '20 at 05:13
  • That is odd. I am also curious how you know the if statement returns yes as when I usually try to include/require a file, if it doesn't exist, PHP gives me a `Fatal Error:` and stops executing at that point. – Dawson Irvine Dec 15 '20 at 05:16
  • @DawsonIrvine That's why I have it echo inside of the file_exists test case, but what confuses me, is if the file_exists function returns true, than why can't require use the file at the exact same location, it's not like they are referencing different endpoints – jx34tech Dec 15 '20 at 06:16
  • 1
    What have you tried to debug the problem? What does `$inc1` contain? Please dump it and add the content to the quesiton, don't try to guess what it could contain – Nico Haase Dec 15 '20 at 07:18
  • @NicoHaase When I dump the variable it returns the correct actual location of the file: `/Users/XXX/Documents/GitHub/XXX/vendor/autoload.php` and file_exists function confirms that the file does exist in the correct location, it's just that require does not seem to be able to access the exact same location – jx34tech Dec 15 '20 at 07:44
  • Can you share more details about how you run the script? The error message you've dumped does not contain the full path – Nico Haase Dec 15 '20 at 08:50
  • @NicoHaase I can recreate this error from PHPUnit and in the browser running the script directly using a local PHP instance on my machine, The dumped error message from the console, doesn't contain the full path unfortunately, but I can echo out the path it's looking for, ie. `echo $inc1` and this does contain the correct path – jx34tech Dec 15 '20 at 09:25
  • Please add all clarification to your question by editing it - `$_SERVER` is an array set by your webserver (Apache or nginx), and I don't think that PHPUnit uses it after all. Why do you need to rely on that server variable after all? – Nico Haase Dec 15 '20 at 10:11
  • Ah, thank you for providing Clarification on that, I wasn't aware that that particular array was set by the server. That would 100% explain why I was getting intermittent errors when writing Unit Tests using PHPUnit. Would there be a best practice way for me to include these library files in a way that would not error with PHPUnit? – jx34tech Dec 15 '20 at 10:37
  • Yes, there is. Simply include the autoloader with a file path that does not depend on any variables, for example like Symfony does it in https://github.com/symfony/recipes/blob/master/symfony/framework-bundle/5.2/public/index.php#L8 – Nico Haase Dec 16 '20 at 16:02

3 Answers3

0

You should try with directory path this way.

$inc1 = dirname(__FILE__).'/(PATH-TO-VENDOR-DIRECTORY)/autoload.php';
$inc1 = dirname(__FILE__).'/vendor/autoload.php';
if(file_exists($inc1)){
    require($inc1);
    echo "yes";
}
else{
    echo "no";
}

This (PATH-TO-VENDOR-DIRECTORY) is important. This will be relative path of the directory from the current directory. Use "/" for a forward directory path or "../" to go back one directory.

I hope this will work for you.

Hafiz Ameer Hamza
  • 462
  • 1
  • 4
  • 14
  • "dirname(__FILE__)" returns the current directory path from root directory. You can include any file with relative path. – Hafiz Ameer Hamza Dec 15 '20 at 05:21
  • I have tried this as a solution, but this doesn't seem to return the desired result and returns this as an error: Warning: require(/Users/XXX/Documents/GitHub/XXX/tests/inc/vendor/autoload.php): failed to open stream: No such file or directory in /Users/XXX/Documents/GitHub/XXX/tests/inc/emailSendTest.php on line 3 – jx34tech Dec 15 '20 at 05:26
  • Okay, Let me know the directory "vendor" is relative to the file in which you want to include the autoload.php ? – Hafiz Ameer Hamza Dec 15 '20 at 05:58
  • I modified my answer, Please follow the path. – Hafiz Ameer Hamza Dec 15 '20 at 06:06
  • It's possible for me to link directly to its location from the file system, but if I try to bring it in in a relative way, so that it will work on any system, that's where things start to break down, The issue seems to be with the way it's linked relatively, but I'm not sure exactly why it's not working, as file_exists returns true – jx34tech Dec 15 '20 at 06:19
  • I found the issue, Your file is autoload.php working and exists and return true. There is another file including with name emailSendTest.php in autoload.php which either not exist or path is not correct. Make sure that file. There is no issue with autoload.php check this /Users/REDACTED/Documents/Github/XXX/tests/inc/emailSendTest.php on line 3 – Hafiz Ameer Hamza Dec 15 '20 at 06:35
  • The issue is with this file. emailSendTest.php which include/require inside autoload.php – Hafiz Ameer Hamza Dec 15 '20 at 06:36
  • Oh sorry I should included in the original post; The snippet posted with the original file is emailSendTest.php in question itself – jx34tech Dec 15 '20 at 07:01
  • Then you should try and test that file instead. When you check file_exists it returned you true for the file autoload.php which path is fine. Your file path for emailSendTest.php is not relative. Make sure its path and then try with that. Mark this accepted answer if you think this helped you to get actual issue to get answer. Let me know if the issue resolved. – Hafiz Ameer Hamza Dec 15 '20 at 07:23
0

By referring to many other StackOverflow questions, I have found that this is a common problem with the way that PHPUnit treats directories and the solution to my problem is to use:

$envConfigInclude = realpath(dirname(dirname(__FILE__))) .  '/inc/env-config.php';

To include the file, this is because it will return the full proper path, and this is something that PHPUnit can interpret and return the correct include and the rest of the script will execute.

This answer is based on the findings of these two StackOverflow questions: PHPUnit doesn't allow me to include files and Get parent directory of running script

jx34tech
  • 21
  • 7
0
$inc1 = '../vendor/autoload.php';

Use double dot before directory name, I think this will work for you.

Fahad Razi
  • 64
  • 1
  • 5
  • Unfortunately due to the way that PHPUnit treats directories, this solution won't work and will fail, the only solution I have found that works, is the one that I have posted as an answer to my own question – jx34tech Dec 16 '20 at 00:14