【问题标题】:Using PHP constant in a class file在类文件中使用 PHP 常量
【发布时间】:2012-09-22 13:12:38
【问题描述】:

我正在尝试构建一个连接到单个数据库的简单脚本。我想将类文件放到我的许多网站上,并希望能够在我的数据库中“注册”该网站。

为了避免对类的每个实例都运行 SQL 查询,我想使用 PHP 常量“注册”域。

在我的方法中,我定义了常量并检查了它 - 它可以工作,但是当我在构造函数中检查常量时,不再定义常量。

这是我的类文件,我确定这只是我对常量不了解的东西。

 <?php

/** 
 * @author bailz777
 * 
 * 
 */
class db_interface {

    public $ServerName = 'localhost:3306'; //hostname:port
    public $UserName = '******'; //mysql user
    public $Password = '******'; //mysql password
    public $DataBase = '******'; //database name
    public $Domain = 'test.com'; //Full domain name (no host)
    public $con = '';

    function __construct() {

        //on construction, we must ensure that the domain is registered in our system
        //first check if it was defined locally to avoid extra DataBase Work
        var_dump(defined('DOMAIN_REGISTERED'));
        if(!defined('DOMAIN_REGISTERED')) {
            $this->db_connect();
            $result = $this->validate_domain();
            if($result) {
                echo "<p>Domain Validated!!</p>";
            }
            $this->db_disconnect();     
        }
        else {
            echo "<p>Domain Validated!!</p>";
        }
    }

    /**
     * 
     */
    function __destruct() {

    }

    /**
     * 
     * @param unknown_type $domain
     * @return boolean
     */
    private function validate_domain() {
        $constants = get_defined_constants();
//      return $this->con;
//      print_r($constants);
var_dump(defined('DOMAIN_REGISTERED'));
        if(defined('DOMAIN_REGISTERED')) {//Check DOMAIN_REGISTERED to avoid unnecessary db work
            return TRUE;
        }
        elseif (!defined('DOMAIN_REGISTERED')) {//Check the domain is in the db
            echo '<p>Domain was not locally registered, checking DataBase</p>';
            $query = "SELECT `name` FROM `$this->DataBase`.`registered_domains` WHERE `name` = '$this->Domain'";
            $result = mysql_query($query,$this->con);
            //var_dump($result);
            if(!$result) {
                die('No result found : ' . mysql_error());
            }
            elseif (mysql_num_rows($result)==0) { //if no rows returned, then domain is not in DataBase 
                $domain_exists = FALSE;
            }
            elseif (mysql_num_rows($result)>0) { //if rows returned, then domain is in DataBase
                $domain_exists = TRUE;
                //If a domain does not exist, a mysql will be passed, use @ to suppress the error
                //The domain will be written to the db and on the next run of this function, the 
                //constant will be defined
            }
            if($domain_exists) {//If it exists Then assign CONSTANT DOMAIN_REGISTERED to TRUE
                echo '<p>Domain Found in DataBase</p>';
                echo '<p>Registering domain locally</p>';
                define("DOMAIN_REGISTERED", TRUE);
                if(DOMAIN_REGISTERED) {
                    echo '<p>Successfully registered domain locally</p>';
                }
                //var_dump(defined('DOMAIN_REGISTERED'));
                //echo DOMAIN_REGISTERED;
                return TRUE;
            }
            elseif(!$domain_exists) {//If it does not exist then add it to the registered_domains table, and assign CONSTANT __DOMAIN_TRUE__ to TRUE
                echo '<p>Domain not found in DataBase</p>';
                echo '<p>Now Registering Domain</p>';
                $query = "INSERT INTO `$this->DataBase`.`registered_domains` (`name`) VALUES ('$this->Domain')";
                $result = mysql_query($query);
                if(!$result) {
                    die('Domain not added : ' . mysql_error());
                }
                else{
                    define("DOMAIN_REGISTERED", TRUE);
                    return TRUE;
                }
            }
        }       
    }

    //Connect to mysql and define the active database
    private function db_connect() {
        $this->con = $con = mysql_connect($this->ServerName,$this->UserName,$this->Password);
        if (!$con) {
            die('Could not connect: ' . mysql_error());
        }
        else {
            echo 'Successfully connected to MySQL<br />';
            //define active database
            $this->db = mysql_select_db($this->DataBase);
            if(!$this->db) {
                die('Could not connect to Database : ' . mysql_error());
            }
            else {
                echo 'Successfully connected to DataBase<br />';
            }
        }
    }

    //disconnect from mysql
    private function db_disconnect() {
        $close =  mysql_close($this->con);
        if($close) {
            echo 'Successfully disconnected from MySQL<br />';
        }
    }

    public function add_record($fname,$lname,$email) {
        $ip = $_SERVER['REMOTE_ADDR'];
        $authorized_date = time();

    }
}

?>

【问题讨论】:

  • 这绝对不是常量和define 的用途。

标签: php oop constants


【解决方案1】:

您可以尝试使用静态类变量来保存该值。一方面,这会将你的常量值限制在你的类中,这比将值暴露给整个应用程序更好。另一方面,常量的意图是它们永远不会改变,看起来你正试图将它用作标志。

【讨论】:

  • 不知道为什么投反对票。问题确实以完全错误的方式使用常量。这不是常量的用途。你想要一个成员变量或一个类变量。
  • 静态只是在类中组织过程代码的一种奇特方式。这与 OO 编程无关!
  • 这个想法是我希望多个站点能够重用具有相同变量的类文件以进行数据库访问。所以我不希望每个站点都能够重新定义要使用的服务器和数据库。我想尝试尽可能少地进行数据库查询以最小化我的内存使用,这就是为什么我想定义一个可引用变量来确认域已注册。这就是为什么我想使用一个常量,因为一旦域被注册,这个常量就永远不会改变。我不明白的是为什么在定义了常量 id 之后,再次调用该类时它变得“未定义”?
  • 是的,虽然所有其他答案都有帮助,但我认为你的答案与我的问题最相关。
  • 我不完全确定,但您是在连续运行两次测试此代码吗?如果是,那么您肯定会观察到这种行为,因为常量的范围仅适用于单次执行。如果你想在执行过程中保持这个值,你需要把它放在像 $_SESSION var 这样的地方。
【解决方案2】:

构造函数是创建对象后立即调用的第一个函数。

如果你在类的其他函数中定义一个常量,你不能期望它在构造函数中定义。原因如下:

  • 创建对象时 - 调用构造函数
    • 在构造函数中,您正在检查是否定义了常量:当然不是,您在哪里定义的?
  • 您正在调用类中的某个函数并定义一个常量
  • 下次创建对象时(即页面刷新) - 不再定义常量

这是完全正常的行为。

【讨论】:

    【解决方案3】:

    我认为您可能没有按照预期的方式使用常量。首先,常量值在代码执行期间不能改变(因此是常量)。

    我们使用它们来分配我们可以在整个代码中使用的硬编码值(仅是非常简单的值)。关键是你最终可以知道它们永远不会不同。

    除此之外,您不必知道常量本身的实际值,因为您只需引用变量名,就可以在不破坏代码的情况下随时更改这些值。

    考虑以下示例:

    <?php
    
    class pizza
    {
      const SIZE_SMALL  = 1;
      const SIZE_MEDIUM = 2;
      const SIZE_LARGE  = 3;
    
      public function getCookingTime($size)
      {
        if ($size == self::SIZE_SMALL) {
          $time = 10;
        } else if ($size == self::SIZE_MEDIUM || $size == self::SIZE_LARGE) {
          $time = 15;
        }
        return $size;
      }
    }
    
    $pizza = new pizza();
    $time  = $pizza->getCookingTime(3);
    
    // or more usefull:
    
    $time = $pizza->getCookingTime(pizza::SIZE_SMALL);
    
    ?>
    

    【讨论】:

      【解决方案4】:

      我在您的代码中找不到您调用 define('DOMAIN_REGISTERED', '...'); 的任何地方。
      无论如何,正如 monitorjbl 所提到的,请考虑为您的数据库连接使用static 保留字,这样您就可以避免重新定义连接、重新注册您的域等。

      【讨论】:

        【解决方案5】:

        你想掌握OO编程是一件好事。一个(众多)优点是您可以构建可重用和可测试的代码。

        如果您想构建一个连接到数据库的类,并且可以在许多站点中重复使用,那么您要避免的一件事是依赖关系。对常量或其他类的依赖使重用代码变得更加困难。或测试调试您的代码。

        这么说意味着您要避免使用预定义的常量和预初始化的公共变量。

        你的类的结构应该是这样的:

        class mydb
        {
           private $host;
           private $database;
           ..
        
           public function __construct($host, $database ..)
           {
             $this->host = $host;
             $this->database = $database;
           }
        }
        

        你可以像这样使用你的类:

        $mydb = new mydb('localhost', 'mydatabase', ..);
        

        如果您希望能够将站点注册到您的数据库,请编写一个 Register 方法:

        class mydb
        {
           private $host;
           private $database;
           ..
        
           public function __construct($host, $database ..)
           {
             $this->host = $host;
             $this->database = $database;
           }
        
           public function Register( $domainname )
           {
              //connect to the database and do register stuff
           }
        }
        

        并像这样使用它:

         $mydb = new mydb('localhost', 'mydatabase', ..);
         $mydb->Register('MyDomain');
        

        【讨论】:

          猜你喜欢
          • 2012-04-14
          • 2020-02-01
          • 2013-01-20
          • 2016-04-17
          • 2011-06-26
          • 2012-03-30
          • 2011-08-19
          • 1970-01-01
          • 2021-02-28
          相关资源
          最近更新 更多