mmofacts.com

Wbb lite und eval

gepostet vor 16 Jahre, 6 Monate von None
hab mir mal den quellcode der index.php des wbb lite angeschaut und mir ist aufgefallen das alles was mit dem template zu tun hat per eval gemacht wird? jz durchblick ich den quellcode garnicht. kann mir mal einer hilfestellung dazu geben?
$filename="index.php";

require("./global.php");
if(isset($_COOKIE['boardvisit'])) $boardvisit=decode_cookie($_COOKIE['boardvisit']);
else $boardvisit=array();
if(isset($_COOKIE['threadvisit'])) $threadvisit=decode_cookie($_COOKIE['threadvisit']);
else $threadvisit=array();
$boardcache=array();
$permissioncache=array();
$modcache=array();
$activtime=time()-60*$useronlinetimeout;
$result = $db->query("
SELECT
b.*".ifelse($showlastposttitle==1,", t.topic, i.*")."
FROM bb".$n."_boards b
".ifelse($showlastposttitle==1,"LEFT JOIN bb".$n."_threads t ON (t.threadid=b.lastthreadid)
LEFT JOIN bb".$n."_icons i USING (iconid)")."
ORDER by b.parentid ASC, b.boardorder ASC");
while ($row = $db->fetch_array($result)) $boardcache[$row['parentid']][$row['boardorder']][$row['boardid']] = $row;
$result = $db->query("SELECT boardid, threadid, lastposttime FROM bb".$n."_threads WHERE visible = 1 AND lastposttime > '$wbbuserdata[lastvisit]' AND closed
3");
while($row=$db->fetch_array($result)) $visitcache[$row['boardid']][$row['threadid']]=$row['lastposttime'];
$result = $db->query("SELECT * FROM bb".$n."_permissions WHERE groupid = '$wbbuserdata[groupid]'");
while ($row = $db->fetch_array($result)) $permissioncache[$row['boardid']] = $row;
$result = $db->query("SELECT bb".$n."_moderators.*, username FROM bb".$n."_moderators LEFT JOIN bb".$n."_users USING (userid) ORDER BY username ASC");
while ($row = $db->fetch_array($result)) $modcache[$row['boardid']][] = $row;
$boardbit = makeboardbit(0);
$index_pms="";
$quicklogin="";
$index_useronline="";
$index_stats="";
/* ############## STATS ############## */
if($showstats==1) {
$members=$db->query_first("SELECT COUNT(*) AS members, MAX(userid) AS userid FROM bb".$n."_users WHERE activation = 1");
$newestmember=$db->query_first("SELECT userid, username FROM bb".$n."_users WHERE userid = '$members[userid]'");
$posts=$db->query_first("SELECT COUNT(*) AS posts FROM bb".$n."_posts");
$threads=$db->query_first("SELECT COUNT(*) AS threads FROM bb".$n."_threads");
$installdays = (time() - $installdate) / 86400;
if ($installdays < 1) $postperday = $posts['posts'];
else $postperday = sprintf("%.2f",($posts['posts'] / $installdays));
eval ("\$index_stats = \"".$tpl->get("index_stats")."\";");
}
/* ############## USERONLINE ############## */
if($showuseronline==1) {
$guestcount=0;
$membercount=0;
$useronlinebit = '';
$result = $db->query("SELECT bb".$n."_sessions.userid, username, groupid, invisible FROM bb".$n."_sessions LEFT JOIN bb".$n."_users USING (userid) WHERE bb".$n."_sessions.lastactivity >= '".(time()-60*$useronlinetimeout)."' ORDER BY username ASC");
while($row = $db->fetch_array($result)) {
if($row['userid']==0) {
$guestcount++;
continue;
}
$membercount++;
if(!$row['invisible']) {
if(isset($useronlinebit) && $useronlinebit != '') $useronlinebit .= ', ';
eval ("\$useronlinebit .= \"".$tpl->get("index_useronline")."\";");
}
}
$totaluseronline = $membercount+$guestcount;
if($totaluseronline>$rekord) {
$rekord=$totaluseronline;
$rekordtime=time();
$db->unbuffered_query("UPDATE bb".$n."_options SET value='$rekord' WHERE varname='rekord'",1);
$db->unbuffered_query("UPDATE bb".$n."_options SET value='$rekordtime' WHERE varname='rekordtime'",1);
require ("./acp/lib/class_options.php");
$option=new options("acp/lib");
$option->write();
}
$rekorddate = formatdate($dateformat,$rekordtime);
$rekordtime = formatdate($timeformat,$rekordtime);
eval ("\$index_useronline = \"".$tpl->get("index_showuseronline")."\";");
}
if(!$wbbuserdata['userid']) {
eval ("\$welcome = \"".$tpl->get("index_welcome")."\";");
eval ("\$quicklogin = \"".$tpl->get("index_quicklogin")."\";");
}
else {
$currenttime=formatdate($timeformat,time());
$toffset=ifelse($default_timezoneoffset>=0,"+").$default_timezoneoffset;
$lastvisitdate = formatdate($dateformat,$wbbuserdata['lastvisit']);
$lastvisittime = formatdate($timeformat,$wbbuserdata['lastvisit']);
eval ("\$welcome = \"".$tpl->get("index_hello")."\";");
if($wbbuserdata['canusepms']==1 && $showpmonindex==1) {
$counttotal=0; $countunread=0; $countnew=0;
$result = $db->query("SELECT view, sendtime FROM bb".$n."_privatemessage WHERE deletepm
1 AND recipientid = '$wbbuserdata[userid]'");
while($row=$db->fetch_array($result)) {
$counttotal++;
if($row['view']==0) {
$countunread++;
if($row['sendtime']>$wbbuserdata['lastvisit']) $countnew++;
}
}
if($countnew>0) eval ("\$new_notnew = \"".$tpl->get("index_newpm")."\";");
else eval ("\$new_notnew = \"".$tpl->get("index_nonewpm")."\";");
eval ("\$index_pms = \"".$tpl->get("index_pms")."\";");
}
}
eval("\$tpl->output(\"".$tpl->get("index")."\");");
?>
gepostet vor 16 Jahre, 6 Monate von DarkPrisma
das eval dient dazu, dass alle variablen inerhalb des templates ersetzt werden.... ansonsten haben die auch selber ein board wo du fragen kannst....
gepostet vor 16 Jahre, 6 Monate von None
aber reicht das nicht, wenn man es ohne eval schriebt?
gepostet vor 16 Jahre, 6 Monate von DarkPrisma
nö, weil die funktionen ja die variablen nicht per parameter berziehiehen. auch nicht durch global etc. die funktion kennt erst ab dem zeitpunkt was hinter den variablen steckt.
gepostet vor 16 Jahre, 6 Monate von None
ich steh grad echt aufn schlauch wie das gemeint ist
gepostet vor 16 Jahre, 6 Monate von DarkPrisma
wenn du variablen in einer funktion hast, sind diese ja nur inerhalb der funktion gültig. wenn du von außen variablen in dieser funktion benutzen willst, musst du diese ja irgendwie in die funktion reinholen....
gepostet vor 16 Jahre, 6 Monate von Kallisti
Stell dir vor, du hast einen String der $template heisst und der Inhalt des Strings ist 'Hallo $name!'. Also mit dem $ als normales Zeichen.
Was gibt dir ein echo $template nun aus?
-> "Hallo $name!"
Das ist ja nicht der Sinn eines Templates, denn dieses soll ja Bezeichner durch ihren aktuellen Wert ersetzen.
Definieren wir nun $name als 'Welt', so gibt echo $template immer noch dasselbe aus. Erst mit eval erzwingt man die Evaluierung des Strings. Deshalb heisst es ja auch so.
Oder mit anderen Worten kurz und knapp:
chris@Gruad:~$ php -a

Interactive shell
php > $template = 'Hallo $name!';
php > echo $template;
Hallo $name!
php > $name = 'Welt';
php > echo $template;
Hallo $name!
php > eval("\$foobar=\"".$template."\";");
php > echo $foobar;
Hallo Welt!
Es ist nichts anderes als dass der Inhalt von $template zwei mal evaluiert wird. Einmal bei der Concatenation des Strings und ein zweites mal durch eval.
Mit Funktionen und dem Scope von Variablen hat das mal schlicht und ergreifend ueberhaupt gar nichts zu tun. Es geht nur darum Text zu parsen und enthaltene Variablen zu ersetzen. Du kannst auch Zeichen fuer Zeichen einlesen, jede Variable einzeln raussplitten und ausgeben. Aber eval macht im Grunde nichts anderes, nur ein paar Dinge mehr, aber dafuer auch performanter.
gepostet vor 16 Jahre, 6 Monate von Nuky
Danke, hab schon gerätselt.
gepostet vor 16 Jahre, 6 Monate von None
Danke euch.
gepostet vor 16 Jahre, 6 Monate von Klaus
Du kannst dir auch den Quellcode des WBB Lite 2 (welches ein abgespecktes WBB3 ist) anschauen, wenn du dir zutraust eine Etage tiefer in OOP einzusteigen.
gepostet vor 16 Jahre, 6 Monate von None
Hmm, OOP wär schon was schönes, aber leider bin ich daran gebunden einen mod fürs wbb lite 1 zu schreiben
gepostet vor 16 Jahre, 6 Monate von wusch
es wäre sinnvoller, sicherer und schneller das ganze per preg_match + schleife zu machen
gepostet vor 16 Jahre, 6 Monate von Klaus
Viele komplexe reguläre Ausdrücke sind schneller als einmal eval()? Ich glaube nicht Tim.
gepostet vor 16 Jahre, 6 Monate von wusch
Hm. Das Forum hat den Post wieder verschluckt, deshalb werd ich kurz zusammenfassen (Codeschnipsel macht es einfacher).
paste.mootools.net/m4f364667 - Siehe Zeile 100 und folgende.
Sammelt man die netten Dinge in einem Array wie zB $array['$blah'] = 'someValue'; und parsed das Template zum schluss einmal und ersetzt die variablen entsprechend dem Array funktioniert alles bestens. Und schneller, sicherer und leichter wartbar.
Der einzige wirkliche einsatz für eval der sich mir erschließt und anders nicht möglich ist, ist wenn man volle Kontrolle hat und man Code aus zB der DB ausführen möchte (zB Items eines Browsergames die verschiedene Auswirkungen haben, sofern man sehr viele Items hat mit unterschiedlichem Code und nette klasse wie zB $user->heal(50) oder sowas). Wobei ich es aber sehr schätzen würde, einen wirklich funktionierenden JavaScript interpreter für PHP zu haben, das wäre toll!
(Weiterer Code für die oben genannte Template Engine gerne auf Anfrage, ist Teil meines Frameworks. Not yet ready).
gepostet vor 16 Jahre, 6 Monate von Klaus
Für deinen eigenen Code kannst du das gerne machen (wobei ich natürlich einen Benchmark im Vergleich zu eval sehen möchte ).
Aber beim WBB hast du noch If, PHP-Code und hasse nicht gesehen im Template. Daher würde sich der Aufwand nicht mehr lohnen.
gepostet vor 16 Jahre, 6 Monate von wusch
Meine template-class unterstützt selbiges auch ohne eval, siehe: paste.mootools.net/m41ed37a5
Eval mag für einen einzigen aufruf sicher nicht extrem langsam sein. Ruft man es aber öfter aus muss jedes Mal alles ausgeführt werden, was sehr aufwändig ist (siehe at.php.net/eval comment 2 ). Da ist ein einzelner Aufruf von preg_match_all nix dagegen. Und in dem WBB Code ist das Eval öfter drin
gepostet vor 16 Jahre, 6 Monate von Klaus
ich habe mal einige Benchmarks zusammengehackt, u.a. mit deiner Code-Logik zur Ersetzung mittels preg.
(Quellen im Anhang)
Kurz und knapp:
preg_match_all und str_replace
44038ms Ausführung
44734ms Total
143360000 Zeichen im Puffer
eval
45533ms Ausführung
46208ms Total
143560000 Zeichen im Puffer
require
48845ms Ausführung
49593ms Total
143560000 Zeichen im Puffer
Dass require am schlechtesten abschneidet finde ich etwas enttäuschend.
gepostet vor 16 Jahre, 6 Monate von Amun Ra
Ich weiss nicht wieso der Unterschied so krass ist,
aber hier mal die Benchmarks mit meiner Kiste:
Xp 2500+ @2200, 1 GB RAM
Apache 2.2.4 Win32, PHP 5.2.1
require
83322ms Ausführung
84748ms Total
137440000 Zeichen im Puffer
preg
93157ms Ausführung
94323ms Total
143360000 Zeichen im Puffer
eval
120944ms Ausführung
122606ms Total
143560000 Zeichen im Puffer
Wie ich erwartet habe, ist require am schnellsten?!

Auf diese Diskussion antworten