2012-02-01 39 views
3

有没有办法在功能之外包含一个文件并使其工作?PHP需要功能以外的文件

即。我有一个文件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个函数,只是要求它在函数之外并且使函数能够工作的任何可能性?

感谢和问候

+0

你的目标是什么,会产生大量的重复的代码是很难测试。只是说,在技术上可以做你想要的东西,问题是你真的想要那么做吗? – hakre 2012-02-01 16:56:33

回答

1

包括功能之外文件后,你可以声明变量是全局的,但这是一个很糟糕的做事方式。相反,你应该让函数传递句柄的调用者作为参数。否则,你可以为数据库创建一个工厂,并在每个函数中调用它。

为什么你必须调用require以外的函数?

+0

是的,我知道globals是坏的,因此我已经避免使用它。理由为什么我想要在外面,是因为我想只需要一次,而不是为了我的每一个功能。 – d123 2012-02-01 16:28:54

+0

require_once()? – 472084 2012-02-02 10:53:35

0

你只是想用全球关键字把它在功能上的作用范围:

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); 
} 
0

可以使用global操作:

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

真的是全局变量的唯一替代方法是使用面向对象的技巧和技巧。例如,如果您将功能实现为一组类,那么您始终可以访问任何静态公共类变量,因为它们将是全局变量。另一种方法是对单个对象类使用标准的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());    
     }    
     ...    
    } 
    ... 
}