2013-04-11 4 views
1

Соединение с моей базой данных находится в родительском классе Model.Использование static для возврата родительской переменной

Я разрабатываю класс утилиты, в котором у меня никогда не будет экземпляра, поэтому я использую статическое ключевое слово. Мне нужен только доступ к функциям вокруг приложения.

class Model { 

    function __construct() { 
     $this->db = new Database(DB_TYPE, DB_HOST, DB_NAME, DB_USER, DB_PASS); 
    } 

} 

Это мой родительский класс.

class Fav extends Model{ 

    public static function getFavourite($data){ 
     return $this->db->select('SELECT favouriteid FROM favourite WHERE type = :type AND linkid = :linkid 
           AND userid = :userid', array('type' => $data['type'], 'linkid' => $data['linkid'], 
           'userid' => Session::get('userid'))); 
    } 
} 

У меня проблема с $ этим ключевым словом, поскольку у меня нет экземпляра класса?

Я знаю о родительских и ключевых словах.

Может кто-то разрешить это и показать мне, как я буду связывать правильное ключевое слово здесь!

Заранее благодарен!

+1

вы можете передать '$ db' в качестве параметра статическому методу. Также попытайтесь выяснить дискуссию о _evilness_ статических методов на SO – Ejaz

+0

Кажется, что подавляющее большинство людей не увлекаются статическими методами! – sark9012

ответ

0

Помимо того, что это не выглядит как реальный твердый код, вы можете расширить базовый класс с чем-то вроде этого:

protected static function getDatabase() 
{ 
    return new Database(DB_TYPE, DB_HOST, DB_NAME, DB_USER, DB_PASS); 
} 

Теперь вы можете использовать свой класс базы данных по телефону self::getDatabase()->select("x");

В сторону: убедитесь, что вы хотите сделать это со статическими функциями. Я бы так не сделал.

+0

Я хочу наилучшего возможного решения, поэтому, если вы считаете, что это может быть достигнуто лучше, не могли бы вы дать предложение? – sark9012

+1

Это не выходит за рамки этого вопроса.Ваша логика тесно связана и имеет иерархию, на которую я бы не пошел, в первую очередь. Читайте об объектно-ориентированных концепциях дизайна и продолжайте пытаться получить более чистые способы программирования вещей. ;) – Sherlock

+0

Это круто, я ценю ответ. В любом случае, все это кривая обучения! Для каждой развитой системы иерархия улучшается. Я буду иметь в виду это для следующего приложения, которое я разрабатываю. – sark9012

2

Вы делаете несколько недостатков дизайна здесь.

  1. Вы даете свою модель знаний о базе данных. Сделайте что-то управление своими моделями, а не «push/flush» в вашу базу данных.
  2. Fav :: getFavourite() может показаться приятным в вашем коде, но это не имеет смысла. Вы не должны запрашивать у себя модель.

Предлагаю вам взглянуть на существующие ORM, такие как Doctrine или Propel, и посмотреть, как они решили проблемы дизайна, которые у вас есть.

редактировать: Решение Я хотел бы использовать для Symfony2:

// I will have this registered under mybundle.favourites as service 
class FavouritesService 
{ 
    private $em; 

    public function __construct(EntityManager $em) 
    { 
    $this->em = $em; 
    } 

    public function getFavourite($what, SomeUserObject $for) 
    { 
    // do some stuff with the manager here and retrieve my favourite.. based on $data 
    } 
} 

// some random action in my controller 
public function someAction() 
{ 
    $favorite_car = $this->get('mybundle.favorites')->getFavourite('car', $this->get('session.user')); 
    // some code 
} 
+0

Базовый класс модели предназначен для предоставления базы данных всем моделям, которые я использую для контроллеров. Это прекрасно работает, поскольку эти модели расширяют базовую модель, и она работает хорошо. В этом случае то, что я хочу сделать, это создать набор функций, которые будут контролировать способность одобрять элемент на сайте. Поэтому я просто нажимаю кнопку, и она идет и что-то делает. Мне не нужны никакие виды/контроллеры/модели для этого, мне просто нужен класс утилиты, который обеспечит функциональность. Это похоже на проблему, которая может быть решена с использованием статических методов? – sark9012

+0

Я не поклонник статики. A) он блокирует unittesting, B) это не что иное, как «глобальная» функция, завернутая в класс. Это полностью против OO. В любом случае, база данных не должна знать о моделях и моделях не о базе данных. Между тем есть слой, который должен знать об обоих и использовать их правильно. Таким образом, вы можете отключить свою базу данных и заменить ее чем-то другим или отключить свои модели и подключить какую-то чужую систему. –

+0

Я обновил свой ответ, чтобы показать вам, что я имею в виду. Таким образом, вы можете, например, высмеять EntityManager, чтобы на самом деле не сохранить материал в вашей базе данных, упрощает тестирование и позволяет вам просто получить FavouritesService в вашем коде, где вам это нужно, используя контейнер для инъекций Symfony2's Dependency Injection Container. –

-1

В OOPS концепции, статические методы могут получить доступ только статические переменные и методы, но PHP не следует все OOPS концепции. В принципе, вы должны следовать Singleton шаблон проектирования, чтобы получить соединение с базой данных, чтобы убедиться, что в то время только один объект инициализируется

class Model { 
    public static $db; 
    public static function getInstance() { 
     if (!isset (self::$db)) 
      self::$db = new Database(DB_TYPE, DB_HOST, DB_NAME, DB_USER, DB_PASS); 

     return self::$db; 
    } 
} 

И вы должны использовать его, как показано ниже

class Fav 
{ 
    public static function getFavourite($data) 
    { 
     return Model::getInstance()->select('SELECT favouriteid FROM favourite WHERE type = :type AND linkid = :linkid 
           AND userid = :userid', array('type' => $data['type'], 'linkid' => $data['linkid'], 
           'userid' => Session::get('userid'))); 
    } 
} 

Нет необходимости расширения модели класс.

+0

Ваше решение также позволяет модели управлять собой, плохим решением. –

Смежные вопросы