[php-src] Issue #13245: require_once throws the exception when try to load file from script directory during autoloading

From: Date: Thu, 25 Jan 2024 20:25:01 +0000
Subject: [php-src] Issue #13245: require_once throws the exception when try to load file from script directory during autoloading
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-246342@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/13245 Author: FuZuK ### Description The following code: file: test.php ```php <?php spl_autoload_register(function ($class_name) { if (class_exists($class_name)) { return true; } $class_sources = [ __DIR__ . '/src', ]; $class_name = trim($class_name, '\\'); $file = str_replace('\\', DIRECTORY_SEPARATOR, $class_name) . '.php'; foreach ($class_sources as $source) { $class_path = $source . DIRECTORY_SEPARATOR . $file; if (is_file($class_path)) { require_once $class_path; return true; } } return false; }); echo 'PHP version: ' . phpversion() . PHP_EOL; print_r((new Product)->getStatuses()); ``` file: src/Product.php ```php <?php class Product { protected array $statuses = [ 'disabled' => ProductStatus::DISABLED, 'enabled' => ProductStatus::ENABLED, ]; public function getStatuses() { return $this->statuses; } } ``` file: src/ProductStatus.php ```php <?php require_once __DIR__ . '/../Exception/ProductException.php'; class ProductStatus { const ENABLED = 1; const DISABLED = 0; const TIMEOUT = 5; } ``` file: Exception/ProductException.php ```php <?php require_once('BaseException.php'); class ProductException extends BaseException {} ``` file: Exception/BaseException.php ```php <?php class BaseException extends Exception {} ``` Resulted in this output: ``` PHP version: 8.2.15 PHP Warning: require_once(BaseException.php): Failed to open stream: No such file or directory in /app/src/Product.php on line 6 PHP Fatal error: Uncaught Error: Failed opening required 'BaseException.php' (include_path='.:/usr/share/php') in /app/src/Product.php:6 Stack trace: #0 /app/src/ProductStatus.php(3): require_once() #1 /app/test.php(19): require_once('...') #2 /app/test.php(29): {closure}() #3 {main} thrown in /app/src/Product.php on line 6 ``` But I expected this output instead: ``` PHP version: 8.2.15 Array ( [disabled] => 0 [enabled] => 1 ) ``` Prior to PHP 8.2 it works fine. PHP 8.1.27: ``` PHP version: 8.1.27 Array ( [disabled] => 0 [enabled] => 1 ) ``` PHP 7.4.33: ``` PHP version: 7.4.33 Array ( [disabled] => 0 [enabled] => 1 ) ``` It relates not only to require_once, other include/require functions execute with the same result. I've discovered the UPGRADING notes, but did not find any points about that something has been changed in include/include_once/require/require_once behavior. The solution for this case is to use __DIR__ in Exception/ProductException.php, but wanna to know the reason why it executes unexpectedly. Possibly that's because it's loading via class autoloader, because if to avoid the use of autoloader and include files src/Product.php and src/ProductStatus.php directly in test.php, it works fine. Dockerfile used for test: ``` FROM debian:bullseye-slim WORKDIR /app RUN apt update RUN apt -y install lsb-release apt-transport-https ca-certificates wget vim nano less curl gnupg2 RUN wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg RUN echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/php.list RUN apt update RUN apt install -y php8.2-cli php8.2-common php8.2-mbstring php8.2-dba php8.2-gd php8.2-gnupg php8.2-igbinary php8.2-imagick php8.2-imap php8.2-bcmath php8.2-ldap php8.2-bz2 php8.2-dom php8.2-mysql php8.2-opcache php8.2-pgsql php8.2-curl php8.2-memcached php8.2-msgpack php8.2-readline php8.2-redis php8.2-soap php8.2-ssh2 php8.2-xml php8.2-xmlrpc php8.2-zip php8.2-maxminddb php8.2-intl php8.2-stomp RUN rm -rf /var/lib/apt/lists/* /var/cache/debconf && apt-get clean ENTRYPOINT [ "/bin/bash" ] ``` Command to run: ```bash # build docker build -f Dockerfile -t php8.2-cli:dev --no-cache ./ # run docker run --rm -ti -v "$(pwd):/app" php8.2-cli:dev -c 'php test.php' ``` ### PHP Version PHP 8.2.15 ### Operating System Debian 11

« previous php.bugs (#246342) next »