Вызов класса внутри другого в PHP

Надеюсь, вы можете помочь мне с этим: у меня есть два класса: база данных и пользователи. База данных подключается к базе данных с помощью PDO (внутри конструктора) и имеет функции для изменения таблиц, вставки данных и т. Д. Класс Users будет обрабатывать вход в систему, а также добавлять / удалять пользователей. Однако класс Users должен подключаться к базе данных. Как я могу это сделать?

Ответы на вопрос(5)

Глобалы
$db = new Database();

class Users
{
  public function foo()
  {
    global $db;
    $db->query();
  }
}
Установка статической переменной
$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();
   }
}

Единственное, чего вы хотите избежать - это создать новое соединение с базой данных для каждой модели или класса.

 Ryan Chouinard02 окт. 2010 г., 19:43
Или внедрение зависимостей, которое передает ресурс базы данных нуждающимся объектам либо при создании экземпляра, либо через метод setDatabase (). Все они имеют свои плюсы и минусы.

class Users  {
  var $database;
  function __construct()  {
    $this->database = new Database();
  }
};

В качестве альтернативы, если база данных является одноэлементной, просто обратитесь к ней напрямую.

 Karel Petranek02 окт. 2010 г., 19:34
@konforce: Иногда мне интересно, что я делаю, спасибо.
 bogeymin02 окт. 2010 г., 19:26
Вы не можете создать экземпляр объекта (или вызвать метод) в объявлении свойства PHP.
 Vinny02 окт. 2010 г., 19:22
Что такое синглтон?
 Karel Petranek02 окт. 2010 г., 19:26
Класс, который имеет только один экземпляр во всей программе, обычно хранится в глобальной переменной в PHP.
 Karel Petranek02 окт. 2010 г., 19:29
@ Bogeymin: Спасибо, исправлено.
 Matthew02 окт. 2010 г., 19:33
Забыл$this указатель.

Это мой класс пользователей:

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 = new Database();

Затем, чтобы получить доступ к общему объекту базы данных, просто используйте встроенный массив $ GLOBALS:

class User {
  function __construct() {
    $DB = &$GLOBALS['DB'];
    // do something
    $DB->callSomeMethod();
  }
  ...
}

Как указывает @Ryan, при использовании этой стратегии возможны коллизии пространства имен. Лучшим средним путем было бы преобразовать класс Database в синглтон. Затем он будет хранить свой собственный экземпляр (перевод: ОДНО соединение независимо от того, что), к которому можно получить доступ через метод Database :: getInstance ().

 Jagtesh Chadha02 окт. 2010 г., 19:50
Скажем, есть класс Posts, который тоже должен использовать соединение с БД. Без глобальных или рефакторинга существующего кода вам нужно было бы создать одно соединение с БД для каждого для сообщений и пользователей. По мере того, как количество классов увеличивается, Globals начинает побеждать :) Это компромисс между осторожностью и неоптимальным использованием ресурсов.
 Vinny02 окт. 2010 г., 20:00
Я преобразовал свой класс Database в singleton, к сожалению, когда я пытаюсь получить доступ к методу из класса Database, внутри класса Users, я получаю: Вызов функции-члена query () для необъекта
 Ryan Chouinard02 окт. 2010 г., 19:39
Глобалы редко бывают хорошей идеей. Они создают потенциальную возможность конфликтов пространства имен и затрудняют использование дискретных ресурсов для различных целей.

как обычно, но это может помочь сделать базу данных свойством класса:

<?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);
    }

}

Тогда вы можете использовать класс User как:

<?php
$users = new Users;
$users->addUser('joebob');
 Vinny02 окт. 2010 г., 19:30
Разве это не было бы неправильно? Я имею в виду ... я подключаюсь к базе данных каждый раз, когда мне нужно выполнить запрос или выбрать.
 Vinny02 окт. 2010 г., 19:37
Использование синглтона это исправит?
 Ryan Chouinard02 окт. 2010 г., 19:29
@ Bogeymin - у меня обычно такая же проблема :-)
 bogeymin02 окт. 2010 г., 19:27
Райан, ты украл мой ответ. Думаю, мне нужно работать над скоростью набора текста. :-)
 Ryan Chouinard02 окт. 2010 г., 19:41
@Vinny - у синглетонов есть свои проблемы, но это еще один (сомнительный) правильный подход. Подход, который я представил, однако, очень гибок для большинства потребностей.
 Matthew02 окт. 2010 г., 19:34
@Vinny. Да, это плохой подход, если вы создаете несколькоUsers классы._db указатель должен быть статическим. На самом деле это должно быть общим для всего приложения. Вы не хотите подключаться к базе данных несколько раз.
 Ryan Chouinard02 окт. 2010 г., 19:35
Вы подключаетесь каждый раз, когда создаете экземпляр класса Database. В этом примере вы также подключаетесь при создании экземпляра Users. Или вы можете повторно использовать соединение, так как конструктор примет экземпляр базы данных: $ users = new Users ($ database);
 Vinny02 окт. 2010 г., 19:37
Я имею в виду, превратить мой класс базы данных в единый.

Ваш ответ на вопрос