php.de

Zurück   php.de > Webentwicklung > PHP Einsteiger > PHP Tipps 2007

 
 
LinkBack Themen-Optionen Thema bewerten
Alt 15.12.2005, 23:31  
Gast
 
Beiträge: n/a
Standard Counterskript - Ressourcenverbrauch? Optimierbar?

Hallo zusammen,

ich hab folgendes Counter-Skript programmiert, das (wie ihr seht) den Counterstand aus der DB ausliest und dann in eine Grafik umsetzt.
Da das Skript im Rahmen eines Counterservices laufen soll, muss es natürlich soweit wie möglich ressourcenschonend sein.
Leider kann ich das selbst nicht beurteilen.
Kann mir jemand von euch zum Ressourcenverbrauch dieser Zeilen etwas sagen bzw., was man besser machen könnte?

PHP-Code:
$benutzername $_GET['benutzername'];
session_start();
if (!isset(
$_SESSION['gezaehlt'])) 
{
    
// Besucher wurde noch nicht gezählt => Counter++
    
$timestamp time();
    
$aufrufurl $_SERVER["HTTP_REFERER"];
    
$sql "UPDATE USERTAB SET Counterstand = Counterstand+1, Aufrufurl = '$aufrufurl', ";
$sql .= "Letzteraufruf = '$timestamp' WHERE Benutzername = '$benutzername'";
    
mysql_query($sql);
    
// Session auf gezaehlt setzen
    
$_SESSION["gezaehlt"] = true;
}
// Counterstand anzeigen
$sql "SELECT * FROM USERTAB WHERE Benutzername = '$benutzername'";
if (
$res mysql_query($sql))
{
    while(
$data mysql_fetch_array($res))
    {
        
$counterstand $data["Counterstand"];
        
$counterlaenge $data["Counterlaenge"];
        
$counterbild $data["Counterbild"];
    }
    
$laenge_akt strlen($counterstand);
    
// Nullen anhängen, damit der Counter die richtige Länge hat
    
for ($n=1$n<=$counterlaenge-$laenge_akt;$n++)
    {
        
$counterstand "0".$counterstand;
    }
    
// Counterbild generieren
    
$masse GetImageSize("http://www.meinedomain.de/digits/$counterbild/1.gif");
    
$breite $masse[0];
    
$hoehe $masse[1];
    
$gesamtbreite $breite*$counterlaenge;
    
$counter ImageCreateTrueColor($gesamtbreite,$hoehe);
    for (
$n=1$n<=$counterlaenge$n++)
    {
        
$ziffer[$n] = substr ($counterstand$n-11);
        
$bild[$n] = ImageCreateFromGif("http://www.meinedomain.de/digits/$counterbild/$ziffer[$n].gif");
        
imagecopymerge ($counter$bild[$n], $xpos000$breite$hoehe100);
        
$xpos $xpos $breite;
    }
}
Header("Content-type: image/gif");
ImageGIF($counter);
ImageDestroy($counter); 
Danke und viele Grüße,

Kai
 
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 16.12.2005, 01:17  
Erfahrener Benutzer
 
Registriert seit: 18.07.2004
Beiträge: 2.162
PHP-Kenntnisse:
Fortgeschritten
Basti
Standard

Hallo Kai.

Ein paar Anmerkungen:

1. Kannst du sicherstellen, dass auf dem Server immer magic_quotes_gpc an ist? Andernfalls kann man ja ganz leicht z.B. alle Counter pro durchlauf hochzählen lassen.

2. Bist du sicher, dass $_SERVER["HTTP_REFERER"] nicht mit Steuerzeichen bestückt werden kann? Müsstest du mal ausprobieren, falls nicht.

3. Anstatt SELECT * nur die Felder auslesen, de du tatsächlich brachst und Indizes verwenden.

4. Anstatt mysql_fetch_array() entweder mysql_fetch_assoc() oder mysql_fetch_row() verwenden.

5. Ist mysqli schneller? Könnte sein, weiß nicht...

6. Für deine Nullen gibt es str_pad().

7. Für die Ziffernmaße ist es vielleicht schonender, diese in eine Info-Datei in das $counter-Bild verzeichnis zu legen. Musst du mal ausprobieren, welche Methode da am schnellsten ist.

8. Die Bilder über HTP ins Skript zu halten ist natürlich Käse!

9. Ich denke mal, du fährst am besten, wenn du die Bilder cachest.

10. Anstatt substr(...) kannst du auch $counterstand{$n} schreiben.

11. Pack die einzelnen Bilder nicht in ein Array, sondern in eine einfache Variable, die du dann jeweils wieder überschreibst beim nächsten Durchlauf. Macht ja keinen Sinn, die zu speichern.

12. Gib doch zuerst das Bild aus und dann aktualisiere die Datenbank.

Keine Ahnung, ob diese Verbesserungen auch nur annähernd relevant sein könnten...

Mir kommt grad die Idee, einfach pro Kunden eine SymLink auf die jeweils nächste, schon zusammengesetzt Ziffer zu sezten. Im Skript gibst du einfach das Bild aus (ganz ohne die gd2-Funktionen) und setzt dann den Link eins weiter, wobei du vorher ggf. die neue Zahl generierst. Wäre sicherlich eine feine Sache, allerdings weiß ich nicht, wie man das Linkziel nur mit PHP herausbekommt.

Nochwas:
Die Session-Lösung ist ziemlich dürftig. Einfach einen Cookie zu setzen ist schneller und hat den gleichen Effekt. Andernfalls müsstest du zumindest probieren, den Benutzer irgendwie wiederzuerkennen.

Basti
Basti ist offline  
Alt 16.12.2005, 10:18  
Erfahrener Benutzer
 
Registriert seit: 13.11.2005
Beiträge: 2.583
xabbuh
Standard

Auch noch eine Anmerkung von mir:
Zitat:
Zitat von Basti
6. Für deine Nullen gibt es str_pad().
Hier würde ich mit dem Attribut MySQL-Spaltenattribut ZEROFILL arbeiten. Dann übernimmt MySQL das auffüllen der Zahl mit 0 selbst.
xabbuh ist offline  
Alt 16.12.2005, 11:56  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Und beim Auswählen des Benutzers per "SELECT * FROM USERTAB WHERE
Benutzername = '$benutzername'" könntest du LIMIT 1 verwenden, denn es
gibt ja nur einen Benutzer (oder etwa nicht?). Das erspart MySQL die Suche
nach weiteren $benutzername'n und ist dadurch erheblich schneller.
Außerdem ist die while-Schleife überflüßig.

Ich weiß nich wie deine GIFs aussehen, aber vielleicht kannst du diese ja
durch CSS ersetzen?
PHP-Code:
<?php
printf
('<span style="height:%upx;width:%upx;background-color:%s;border:1px outset %s"></span>'$hoehe$breite'silver''green');
?>
Zergling-new ist offline  
Alt 16.12.2005, 17:05  
Gast
 
Beiträge: n/a
Standard

Vielen Dank für eure ausführlichen Anworten!! Zu einige genannten Punkten muss ich allerdings erstmal ein bisschen recherchieren, weil ich deren Sinn nicht auf Anhieb verstehe. Melde mich dann wieder, wenn ich schlauer geworden bin...

Viele Grüße,

Kai
 
Alt 19.12.2005, 18:17  
Gast
 
Beiträge: n/a
Standard

@ Basti

Die meisten Punkte sind klar, bei folgenden weiß ich nicht genau, was du meinst:

Zu 8: Welche Alternative gibt es dazu und was ist deren Vorteil?
Zu 9: Könntest du kurz genauer erklären, wie du das meinst?

Vielen Dank und viele Grüße,

Kai
 
Alt 20.12.2005, 00:23  
Erfahrener Benutzer
 
Registriert seit: 18.07.2004
Beiträge: 2.162
PHP-Kenntnisse:
Fortgeschritten
Basti
Standard

Hallo Kai

Zitat:
Zitat von Kaischum
[Bilder über HTTP laden]

Welche Alternative gibt es dazu und was ist deren Vorteil?
Du wirst die Bilder doch auf deinem Server liegen haben. Also kannst du
sie doch einfach über den Dateipfad ansprechen. Es ist ziemlich
übertrieben, für jede Ziffer eines Counters bei jedem(!) Aufruf eine
Anfragedurchs Netz zu jagen. Selbst wenn die Ziffern beim Kunden liegen,
dann reichen zehn Anfragen, um die zehn Ziffern auf deinen Server zu
holen und wenn der Kunde was ändert, soll er halt mit einem Klick
irgendwo eine Aktualisierung deiner Ziffern veranlassen.

Zitat:
[Cacheing]

Zu 9: Könntest du kurz genauer erklären, wie du das meinst?
Es ist doch anzunehmen, dass mehrere Kunden die selben Ziffern und die
selbe Counterlänge verwenden, oder? In dem Fall wäre es doch unnötig,
die Bilder jedes mal neu zusammenzustellen. Leg dir die berechneten
Bilder einfach mit dem Namen der Zahl in den Ordner des Themes und
schau bei den Aufrufen, ob das entsprechende Bild bereits existiert und
erzeuge es nur dann, wenn es eben noch nicht existiert.

Möglich wäre auch, wirklich viele von diesen Bildern im Voraus zu
berechnen und auf den Server zu legen und dann per Cron-Job zu
überwachen. Ist halt dann die Frage, wie schnell die Platte die Daten
ausliefern kann, wenn du ein paar Hunderttausend 1kB-Bildchen drauf
liegen hast.

Ich denke, es gibt unzählige Möglichkeiten, das anzugehen. Eine wäreauch
z.B. folgende:
PHP-Code:
<?php

// get user data
$iUser = (int) $_GET['user'];
$sHits file_get_contents("../stats/$iUser"); // i.e. 12456
list($sTheme$sLen) = explode("\t"file_get_contents("../users/$iUser")); // back_and_white    6

// echo image
header("Content-type: image/gif");
echo 
file_get_contents("../cache/$sTheme/$sLen/$sHits");
flush();

// increase counter
$iHits = (int) $sHits;
$iHits++;

// don't point on not existing files
if (!file_exists("../cache/$sTheme/$sLen/$iHits")) admin_notification();

// write new counter value to users stat file
file_put_contents("../stats/$iUser"$iHits);

// create some new images on buffer underrun
if (!file_exist("../cache/$sTheme/$sLen/" settype($iHits 50'string')))
    
create_next_100_pic(...);
?>
Da gibt es natürlich eine Race Condition, aber in dem Umfang in dem du
das betreibst (unterstelle ich mal) und angesichts des minimalen
Schadens, wenn mal ein Besucher verschluckt wird bzw. angesichts der
Ungenauigkeit durch die Session-Funktion (die hier grad nicht drinnen ist)
und der Manipulierbarkeit ist das eh Wurscht.

Basti
Basti ist offline  
 


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Fehler im Counterskript ? PHP Tipps 2005 23 25.03.2005 13:00
php laufzeit und ressourcenverbrauch überwachen PHP-Fortgeschrittene 14 25.06.2004 15:26

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
getimagesize ressourcenverbrauch

Alle Zeitangaben in WEZ +2. Es ist jetzt 15:29 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum

Creative Commons License
Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.