【问题标题】:PHP Require file outside of functionPHP在函数之外需要文件
【发布时间】:2012-02-24 08:04:30
【问题描述】:

有没有办法在函数之外包含一个文件并让它工作?

即。我有一个文件 db.inc.php,其中包含我的数据库连接字符串:

switch (DB_TYPE) {
case MYSQL :
    try {
        $DBH = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . "", DB_USER, DB_PASS);
        $DBH -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch(PDOException $e) {
        echo "Error in Connection" . $e -> getMessage();
    }
}

现在我在我的函数文件functions.php中需要这个文件:

require('db.inc.php')
function add() {

        $n = $DBH -> prepare("");
        $n -> execute((array)$s);
}

因此文件已正确添加,但我的函数无法访问 $DBH 句柄。仅当我在函数中包含文件时:

function add(){
require('db.inc.php')

....etc....

}

我的功能会起作用吗?

由于我将在许多文件中至少有 4-5 个函数,是否有可能只在函数之外需要它并让函数工作?

感谢和问候

【问题讨论】:

  • 你的目标会产生大量难以测试的重复代码。只是说,技术上可以按照您的要求去做,问题是您真的想要这样做吗?

标签: php function require


【解决方案1】:

在函数外部包含文件后,您可以将变量声明为全局变量,但这确实是一种糟糕的处理方式。相反,您应该让函数的调用者将句柄作为参数传递。如果做不到这一点,您可以为数据库创建一个工厂并在每个函数中调用它。

为什么一定要在函数外调用require

【讨论】:

  • 是的,我知道全局变量不好,因此我避免使用它。我之所以想要它在外面,是因为我只想要求它一次,而不是我的每一个功能。
【解决方案2】:

真正唯一的全局变量是使用面向对象的技巧和技术。例如,如果您将功能实现为一组类,那么您始终可以访问任何静态公共类变量,因为它们将是全局的。另一种方法是对单个对象类使用标准 PHP 模式。这与您的情况特别相关,因为您似乎正在包装标准 PDO 类。就我而言,我使用 mysqli,但同样的技术也适用。任何模块都可以使用AppDB::get() 访问数据库对象。这是我的模块的序言,为您提供了这个想法(我已经修剪了 doxygen 文档以使其简短):

class AppDB extends mysqli {            

    /**            
     * This class uses a standard single class object pattern.            
     */            
    private static $_instance;            
    private static $_class = __CLASS__;            
    private function __clone() {}            
    /**            
     * Initialise the blog context. This is a static method since only one AppDB instance is allowed. The            
     * $connectParams must be provided on first invocation.            
     */            
    public static function get() {            

        if ( !isset( self::$_instance) ) self::$_instance = new self::$_class ();            
        return self::$_instance;            
    }            

    /**            
     * AppDB constructor. Connect to the database and initialise the list of tables with the given prefix.            
     */            
    private function __construct() {            

        parent::init();            
        list( $host, $db, $user, $passwd, $this->tablePrefix ) = explode ( ':', SQL_CONTEXT );            

        if( !parent::real_connect($host, $user, $passwd, $db)) {            
            throw new Exception ('Connect Error (' .             
                mysqli_connect_errno() . ') ' . mysqli_connect_error() );            
        }            
        ...            
    }
    ...
}

【讨论】:

    【解决方案3】:

    您可以使用global 运算符:

    require('db.inc.php')
    function add() {
            global $DBH;
            $n = $DBH -> prepare("");
            $n -> execute((array)$s);
    }
    

    【讨论】:

      【解决方案4】:

      您只想使用 global 关键字将其带入函数的范围:

      function add() {
          global $DBH;
          $n = $DBH -> prepare("");
          $n -> execute((array)$s);
      }
      

      有关变量范围的更多信息,请参阅this link

      您也可以使用$GLOBALS,但我不喜欢这种方法。

      或者,您可以在调用 add() 时通过引用传递句柄:

      add($DBH);
      
      function add(&$DBH) {
          global $DBH;
          $n = $DBH -> prepare("");
          $n -> execute((array)$s);
      }
      

      【讨论】:

        猜你喜欢
        • 2018-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-26
        • 1970-01-01
        • 2017-07-23
        相关资源
        最近更新 更多