View Full Version : Объектно-ориентированный PHP5 рулит!
crazy-mike
11-03-2008, 02:59 PM
Если к JavaScript добавить возможность сохранения значений переменных и вводимых данных в файл на сервер
Это тривиально делается через DOM API. document.createElement("form") и т.д. Даже скучно немного...:grum: На сервере всё равно нужно писать какую-нибудь муть. Совсем без "серверной части" обойтись не получится. Аттрибут action тэга form вообще-то может иметь вид mailto:... или даже ftp:...Но это очень неудобно!
Olezhik
11-03-2008, 05:53 PM
Это тривиально делается через DOM API. document.createElement("form") и т.д. Даже скучно немного...:grum: На сервере всё равно нужно писать какую-нибудь муть. Совсем без "серверной части" обойтись не получится. Аттрибут action тэга form вообще-то может иметь вид mailto:... или даже ftp:...Но это очень неудобно!
Нипонимаю, зачем заного придумывать колесо?
crazy-mike
11-04-2008, 02:04 AM
Нипонимаю, зачем заного придумывать колесо?
Ну - вдруг квадратное колесо крутиться начнёт? :grum:
При хостинге на narod.ru такие "колёса" и в самом деле имеют определённый смысл (там пользователю можно использовать только HTML/XHTML без всяких php,cgi,jsp,asp :evillaugh:)
Конечно же JavaScript и Java-апплеты эти "хост-провайдеры" запретить просто не могут. Меня больше всего достаёт то - что они уродуют контент веб-страницы вставками своих идиотских баннеров. Могли бы уже просто страницу пользователя вставлять в свой <iframe> и ничего не портить. :grum:
crazy-mike
11-04-2008, 07:18 AM
Нипонимаю, зачем заного придумывать колесо?https://developer.mozilla.org/en/SOAP_in_Gecko-based_Browsers
Firefox 3 note
Native WSDL and SOAP support has been removed from Mozilla 1.9/Firefox 3.
Это тоже причина - по которой появляются новые "квадратные колёса".
:D
crazy-mike
11-15-2008, 10:15 AM
А сейчас попробуем сравнить "круглые колёса" с "квадратными"....
(ну DOM API для JavaScript и "реализацию на php5" (я конечно же "скромно так" имею ввиду "свою реализацию" myhtml.php)).
Основное различие - в JavaScript используются ссылки на объекты (references to document elements). У меня вообще-то в реализации метода add ссылки на "объекты" заменяются "вычисленными значениями".
Имеется ввиду то - что если я выполню в скрипте:
$br=new xhtmlBr();
то я это $br смогу добавить в любой элемент.
Например:
$a=new xhtmlTag("div"); $b=new xhtmlTag("div");
$a->add($br); $b->add($br);
С использованием DOM API в JavaScript этот подход эквивалентен:
function br() { r=document.createElement("br"); return r; }
a=document.createElement("div"); b=document.createElement("div");
a.appendChild(br()); b.appendChild(br());
Но не:
br=document.createElement("br");
a=document.createElement("div"); b=document.createElement("div");
a.appendChild(br); b.appendChild(br);
:D
crazy-mike
11-16-2008, 05:31 AM
А теперь добавим ещё одно "квадратное колесо":
class linkJS extends xhtmlTag {
public final function __construct($fn)
{ parent::__construct("script");
$this->setA("type","text/javascript");
$this->setA("src",$fn);
}
}
Ну и теперь у "любой страницы разработчика" есть возможность выглядеть примерно так:
<?xml version="1.0" encoding='KOI8-U'?><!DOCTYPE HTML PUBLIC "-//W3C/DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtmml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="uk" lang="uk"><head><meta http-equiv="Content-Type" content="text/html; charset=koi8-u; lang=uk"><title>Something Terrible</title><meta name="robots" content="noindex,nofollow" /><link rel="SHORTCUT ICON" href="./im/tech.jpg" /><link rel="stylesheet" type="text/css" href="../admin/sty/my.css" /><link rel="stylesheet" type="text/css" href="./myst/my.css" /><script type="text/javascript" src="./js/index.js" /></head><body onload="xLoad()" ></body></html>
Что-то такое могло бы получиться после работы php-скрипта примерно такого вида:
class mB extends xhtmlBody {
public final function __construct()
{ parent::__construct("","","xLoad()");
}
}
class mH extends xhtmlHead {
public final function __construct()
{ parent::__construct("Something Terrible");
$this->attach(
new linkCSS("./somewhere/my.css"),
new linkJS("./js/index.js")
)
}
}
$p=new xhtmlApp(new mH(),new mB());
php - в этом случае используется (откровенно говоря , не особенно и понятно - зачем "оно" теперь нужно) как "мета-http". Весь контент создаётся средствами JavaScript через вызовы DOM API.
Правда в случае замены linkJS на jsFile - использование PHP для организации "gzipped xhtml" даже можно и понять...:grum:
crazy-mike
11-20-2008, 05:24 PM
Для того , чтобы "квадратное колесо" linkJS работало не только в браузерах Opera и Google Chrome - но и в Mozilla Fire Fox , код для класса linkJS нужно немного изменить:
class linkJS extends xhtmlTag {
public final function __construct($fn)
{ parent::__construct("script");
$this->setA("type","text/javascript");
$this->setA("src",$fn);
$this->cat("/*** fuck up Mozilla Firefox! ****/");
}
}
Ну не понимает Mozilla Firefox XHTML-тега <script type="..." src="..." />
"Оно" думает что он обязательно должен состоять из пары
<script> ....</script>
:leader:
crazy-mike
11-28-2008, 04:05 PM
;) Ну а сейчас попробуем "столкнуться с суровой реальностью".
Не секрет - что при загрузке страницы браузеры устанавливают не одно соединение с сервером , а несколько и пытаются осуществлять параллельную загрузку контента.
Вот как раз здесь и начинается "хроническая загадочность". Если javascript и css находятся внутри страницы - то загрузка может осуществится за счёт одного соединения , а если они находятся во внешних файлах - то за счёт не менее трёх "параллельных". На установку каждого из соединений затрачивается время (на выполнение сonnect).
Соответственно AJAX-запрос тоже инициирует установку соединения по connect. Загрузки картинок тоже обычно в таких браузерах как Mozilla Firefox осуществляются "параллельно". Всё бы хорошо - но провайдеры обычно "шейпят клиентов". Это означает в том числе и ограничение числа соединений между клиентом и веб-сервером. В результате - страница , сделанная "по последнему слову заумной техники" может грузиться "неожиданно медленно". :evillaugh :evillaugh :evillaugh
crazy-mike
12-04-2008, 03:17 PM
Здесь правда никто ещё не пробовал сравнивать объектно-ориентированный php5 и объектно-ориентированный perl.
:evillaugh :evillaugh :evillaugh :evillaugh
Для чего? Для apache есть модули и php5 , и perl. Для других http-серверов - тоже.
Для начала - php по сравнению с perl выглядит более "высокоуровневым" (или даже - похожим на Java. Так , наверное , точнее).
На "примитивном уровне" эти языки похожи. Хотя в perl вот есть goto-statement , а в php его нет вообще (в явном виде). Но вот всё остальное...В скриптах на php объекты может создавать даже полный идиот. В perl даже написание подпрограмм требует определённого "понимания". Зато в perl модули есть. Но namespace есть и в php5.
crazy-mike
12-05-2008, 02:02 PM
Самое интересное - сравнивать реализацию объектов в php5 и Perl5.
Объект как instantiated module (в Perl5) = довольно странная вещь. И читается "такое" очень неудобно "в исходных текстах".
Но самая идиотская вещь (после php) - передача ссылки на объект в качестве первого параметра для метода.
:evillaugh
После php - переход к Perl похож на "путешествие во времени в 1970е годы". :grum:
Конечно же в Perl очень много "элегантных трюков" из-за довольно своеобразной нотации для обращения к подпрограммам. Но всё это очень трудно читать (как будто готическим шрифтом :grum: ).
crazy-mike
12-09-2008, 02:03 AM
Для сравнения различий между "объектным Perl" и "объектным php5" полезно построить кусочек реализации "библиотеки myhtml" на Perl5.
#!/usr/local/bin/perl
package Xhtml;
sub new
{ my $cl = shift;
my $xt = shift;
my $self = { @nodes => [], %attr => { } };
$self->{xtag}=$xt;
$self->{content}="";
bless $self;
return $self;
}
sub SetA
{ my $self = shift;
my $at = shift;
my $av = shift;
$self->{%attr}{$at}=$av;
}
sub See
{ my $self = shift;
my $v="<".$self->{xtag};
my $a=$self->{%attr};
while(($ke,$va) = each %{$a}) {
$v.=' '.$ke.'="'.$va.'"';
};
my $n=length($self->{content});
if($n>0) {
$v.=">".$self->{content}."</".$self->{xtag}.">";
};
if($n==0) {
$v.=" />";
};
return $v;
}
sub Add
{ my $self = shift;
my $some = shift;
$self->{content}.=$some->See();
}
sub Cat
{ my $self = shift;
my $some = shift;
$self->{content}.=$some;
}
#
@EXPORT = qw( &new &Data &See &SetA &Add &Cat );
#
Ну и пользоваться этим как
#!/usr/local/bin/perl
use Xhtml;
my $a=Xhtml->new("p");
$a->SetA("align","left");
$a->SetA("style","margin :5px; border :1px solid");
my $b=Xhtml->new("b");
$b->Cat("Hello!");
$a->Add($b);
print $a->See();
#
Внутри php5 "такое" всё же легче читается. :grum:
Olezhik
12-09-2008, 11:14 AM
Для сравнения различий между "объектным Perl" и "объектным php5" полезно построить кусочек реализации "библиотеки myhtml" на Perl5.
#!/usr/local/bin/perl
package Xhtml;
sub new
{ my $cl = shift;
my $xt = shift;
my $self = { @nodes => [], %attr => { } };
$self->{xtag}=$xt;
$self->{content}="";
bless $self;
return $self;
}
sub SetA
{ my $self = shift;
my $at = shift;
my $av = shift;
$self->{%attr}{$at}=$av;
}
sub See
{ my $self = shift;
my $v="<".$self->{xtag};
my $a=$self->{%attr};
while(($ke,$va) = each %{$a}) {
$v.=' '.$ke.'="'.$va.'"';
};
my $n=length($self->{content});
if($n>0) {
$v.=">".$self->{content}."</".$self->{xtag}.">";
};
if($n==0) {
$v.=" />";
};
return $v;
}
sub Add
{ my $self = shift;
my $some = shift;
$self->{content}.=$some->See();
}
sub Cat
{ my $self = shift;
my $some = shift;
$self->{content}.=$some;
}
#
@EXPORT = qw( &new &Data &See &SetA &Add &Cat );
#
Ну и пользоваться этим как
#!/usr/local/bin/perl
use Xhtml;
my $a=Xhtml->new("p");
$a->SetA("align","left");
$a->SetA("style","margin :5px; border :1px solid");
my $b=Xhtml->new("b");
$b->Cat("Hello!");
$a->Add($b);
print $a->See();
#
Внутри php5 "такое" всё же легче читается. :grum:
Не хотел бы я оказаца на месте того програмиста кому придёца в твои кода что-то новинькое прибавить. Тут как гаварица, "сам чёрт голову сломит".
crazy-mike
12-09-2008, 12:09 PM
Не хотел бы я оказаца на месте того програмиста кому придёца в твои кода что-то новинькое прибавить. Тут как гаварица, "сам чёрт голову сломит".
В Perl - в самом деле всё не особенно удобно читать. В приведённом примере просто показано как можно использовать Hash и Array внутри "данных объекта".
Использовать Perl для скриптов вместе с mod_perl - это кошмарная идея для apache2 под каким-нибудь юниксом. Это слишком низкоуровневый язык. Там очень много можно , но заголовки http нужно правильно формировать самостоятельно. ;)
Вот - совсем забыл - у Perl остаётся достаточно "фанов" хотя бы потому , что в этом языке уцелел goto statement!!!!!!!! :grum:
crazy-mike
12-09-2008, 05:49 PM
На самом деле в Perl довольно много своих выразительных средств (но совсем не таких как в php5).
В php5 описаний классов в одном файле скрипта может быть несколько.
В perl - классом является instantiated module. Но поскольку каждый модуль размещается в отдельном файле , то и несколько модулей (и несколько классов) в одном файле как будто бы описать невозможно. На самом деле это совсем не так. У "класса" в Perl может быть несколько конструкторов. За счёт этого один и тот же класс может представлять совершенно разные "структуры объектов". Это конечно же не самый лучший способ ООП на Perl , но он отражает выразительные возможности этого языка. Например "почти полная реализация" аналога myhtml.php могла бы выглядеть так:
#!/usr/local/bin/perl
package Xhtml;
sub new
{ my $cl = shift;
my $xt = shift;
my $self = { @nodes => [], %attr => { } };
$self->{xtag}=$xt;
$self->{content}="";
bless $self;
return $self;
}
sub SetA
{ my $self = shift;
my $at = shift;
my $av = shift;
$self->{%attr}{$at}=$av;
}
sub See
{ my $self = shift;
my $v="<".$self->{xtag};
my $a=$self->{%attr};
while(($ke,$va) = each %{$a}) {
$v.=' '.$ke.'="'.$va.'"';
};
my $n=length($self->{content});
if($n>0) {
$v.=">".$self->{content}."</".$self->{xtag}.">";
};
if($n==0) {
$v.=" />";
};
return $v;
}
sub Add
{ my $self = shift;
my $some = shift;
$self->{content}.=$some->See();
}
sub Cat
{ my $self = shift;
my $some = shift;
$self->{content}.=$some;
}
sub Init
{ my $self={};
$self->{content}='<?xml version="1.0" '.'encoding="windows-1251"?>'
.'<!DOCTYPE HTML PUBLIC '
.'"-//W3C/DTD XHTML 1.0 Transitional//EN" '
.'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
bless $self;
}
sub Publish
{ my $self = shift;
my $v=$self->{content};
$n=length($v);
print "Content-type: text/html\n";
print "Content-length: ".$n."\n\n";
print $v;
}
sub Html
{ my $self = shift;
$self->{xtag}="html";
$self->SetA("xmlns","http://www.w3.org/1999/xhtml");
$self->SetA("xml:lang","uk");
$self->SetA("lang","uk");
}
sub DESTROY
{ my $self = shift;
unset $self->{content};
}
#
@EXPORT = qw( &new &Data &See &SetA &Add &Cat &Init &Html &Publish );
#
Ну а её использование как:
#!/usr/local/bin/perl
use lib qw(/data/ap2/pl);
require Mu::Xhtml;
use CGI;
my $pg=Xhtml->Init();
my $html=Xhtml->new("html"); $html->Html();
my $hd=Xhtml->new("head");
my $ti=Xhtml->new("title");
$ti->Cat("Hello"); $hd->Add($ti);
$html->Add($hd);
my $a=Xhtml->new("body");
$a->SetA("align","left");
$a->SetA("style","margin :5px; background :#ffff00");
my $b=Xhtml->new("b");
$b->Cat("Привіт!");
$a->Add($b);
$html->Add($a);
$pg->Add($html);
$pg->Publish();
#
Здесь в одном и том же модуле для создания класса используется два разных конструктора Init и new. Конструктор Init служит для создания контейнера для доставки документа по http. Конструктор new используется для создания объектов , соответствующих тегам xhtml.
:evillaugh Всё выглядит даже немного "логичнее" чем в php5. А корректные http headers формируются в методе Publish. Один недостаток здесь есть - методы не защищены от неправильного применения. Publish должен вызываться только для "всей страницы". В приведённой реализации контроль правильности наполнения контейнера отсутствует.
crazy-mike
12-11-2008, 03:06 AM
Ещё один "нюанс" (если сравнивать работу с mod_php5 и mod_perl):
Если внутри скрипта на Perl , который работает под mod_perl
попробовать вывести внутри генерируемой страницы <link rel="SHORTCUT ICON" href="my.ico" /> - то просто ничего не выйдет. Apache2 в этом случае всё равно вставит favicon.ico (наверное - чтобы подчеркнуть , что выполняется "модуль" :grum: ).
"Такое" правда легко обходится через JavaScript.
Если по onload для <body> выполняется что-то такое:
function xLoad()
{ ff=document.createElement("link");
ff.setAttribute("rel","SHORTCUT ICON");
ff.setAttribute("href","/im/camera.gif");
document.body.appendChild(ff);
}
То иконка создаётся "после загрузки страницы" - и замещает ту - которую принудительно "поставило" apache2. :D
Как я уже постил - вообще-то весь контент страницы можно формировать внутри JavaScript. За счёт этого можно размер загружаемых данных довольно сильно уменьшить (даже иногда сильнее чем при использовании gz-handler).
crazy-mike
12-23-2008, 08:57 AM
Ну а теперь попробуем заставить PHP5 "порулить" по-настоящему.
Есть такой фокус - использование внутри Perl (mod_perl) сессий из php (mod_php5). Для этого есть очень удобный модуль PHP::Session , но он правильно работает (должен работать :grum:) для php4.
Для php5 там конструктор Session::new просто немного "не там" ищет данные сессий php.
sub new {
my($class, $sid, $opt) = @_;
my %default = (
save_path => '/tmp',
serialize_handler => 'php',
create => 0,
auto_save => 0,
);
$opt ||= {};
my $self = bless {
%default,
%$opt,
_sid => $sid,
_data => {},
_changed => 0,
}, $class;
$self->_validate_sid;
$self->_parse_session;
return $self;
}
Чтобы всё работало для php5 - достаточно просто save_path => '/var/tmp' (под FreeBSD)
Можно даже и ничего не менять. Но тогда просто под var сделать ln -s /tmp
http://search.cpan.org/~miyagawa/PHP-Session-0.26/lib/PHP/Session.pm
crazy-mike
12-23-2008, 04:02 PM
http://search.cpan.org/~miyagawa/PHP-Session-0.26/lib/PHP/Session.pm
Кстати save_path там можно и "в качестве параметра" передавать.
my $se=PHP::Session->new($sid,{'save_path' => '/var/tmp'});
Ну - это уже "мелочь". :yel:
crazy-mike
01-09-2009, 03:45 AM
Но если уже совсем точно - то session data между php и perl лучше передавать через БД. Дело в том - что mod_perl время от времени "затыкается" именно при использовании "php session data" (особенности flock :D). Но проще всего делать вызов session_start в php , но использовать sid именно как ключ для записи в БД. А сами данные передавать через БД.
bukabyka
05-26-2009, 07:20 AM
А сами данные передавать через БД.
а на сколько это быстро работает и нет ли вероятности замусорить базу?
что-то мне кажется этот способ какой-то тяжелый. нет? я не прав?
если есть личный опыт и статистика, было бы интересно прочитать.
crazy-mike
05-26-2009, 12:01 PM
а на сколько это быстро работает и нет ли вероятности замусорить базу?
что-то мне кажется этот способ какой-то тяжелый. нет? я не прав?
если есть личный опыт и статистика, было бы интересно прочитать.
С "точностью до наоборот" - "через базу" является самым "лёгким способом" (из-за кеша-результатов запросов и оптимизации I/O при работе с БД). Файловые блокировки в этом случае "тяжелее" (для session_id - в случае "по умолчанию" как раз создаются файловые дескрипторы в /tmp ) .