【问题标题】:Using Variable From Other File To Be Used Inside PHP Class使用其他文件中的变量在 PHP 类中使用
【发布时间】:2016-04-17 22:01:44
【问题描述】:

我从一个名为 config.php 的文件中获取数据库凭据变量:

$db_server = 'localhost';
$db_user = 'username';
$db_password = 'secret'
$db_name = 'dbname';

现在,我在 /class 文件夹下有一个 PHP 类,它非常适合 CRUD 过程。命名为MysqlCrud.class.php

class Database {

    private $db_host = 'localhost';  // Change as required
    private $db_user = 'username';  // Change as required
    private $db_pass = 'secret';  // Change as required
    private $db_name = 'dbname';    // Change as required

}

但是,我想使用来自config.php 的集中变量。这就是为什么我添加一些这样的行:

include('../config.php');
class Database {

    global $db_server;
    global $db_user;
    global $db_password;
    global $db_name;

    private $db_host = $db_server;  // Change as required
    private $db_user = $db_user;  // Change as required
    private $db_pass = $db_password;  // Change as required
    private $db_name = $db_name;    // Change as required

}

但是,我收到以下错误消息:

Parse error: syntax error, unexpected 'global' (T_GLOBAL), expecting function (T_FUNCTION) in /home/*** on line **

为什么我不能在 Database 类中使用 config.php 文件中的变量?我在这里做错了什么?谢谢。

【问题讨论】:

  • 这个post几乎是同样的问题

标签: php


【解决方案1】:

您选择使用的方法的问题是该类不再可重用。任何时候实例化Database 类时,都会使用全局变量。

我更倾向于这样设置:

数据库.php

class Database {

  private $host;
  private $db_name;
  private $username;
  private $password;

  function __construct($host, $db_name, $username, $password) {
    $this->host = $host;
    $this->db_name = $db_name;
    $this->username = $username;
    $this->password = $password;
  }
}

然后在文件中使用Database 类:

include('../config.php');

$db = new Database($db_server, $db_name, $db_user, $db_password);

【讨论】:

    【解决方案2】:

    也许你可以这样尝试:

    function connDB()
    {
        $conn=mysql_connect("localhost", "root", "") or die(mysql_error());
        mysql_select_db("database") or die(mysql_error()); 
        return $conn;
    };
    

    将此函数放在您的配置文件或其他文件中,例如 globalFunctions.php(其中包含您需要的所有通用函数)。每次需要时调用此函数即可。

    【讨论】:

      【解决方案3】:

      在一个类中你只能有成员声明。全局变量不是类成员,因此您不能将它们放在类中。但是您可以将它们包含在方法中。

      class Database {
          private $db_host;
          //... the rest of them here
      
          //class constructor. Gets called every time you create an instance of this class.
          function __construct() {
              global $db_server;
              global $db_user;
              global $db_password;
              global $db_name;
      
              $this->db_host = $db_server;
              //.... you get the idea
          }
      }
      

      编辑 2017-07-11:

      不要这样做。不要使用全局变量。它们很容易在某处被覆盖,并且您最终会进行很多调试。加上要求global 关键字很脏。 @br3nt 提供了适当的部分解决方案。但它仍然使用全局变量,并在全局范围内初始化$db变量。

      如果您可以访问 Apache 中的站点配置,例如,对于该网站,您可以使用 mod_env 在环境变量中设置配置。示例:

      <VirtualHost *:80>
          .....
          SetEnv DB_USER=myDatabaseUser
          SetEnv DB_PASSWORD=12345
          ...
      </VietualHost>
      

      然后你可以在 PHP 中使用 getEnv('DB_USER') http://php.net/manual/en/function.getenv.php 阅读此内容

      另一种选择是让您的配置返回一个数组:
      config.php

      <?php
      return [
          'db_user'=>'myDbUser,
          'db_password'=>'12345'
      ];
      

      您应该有一个单一的入口点,以确保对该配置的只读访问。

      Config.class.php

      <?php
      class Config {
          private $_config;
          public function __construct() {
              $this->_config = include('path/to/config.php');
          }
      
          public function __get($key) {
              if(isset($this->_config[$key])) {
                  return $this->_config[$key];
              }
              return null;
          }
      }
      

      用法:

      $config = new Config();
      $dbUser = $config->db_user;
      $dbPassword = $config->db_password;
      

      编辑 2,同一天

      为什么全局变量不好?

      拥有全局变量很好,因为您可以在任何地方访问它们,对吗?让所有班级成员公开也是一种好习惯吗?不,假设您有一个在许多地方使用的全局变量。有人不小心写了这个:

      if($myGlobalVariable='something') { ... }
      

      而且他的代码只处理了一个没人关心的奇怪错误。但是您的代码会中断,因为您实际上依赖于$myGlobalVariable 的确切值。然后您查看配置,发现它是正确的值,然后挠头。

      这只是一种情况。对共享资源的不受阻碍的读写访问可能很危险。很容易覆盖,不会输出错误。它还污染了全球空间。

      如果您在配置文件中有全局函数,这也是一种代码异味。将配置文件视为甚至不应该包含代码的静态文本文件。它们是 PHP 文件的唯一原因是速度、易用性以及以这种方式破坏安全性的难度。

      【讨论】:

      • +1 将它们包含在方法中...我想知道为什么我的代码在我看到之前无法正常工作...谢谢!
      • @AbrahamMurcianoBenzadon 请查看我的编辑。使用全局变量是一种不好的做法。我提供了 2 种选择。存在更多选项,但如果您使用其中任何一个,它将更易于访问。
      • 感谢您的提示,但是我真的不明白为什么每个人都说全局变量是不好的做法……我正在使用一个变量 $root 来存储文档根目录 /var/.../public_html所以我可以使用绝对路径包含文件。这是因为我在生产服务器和托管服务器中有不同的根。也是因为我有时会包含包含其他文件的文件,但有时我会单独调用这些文件,因此使用相对 URL 不可能包含其中的文件。那么基本上为什么这是不好的做法?这似乎是一个非常合乎逻辑的方法……
      • 这个答案怎么样?这被认为是好的做法吗? stackoverflow.com/a/34758147/5525901
      • 再次编辑答案。
      【解决方案4】:

      这是一个使用 __construct() 将您的班级成员设置为全局值的选项

      include('../config.php');
      
      class Foo {
          private $db_host;
          private $db_user;
          private $db_pass;
          private $db_name;
      
          public function __construct() {
              global $db_server;
              global $db_user;
              global $db_password;
              global $db_name;
      
              $this->db_host = &$db_server;    // Change as required
              $this->db_user = &$db_user;      // Change as required
              $this->db_pass = &$db_password;  // Change as required
              $this->db_name = &$db_name;      // Change as required
          }
      }
      

      由于我们使用Assignment by Reference,因此内部类成员与全局变量是相同的变量(因此可以根据需要进行更改)。

      另外,如果您想避免写入global,您可以使用保留变量$GLOBALS,如documentation 中所述:

      一个关联数组,包含对当前在脚本全局范围内定义的所有变量的引用。变量名是数组的键。

      所以你的代码可以变成这样:

      $GLOBALS = array(
          'DB_HOST' => 'localhost',
          'DB_USER' => 'user',
          'DB_PASS' => 'secret',
          'DB_NAME' => 'my_db'
      );
      
      class Foo {
          private $db_host;
          private $db_user;
          private $db_pass;
          private $db_name;
      
          public function __construct() {
              $this->db_host = &$GLOBALS['DB_HOST'];  // Change as required
              $this->db_user = &$GLOBALS['DB_USER'];  // Change as required
              $this->db_pass = &$GLOBALS['DB_PASS'];  // Change as required
              $this->db_name = &$GLOBALS['DB_NAME'];  // Change as required
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-08
        • 2012-02-03
        • 1970-01-01
        • 2018-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-15
        相关资源
        最近更新 更多