【问题标题】:How to create an instance of a class in another class如何在另一个类中创建一个类的实例
【发布时间】:2010-08-19 15:45:09
【问题描述】:

我可能在这里遗漏了一些东西,我不确定。 Google 搜索也无济于事。

我想要做的是调用 databaseServer 类并在我的 userControl 类中使用它的方法。这是我的 lib_class.php 文件:

<?php

include('definitions.php');

class databaseServer {

    var $con;
    var $db;
    var $close;
    var $qry;
    var $sql;

    function connect($host,$user,$pw,$db) {
        $this->con = mysql_connect($host,$user,$pw);
        if (!$this->con) {
            die('Could not connect: ' . mysql_error());
            }
        else {
            echo "Database Connected";
            }
        $this->selectDb($db);
        }

    function selectDb($database) {
        $this->db = mysql_select_db($database,$this->con);
        if (!$this->db) {
            echo "Could not Select database";
            }
        else {
            echo "Database Selected";
            }
        }

    function disconnect() {
        $this->close = mysql_close($this->con);
        if ($this->close) {
            echo "Disconnected";
            }
        }

    function query($test) {
        if (!mysql_query($test)) {
            die("Error: " . mysql_error());
            }
        }

} // databaseServer

class cookie {

    var $expireTime;

    function set($name,$value,$expiry) {
        $this->expireTime = time()+60*60*24*$expiry;
        setcookie($name,$value,$expireTime);
        }

    function delete($name) {
        setcookie($name,"",time()-3600);
        }

    function check($name) {
        if (isset($_COOKIE["$name"]))
            echo "Cookie Set";
        else
            echo "Cookie failed";
        }

} //cookie

class userControl {

    public function __construct(databaseServer $server) {
        $this->server = new databaseServer();
    }

    function createUser($uname,$pword) {

        $this->server->connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
        $result = $this->server->query("SELECT * FROM user_list WHERE uname='" . $this->server->real_escape_string($uname) . "'");
        if ($this->result->num_rows() === 0) {

            if ($this->server->query("INSERT INTO user_list (uname, pword) 
            VALUES ('" . $this->server->real_escape_string($uname) . "','" . $this->server->real_escape_string($pword) . "')") {
                echo "User Added Successfully!";
            }
            else {
                echo "Error Adding User!";
            }
        }

        else {
            echo "User Already Exists!";
        }

    } // createUser

} // userControl

?>

但是,这不起作用,我不明白为什么。当我从文件中省略 userControl 类时,我的 databaseServer 和 cookie 类工作正常,所以我知道错误必须在该类的某个地方。 OOP 是我正在努力学习的东西,但我一直在磕磕绊绊。

databaseServer 类中的回声仅供我测试。我在 index.php 文件中实现类如下:

<?php

include('definitions.php');
include('class_lib.php');

$bmazed = new databaseServer();

$bmazed->connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);

$sql = "INSERT INTO blah
VALUES ('testing 92')";

$bmazed->query($sql);

$bmazed->disconnect();

// $control = new userControl();

// $uname = "Test1";
// $pword = "test1";

// $control->createUser($uname,$pword);

echo "<br />";
echo "<br />";

?>

出于测试目的已将行注释掉,因此我不必继续重写代码。

我真的不知道问题出在哪里,我检查了语法,一切似乎都很好。

【问题讨论】:

  • 我已经尝试了所有建议的答案,但似乎没有一个能让脚本正常工作。我已经编辑了原始问题以显示更多我的代码。如前所述,代码纯粹是为了测试目的,所以里面有一些奇怪的东西,比如看似随机的回声。
  • @Saladin 运行php -l lib_class.php,您会看到它在您执行INSERTif 块中抱怨意外的{else。那是因为您在该 if 块上缺少关闭 )。开发代码时,请确保您启用了 error_reportingdisplay_errors

标签: php oop class


【解决方案1】:

在声明类时,不能分配依赖于运行时信息的类或实例属性。请参阅chapter on Class Properties in the PHP Manual

将类改为阅读:

class userControl
{
    protected $_server;

    public function __construct ()
    {
        $this->_server = new databaseServer();
    }
}

另外,要访问类/实例成员,您必须使用 $this 关键字,例如

$this->_server->connect();

顺便说一句,composition 很好,aggregation 更好。它可以帮助您的代码保持可维护性和松耦合,这意味着替换组件会更容易,例如在编写UnitTests 时。所以考虑将构造函数改成使用Dependency Injection

【讨论】:

【解决方案2】:

在构造函数中初始化$server

class userControl {

 private $server;

 function __construct() {
  $this->server = new databaseServer();
 }

 function createUser($uname,$pword) {
  $this->server->connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
  $result = $this->server->query("SELECT * FROM user_list WHERE uname='" . $this->server->real_escape_string($uname) . "'");
  if ($this->result->num_rows() === 0) {

   if ($this->server->query("INSERT INTO user_list (uname, pword) VALUES ( '" . $this->server->real_escape_string($uname) . "','" . $this->server->real_escape_string($pword) . "')") {
    echo "User added Succesfully";
    }
   else {
    echo "Error Adding User";
    }

  else {
   echo "User already exists";
   }
 }

}

【讨论】:

  • 除了在 createUser 方法中你应该引用 $this->server 而不是 $server
  • $server 需要一个关键字。 var 或可见性修饰符。
【解决方案3】:

一方面,$server 无法从 createUser() 中访问,因为它位于不同的范围内。 PHP 作用域的工作方式与人们对 C 风格语言的预期有些不同。

尝试将 $server 传递给 createUser(),或者在 createUser() 中初始化服务器,在这种情况下,您可能应该有一个 getServer() 函数,这样您就不会不必要地对其进行初始化。

第三个选项是迄今为止最糟糕的,它在函数内部的顶部执行“global $server”。但这是非常糟糕的做法。您已收到警告。

最后但同样重要的是,您可能应该在 SQL 查询中查找 COUNT(*) 而不是 *,否则您将选择所有用户。 :)

如果您想了解有关 PHP 范围的更多信息,请参阅此处(强烈推荐): http://php.net/manual/en/language.variables.scope.php

希望对你有帮助!

【讨论】:

    【解决方案4】:

    语法的东西肯定是个问题。但我的代码更根本的错误是 databaseServer->query 方法没有返回值。让它返回一个值解决了这个问题。

    我认为,有时,只见树木不见森林是不可能的。 :)

    【讨论】:

      猜你喜欢
      • 2020-10-16
      • 2018-11-02
      • 1970-01-01
      • 2016-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多