Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 8
На сайте нет зарегистрированных пользователей

Пользователей: 13,361
новичок: uehuat
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Моделирование работы ЭВМ на GPSS + Пояснительная записка
Лабораторная работа по динамическим спискам на Turbo Pascal (перемещение...
Изменения контуров и сортировка в двумерном массиве чисел на Turbo Pasca...

Подход к реализации динамически подключаемых библиотек (классов) на 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;

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

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

Целую и обнимаю всех кто это читает, успехов вам !
Опубликовал Kest November 06 2008 15:47:25 · 0 Комментариев · 18581 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Профессиональное ...
С. Г. Горнаков - ...
Платформа програм...
Создание оригинал...
Язык программиров...
netBIOS
Панель "ссылки"
С# для профессион...
FreeSMS v1.3.1
3D Октаэдр
Prolog Interprete...
MPTools
INSTANT BOOSTER v...
Animation Effect ...
Page Promoter 7.7...
Дешифратор содерж...
MiniChat
начисление процен...
TsHintManager
FilesInfo

Топ загрузок
Приложение Клие... 100772
Delphi 7 Enterp... 97809
Converter AMR<-... 20260
GPSS World Stud... 17014
Borland C++Buil... 14189
Borland Delphi ... 10267
Turbo Pascal fo... 7372
Калькулятор [Ис... 5972
Visual Studio 2... 5206
Microsoft SQL S... 3661
Случайные статьи
Кузовной ремонт в ...
Отображение параме...
MixColumn
Хотя компьютеры, в...
В типичной реализа...
Объекту DataAdapte...
Поимей халявный Ин...
Понимание хеш-функций
файлов
Ассоциативные масс...
ИЗУЧЕНИЕ ПРОГРАММН...
Файлы посещений: м...
Как это настраивается
Вулкан игры онлайн
Разделители
Сообщения возвраща...
Топология соединен...
Время и материалы
Набор команд объек...
Операнды памяти
Снова об интерфейс...
Оптимизация расход...
Игровые автоматы в...
Вычисление конечны...
На вход поступает ...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?