在PHP中调用另一个类中的类
希望你能在这方面帮助我:我有两个类:数据库和用户。数据库使用PDO(构造函数内部)连接到数据库,并具有更改表、插入数据等功能。Users类将处理登录以及添加/删除用户。但是,Users类需要连接到数据库。我该怎么做 只需将对数据库类实例的引用添加到用户中:在PHP中调用另一个类中的类,php,oop,Php,Oop,希望你能在这方面帮助我:我有两个类:数据库和用户。数据库使用PDO(构造函数内部)连接到数据库,并具有更改表、插入数据等功能。Users类将处理登录以及添加/删除用户。但是,Users类需要连接到数据库。我该怎么做 只需将对数据库类实例的引用添加到用户中: class Users { var $database; function __construct() { $this->database = new Database(); } }; 或者,如果数据库是单例的
class Users {
var $database;
function __construct() {
$this->database = new Database();
}
};
或者,如果数据库是单例的,只需直接引用它。与您通常使用的方法相同,但它可能有助于将数据库变成类属性:
<?php
class Users
{
protected $_db;
public function __construct(Database $database = null)
{
if (!$database) {
$database = new Database;
}
$this->_db = $database;
}
public function addUser($username)
{
// Do stuff ...
$this->_db->insert($data);
}
}
您可以做以下几件事:
全球的
设置静态变量
使用单例
要避免的一件事是为每个模型或类创建新的数据库连接。一种方法是创建数据库类的一个共享实例,然后在需要时将其用作全局变量
从在项目中的任何位置创建实例开始,只需确保它位于全局空间中(而不是在另一个类或函数中)
然后,要访问共享数据库对象,只需使用$GLOBALS内置数组:
class User {
function __construct() {
$DB = &$GLOBALS['DB'];
// do something
$DB->callSomeMethod();
}
...
}
正如@Ryan所指出的,使用此策略可能会发生名称空间冲突。最好的中间解决方案是将数据库类转换为单例。然后,它将存储自己的实例(翻译:一个连接,不管怎样),可以通过Database::getInstance()方法访问该实例。这是我的用户类:
class Users {
private $data;
private $db;
public function __construct() {
$db = Database::getInstance('localhost', 'database', 'root', '123456');
}
public function __get($key) {
return $this->data[$key];
}
public function __set($key, $value) {
$this->data[$key] = $value;
}
public function test() {
foreach($this->db->query('table', '*', '', '', '', '', '0,5') as $value) {
$results .= $value['field1'] . "<br />";
}
return $results;
}
}
类用户{
私人数据;
私人$db;
公共函数构造(){
$db=Database::getInstance('localhost','Database','root','123456');
}
公共功能获取($key){
返回$this->data[$key];
}
公共函数集($key,$value){
$this->data[$key]=$value;
}
公共功能测试(){
foreach($value形式的this->db->query('table','*','','','','','0,5')){
$results.=$value['field1']。“
”;
}
返回$results;
}
}
一个在整个程序中只有一个实例的类,它通常存储在PHP中的全局变量中。你不能在PHP属性声明中实例化对象(或调用方法)。Ryan,你偷了我的答案。我想我需要提高打字速度。:-)@bogeymin-我通常也有同样的问题:-)那不是不对吗?我是说。。。每当我需要执行查询或选择时,我都会连接到数据库。@Vinny。是的,如果要创建多个用户
类,这是一种糟糕的方法。\u db
指针应该是静态的。实际上,它需要在整个应用程序中共享。您不希望多次连接到数据库。您每次实例化数据库类时都在连接。在本例中,您还可以在实例化用户时进行连接。或者,您可以重用连接,因为构造函数将接受数据库实例:$users=newusers($Database);全球化很少是个好主意。它们引入了名称空间冲突的可能性,并使得为不同目的使用离散资源变得困难。如果不使用globals或重构现有代码,则必须为POST和用户分别创建一个DB连接。随着类数量的增加,Globals开始胜出:)这是谨慎使用资源和非最佳使用资源之间的权衡。我将我的数据库类转换为单例,不幸的是,当我尝试从数据库类访问方法时,在Users类内,我得到:对非对象的成员函数query()的调用,依赖项注入,在实例化时或通过setDatabase()方法将数据库资源传递给需要它的对象。所有这些都有其利弊。
$db = new Database();
class Model
{
static public $db;
}
Model::$db = $db;
class Users extends Model
{
public function foo()
{
self::$db->query();
}
}
class Database
{
private static $instance;
private function __construct()
{
}
public static function instance()
{
return self::$instance ? self::$instance : self::$instance = new self();
}
}
class Users
{
public function foo()
{
Database::instance()->query();
// or $db = Database::instance(); $db->query();
}
}
$DB = new Database();
class User {
function __construct() {
$DB = &$GLOBALS['DB'];
// do something
$DB->callSomeMethod();
}
...
}
class Users {
private $data;
private $db;
public function __construct() {
$db = Database::getInstance('localhost', 'database', 'root', '123456');
}
public function __get($key) {
return $this->data[$key];
}
public function __set($key, $value) {
$this->data[$key] = $value;
}
public function test() {
foreach($this->db->query('table', '*', '', '', '', '', '0,5') as $value) {
$results .= $value['field1'] . "<br />";
}
return $results;
}
}