PHP Include_once will include file a second time if a parent directory has a different case

198 Views Asked by At

I have a directory structure as follows:

  • test
    • scripts
      • testClasses.php
    • testSubDirectory
      • otherSubDirectory
        • include1.php
        • include2.php
        • includeTest.php

Here is the code for each file:
testClasses.php:

<?php
echo __FILE__."<br/>";

include1.php:

<?php
include_once("include2.php");
include_once $_SERVER['DOCUMENT_ROOT'] . "/test/scripts/testClasses.php";

incude2.php:

<?php
include_once("/test/scripts/testClasses.php");

includeTest.php:

<?php
include_once($_SERVER['DOCUMENT_ROOT'] . "/TEST/scripts/testClasses.php");
include_once("include1.php");
var_dump(get_included_files());
var_dump(get_include_path());
var_dump(__FILE__);
echo "PHP Version: ".phpversion().PHP_EOL;

When running PHP 5.4.3 I see the following output: PHP 5.4.3 output

When running PHP 7.4.8 I see the following output: PHP 7.4.8 output

Both servers are running on Windows machines.

The testClass.php file is included twice on the PHP 7.4.8 version due to the include having a different case on both even though it is the same file in the same directory. If testClass.php had some class declarations, an error would be thrown. Is there a way to get around this so I don't have to change the case in my include statements throughout the code?

1

There are 1 best solutions below

0
kmoser On

Your testClass.php can test if a constant is defined. If it is not defined, define it and continue with the rest of that file:

if (!defined('foo')) {
  define('foo', 'bar'); // Any value will do
  // The rest of testClass.php goes here
}

If you want to do this for multiple included files, you'll have to come up with a better naming convention than "foo", to ensure your symbols don't clash.

Alternately, if you know that testClass.php already defines a certain function (let's say function foo()), you can test for that instead:

if (!function_exists('foo')) {
  // The rest of testClass.php goes here
}