[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: require внутри класса
Гость_Александр
Доброго времени суток, заранее извиняюсь может быть для кого-то вопрос покажется глупым, но всё-таки.

Сегодня столкнулся с несколько забавной проблемой:

Кроется она в том что есть класс-прослойка для работы с БД. Фактически в нём очень много функции которые просто позволяют удобнее и красивее вызывать хранимые процедуры и функции из БД и возвращают ответ.
Грубо говоря примерно таких:


function addUser($login, $password)
{
$querry_text = 'SELECT addUser($login, $password)';
$querry_result = mysql_querry($querry_tex);
$querry_value = mysql_fetch_row($querry_result);
return $querry_value[0];
}


При этом несмотря на то что база данных одна на ней висит очень много несвязанных модулей которые будут создаваться раздельно как руки дотянутся до них.
Так вот меня заинтриговало можно ли сформировать php-класс из нескольких файлов? Т.е. например:


class DBLayer
{
var $userLogin; // Логин
var $userKey; // Ключ доступа

//
// Базовый общий код типа конструктора
//

// Функции для работы модуля #1

require 'dblayer/module1.php';

// Функции для работы модуля #2
require 'dblayer/module2.php';
}


И php ругается на это самое "require", насколько я понимаю это препроцессорная функция и она должна выполнятся перед интерпритацией, но тем не менее выбивается ошибка:
Parse error: syntax error, unexpected T_REQUIRE_ONCE, expecting T_FUNCTION


Конечно однозначно в голову приходят мысли о том чтобы не придумывать велосипед и использовать наследование, но по моему так не "шарман" ;-) т.е. не так нагляден смысл этого наследования.

Если кто сталкивался с подобным скажите решение, или предложите что-нибудь альтернативное, буду вам благодарен.



Спустя 43 минуты, 41 секунда (17.11.2010 - 02:49) kirik написал(а):
А что мешает просто замутить один мега-класс на тысячу строчек? smile.gif
Вообще наследование в вашем случае - это выход. Можно разбить классы на логические группы по функционалу, напримр класс DBlayer_user - где будут храниться методы которые работают с юзерами. Этот класс будет наследовать DBLayer в котором будет основной функционал. А если к этому еще и автолоад прикрутить, то память не будет забиваться неиспользуемым функционалом.

Спустя 6 часов, 24 минуты, 50 секунд (17.11.2010 - 09:13) linker написал(а):
Так действительно нельзя. Но если внутри статического или обычного метода заинклудить файлик, то в нем можно писать self::$staticField и $this->field соответственно.

Спустя 2 минуты, 4 секунды (17.11.2010 - 09:16) kirik написал(а):
Цитата (linker @ 17.11.2010 - 01:13)
то в нем можно писать self::$staticField и $this->field соответственно.

Вызывать-то можно, создавать новые методы никак не получится.

Спустя 11 часов, 15 минут, 33 секунды (17.11.2010 - 20:31) Гость_Александр написал(а):
Мне понравилась идея про автолоад... ;-)
В общем класс я сваял с учётом двух паттернов: синглтона и ленивой инициализации, получилось нечто вроде этого:

// Подключение классов DBAccount, DBHome
require 'scripts/dblayer/includes/account.php';
require 'scripts/dblayer/includes/home.php';

class DBLayer
{
//
// Данные пользователя от которого открыт слой
//

private $accessLogin = null;
private $accessKey = null;
//
// Реализация синглтона
//
// Ссылка на экземпляр класса

private static $instance;
// Инкапсулируем конструкторы (что бы их не вызывали извне)
private function __construct($login, $key)
{
if (isset($login) && isset($key))
{
$this->accessLogin = $login;
$this->accessKey = $key;
}
}

private function __clone() { }
// Единственный метод получения объекта
public static function getInstance($login, $key)
{
if (self::$instance === null)
self::$instance = new self($login, $key);
return self::$instance;
}
//
// Реализация ленивой инициализации
//
// Данные подключаемых модулей

private $units = array
(
"account" => array ("instance" => null, "className" => "DBAccount"),
"home" => array ("instance" => null, "className" => "DBHome")
);

// Перегрузка __get для удобного получения модуля
function __get($unit)
{

if (array_key_exists($unit, $this->units)) // Модуль существует в списке
{
if (is_null($this->units[$unit]["instance"])) // Модуль не был создан
$this->units[$unit]["instance"] = new $this->units[$unit]["className"]($login, $key);
return $this->units[$unit]["instance"];
}
return null;
}
}



В коде вызывается соответственно:
$db = DBLayer::getInstance('login', 'key');
$db->account->foo();


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

Спустя 1 час, 12 минут, 46 секунд (17.11.2010 - 21:44) kirik написал(а):
Цитата (Гость_Александр @ 17.11.2010 - 12:31)
Мне понравилась идея про автолоад... ;-)

Понравиться-понравилась, а реализацию не доделали smile.gif Инклюдиться файлы должны по надобности.

Спустя 4 часа, 53 минуты, 25 секунд (18.11.2010 - 02:37) Гость_Александр написал(а):
Цитата (kirik @ 17.11.2010 - 18:44)
Понравиться-понравилась, а реализацию не доделали :) Инклюдиться файлы должны по надобности.

Да, кстати... что-то я забыл о самом главном ;-)
Вот если кому-то понадобится

// Класс-адаптер для работы с БД через подключаемые модули-классы
class DBLayer
{
// Данные слоя: пользователь и ссылка на БД
private $accessLogin = null;
private $accessKey = null;
private $accessLink = null;
// Ссылка на экземпляр класса
private static $instance;
// Инкапсулируем конструкторы (что бы их не вызывали извне)
private function __construct($login, $key)
{
if (isset($login) && isset($key))
{
$this->accessLogin = $login;
$this->accessKey = $key;
}
}

private function __clone() { }
// Единственный метод получения объекта
public static function getInstance($login, $key)
{
if (self::$instance === null)
self::$instance = new self($login, $key);
return self::$instance;
}
// Динамическая инициализация модулей
// Данные подключаемых модулей

private $units = array
(
"account" => array ("instance" => null, "className" => "DBLayerAccount", "implementationFile" => "includes/account.php"),
"home" => array ("instance" => null, "className" => "DBLayerHome", "implementationFile" => "includes/home.php")
);

// Перегрузка __get для удобного получения ссылки на модуль
function __get($unit)
{
// Модуль существует в списке
if (array_key_exists($unit, $this->units))
{
// Модуль не был подгружен ранее
if (is_null($this->units[$unit]["instance"]))
{
// Подгружаем файл с классом
include $this->units[$unit]["implementationFile"];
// Создаём экземпляр этого класса
$this->units[$unit]["instance"] = new $this->units[$unit]["className"]($this->accessLogin, $this->accessKey, $this->accessLink);
}
return $this->units[$unit]["instance"];
}
return null;
}
}

Вот теперь я думаю точно всё ^_^

Спустя 3 часа, 29 минут, 29 секунд (18.11.2010 - 06:07) Guest написал(а):
А интерфейсами не проще будет?
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.