【问题标题】:require_once does not work properly when requiring the file from the classes当需要类中的文件时,require_once 无法正常工作
【发布时间】:2015-02-20 12:32:47
【问题描述】:

我正在构建一个小型 PHP MVC 框架,这是我的文件夹结构

/app
  /controllers
  /models
  /views
  /templates
  /config
    /config.php
  /core
    /Controller.php
    /Router.php
    /init.php
/index.php

在作为前端控制器的 index.php 内部,我有这段代码需要 /app/core/init.php 中的 init.php

index.php

<?php
require_once 'app/core/init.php'
$Router = new Router();
$Controller = new Controller();
?>

app/core/init.php

<?php
require_once 'Controller.php';
require_once 'Router.php';
?>

init.php 需要 /core 目录中的每个基本控制器和类,包括 Controller.php 和 Router.php,这里 index.php 还实例化类

此时一切正常,因为我通过在 Controller.php 和 Router.php 中创建构造函数来测试这一点,所以这两个文件中的代码将是这样的

app/core/Controller.php

<?php
class Controller {
    public function __construct() {
        echo 'OK!';
    }
}
?>

app/core/Router.php

<?php
class Router {
    public function __construct() {
        echo 'OK!';
    }
}
?>

在 index.php 内它回显 OK!因为这些类是正确实例化的,但问题是当我想从位于 /app/core/Controller.php 的 Controller.php 中包含位于 /app/config/config.php 中的 config.php 时,此代码

<?php
class Controller {
    public function __construct() {
        require_once '../config/config.php';
    }
}
?>

每当我这样做时,它都会返回此错误

Controller::include(../config/config.php) [controller.include]: failed to open stream: No such    file or directory in C:\AppServ\www\myapp\app\core\Controller.php on line 6

Controller::include() [function.include]: Failed opening '../config/config.php' for inclusion (include_path='.;C:\php5\pear') in C:\AppServ\www\myapp\app\core\Controller.php on line 6

我认为我使用了正确的位置,我在 /app/core/Controller.php 中工作并且想要要求 /app/config/config.php。我使用 ../

返回一个目录

那为什么我不能要求该文件?

【问题讨论】:

  • 了解自动加载。在构造函数中包含一些东西在很多层面上都是错误的。
  • 你为什么要在控制器中加载config?你的方法不适合有一个工作的 mvc

标签: php


【解决方案1】:

虽然 AnotherGuy 已经给出了正确的解决方案,但我想补充一点,PHP 显示的行为实际上非常奇怪。我设置了一个小包含树,其中脚本 A 包含 B,其中包含 C(都在单独的目录中),但是如果我指定相对于 A 的路径,B 只会包含 C,即使此时 _FILE__ 常量显示了 B 的路径. 我猜文档中提到的调用脚本不是我期望的调用这个函数的脚本,而是最初为请求服务的脚本。

我完全同意不使用相对路径,但经过多年的 PHP 修补,它永远不会让我感到惊讶,这很好。

【讨论】:

    【解决方案2】:

    我不知道发生了什么,但require_once() 不会抛出将自己称为include() 的错误,因为它们是不同的函数,另外,如果这是整个代码,则错误行号不会t 也与您的 require_once() 呼叫线路匹配,因为它应该是 4。尝试重新启动您的网络服务器,看看它是否修复了某些问题,否则您可能会搞砸一些事情

    【讨论】:

      【解决方案3】:

      根据我的个人经验,使用相对文件路径有时会让人头疼。所以我通常使用 go 和文件的绝对路径。这也具有更快一点的优势。 然后,如果您在某个时候遇到包含错误,则更容易找到错误,因为您拥有可用的整个路径。

      为了能够创建绝对路径,我建议您在 index.php 文件(前端控制器)中添加一个常量。类似于以下内容:

       define('ROOT_PATH', realpath(dirname(__FILE__)) . DIRECTORY_SEPARATOR);
      

      这里有函数define()realpath()dirname()的文档。

      这定义了一个名为ROOT_PATH 的常量,它引用了index.php 文件所在的目录,因此是您的根目录。同时我在末尾附加了一个目录分隔符,以便于编写路径。要使用它,您将编写。

      require_once ROOT_PATH . 'config/config.php';
      

      奖金信息

      但是,如果您在 controller.php 类中使用这种方法,您将使其依赖于该常量。为了解决这个问题,您可以在构造函数中将根路径作为变量传递。

      public function __construct($root) {...
      

      然后像下面这样使用它:

      public function __construct($root) {
      
          require_once($root . 'config/config.php');
      
      }
      

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-06
        • 1970-01-01
        • 2011-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-09
        • 2016-04-01
        相关资源
        最近更新 更多