Подход к реализации динамически подключаемых библиотек (классов) на PHP5
Автор: К.Карпенко
http://e-code.tnt43.com/
Приветствую всех читающих, ищущих, спотыкающихся и стремящихся рости над собой. Сегодня я бы хотел поразмышлять на тему разработки системы подкючения пакетов функций в рамках платформы PHP. Что же я имею ввиду.
Под пакетами функций, я подразумеваю некоторый набор методов объеденённых относительно семантической зависимости устанавливаемой между ними. Понятие пакета очень хорошо описано в рамках технологии Java, и позволяет создавать более упорядоченные наборы методов, разделяя их относительно их задач и контекста..
Мы же под пакетом будем подразумевать некоторый набор методов и их прототипов (интерфейс класса), зависимых друг от друга по целевому предназанчению.
Структура пакета будет следующей:
packages / {имя_пакета}
class.{имя_пакета}.php
interface.{имя_пакета}.php
errors.{имя_пакета}.php
То есть пакет функций будет разделятся на:
Прототипы методов, описанные в рамках интерфейса, описываемого основным классом пакета (идентификатор интерфейса должен соответствовать идентификатору класса, с добавление символа "I", в качестве последнего символа справа в тексте идентификатора)
Непосредственная реализация прототипов методов, объявлённых в интерфейсе пакета, в основном классе пакета (идентификаторру класса должно соответствовать названию пакета)
Информация относительно исключений, которые могут быть возбуждены во время активации того либо иного метода входящего в реализацию основного класса.
Так же, последуюя принципам стандартизации, я считаю необходимым ввести некоторую обязательную структуру для каждого класса, а то есть те его методы и свойства, которые должны в нём присутствовать в любом случае, такой подход очень полезен при модульной структуре информационной системы, и при условии того, что система расширяется не только непосредственными разработчиками, но и третьими лицами. При этом это вводит некую упорядоченность и "чистоту" пакетов функций подключаемых к системе.
Среди обязательных компонентов подключаемого модуля я предпочитаю выделять следующие обязательные составные:
Св-ва:
Версия данного пакета
Информационный массив об разработчиках пакета
Методы:
Основной метод класса, реализующий основную логику класса
Функция для получения версии данного пакета (стандарт ООП)
Фукнция для получения информационного массива об авторах(е) пакета
Продолжать данный список можно в зависимости от требований к информационной системе и реализуемых в её контексте задач. Заниматься его совершенствованием и корректировкой предстоит вам.
Это была небольшой обзор структурной части системы, теперь же давайте поговорим об подключении и создании экземпляров основных классов непосредственно.
Ниже приведён код для подключения заданных пользователем пакетов, и добавления ссылок на них в ассоциативный массив, в котором будут хранится экземпляры классов. Подход реализован с использованием процедурного программирования, так как в данном случае это будет более универсальное и менее проблематичное с точки зрения реализации решение.
$path_to_packages='core/kernel'; //Путь к директории, содержащей библиотеки
$instances=array(); //Массив ссылок на объекты классов
$package_members=array('errors','interface','class'); //Составные пакетов данных
$packages_to_include=array(); //Подключаемые пакеты (данные добавляются по-методу
//функции registerPackage($indefier)
function registerPackage($indefier){
global $path_to_packages,$packages_to_include;
//Функция реализующая непосредственное подключение библиотеки к программе
function includePackage($indefier){
global $instances,$path_to_packages,$package_members;
if(trim($indefier)!=''){
//Подключить все компоненты пакета
foreach($package_members as $k=>$v){
$member=$path_to_packages.'/'.$indefier.'/'.$v.'.'.$indefier.'.php';
if(!file_exists($member)){
return false;
}else{
if(!include($member))
return false;
}
}
//Добавить экзмепляр класса в коллекцию $instances[]
if(class_exists($indefier) && !isset($instances[$indefier])){
//Проверка вхождения обязательных компонент в пакет
$err=0;
foreach($main_pieces as $k=>$v){
//Входит ли данный метод в список методов класса
//(проверку вхождения полей добавите сами ;) ).
if(!in_array($v,get_class_methods(get_class($indefier))))
$err=1;
break;
}
}
if(!$err) $instances[$indefier]=new $indefier();
else return(false);
}
}else{
return false;
}
return true;
}
//Функция для подключения всех зарегистрированных пакетов
function loadLibs(){
global $packages_to_include;
Ну вот и всё, как видите всё довольно просто. Хотя в этой реализации есть однин весомый недочёт, и не упомянуть о котором было бы надеждой, что данную статью читает неопытный читатель, либо же просто показать собственное незнание.
Но при написании не подразумевался не тот ни другой случай, а скорее расчитывалось на собственную работу читателя, которая очень положительна в любом случае. Я не буду приводить описания данной проблемы, и не буду приводить её решения, я лишь скажу, что нарушается основной подход к реализации возвращения функцией данных, а то есть одной из главных проблем стиля программирования.
Итак, чтобы показать всё это "чудо" на практике приведу пример небольшого класса, который реализует общение с удалённым сервером посредствам сокетов:
Файл: interface.csc.php
interface cscI{
private function setPort($port);
private function correctMethod($method);
public function openConnection($host);
public function sendQuery($method,$uri);
public function isError($code);
public function readAnswer($cut_headers=false);
public function closeConnection();
public function logon();
}
?>
Файл: class.csc.php
class csc implement cscI {
private $_package=' Cross Server Communication Library';
private $_version=0.1;
private $_author=array('company'=>'Transfer of New Technologyes',
'author'=>'K.Karpneko');
private $_space=" ";
private $_crlf="\r\n";
private $_host='';
private $_port=80;
private $_protocol='HTTP/1.1';
private $_timeout=30;
private $_err_str='';
private $_err_no=0;
private $_answer='';
private $_errors_codes=array(21,205,51,86,31,11,7);
private $_status=200;
private $_server_info='';
private $_request='';
var $_conn_id=null;
public function setPort($port){
//Реализация
}
public function openConnection($host){
if(!$this->_conn_id){
$this->_host=$host;
private function correctMethod($method){
switch($method){
case 'POST':
case 'HEAD':
case 'GET':
case 'PUT':
case 'TRACE':
return true;
default:
return false;
}
}
public function logon(){
//METHOD NOT IMPLEMENTED
}
public function closeConnection(){
return(isset($this->_conn_id)?fclose($this->_conn_id):CONNECTION_NOT_ESTABILISHED);
}
}
?>
Далее подразумевается, что функции для динамического подключения были помещены в документ connector.php:
include 'connector.php';
registerPackage('csc');
if(!loadPackages())
die('Critical system error !');
print $instances['csc']; //В данном случае должен быть возвращён идентификатор ресурса
?>
При этом следует заметить, что при реализации механизма создания экземпляра основного класса подключаемых документов, ссылка на класс создаётся лишь раз, а после вызов функции создания просто игнорируется. В целом, я думаю, что на сегодня вполне достаточно, и предлагаю подумать получше об упомянутом в тексте статьи недочёте )
Целую и обнимаю всех кто это читает, успехов вам !
Опубликовал Kest
November 06 2008 15:47:25 ·
0 Комментариев ·
19099 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Нет комментариев.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.