Этот сайт не наркоманов. Это сайт программистов.

Добро пожаловать на Пыху!

Логин:
Пароль:
 

Нет прописки? Зарегистрируйся!

Новости

Пыха переехала на новый сервер, ура!

Краснодарское время: 25 Май, 2012, 08:29:18

Страниц: [1] 2
Печать
Автор Тема: Синглтон и жуткие извращения  (Прочитано 317 раз)
0 Пользователей и 1 Гость смотрят эту тему.
StGeass    ↓ 
24 Декабрь, 2011, 07:49:14
НЕ ХУЕТА! ХУЕТА!


Карма: 0
Сообщений: 8
Сила слова: 0

В общем сабж страшный боян и состоит в следующем, есть банальный класс работы с БД:
 
PHP
$db =& new db();

Все прекрасно и замечательно, но меня корежит то что каждому классу, которому необходима работа с БД, приходится передавать ссылку на экземпляр класса скажем так:
 
PHP

private function __construct(&db) {
  $this->db =& $db;
}
 

В общем удобства это не доставляло, зависимость кода только повышалась и вообще полная печаль.
 
В идеале хотелось что бы из любого места без всяких ссылок можно было сделать вызов метода класса вида
PHP
db::getRow();
. Это легко решалось бы использованием статических методов, однако при этом бы исчезло множество удобных вещей, в частности логирование и дебаг запросов.
 
Дальше на ум конечно же приходит пресловутый паттерн Singlton который отчасти решал задачу позволяя делать запросы вида:
PHP

dh::getInstance()->getRow();
//OR
dh::instance->getRow();
 

Но тут меня понесло и я желая получить то что хотел родил это:
PHP

class db {
  public $test_row = 'Work!';
  public static $instance;
 
  function __construct() { }
 
  public static function __callStatic($name, $arguments) {
    if(!self::$instance) self::getInstance();
   
    $methodname = preg_replace('/\_?/', '', $name);
   
    self::$instance->$methodname($arguments);
  }
 
  public static function getInstance() {
    self::$instance = new db();
   
    return self::$instance;
  }
 
  public function getRow () {
    return $this->test_row;
  }
}
 
echo db::_getRow(); //Выведет 'Work!'
 

В общем получилось то что хотел, к методам можно обращаться либо через экземпляр класса, либо как к статическим (через '_'), при этом не теряя указателя $this. Но все это изрядно попахивает и отнюдь не цветочками.
 
Собственно вопрос:
Есть у кого то адекватная реализация, балансирующая между удобством и здравым смыслом?
Записан
Ivan    ↓ 
24 Декабрь, 2011, 08:12:43 , спустя 23 минуты 29 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 27
Сообщений: 1366
Сила слова: 1.98

$db =& new db();
Сам то понял что написал?
Записан

StGeass    ↓ 
24 Декабрь, 2011, 08:15:18 , спустя 2 минуты 35 секунд
НЕ ХУЕТА! ХУЕТА!


Карма: 0
Сообщений: 8
Сила слова: 0


$db =& new db();
Сам то понял что написал?
 
А что там не так?
 
P.S. Код естественно далек от реального и намеренно минимизирован для более простого понимания.
Записан
Абырвалг    ↓ 
24 Декабрь, 2011, 08:20:47 , спустя 5 минут 29 секунд
НЕ ХУЕТА! ХУЕТА!

PHP Infected, симфоеб, маконенавистник
Группа: Джедаи

Карма: 80
Сообщений: 6096
Сила слова: 1.31

так писали во времена пхп4
Записан

PHP does the job since 1995
Пожалуйста, не надо делать двойные клики по ссылкам. Это создает избыточную нагрузку на сервер
Frozzeg    ↓ 
24 Декабрь, 2011, 08:22:31 , спустя 1 минуту 44 секунды
НЕ ХУЕТА! ХУЕТА!

Группа: Пятросянище

Карма: 92
Сообщений: 5501
Сила слова: 1.67

Сам то понял что написал?
ну а че, вполне логично, получить ссылку вместо самого объекта
Записан
StGeass    ↓ 
24 Декабрь, 2011, 08:27:26 , спустя 4 минуты 55 секунд
НЕ ХУЕТА! ХУЕТА!


Карма: 0
Сообщений: 8
Сила слова: 0


так писали во времена пхп4
Ну первой попавшей мне в руки литературой была книга по php4, так что не исключаю наличие пары не существенных атавизмов, главное что бы не были критичными
Записан
Ivan    ↓ 
24 Декабрь, 2011, 08:36:54 , спустя 9 минут 28 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 27
Сообщений: 1366
Сила слова: 1.98


Сам то понял что написал?
ну а че, вполне логично, получить ссылку вместо самого объекта

Так это одно и то же получится
Записан

master    ↓ 
24 Декабрь, 2011, 09:56:48 , спустя 1 час 19 минут 54 секунды
НЕ ХУЕТА! ХУЕТА!

Квадратов сколько видишь ты?
Группа: Джедаи

Карма: 44
Сообщений: 2080
Сила слова: 2.12

Так это одно и то же получится
в пхп4 - нет )
Записан

Tekuto    ↓ 
24 Декабрь, 2011, 10:01:39 , спустя 4 минуты 51 секунду
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 0
Сообщений: 1229
Сила слова: 0

Пых 4-ый разве актуален??? Сегодня, когда готовится уже 6-ой???
Записан

Just a man and his will to survive
phpdude    ↓ 
24 Декабрь, 2011, 10:16:40 , спустя 15 минут 1 секунду
НЕ ХУЕТА! ХУЕТА!

я - ЭМО
Группа: в ухо

Карма: 345
Сообщений: 20790
Сила слова: 1.66


Пых 4-ый разве актуален??? Сегодня, когда готовится уже 6-ой???
ДА КОНЕЧНО БЛЯДЬ
Записан

забанен. могу забанить других, пишите в личку
BEER. Helping ugly people have sex since 1862.
master    ↓ 
24 Декабрь, 2011, 11:21:42 , спустя 1 час 5 минут 2 секунды
НЕ ХУЕТА! ХУЕТА!

Квадратов сколько видишь ты?
Группа: Джедаи

Карма: 44
Сообщений: 2080
Сила слова: 2.12

В общем получилось то что хотел, к методам можно обращаться либо через экземпляр класса, либо как к статическим (через '_'), при этом не теряя указателя $this. Но все это изрядно попахивает и отнюдь не цветочками.
Правильно, с этим говнищем поймаешь только баги.
 
Есть у кого то адекватная реализация, балансирующая между удобством и здравым смыслом?
Ну а как же. Но она довольно сложна для твоего уровня.
Во-первых она реализуется в паттерне MVC, где есть контроллеры с собственно рабочим кодом, а есть модели - это объекты для доступа к данным, имитирующие структуру таблиц. Во-вторых не используй статические вызовы, с ними наебёшься.
Используем регистрозависимость пыха:
 
PHP

class ControllerPrototype{
  function __get($name){
    if (preg_match('#^[A-Z]', $name)){
      $this->$name = new $name;
    } else {
      // ошибка, нет такого поля
    }
  }
}
 
function ModelPrototype(){
  protected $db_instance;
  protected $db_alias;
  protected $table_name;
  
  function __construct(){
    $this->db_instance = Factory::getDB($this->db_alias);
    // находим экземпляр класса базы данных по его алиасу. алиасов может быть несколько, по количеству баз, обычно он один т.к. база одна, но может быть сколько угодно
    // обращаемся к фабрике, можно использовать статический вызов или какой-то другой способ.
  }
 
  function direct_query($query_str){
    return $this->db_instance->query($query_str);
  }
 
  function item($id){
    $this->db_instance->query("SELECT * FROM {$this->table_name} where `id`=?", $id);
    return $this->db_instance->fetch_result();
  }
 
  // любые другие функции для работы с данными - выборки, удаления и т.д.
}
 

// Опишем модель для работы с пользователями
class Users extends ModelPrototype{
  protected  $db_alias = 'db1';
  protected $table_name = 'users';
}
 
class FooController extends Controller {
  function my_action(){
    $user = $this->Users->item(7); // получаем юзера с id=7
    var_dump ($user);
  }
}
 

запросы к БД и создание экземпляра БД показаны схематично, главное здесь - вызов модели
$this->Users
экземпляр модели создаётся в момент первого к ней обращения. естественно, поле $this->Users не должно быть инициализировано
считаем что за один запуск скрипта вызывается только один контроллер. если будет использоваться несколько контроллеров - то потребуется какой-то глобальный массив для хранения загруженных моделей
 
PHP

class ControllerPrototype{
  function __get($name){
     if (preg_match('#^[A-Z]', $name)){
       $this->$name = Factory::getModel($name);
     } else {
       // ошибка, нет такого поля
     }
   }
}
 

моар примеров тут:
http://pyha.ru/forum/topic/7079.msg161461#msg161461
http://pyha.ru/forum/topic/6255.msg142119#msg142119
« Последнее редактирование: 24 Декабрь, 2011, 11:21:42 от master » Записан

Tekuto    ↓ 
24 Декабрь, 2011, 11:07:12 , спустя
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 0
Сообщений: 1229
Сила слова: 0

ДА КОНЕЧНО БЛЯДЬ
Почему актуален?
Записан

Just a man and his will to survive
phpdude    ↓ 
24 Декабрь, 2011, 11:11:35 , спустя 4 минуты 23 секунды
НЕ ХУЕТА! ХУЕТА!

я - ЭМО
Группа: в ухо

Карма: 345
Сообщений: д-о-х-у-я!
Сила слова: 1.66

Tekuto, ВОПРОСЫ ЗАДАВАТЬ БУДЕШЬ В АРМИИ
Записан

забанен. могу забанить других, пишите в личку
BEER. Helping ugly people have sex since 1862.
Tekuto    ↓ 
24 Декабрь, 2011, 11:34:26 , спустя 22 минуты 51 секунду
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 0
Сообщений: 1229
Сила слова: 0

РЯДОВОЙ ЗАПАСА (2 РА 999000А)
Спустя 1 минуту 55 секунд добавил
даже так
 
РЯДОВОЙ ЗАПАСА
2 РА
999000А
 
поэт блеать
Записан

Just a man and his will to survive
phpdude    ↓ 
24 Декабрь, 2011, 11:34:57 , спустя 31 секунду
НЕ ХУЕТА! ХУЕТА!

я - ЭМО
Группа: в ухо

Карма: 345
Сообщений: д-о-х-у-я!
Сила слова: 1.66


РЯДОВОЙ ЗАПАСА (2 РА 999000А)
Спустя 1 минуту 55 секунд добавил
даже так
 
РЯДОВОЙ ЗАПАСА
2 РА
999000А
 
поэт блеать
А НОМЕРОК ТО КУПИЛ БЛЕЯДЬ СТОПУДОВО! ПОД ТРИПУНАЛ ТЕПЯ НАДО ПЛЕЯТЬ!
Записан

забанен. могу забанить других, пишите в личку
BEER. Helping ugly people have sex since 1862.
Страниц: [1] 2
Печать
 

Перейти в: