繁体   English   中英

使用 require_once 找不到 PHP 类

[英]PHP Class not found with require_once

我很诚实。 我几乎不知道如何正确使用“require_once”。 现在我正在尝试一件简单的事情:

PHP-Class EmergencyTicket.php:

<?php

require_once(dirname(__FILE__)."/../../classes/DB.php");
require_once __DIR__ . '/Ticket.php';

class EmergencyTicket extends Ticket {
 (... code ...)
}

PHP-Class Ticket.php

<?php
class Ticket
{
(... code ...)
}

这些文件位于服务器上: 1) 票证 1:webservice/v1/Ticket/EmergencyTicket.php 1) 票证 2:webservice/v1/Ticket/Ticket.php

在 Ticket2 文件中,我在加载时收到以下错误消息:

Fatal error: Class 'Ticket' not found in /usr/www/users/kontug/api.medifaktor.de/webservice/v1/Ticket/EmergencyTicket.php on line 6

第 6 行是:

class EmergencyTicket extends Ticket {

我在文件夹中看到文件Ticket.php,我只想扩展这个类,但似乎没有找到文件。 还有什么我可以检查的吗?

需要文件时要记住的一些事情:

  1. 你必须有正确的路径。
  2. 该文件必须具有读取权限。
  3. 必须首先加载依赖项。 如果类扩展抽象,具有接口或特征,则必须在到达类声明之前加载它们。 同样,如果依赖项也有依赖项,则还必须在加载依赖项本身之前加载这些依赖项。

根据您列出的信息,#3 似乎是您的问题。 父类必须在子类声明之前加载。

使这更容易的良好做法:

  • 在需要各种文件之前声明映射到应用程序根目录、库等的常量,因此您无需使用复杂的导航来查找它们。
  • 使用自动加载器,最好是 psr-0 或 psr-4 兼容。

检查的快速方法(合理稳健):

/**
 * Provided for documentor/apigen support.
 * This function will attempt to load a file, and return information about
 * failure if it cannot be found or is not readable. It will also by default
 * avoid double inclusion to prevent redeclaration errors, though this can be 
 * configured to be ignored if required. 
 * NOTE: This function will mitigate common inclusion mistakes like duplicated or missing directory separators and file extensions.
 * @param string $file The name of the file, may be the actual file or full path.
 * @param string $dir (optional) The directory to check for the file. This param is best used with search functions that know the file name but not explicitly the directory, which allows for more robust usage elsewhere with minimal variable modification. This function can be used perfectly fine without it though.
 * @param string $suffix (optional) The file suffix that will be checked for. This will be appended to your file, and defaults to .php. You must alter this parameter if you are searching for a different file type.
 * @param boolean $nodup (optional) If true, will not include a file that has already been loaded to prevent class redeclaration errors. If false, will require the file regardless.
 * @return boolean TRUE if file was included, FALSE if not included (NOTE: you may want to modify the return line in the catch block depending on your needs.)
 */
function _requireFile($file, $dir = NULL, $suffix = '.php', $nodup = TRUE) {
    //this is not necessary in this example, but is generally good practice, and will prevent accidentally duplicated or missing extensions.
    //This function assumes that it will be used frequently, and contains redundancies to mitigate common inclusion errors such as missing or duplicated extenstions, missing or duplicated directory separators, etc.
    $file = ( ( isset($dir) ) ? rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : NULL ) . rtrim($file, $suffix) . $suffix);
    try {
        if (!file_exists($file)) {
            //the file does not exist at the specified location, throw an exception with information about the request.
            throw new \Exception("File not found at: " . $file);
        } elseif (file_exists($file) && !is_readable) {
            //the file exists in the specified location, but cannot be read due to a file permission conflict. Throw an exception with information about the request and how to fix it.
            throw new \Exception("File exists but is not readable at: " . $file . " <hr>You can correct this by using 'chmod 755 " . $file . "' from the command line.");
        }
        //This allows you to perform a duplication check to avoid class redeclaration errors. If you intend to include the file multiple times, pass the $nodup param as FALSE or 0 to ignore this check.
        if (!$nodup == TRUE && in_array($file, get_included_files())) {
            return FALSE;
        } else {
            //The file exists, is readable, and passed the no-duplication check, require the file. Note that require_once was intentionally not used to provide the option to require files multiple times if needed. If you are only ever going to use this for files that should not be redeclared, you can change this to require_once but it will really not make any appreciable difference.
            require($file);
            return TRUE;
        }
    } catch (\Exception $e) {
        //You may want to use a logging function here rather than echoing to the screen. The echo statement is provided for quick debugging, but should not be used in production.
        echo 'Error fetching file at ' . $e->getLine() . ' of ' . $e->getFile() . ': ' . $e->getMessage();
        //you may want to rethrow the exception and catch it in the referencing method or function, kill the program, or otherwise mitigate errors here depending on your program structure. Non-essential files should not kill your program though.
        return FALSE;
    }
}

$file = "/path/to/file.php";
_requireFile($file);

//OR

$dir =  "/path/to/";
$file = "/path/to/file.php";
_requireFile($file, $dir);

//OR

$dir =  "/path/to/";
$file = "/path/to/file";
$suffix = ".php";
_requireFile($file, $dir, $suffix);

更好的方法:

- 使用PSR-4PSR-0自动加载器。

由于您之前的示例中已经有拼写错误,因此我非常怀疑这是一个很好的真实示例。

  1. 例如,错误消息.php扩展名。
  2. 此外,如果Ticket1.php您收到的错误消息也不会发生,因为这首先会作为致命错误而失败。

您的源代码很好,您会收到您所说的错误的唯一原因是,如果您还成功包含了另一个名为Ticket1.php的文件,并且它没有该类定义。

如果这不是您遇到的问题,那么您需要再次尝试使用真实的工作代码编写此问题。 尝试稍微简化您的内容,并为我们提供可以在我们自己的系统上执行的内容。

例如,这对我有用:

票务1.php

<?php

class Ticket1 { }

?>

票务2.php

<?php

require_once 'Ticket1.php';

class Ticket2 extends Ticket1 { }

运行Ticket1.phpTicket2.php不会出错。

应该注意的一件事可能与您要包含的目录有关。

如果第三个脚本包含来自不同目录的Ticket2.php ,这将失败.. 因为 PHP 的当前目录始终是您启动的第一个脚本的目录。

为确保这不是您遇到的问题,请包含如下文件:

require_once __DIR__ . '/Ticket1.php';

__DIR__是一个神奇的 PHP 常量,它始终包含您使用该常量的文件目录的完整路径。

一探究竟:

require_once (__DIR__ . DIRECTORY_SEPARATOR . 'Ticket.php');

我有同样的问题,我尝试使用include('path/to/file.php')而不是require_once 嗯,它只是有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM