PHP-在类中使用全局变量(致命错误)

PHP-在类中使用全局变量(致命错误),php,function,pdo,Php,Function,Pdo,我有一个class.php文件,其中包括另一个文件中的类: class.php: include($_SERVER['DOCUMENT_ROOT'] . "/includes/user.php"); $user = new User; include($_SERVER['DOCUMENT_ROOT'] . "/includes/user.php"); $user = new User; Class feed { function randomFunction

我有一个
class.php
文件,其中包括另一个文件中的类:

class.php:

 include($_SERVER['DOCUMENT_ROOT'] . "/includes/user.php");
 $user = new User;     
 include($_SERVER['DOCUMENT_ROOT'] . "/includes/user.php");
 $user = new User;  


 Class feed {

   function randomFunction($username) {
   global $user;
   $username = "test";
   $viewuser = $user->getSocialUser($username);

   echo $viewuser['avatar'];
  }
}
因此,在
/includes/user.php
中定义了
$user

/includes/user.php
中有一个名为
getSocialUser($username)的函数

$dbh
保存数据库值。我已经测试过了,它确实与数据库有连接)

但是,我希望能够在
class.php
文件中使用上述函数:

这就是我现在正在做的:

class.php:

 include($_SERVER['DOCUMENT_ROOT'] . "/includes/user.php");
 $user = new User;     
 include($_SERVER['DOCUMENT_ROOT'] . "/includes/user.php");
 $user = new User;  


 Class feed {

   function randomFunction($username) {
   global $user;
   $username = "test";
   $viewuser = $user->getSocialUser($username);

   echo $viewuser['avatar'];
  }
}
上面的代码不起作用。我得到这个错误:

Fatal error: Call to a member function getSocialUser() on a non-object in/path/class.php on line 6

我做错了什么?

首先,使用全局是不好的做法。相反,将数据库连接添加为参数,因此将函数更改为

function getSocialUser ($dbh, $username)
{
    $stmt = $dbh->prepare("SELECT * FROM users WHERE username=:username");
    $stmt->bindParam(':username', $username);
    $stmt->execute();

    $udata = $stmt->fetch();

    if(count($udata) == 0)
        return false;

    return $udata;
}
接下来,在类的构造中启动数据库连接和用户类

 Class feed {
     private $dbh;
     private $user;

     function __construct() {
         $this->dbh = new PDO('your data here');
         $this->user = new User();
     }

     function randomFunction($username) {
         $username = "test";
         $viewuser = $this->user->getSocialUser($this->dbh,$username);
         echo $viewuser['avatar'];
     }
 }

我不建议使用GLOBALS,因为它们会将您的类绑定到特定的上下文,降低软件的可重用性和内聚性,以及其他使GLOBALS做出糟糕设计决策的问题。在提要构造函数中实例化用户对象如果也不推荐,因为您必须更改用户类构造函数,那么您必须返回到提要类并对其进行更改。尽量只给你的类一个改变的理由,这将提高凝聚力

使用依赖项注入来改进您的设计:

对于用户类,可以将数据库处理程序作为参数传递给类构造函数,这称为构造函数注入:

/*file User.php*/

class User 
{
    private $dbh;

    public function __construct(PDO $dbh)
    {
        $this->dbh = $dbh;
    }

    public function getSocialUser($username)
    {
        $stmt = $this->dbh->prepare("SELECT * FROM users WHERE username=:username");
        $stmt->bindParam(':username', $username, PDO::PARAM_STR);
        $stmt->execute();

        $udata = $stmt->fetch();

        if (empty($udata) == 0) {
            return false;
        }

        return $udata;
    }
}
对于提要类,可以使用委托和构造函数注入或setter注入:

/* File Feed.php*/

require_once 'User.php';

Class Feed
{
    private $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    function randomFunction($username) {

        $viewuser = $this->user->getSocialUser($username);

        return $viewuser['avatar'];
    }
}
现在您可以使用:

/* file foobar.php */

require_once 'User.php';
require_once 'Feed.php';

// Create your PDO - $dbh

$user = new User($dbh);
$feed = new Feed($user);

$testName = 'test';

echo $feed->randomFunction($testName);

我试图使代码保持简单,因此跳过了错误检查。我希望这能帮助你解决你的问题。以下是有关依赖项注入的一些信息:

如果您的代码与您描述的完全一样,那么就不会有错误。@TomHoang:他已经有了错误。@Boann,是的。@oliverbj那么真正的代码与问题中的代码不同。您确定显示的代码正确吗<第6行的/path/class.php中的code>非对象
->getSocialUser
不在第6行。在_构造()中会有什么?什么都没有。您不需要为它提供任何参数。构造是一个神奇的函数,它将在调用该类时运行,它将启动您需要的另外两个类,PDO和user类,以便您可以在进一步的方法(函数)中使用它们并将它们作为属性引用。
/* File Feed.php*/

require_once 'User.php';

Class Feed
{
    private $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    function randomFunction($username) {

        $viewuser = $this->user->getSocialUser($username);

        return $viewuser['avatar'];
    }
}