Главная
Трудоустройство
Ваши объявления
Наши новости
Информация







Подход к реализации динамически подключаемых библиотек (классов) на PHP5

Автор: К.Карпенко <LoRd1990@gmail.com> http://e-code.tnt43.com/







Приветствую всех читающих, ищущих, спотыкающихся и стремящихся рости над собой. Сегодня я бы хотел поразмышлять на тему разработки системы подкючения пакетов функций в рамках платформы PHP. Что же я имею ввиду.

Под пакетами функций, я подразумеваю некоторый набор методов объеденённых относительно семантической зависимости устанавливаемой между ними. Понятие пакета очень хорошо описано в рамках технологии Java, и позволяет создавать более упорядоченные наборы методов, разделяя их относительно их значения и семантики.

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

Структура пакета будет следующей:

packages / {имя_пакета}
 class.{имя_пакета}.php
 interface.{имя_пакета}.php
 errors.{имя_пакета}.php

То есть пакет функций будет разделятся на:

  • Прототипы методов, описанные в рамках интерфейса, описываемого основным классом пакета (идентификатор интерфейса должен соответствовать идентификатору класса, с добавление символа "I", в качестве последнего символа справа в тексте идентификатора)
  • Непосредственная реализация прототипов методов, объявлённых в интерфейсе пакета, в основном классе пакета (идентификатор класса должно соответствовать названию пакета)
  • Информация относительно исключений, которые могут быть возбуждены во время активации того либо иного метода входящего в реализацию основного класса.

    Так же, последуюя принципам стандартизации, я считаю необходимым ввести некоторую обязательную структуру для каждого класса, а то есть те его методы и свойства, которые должны в нём присутствовать в любом случае, такой подход очень полезен при модульной структуре информационной системы, и при условии того, что система расширяется не только непосредственными разработчиками, но и третьими лицами. При этом это вводит некую упорядоченность и "чистоту" пакетов функций подключаемых к системе.

    Среди обязательных компонентов подключаемого модуля я предпочитаю выделять следующие обязательные составные:

    Св-ва:

  • Версия данного пакета
  • Информационный массив об разработчиках пакета

    Методы:

  • Основной метод класса, реализующий основную логику класса
  • Функция для получения версии данного пакета (стандарт ООП)
  • Фукнция для получения массива об авторах(е) пакета

    Продолжать данный список можно в зависимости от требований к пакету и реализуемых им методах. Заниматся его совершенствованием и корректировкой предстоит вам.

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

    Ниже приведён код для подключения заданных пользователем пакетов, и добавления ссылок на них в ассоциативный массив, в котором будут хранится экземпляры классов. Подход реализован с использованием процедурного программирования, так как в данном случае это будет более универсально и менее проблематично с точки зрения реализации.

    <?php
    $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;
     if(file_exists($path_to_packages./.$indefier)){
     $packages_to_include[]=$indefier;
     }else{
     return false;
     }
     return true;
    }
    //Функция реализующая непосредственное подключение библиотеки к программе
    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;
     foreach($packages_to_include as $k=>$v){
     if(!includePackage($v)){
     return false;
     }
     }
     return true;
    }
    ?>
    

    Ну вот и всё, как видите всё довольно просто. Хотя в этой реализации есть однин весомый недочёт, и не упомянуть о котором было бы надеждой, что данную статью читает неопытный читатель, либо же просто показать собственное незнание.

    Но при написании не подразумевался не тот ни другой случай, а скорее расчитывалось на собственную работу читателя, которая очень положительна в любом случае. Я не буду приводить описания данной проблемы, и не буду приводить её решения, я лишь скажу, что нарушается основной подход к реализации возвращения функцией данных.

    Итак, чтобы показать всё это "чудо" на практике приведу пример небольшого класса, который реализует общение с удалённым сервером посредствам сокетов:

    Название пакета: csc (Cross Server Communicator)

    Файл: errors.csc.php

    <?php
    define(CONNECTION_ERROR,21);
    define(CONNECTION_SUCCESSFUL,3);
    define(CONNECTION_EXISTS,205);
    define(REQUEST_SUCCESSFUL,2);
    define(REQUEST_FAILED,51);
    define(INCORRECT_METHOD,31);
    define(POINTER_NE,7);
    define(CONNECTION_NOT_ESTABILISHED,86);
    define(WRONG_DATA,11);
    ?>
    

    Файл: interface.csc.php

    <?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;
     $this->_conn_id=fsockopen(
     (eregi(http://,$this->_host)?
     str_replace(http://,,$this->_host):$this->_host),
     $this->_port,$this->_err_no,$this->_err_str,
     $this->_timeout);
     if(!$this->_conn_id){
     return CONNECTION_ERROR;
     }else{
     return CONNECTION_SUCCESSFUL;
     }
     }else{
     return CONNECTION_EXISTS;
     }
     }
     private function correctMethod($method){
     switch($method){
     case POST:
     case HEAD:
     case GET:
     case PUT:
     case TRACE:
     return true;
     default:
     return false;
     }
     }
     public function sendQuery($method,$uri){
     if($this->_conn_id){
     if(trim($method)!= && trim($uri)!=){
     $uri=substr($uri,strpos(?,$uri),strlen($uri));
     $uri=explode(&,$uri);
     foreach($uri as $k=>$v){
     $v=explode(=,$v);
     $v=$v[0].=.rawurlencode($v[1]);
     $uri[$k]=$v;
     }
     $uri=implode(&,$uri);
     $this->_request=;
     if($this->correctMethod($method)){
     $this->_request.=$method.$this->_space;
     $this->_request.=$uri.$this->_space;
     $this->_request.=$this->_protocol.$this->_crlf;
     $this->_request.=Host: .$this->_host.$this->_crlf;
     $this->_request.=Connection: Close.$this->_crlf.$this->_crlf;
     #die($this->_request);
     $this->_answer=fwrite($this->_conn_id,$this->_request);
     if($this->_answer){
     return REQUEST_SUCCESSFUL;
     }else{
     return REQUEST_FAILED;
     }
     }else{
     return INCORRECT_METHOD;
     }
     }else{
     return WRONG_DATA;
     }
     }else{
     return CONNECTION_NOT_ESTABILISHED;
     }
     }
     public function isError($code){
     return(in_array($code,$this->_errors_codes)?true:false);
     }
     public function readAnswer($cut_headers=false){
     $this->_result=;
     if($this->_conn_id){
     if($this->_answer){
     while(!feof($this->_conn_id)){
     $this->_result.=fread($this->_conn_id,4096);
     }
     if($cut_headers){
     $this->_result=substr($this->_result,0,1024);
     }
     }else{
     return POINTER_NE;
     }
     }else{
     return CONNECTION_NOT_ESTABILISHED;
     }
     return $this->_result;
     }
     public function logon(){
     //METHOD NOT IMPLEMENTED
     }
     public function closeConnection(){
     return(isset($this->_conn_id)?fclose($this->_conn_id):CONNECTION_NOT_ESTABILISHED);
     }
    }
    ?>
    

    Далее подразумевается, что функции для динамического подключения были помещены в документ connector.php:

    <?php
     include connector.php;
    registerPackage(csc);
    if(!loadPackages())
     die(Critical system error !);
    print $instances[csc]; //В данном случае должен быть возвращён идентификатор ресурса
    ?>
    

    При этом следует заметить, что при реалиацзии механизма создания экземпляра основного класса подключаемых документов, ссылка на класс создаётся лишь раз, а после вызов функции создания просто игнорируется. В целом, я думаю, что на сегодня вполне достаточно, и предлагаю подумать получше об упомянутом в тексте статьи недочёте )

    Целую и обнимаю всех кто это читает, успехов вам !

    Ваш К.Карпенко, компания ИНПП "Трансфер Новых Технологий - 43"




    www.codenet.ru
    Что необходимо знать программисту 24-08-2007
    Использование технологии InternetExpress в Borland Delphi 20-08-2008 Что необходимо знать программисту
    Одной из примечательных возможностей Borland Delphi 5 является технология InternetExpress - средство обработки и публикации данных в Internet на основе технологии MIDAS.В Delphi реализован набор компонентов, позволяющих реализовать полный цикл клиент-серверной обработки данных на базе Internet как с использованием средств создания приложений на основе ISAPI/NSAPI, ASP и CGI, так и новых технологий, к примеру, стандарта XML (eXtended Markup La...


    Программный поиск файлов 07-07-2008 Что необходимо знать программисту
    В этом уроке мы с вами ознакомимся с основными принципами программной организации поиска файлов. Для начала определимся, зачем нам это может быть нужно. Например, вам нужно при запуске программы на выполнение просканировать определенный каталог на присутствие DOC файлов, и при наличии таковых открыть их на редактирование или напечатать. А как вам такая идея: фоновый поиск EXE файла в сети, и при обнаружении новой версии, автоматическое обновление...


    Деньги в Интернет 07-05-2008 Что необходимо знать программисту
    Интернет прочно входит в нашу жизнь. А вмести с ним такие понятие как электронная коммерция и электронные деньги. Многие предприниматели уже воспринимают пользователей Интернета как «потребителей» их интернет-рекламы, но и как потенциальных покупателей. Рассмотрим такие интересующие многих пользователей Интернета вопросы. 1) Что такое электронные деньги?2) Как их обналичивают (конвертируют).3) Как этот вопрос рег...

  • Copyright © 2005
    "service-centers.com.ua"


    Rambler's Top100   Рейтинг@Mail.ru

    Работа
    Карта сайта
    О сайте
    Реклама
    все объявления
    поиск резюме
    поиск вакансий
    добавить резюме
    добавить вакансию

    Все объявления
    Компьютеры, оргтехника
    Автомобили
    Продукты питания
    Аудио, Фото, Видео
    Связь
    Отдых, путешествия
    Мебель
    Разное
    Добавить объявление
     Автомобили
     Ремонтно-строительные услуги
     Пресс-релизы
     Железо
     Soft
     Мобильная планета
     Для милых дам
     Родительский клуб
     Недвижимость
     Домашний очаг, усадьба
     Строительство
     Обустройство и безопасность дома
     Сантехника