Artikel verknüpft mit 'php':
Link 29.04.11, 23:18:22

Benachrichtigungsfunktion

Ich hab mal wieder etwas an meinem zusammengeschusterten Blogsystem gewerkelt und ein viel gewünschtes Feature implementiert, nämlich die Benachrichtigung per Mail bei neuen Kommentaren.

Bildschirmfoto von Benachrichtigungsfunktion

Falls ihr also nicht jeden Tag meinen Blog aufrufen wollt nur um festzustellen, dass der doofe Blogger noch gar nichts zu eurem Kommentar geschrieben habt, hinterlasst einfach eine Email-Adresse beim Schreiben eines Kommentars. Aber nur, wenn ihr eine Benachrichtigung wollt. Ich verzichte ausdrücklich auf die Angabe einer Email-Adresse, macht das nur wenn ihr Mails bei darauf folgenden Kommentaren haben wollt, sonst werdet ihr unweigerlich welche bekommen.
Email angeben ⇒ Benachrichtigungen, kapiert?

Gut. Was gibt es sonst noch zu sagen? Achja, ihr findet in den Mails selbstverständlich einen Link um diese Funktion zu deaktivieren. Diese Deaktivierung gilt jedoch nur für einzelne Blogposts.
Wichtig ist noch, dass es genügt bei mehreren Kommentaren zu einem Eintrag nur einmal eine Email-Adresse anzugeben. Sonst bekommt ihr doppelt und dreifach Mails.

Ich hoffe zwar es gibt keine Bugs mehr, aber falls irgendwelche Probleme auftreten sollten sagt mir Bescheid, ich werde mich darum kümmern. Vielleicht.

tags:#blog #php #update


Link 15.02.11, 20:37:38

Ein simpler Cache mit PHP

Der Sinn von Caches
Caches kommen immer dann zur Anwendung, wenn ein hoher Aufwand für das Neu-Generieren von Inhalten vermieden werden soll. Einen Cache kann man also als Zwischenspeicher bzw. Puffer für Daten, die bereits einmal vorlagen verstehen, der beim nächsten Aufruf verwendet wird, um die Daten schneller zur Verfügung zu stellen.

Beispiele finden sich in diversen Anwendungen (v.a. in Browsern wäre ein Fehlen undenkbar), bei Festplatten, Prozessoren und auch bei (nicht statischen) Webseiten. Zur letzteren Art gehört auch mein Blog, der sich die Inhalte bisher bei jedem Seitenaufruf aus meiner MySQL-Datenbank geholt hat. Das ist sehr rechenzeitlastig, da immer beim Aufruf meines Blogs mehrere SQL-Abfragen ausgeführt werden müssen. Außerdem würde sich ein Cache besonders für viel aufgerufene Seiten rentieren.
Also habe ich mich hingesetzt und eine Art Puffer in meiner Blogsoftware implementiert.

Die Funktionsweise
Grob zusammengefasst tut mein Cache folgendes: Beim Aufruf einer Seite mit einem bestimmten GET-Parameter wird eine Funktion aufgerufen, die die URL der aufgerufenen Seite ausliest. Die Funktion holt sich die generierte Ausgabe der Seite, also das Ergebnis der SQL-Abfragen, und speichert diese in einer nach der Seite benannten Textdatei ab. Wenn anschließend ein Seitenaufruf stattfindet, wird von nun an nicht mehr die Datenbank bemüht, sondern der komplette Inhalt der Textdatei ausgegeben. Das ist wesentlich performanter und verkürzt die Ladezeiten.

Die Grundlage, also das Speichern der generierten Inhalte einer Seite, bieten die Funktionen der PHP-Ausgabepufferung:
function cache_schreiben() { $datei = fopen("cache/".preg_replace("/([&\?]cache=)([^&^\"]+)/i","",$_SERVER[REQUEST_URI]).".cache","w+"); $file=ob_get_contents(); fwrite($datei, $file); fclose($datei); }
Das ist die Funktion, die den PHP-Buffer ausliest und den Inhalt in eine Datei schreibt. Mit dem regulären Ausdruck wird der GET-Parameter „cache“ ausgefiltert, der lediglich dazu zuständig ist die Erneuerung des Caches zu bewirken. Möglicherweise muss vorher noch die Ausgabebufferung aktiviert werden, bei mir ist das nicht der Fall.
$datei="cache/".preg_replace("/([&\?]feed=)([^&^\"]+)/i","",preg_replace("/([&\?]cache=)([^&^\"]+)/i","",$_SERVER[REQUEST_URI])).".cache"; if(!isset($_GET['cache']) AND file_exists($datei)) { $datei=fopen($datei, "r"); while (!feof($datei)) { $buffer = fgets($datei, 4096); echo $buffer; } die; }
Diese Abfrage sollte am Anfang der Seite eingebaut werden. Die Textdatei wird, wenn sie existiert und der GET-Parameter nicht gesetzt ist, ausgelesen und der Inhalt ausgegeben. Jetzt muss nur noch festgelegt werden, was passiert wenn die Datei nicht vorhanden ist oder der Parameter an die URL angehängt worden ist:
if (!file_exists($datei) OR $_GET['cache']==1) { cache_schreiben(); }
Fertig!

tags:#php #programmierung #web


Link 24.01.11, 22:19:20

Gefragt: Problemlösendes Denken

Als treue Leser kennt ihr sicherlich mein Archiv, erreichbar über einen Klick auf „Alle Einträge“ gaaaaaanz unten auf der Startseite. Natürlich kennt ihr es. Ganz besonders treue Leser kennen natürlich auch den Inhalt des Archivs auswendig, aber das tut hier nichts zur Sache.

Jedenfalls wollte ich das Ding gestern ein bisschen ansprechender gestalten.
Für alle die von Design keine Ahnung haben: Eine ÜBER 9000 Scrolleinheiten (Einheit hab ich gerade erfunden) lange Liste von Blogeinträgen ist nicht ansprechend gestaltet.

Deswegen kam ich auf die tolle Idee doch die einzelnen Blogposts zu den jeweiligen Monaten und Jahren zu gruppieren, damit da wenigstens ein bisschen Ordnung reinkommt. Da stand ich dann erstmal vor der Frage, wie ich das per PHP und MySQL bewerkstelligen sollte. (Jaja, PHP ist kacke, benutz doch Brainfuck/Perl/Java/Assembler das ist hundertmal besser, ich weiß, ich weiß.)

Letztendlich bin ich dann auf eine Lösung gekommen — sonst wäre das Archiv jetzt nicht so übersichtlich gestaltet :) —, aber ich möchte wissen ob ihr nicht eine bessere als die folgende Lösung habt. Und zwar läuft das ganze momentan so ab:

Mit Hilfe einer SQL-Abfrage bekomme ich alle Daten heraus die ich zum Anzeigen der Blogposts wissen muss, also Titel, Datum, Tags, usw. Danach wird während der Ausgabe überprüft ob der Name des Monats, den ich aus dem Datum extrahiere mit dem Namen des Monats des vorherigen Elements aus der Datenbank übereinstimmt:// Ausgabe des Monatsnamen wird auf Deutsch umgestellt setlocale(LC_ALL, "de_DE"); //gekürzte Datenbank-Abfrage $abfrage = "SELECT Datum, Titel, ID FROM weblog ORDER BY id DESC "; $ergebnis = mysql_query($abfrage); while($row = mysql_fetch_object($ergebnis)) { if (date("Y",$row->datum)!=$jahr_davor) { echo "<h2>".date("Y",$row->datum)."</h2>"; } if (strftime("%B", $row->datum)!= $monat_davor) { echo "<h1>".strftime("%B", $row->datum)." ".date("Y",$row->datum)."</h1>"; } $jahr_davor=date("Y",$row->datum); //strftime benutzen, sonst werden die Monatsnamen nicht korrekt ausgegeben $monat_davor=strftime("%B", $row->datum); // Code gekürzt, hier kommt noch anderes Zeug } Dann wird noch der Name des Monats in die Variable $monat_davor gespeichert, um das dann im nächsten Durchlauf vergleichen zu können. Mit der Ausgabe der Jahreszahl ist es das gleiche. Einfach mal auf der Archiv-Seite anschauen, dann bekommt man schnell einen Überblick.

Meine Frage an euch ist jetzt aber: Kann man das schöner/besser/schneller lösen? Ich hab da zuerst an eine Lösung per "GROUP BY" und Kreuzanfragen mit MySQL gedacht, bin aber auf kein Ergebnis gekommen. Vielleicht würdet ihr es ja auch nicht anders als ich machen, mir egal, sagt mir was ihr davon haltet.

Verbesserungsvorschläge zur weiteren Gestaltung des Blog-Archivs sind ebenso gerne gesehen.
Mal unter uns: Das Archiv habt ihr noch nicht gekannt, oder? :P

tags:#php #programmieren #blog


Link 23.12.10, 20:54:17

Verbesserungen am Blog

Da mir in letzter Zeit ein wenig langweilig war, habe ich ein paar Verbesserungen in mein selbstgeschriebenes Blog-System eingebaut.

Jetzt wird nämlich endlich richtig angezeigt, wenn per URL eine ID mitgegeben wird, zu der (noch) kein Blogpost existiert. Ich weiß noch, dass ich damals bei der Programmierung des Grundgerüsts blöderweise keine Idee hatte, wie ich das implementieren sollte. Geht aber ganz einfach und kann man hier nachlesen.
Beispiele: nicht existenter Blogpost und nicht existenter Kommentar

Als zweites habe ich das Kommentarsystem in Angriff genommen, und das Eintragen eines neuen Kommentars so realisiert, dass es auf einer einzigen Seite stattfindet und man nicht wie bisher auf eine extra Seite weitergeleitet wird. Ich denke das vereinfacht den Vorgang doch wesentlich. Ausprobieren kann man das durch Abgeben eines Kommentars, beispielsweise unter diesem Blogpost.

Endlich konnte ich mich auch dazu aufraffen individuelle Fehlerseiten zu erstellen. Davor wurde bei einem Fehler (z.B. einen 404er) auf die Fehlerseite meines Hosters bplaced weitergeleitet. Ab heute bekommt man jedoch einen hilfreichen Text über Superhelden und ein passendes Bild dazu zu sehen.
Beispiele: Momentan habe ich nur die wichtigstens und häufigsten HTTP-Statuscodes abgedeckt, d.h. 401, 403, 404, 410, 500. Außerdem hab ich auch den eigentlich für ein Kaffeemaschinen-Protokoll gedachten Fehlercode 418 eingebaut. :8

tags:#blog #php #website


Link 24.10.10, 21:12:32

Spamkommentare per Zeitmessung erkennen

Vor kurzem habe ich mich ja schon darüber aufgeregt, dass Spambots meinen Blog heimsuchen und wollte wissen wie und warum. Dazu habe ich dann erstmal den Spamschutz ausgeschaltet, um zu schauen, wie viel Spam hier so täglich aufschlägt. Der Spamschutz funktionierte im Grunde genommen so:
Ein per CSS verstecktes Formularfeld darf nicht ausgefüllt werden, sonst wird der Kommentar nicht akzeptiert. Die meisten Bots befüllen nämlich automatisiert jedes Formularfeld mit ihrem Gebrabbel und sind dadurch dann identifizierbar. Dieses Eingabefeld ist natürlich sinnvoll benannt, so dass die Roboter nicht bemerken, dass es sich hierbei um eine Falle handelt. Neuerdings funktioniert dieser Spamschutz leider nicht mehr so recht, da wohl eine andere Art von Bot auf meine kleine Seite aufmerksam geworden ist. Diese agiert aus irgendwelchen Gründen schlauer im Befüllen von Eingabefeldern und rutscht somit durch den Filter.
Jedenfalls musste ich mir eine neue Methode suchen, um unerwünschte Kommentare im Voraus zu erkennen und nicht in die Datenbank einzutragen, damit ich sie dann manuell löschen muss. Die hab ich dann auch gefunden:
Diese Strategie beruht darauf, dass Bots — im Gegensatz zu menschlichen Benutzern — nicht eine halbe Ewigkeit brauchen um ein lächerliches kleines Formularfeld auszufüllen und abzuschicken. Also muss man nur irgendwie herausfinden, wie lange der Zeitraum zwischen dem Laden der Seite mit dem Formular und dem Abschicken desselbigen ist. Dazu empfiehlt es sich den Zeitpunkt des Seitenaufrufs in ein verstecktes Formularfeld schreiben, beim Absenden zu übergeben, um ihn dann mit der aktuellen Uhrzeit zu vergleichen. Danach muss noch überprüft werden, ob die benötigte Zeit typisch für einen Bot ist oder nicht, und dementsprechend gehandelt.
So sieht das verstecke Eingabefeld aus:

<form action="example.php" method="post"> <input name="zeit" type="hidden" value="<?php echo time(); //Hier wird die Zeit gespeichert ?>" readonly> <input type="submit" value="Abschicken" > </form>
Das "readonly" stellt sicher, dass der Benutzer den Wert des Feldes nicht verändern kann, "type="hidden"" versteckt das Feld, damit es nicht nervt.
Jetzt muss lediglich noch ausgewertet werden, wie groß die verstrichene Zeit zwischen Aufruf und Absenden ist.

example.php:
<?php $posted = $_POST['zeit']; if (isset($posted) && is_numeric($posted)) { //überprüfen ob der Wert eine Zahl ist $sendezeit = (time() - $posted); //verstrichene Zeit if ($sendezeit < 10 || $sendezeit > 36000) { //weniger als 10 Sekunden oder mehr als 10 Stunden? //10 Stunden deshalb, weil manche Bots auch extrem zeitverzögert absenden $text = "Gerade wurde der Kommentar in $sendezeit Sekunden zugespammt"; mail('admin@example.com', 'Abgewehrter Kommentarspam', $text); //Extra-Gimmick: Bei abgewehrtem Spamversuch E-Mail versenden die("Du hast das Formular zum Kommentieren in weniger als 10 Sekunden ausgef&uuml;llt, das ist ziemlich schnell.<br> Deswegen bist du vermutlich ein Bot und kein Mensch. Bots sind hier nicht erw&uuml;nscht. Menschen schon. Falls du kein Bot bist gehe bitte eine Seite zur&uuml;ck und warte ein paar Sekunden, so dass meine Automatisiertekommentarabsenderdetektiermaschine nicht anschl&auml;gt. Danke :) //Abbruch + Fehlermeldung, damit menschliche Besucher mit schnellen Fingern nicht vor einem Rätsel stehen } } //Wenn der Kommentar kein Spam ist geht es hier ganz normal weiter und die Daten werden in die DB eingetragen //... ?>
Diese Methode habe ich jetzt mit der "Verstecktes-Eingabefeld-Methode" kombiniert und bereits einige Spamversuche erfolgreich durchkreuzt. Wenn mich die vielen Mails irgendwann nerven sollten schalte ich die Funktion ab :)

tags:#spam #blog #php


Link 30.12.09, 21:20:11

Blogroll mit PHP

Mal ein bisschen Web 2.0 hier reinbringen, denn zu jedem Blog gehört eine Blogroll(e). Ich hab das eben mal mit PHP und MySQL implementiert. Als Erstes muss eine neue MySQL-Tabelle angelegt werden, die so aussieht:

CREATE TABLE IF NOT EXISTS `blogroll` (

  `ID` int(150) NOT NULL auto_increment,

  `URL` varchar(150) NOT NULL,

  `NAME` text NOT NULL,

  PRIMARY KEY  (`ID`)

) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=16 ;


Die entstandene Tabelle muss dann noch mit Blogs und deren URL befüllt werden. Jetzt gehts ans PHP-Skript:
Code bei pastebin.com ausgelagert
Das Skript kann man jetzt auf einer beliebigen Seite einbinden und die Anzahl der zufälligen Links kann natürlich im Skript verändert werden.
tags:#php #coding #blog


Link 27.08.09, 11:28:29

Kommentare...

Viel Spaß beim Kommentare schreiben!
Aber bitte nicht spammen, flamen oder sonstige Scheisse machen. Smiley Solche Kommentare haben sowieso keine Chance, da sie erst manuell von mir freigeschaltet werden müssen.
Hoffentlich ist euch der neue Header schon aufgefallen, Kritik bitte als Kommentar unter diesen Artikel schreiben, danke.
Wenn ihr mögt könnt ihr auch den Addthis Button unter jedem Blogpost verwenden, welcher zahlreiche Möglichkeiten anbietet den Eintrag als Lesezeichen zu setzen.
Ich freue mich über Feedback,
ucn|

tags:#blog #php #web 2.0


Link 15.07.09, 21:57:18

Gute Neuigkeiten!

Die Kommentarfunktion macht Fortschritte! Tatsächlich hab ich mich hingesetzt und wenigstens schonmal begonnen.
Ihr dürft zuversichtlich sein!

tags:#blog #php #


Link 12.07.09, 21:44:25

Schulhaustour und YALM Artikel

So ich sitze hier grad und sortiere Bilder auseinander, die irgendjemand in unserer Schule gemacht hat. So weit so gut, muss ich wenigstens selber keine machen, aber: Einige Bilder sind doppelt, andere aus einer total beschissenen Perspektive geschossen, verwackelt, und das Schlimmste ist ich muss die alle noch einer bestimmen Stelle auf dem Plan zuordnen.
Ich bin mit dem Erdgeschoss fast fertig. Aber trotzdem muss ich selber noch welche machen, aber ein bisschen strukturierter und organisierter.
Achja, meine Fortschritte können hier bewundert werden.
Übrigens, mein Artikel für YALM ist fertig, vermutlich kommt er schon in die nächste Ausgabe. Jetzt such ich nur noch nach einer Idee für einen weiteren Beitrag.
so long, ucn|

tags:#schule #php #yalm