Plugin der Woche: Personal Blocklist

Google hat für den Chrom Browser dieses Wundervolle Plugin veröffentlicht. Es ermöglicht das Entfernen von Webseiten aus den Suchergebnissen von Google. Jeder kennt nervige Seiten wie Ciao oder Idealo. Nützliche Informationen habe ich dort noch nie gefunden – ich würde sogar soweit gehen solche Seiten als Suchmaschinen-Spam zu bezeichnen. Personal Blocklist bietet eine wundervolle Filterliste. Wenn eine Seite es bis dahin geschafft hat sieht man sie nie mehr in den Ergebnissen von Google. Seeehr schön:)

Der aufmerksame Beobachter sieht den für mich uninteressanten Link zu Idealo

Der aufmerksame Beobachter sieht den für mich uninteressanten Link zu Idealo. Ein Klick auf idealo.de unter dem Eintrag wird Idealo aus zukünftigen Suchen ausschließen. Eventuell muß man die Seite einmal neu laden.

Problem erkannt Gefahr gebannt 🙂

Wer den Button in der Menüleiste nicht mag kann ihn einfach mit einem rechten Mausklick-> Hide Button ausblenden.

Zusammenfassend läßt sich sagen, daß Personal Blocklist ein sehr sinnvolles Plugin ist. Die Handhabung ist genial gelöst, das Ausblenden von Seiten erfordert einen Klick, das Enternen von Seiten maximal 2 Klicks. Die Vorfilterung spart – zumindest bei mir – viel Zeit und Nerven. Was jetzt noch fehlt wären Filterlisten wie bei Adblock Plus 🙂

Download Personal Blocklist (Chrome Webstore)

Rtmpdump #1

Ich besitze zwar einen Fernseher aber kein Rundfunkempfangsgerät. Der Fernseher dient  nur dem Zweck ab und an ein wenig Konsole zu spielen oder mit dem WDTV einen Film zu schauen. Ich schaue mir einmal am Tag die Tagesschau an und würde das auch gerne mal auf meinem eigenen Fernseher ansehen und nicht vor dem Monitor oder bei Bekannten.

Dank der modifizierten Firmware von b-rad kann man ja einiges mit dem WDTV anstellen  und es gibt auch einige Livesender im Internet. Beides zu verbinden hat durchaus seinen Reiz. Leider ist es von den diesen Anbietern ja meist nur angedacht den Stream im Browser mit Flash zu schauen. Bei dem WDTV brauche ich gar nicht an Flash zu denken. Also  muß ich wohl oder übel an den eigentlichen Stream und etwas für die WDTV basteln.

Ab und an hat man das Glück und kommt an eine mms:// Adresse aber  oft ist das leider nicht der Fall. Den Stream von Phoenix kann man sich unter der

mms://live.msmedia.zdf.newmedia.nacamar.net/zdf/phoenix_vh.wmv

konsumieren wenn Phoenix Lust hat den Stream einzuschalten. Ohne solche Urls muß man wohl oder übel einen Blick in den Seitenquelltext (Bitte niemals nie mit Source Code oder Code bezeichnen) der Html Seite schauen. Sehr nützlich ist dabei Firefox und die Adblock Plus Erweiterung.

Dieser Artikel ist primär für mein vergessliches Hirn gedacht. Drum rücke ich hier eine sehr grobe Erklärung wie ich mir das mit dem Streaming vorstelle ein.

Prinzipiell kommt beim Streamingkonsum neben dem Browser noch ein 2. Client ins Spiel. Dabei handelt es sich leider zu oft um den Flash Player. In Html erkennt man ihn an der Endung .swf (Shockwave Flash). Dieser Client verbindet sich mit einem Server  der das Video zum Client bringt.

Wir haben also einen Client im Client. Von daher ist es nicht nur logisch, sondern auch gerecht, daß man die Adresse des Streaming Servers herausfinden kann.   Wenn der Streamingserver eine andere Adresse als der Webserver hat welcher die Seite mit dem Flashplayer hostet ist das meiner/unserer/Eurer Sache mehr als dienlich.

An manche Streams kommt man sehr einfach. Hier ist Adblock+ sehr hilfreich. Man klicke auf das rote Icon und dann auf Blockierbare Elemente anzeigen. Nun ordnet man die Elemente der geöffneten Seite nach der Adresse und schaut sich einfach mal an was da so referenziert wird:  

In der Liste sieht man sehr schön, daß Elemente von 3 verschiedenen Seiten hier gelistet sind. Auf einer dieser Seiten befinden wir uns gerade. Nun schließen wir Google als Quelle aus und natürlich die xml Datei. Die 3. Url übergeben wir einfach mal dem wahren Omnivoren unter den Mediaplayern: mplayer. Der kommt auch direkt damit klar.

Glück gehabt:).

Nun haben wir schon 2 Quellen aus denen wir recht einfach Livestreams abgreifen können und das Thema ist zur 2/3 erschöpft – jedenfalls was mein aktuelles Wissen betrifft. 🙂

Adobe hat sich extra ein proprietäres Netzwerkprotokoll ausgedacht um diese Flashplayer zu bedienen. Das Ganze hört auf den Namen RTMP.

Ich möchte kein Beispiel aus dem Leben zeigen, da ich keine Ahnung habe, ob ich mich da irgendwie strafbar mache.

Bevor man loslegen kann wird das Programm rtmpdump benötigt. Dieses Tool scheint auch aus der Feder der Omnivorenschöpfer zu stammen. Das Teil ist recht einfach gebaut, einzig bei Debian für ARM Plattformen (dazu später mehr) mußte ich explizit die libc6-dev installieren.Das Paket gcc kommt ohne aus. Fachlich korrekt aber irgendwie sinnfrei. 5 Minuten meines Lebens wieder mal mit nichts verschwendet. Wie das auf meinem PC war kann ich nicht mehr genau bestimmen. Doch zurück zu RTMP. Ich wollte einen Stream der vom JW Player abgespielt wird.

Die Bedienung von rtmdump wirkt auf den ersten Blick reichlich schräg – wie alles was mit Multimedia auf der Konsole zu tun hat – ist jedoch recht eingängig wenn man die Readme sorgfältig liest.

Um dem JW Player den Stream abzuringen werden einige Dinge benötigt, die man ausschließlich im Markup findet:

  • die swf Url: http://player.longtailvideo.com/player.swf
  • die Url des RTMP Streams – schaut immer so aus rtmp://<Dein Stream>
  • ein File(file=“) –  immer in der Nähe von rtmp und swf zu finden

Der JW Player möchte noch einen recht dämlichen Handshake bevor der Spaß losgeht. Der sieht so aus:

Zuerst wird die swf Datei heruntergeladen, deren Größe bestimmt und der sha-256 digest des Files bestimmt. Beide Werte müssen wir rtmpdump übergeben.  Ohne diese Argumente gibt es auch keinen Stream :).

Zum Testen bietet es sich an ein Script anzulegen um bequem mit dem Unfug spielen zu können. Bei mir sieht das nun so aus:

#!/bin/bash
name=’arte‘
###SWF url
swfurl=’http://player.longtailvideo.com/player.swf‘
###RTMP
urlrtmpuri=’rtmp://<URL>/‘
##file
file=“
wget -O /tmp/player.swf $flvurl  &>/dev/null
sum=$(sha256sum /tmp/player.swf |cut -d “ “ -f 1)
size=$(ls -l /tmp/player.swf | cut -d “ “ -f 5)
output=$name.flvrtmpdump -V -r $rtmpuri -y $file -s $swfurl -w $sum -x $size -o $output

Die Option -V steigert wie immer die Gesprächigkeit, den Rest kann man der Readme entnehmen. Nun öffnet man einfach den Output von rtmpdump mit mplayer  – in diesem kleinen  Beispiel arte.flv und man sieht hoffentlich einen schönen Stream.

Auf der Projektseite sind ein paar Programme gelistet, die auf rtmpdump aufbauen, doch empfinde ich es immer wieder als nette Erfahrung mir solche Dinge einmal genauer anzuschauen.

Soviel zu meinen Erfahrungen mit Livestreams und rtmpdump. Dieses Intermezzo war recht kurz weil ich noch nicht wirklich viel Ahung von der Geschichte habe. Zum Spaß habe ich mir das Ganze auch mal mit Wireshark angesehen und dabei andächtig über die Entwickler von rtmpdump reflektiert. Über weitere Infos zudem Thema würde ich mich natürlich sehr freuen.

Im nächsten Schritt muß natürlich Bild und Ton auf das WDTV. Ein rudimentäres UMSP Skript habe ich mal erstellt aber noch nichts wirklch Vorzeigbares. Momentan plane ich das Encodieren und Dumpen auf meinem neuen NAS zu erledigen an dem sich dann mehrere Clients bedienen können. Das spart nicht nur Bandbreite im Flaschenhals DSL Anschluss falls mehere Clients darauf zugreifen, sondern reduziert auch grausame WDTV Friemeleien auf ein Minimum.

Nun bleibt mir nur noch zu fragen wie Ihr Streams konsumiert. Schaut Ihr im Browser? oder habt Ihr gar ein schönes Skript um Flash zu umgehen?

Firewall mit reverse ssh Tunnel perforieren

Im „Linuxnetz“ las ich heute einen Artikel über das Erstellen von SSH Tunneln um z.B. sicher zu surfen. Mit der Secure Shell kann man unglaublich viele Dinge tun, darunter auch groben bis gröbsten Unfug. Ein schönes Beispiel dafür möchte ich hier kurz und nicht vollständig aufzeigen.

Ich bin Besitzer eines WDTV. Dabei handelt es sich um einen Multimedia Player um am TV Filme zu konsumieren. Das Gerät besitzt einen Netzwerkanschluss und kann auch Medien aus „Netzwerkfreigaben“ abspielen. Ich verwende eine modifizierte Firmware für das Gerät, auf der ein openssh Server läuft. Nun kann ich mich per SSH auf das Gerät einwählen und z.B. Kommandos wie Stop, Pause oder Vorspulen absetzen. Ein Freund von mir interessierte sich auch für ein solches Gerät und fragte mich, ob er es sich mal ausleihen könne.

Natürlich war das kein Problem für mich. Allerdings reizte es mich schon ein wenig das Gerät aus der Ferne zu steuern. Sprich der Freund schaut zuhause einen Film und ich drücke per ssh auf Pause oder Spule ein wenig vor. Von wegen der böse Geist in der Maschine und so 🙂

Um dies zu erreichen muß ich mit dem WDTV direkt kommunizieren können. Zuhause bewerkstellige ich das mit

ssh wdtv

Durch den Umzug zu meinem Kumpel kamen nun jedoch 2 Router und das Internet zwischen meine Maschine und das WDTV.

Die auf den 1. Blick einfachste Methode sieht so aus:

Um per SSH auf das WDTV zu kommen brauche ich die public IP und eine Portweiterleitung auf das WDTV bei meinem Kollegen. Nicht sehr elegant wie ich finde. Der Schabernack würde auch recht schnell auffliegen wenn ich ihn um beides bitten würde.

Meine Idee war das Pferd von hinten aufzuzäumen. Das WDTV erzeugt einen Tunnel auf meine Maschine über den ich die Kiste besuchen kann :).

In diesem Szenario wird meine IP benötigt und eine Weiterleitung von Port 22 auf meinen Rechner in meinem Netz sowie 2 Kommandos die beim Start des WDTV ausgeführt werden.

Das ist schon eher machbar.

Die Weiterleitung des Ports kann man in jeden 08/15 Router bequem konfigurieren.

Meine „public IP“ (wie lautet die korrekte Bezeichnung dafür?) finde ich immer mit einem netten Alias heraus:

ms@nostromo:~$ alias |grep wieist*

alias wieistmeineip=’curl icanhazip.com‘

Nun muß ich diese Adresse an einem Ort hinterlegen den das WDTV findet. Man könnte die IP in eine Textdatei schreiben und diese per FTP auf einen Gratis-Webspace kopieren. Wer einen Dienst wie DynDns nutzt hat es wohl noch leichter.

Das WDTV muß nachdem es gestartet ist diese IP abfragen und den Reverse Tunnel aufbauen:

ssh  -T  -R 2222:localhost:22 ms@$PUBIP

Wenn das Gerät an ist – und es ist immer an, auch wenn die Anzeige „Betrieb“  nicht leuchtet – kann ich eine SSH Verbindung zu dem Gerät aufbauen:

ssh ms@localhost -p 2222

Abends hatte ich per Fon sichergestellt, daß mein Kumpel einen Film schaut, 20 Minuten gewartet und dann ab und an mal auf Pause gedrückt, Vorgespult oder das Gerät komplett ausgeschaltet und so für Verwirrung gesorgt. Der Freund begann sogar im Internet nach der Ursache für solche Probleme zu recherchieren nachdem ich sagte, daß ich keine solchen Probleme hätte :). Nach 4 Tagen ließ ich den Unfug dann doch bleiben, da es doch Öde wurde.

Kachingle – eine Alternative zu Flattr?

Draußen ist es so warm, dass ich schon gar keine Lust mehr habe vor die Tür zu gehen. Also surfe ich  sinnlos rum und müll den Blog von Grabi voll. Dabei bin ich auf dieses interessante Interview mit der Gründerin von Kachingle gestoßen. Meiner Meinung liest sich das Interview ein wenig wie Eigenwerbung, ist aber dennoch brauchbar.

Das Prinzip ist das ähnlich wie bei Flattr: Ich habe einen Button in meiner Seitenleiste. Wenn nun jemand Freude an meinem Blog hat, klickt er den Kachingle Button. Der geneigte Leser kann dies natürlich auch öfter tun. Am Ende des Monats wird die Einlage des Benutzers gleichmäßig auf die angeklickten Anbieter verteilt.

Das Bezahlmodell ist analog zu Flattr. Im Moment sind nur Zahlungen via PayPal möglich. Momentan kann man nur 5 US$ monatlich einzahlen. Es fallen 15%  Gebühren an (inkl. PayPal). Bei Flattr zahlt man 10% Gebühren exklusive  Kosten für den Bezahldienst. Falls ich mich nicht irre, muß man als Content Erzeuger nichts zahlen. (aufgrund der hohen Temperaturen kann ich mich aber durchaus irren). Schön an der Geschichte ist das transparente Abrechnungssystem. Ich glaube, daß man auch ohne Account Einsicht in die Daten hat. Als Beispiel soll der Benutzer „Jörg Eisfeld-Reschke“ dienen, denen ich zufällig und ohne Absicht ausgesucht habe. Das System kann man sich auch von der anderen Seite anschauen, hier exemplarisch die Statistik von Neunetz.com. Ausgeschüttet werden Beträge ab 3,35 US$

Anbindung: Momentan habe ich ein kleines TextWidget mit JavaScript in der Seitenleiste.

Fazit: Nun ja, das kann ich jetzt schlecht ziehen. Der Dienst sieht interessant aus, Kachinglen kann ich noch nicht, da mein PayPal Konto mal wieder leer ist und ich eben erst auf der Bank war zum Überweisen. Am Ende des Monats werde ich mal wieder was drüber schreiben. Bis dahin wünsche ich Euch viel Freude in der Hitze:)

Minikamera MD80 aus China

minikamera

Am 9. Juni dieses Jahres habe ich beschlossen mir die Kleinstkamera MD80 zuzulegen. Auslöser war dieses Video, auf das ich irgendwie beim „Sinnlos-Surfen“ gestoßen bin. Sehr interessant waren die Preisunterschiede. Bei Amazon kostet die Kamera 100€ . Bei Ebay gibts das schöne Teil für  3,98€ zzgl.6,99€ Porto – aus China. Da ich keinerlei Interesse daran hatte, einen Kapitalismusaufschlag von 89,03€ zu zahlen, orderte ich  direkt bei den Kommunisten.

Abgesehen davon wollte ich schon immer mal was  aus China bestellen 🙂

Mein freundlicher Freund Hannes orderte den Artikel, da ich nicht im Besitz eines Ebayaccounts bin und Angst vorm deutschen Zoll habe.

Sie haben eine Zahlung über 10,97 EUR an 傅清清  gesendet.

Trotz aller Unkenrufe, das ich das Gerät im besten Falle an Weihnachten habe, kam sie schon gestern an.

Im Lieferumfang enthalten waren zahlreiche nützliche Halter für die Kamera, eine Installations CD (nicht angesehen), Mini USB Kabel, chinesisches Handbuch (von vorne bis hinten durchgelesen) sowie ein Netzteil um das Gerät über Steckdose zu laden. (Natürlich kein Schukostecker).

Die Halter sind wirklich super.

  • Nr.1 läßt sich mit Kabelbindern oder Schrauben befestigen,
  • Nr. 2 hat eine Klammer für die Montage an Textilien.
  • Nr.3 hat einen Magneten um die Kamera an metallischen Oberflächen zu montieren.

Hier noch ein paar weitere technische Daten:

  • Aufnahmequalität: 2 Mega Pixel / Farbe CMOS
  • Aufnahmewinkel: 62°
  • Lichtempfindlichkeit: 1Lux (min)
  • Speichermedium: Micro SD Max. 8GB Micro SD
  • Videofunktion und Format: JPEG, AVI format VGA(640 x 480 / 30 Bilder/sec.)
  • Gewicht: 50g * Größe: 55 x 28 x 20 mm
  • Speicherverbrauch: 1GB per 40 min * Aufladezeit: 2h * Standby Zeit: 260h

Angeblich kann das Gerät bis zu 2h aufzeichnen. Da ich momentan nur eine 1GB SD Karte besitze, konnte ich das noch nicht testen.

Bemerkenswert war auch die Verpackung. Die Schachtel sieht aus wie mit einem Tintenstrahldrucker bedruckt un trägt den Titel „World’s smallest voice recorder“. Kamera und Zubehör waren nicht in die entsprechenden Halterungen geklipst, sondern flogen einfach darin rum. Nicht toll, aber besser als die unmöglichen USB-Stick Verpackungen, die nur mit dem Messer zu öffnen sind.

Das Gerät ist für Menschen mit großen Fingern schwierig zu bedienen. Die Speicherkarte konnte ich nur mit einem Schraubenzieher zum Einrasten bewegen. Auch sind die Knöpfe  konstruktionsbedingt recht klein.

Das Gerät hat 3 Betriebsmodi:

  • normale Aufnahme
  • Webcam (hab ich unter Linux noch nicht zum Laufen bekommen, da merkwürdiger Chip)
  • Sound Control (Kamera zeichnet auf, wenn Umgebungsgeräusche > 60 DB vorhanden).

Für den interessieren hier noch ein deutschsprachiges Handbuch im PDF Format.

Wenn Ihr das Gerät via USB mit dem Rechner verbindet, habt Ihr man Zugriff auf die Micro SD Karte.

Was mich momentan noch sehr stört ist der Zeitstempel im Bild. Ich habe noch nicht herausgefunden, wie ich den entfernen kann.

Hier mal ein 1. Test der Kamera. Da ich seit heute morgen um 2 Muttermale ärmer bin, wurde nicht mit dem Fahrrad gefilmt.   Befestigt wurde die Kamera mit Halter #1  unter dem Nummernschild meines Autos. Ich habe die Kamera zusätzlich mit einem Kabelbinder im Halter befestigt. 6:53 Minuten Film  benötigen 576 MB auf der SD Karte.

Das Video wurde mit Avidemux konveritert (Schnelleinstellung FLV).

http://www.youtube.com/v/eWg1xH556fU&hl=de_DE&fs=1?rel=0

Ich finde, daß die Kamera für 11 € ein recht gutes Bild liefert.  Wenn ich weitere Informationen oder Nützliches zu der Kamera finde, werde ich diesen Artikel aktualisieren. HF^^

Nachtrag:

Durch Mike habe ich erfahren, daß das beiliegende USB Kabel unbrauchbar ist. Sowohl bei mir als auch bei ihm konnte die Kamera nicht damit geladen werden.

Und noch einmal:

Zeitstempel im Bild bearbeiten und / oder entfernen

Der Peer fand heraus, dass es ein sehr nützliches Tool zum Stellen der Uhr gibt. Unter Linux läuft das Tool mit Wine leider nicht.

Dank einer kleinen Recherche auf dieser Seite weiß ich nun, daß ich eine Kamera des Typs 3 habe. Wie das Datum per Textdatei eingestellt wird kann man ausführlich auf der Seite nachlesen.

Im Schnelldurchlauf gehts so:

schmiddi@schmiddi-laptop:/media/60E7-215B$ echo  [date] 2009/12/29 16:58:00 >tag.txt
schmiddi@schmiddi-laptop:/media/60E7-215B$ sync
Kamera vom PC trennen, Aus und Einschalten tadaaa dann müßte es gehen. Die Datei tag.txt wird von der Kamera automatisch gelöscht.
Den Pfad müßt ihr bei euch anpassen. Das Entfernen des Timestamp ist mir bis jetzt leider nicht gelungen. Chuck Lohr  meint auf seiner Seite, daß man bei meinem Modell die Timestamp nicht deaktivieren kann :(. Einen schönen Vergleich der Kameras gibts auch bei Cuck.
Für Virtual Dub gibts einen Filter, der die Timestamp entfernen kann. Logoaway nennt sich das Ganze und es scheint recht ordentlich zu klappen

http://www.youtube.com/v/feQU98TzyzY?fs=1&hl=de_DE

Der Windows Fraktion ist nun geholfen. Leider gibts Virtual Dub nicht für Linux und Avidemux kommt mit dem Filter zurecht. Verdammte Axt! Ich werd mir jetzt mal ein paar Gedanken machen. Erfolge und Niederlagen werde ich wie immer hier niederschreiben

Mal was sehr lustiges

„The National Poetry Contest had come down to two semifinalists
A Yale graduate and a redneck from Montana.

They were given a word,
then allowed two minutes to study the word and come up with a poem that contained the word.
The word they were given was „Timbuktu.“

First to recite his poem was the Yale graduate.
He stepped to the mike and said

Slowly
across the desert sand
Trekked
a lonely caravan
Men on camels,
two by two
Destination – Timbuktu.

The crowd went crazy.
No way the redneck could top that, they thought.
However, the redneck calmly took his place on the stage and recited

Me and Tim
a huntin went
Met three whores
in a pop-up tent
They was three
and we was two
So I bucked one,
and Timbuktu.

Schneller zu validem Html mit Ubuntu und Eclipse

Tree on Monument Hill
Attribution-NonCommercial-NoDerivs License by zachstern

Valides Html ist wichtig – keine Frage. Leider ist der Weg dorthin oft beschwerlich, vor allem, wenn man wie ich eher selten damit arbeitet. Für größere PHP Sachen verwende ich Eclipse für „PHP Menschen“.  Wenn nun irgendwas mit meinem Html nicht stimmt, bekomme ich meist so ein kleines Ausrufezeichen, jedoch nicht immer.

phpnwe7CH

Deswegen bemühe (bemühte) ich häuft den Validator der W3C Seite, der endgültige Gewissheit über das Markup verschafft. Da ich meist lokal arbeite und auch nicht  Dyndns oder ähnliches verwenden möchte, hat sich das „Debuggen“ mit dem Validator immer in eine Copy & Paste Orgie verwandelt. Ein wenig Lesen auf der W3C Seite brachte mir diese schöne Erkenntnis:

All software developed at W3C is Open Source / Free software. Which means that you can download and use them for free, if you like. It also means that you are welcome to participate in making them better, cooler, more useful for you and everyone.

Juhu. Schnell stand fest, daß es da auch ein Ubuntu Paket namens w3c-markup-validator im Repository gibt. Nach der Installtion muß man  in der Datei /etc/w3c/validator.conf noch die Option Allow Private IPs auf yes setzen. Den Validator erreicht man unter http://localhost/w3c-markup-validator. Sehr schön.

Um den Validator bequem mit Eclipse zu nutzen, werden noch 5 Minuten Rumklicken benötigt. Mir reicht es, wenn ich per Mausklick die aktuelle Seite validieren kann. Dazu konfiguriere ich unter Run->External Tools->External Tools Configuration den Browseraufruf. Zu beachten wäre hierbei, daß der absolute Pfad zum Programm angegeben werden muß. (Ich verwende Chrome. Firefox findet man unter /usr/bin/firefox)

Hier der Screenshot des Fensters mit meinen Einstellungen:

phpo16zCr

Im Reiter common sollte man noch das Häckchen bei  „Allocate Console“ rausnehmen und „Launch in Background“ setzen.

Nun kann man bequem per Mausklick validieren:

phpjls8gg

Zum Ende bleibt nur noch zu fragen, wie Ihr euren HTML Krams validiert. Meine Lösung ist zwar relativ einfach, aber simpler gehts – finde ich –  immer 🙂

Geekstuff von 3Dsupply

Jeder der im IT Umfeld herumläuft kennt diese coolen „Geek-Shirts“. Auf dem Blog von Christoph Grabmer bin ich auf die äußerst nette Aktion Shirt4Link gestoßen: Wenn man einen netten Artikel über 3D Supply schreibt und der Blog die Bedingungen erfüllt, bekommt man ein gratis T-Shirt. Ich versuche mal mein Glück. Die Wahl fällt leider schwer bei so vielen coolen Motiven, also hab ich spontan was mit Bezug auf mich ausgewählt:

Persistenz und Reflexion mit PHP

City Refraction, City Reflection
Attribution License by lrargerich
Reflexion oder Introspektion bedeutet dass ein Objekt seine eigene Struktur kennt und diese Modifizieren kann.
Sehr praktisch ist dies, wenn es um Typsicherheit oder die Persistenz von Daten geht. PHP stellt dafür die Klasse ReflectionClass zur Verfügung. Ich möchte hier beschreiben, wie man mit Reflexion die Typen und Werte von Attributen auslesen kann, um diese z.B. persistent zu halten.
Zuerst ein Beispiel für Reflexion:

class ReflectionExample{
	protected $attribute1;
	protected $attribute2;
	protected $attribute3;
	public 	  $attribute4;

	public function method1(){}
	public function method2(){}

	public function __construct(){
		Reflection::export(new ReflectionClass($this));

	}
}//class
$reflect = new ReflectionExample();

Die Ausgabe:

Class [  class ReflectionExample ] {
  @@ /home/schmiddi/web/gloria2/Reflection.php 8-21

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [4] {
    Property [  protected $attribute1 ]
    Property [  protected $attribute2 ]
    Property [  protected $attribute3 ]
    Property [  public $attribute4 ]
  }

  - Methods [3] {
    Method [  public method method1 ] {
      @@ /home/schmiddi/web/gloria2/Reflection.php 14 - 14
    }

    Method [  public method method2 ] {
      @@ /home/schmiddi/web/gloria2/Reflection.php 15 - 15
    }

    Method [  public method __construct ] {
      @@ /home/schmiddi/web/gloria2/Reflection.php 17 - 20
    }
  }
}

Wie man sieht bekommt man jegliche Information über die Klasse geliefert. Ich möchte wie gesagt Daten bequem in einer Datenbank speichern, bearbeiten oder löschen. Der funktionale oder „PHP Tutorial“ Weg sähe so aus, dass man für jedes Objekt / Aspekt der PHP Seite die SQL Befehle INSERT, UPDATE und DELETE schreibt. Das ist nicht nur sehr Aufwändig, sondern benötigt auch große Aufmerksamkeit, wenn Attribute oder Variablen wegfallen oder neue hinzukommen.

Schauen wir uns noch einmal das Anfangsbeispiel an, um ein kleines Problem mit der Reflection Class zu verdeutlichen:

reflect

Die Klasse Reflect liest die Attribute der erbenden Klasse ReflectMe ein und macht eine Ausgabe:

abstract class Reflect{
	private $types = array();
	private $values= array();
	private $parentAttribute ;
	protected  $parentAttribute2;
	public function getAttributes(){
		$reflection = new ReflectionClass($this);
		$types=$this->types;
		$values=$this->values;
		foreach ($reflection->getProperties() as $key ){
			$value=str_replace("$",' ',$key->name);
			$type =  gettype($this->$value);
			$types[$key->name] = gettype($this->$value);
			$values[$key->name] = $this->$value;
			echo gettype($this->$value).
				" {$key->name} {$this->$value}
";
		}//each
	}//getAtrributes
}//class

Die Kindklasse ReflectMe hat nur ein paar Attribute die ich ausgeben möchte:

class ReflectMe extends Reflect{
	protected $child_attribute1= "Hallo Otto";
	protected $child_attribute2= 3.1415;
	protected $child_attribute3= 1337;
	private	  $child_attribute4= array();

	public function method1(){}
	public function method2(){}

}//class

$reflect = new ReflectMe();
$reflect->getAttributes();

Ein Blick in die Ausgabe verdeutlicht 2 Probleme:

string child_attribute1 Hallo Otto
double child_attribute2 3.1415
integer child_attribute3 1337
NULL parentAttribute2
Fatal error: Cannot access private property ReflectMe::$child_attribute4 in /home/schmiddi/web/gloria2/Reflection.php on line 30

Die ReflectionClass kann nicht auf private Attribute der Kindklasse zugreifen. Für meinen Geschmack ist dieser Grad der Kapselung ein wenig übertrieben. Mit Version 5.3 von PHP wird die Methode ReflectionMethod::setAccessible eingeführt, die den Zugriff erlaubt. Ein weiteres Problem wäre, dass wir auch die protected Werte der Elternklasse bekommen, da diese ja vererbt werden. Dies kann man Umgehen, indem man die Attribute von Reflect private deklariert. Damit schießt man sich jedoch in Sachen Vererbung ins Bein. Eleganter ist es die Elternklasse ebenfalls zu „reflektieren“ und die Schnittmenge der beiden Reflektionen zu entfernen:

/* ... */
	public function getAttributes(){
		//neues ReflectionObject für die Eltern Klasse erzeugen
		$reflectParent = new ReflectionClass(__CLASS__);
		$parentTypes=array();
		//Attribute in ein Array speichern
		foreach ($reflectParent->getProperties() as $key)
			$parentTypes[$key->name] = gettype($this->value);

		$reflection = new ReflectionClass($this);
		$types=$this->types;
		$values=$this->values;
		foreach ($reflection->getProperties() as $key ){
	//nur die Attribute der erbenden Klasse in die Array's schieben
			if(!array_key_exists($key->name, $parentTypes)){
				$value=str_replace("$",' ',$key->name);
				$type =  gettype($this->$value);
				$types[$key->name] = gettype($this->$value);
				$values[$key->name] = $this->$value;
				echo gettype($this->$value).
					" {$key->name} {$this->$value}
";
			}//if
		}//each
	}//getAtrributes

Nun können wir die Attribute der Klasse bequem auslesen, es sei denn sie sind als private deklariert. Für mein Skript möchte ich nicht PHP 5.3 voraussetzen, entsprechend muß darauf geachtet werden, dass nur gespeichert werden kann, was public oder protected ist.
Nun ist alles beisammen, was einen ordentlichen SQL Befehl ausmacht.
Zur Sache also:

private function generateInsertCommand(){
	$this->getAttributes();
		if ($this->insertCommand!=null)
			return $this->insertCommand;

		$classname =  $this->childClassName;
		$values = $this->attributeValues;

		$sql ="
		INSERT INTO  $classname (";
		$counter = 0;
		$count = count($this->attributeValues);
		foreach ($values as $key =>$value){
			$counter+=1;
			$sql.=$key;
			if($counter $count)
				$sql.=',';
		}
		$sql.=")VALUES (";
		$counter = 0;
		foreach ($values as $key =>$value){
			$counter+=1;
			$sql.='?';
			if($counter $count)
				$sql.=',';
		}//each

		$sql.=");";
		$this->insertCommand = $sql;
		return $this->insertCommand ;
	}//function

Die counts sind zwar nicht sehr schön, aber ich brauche sie für die Klammern. Wenn ich mal wieder ein wenig Zeit habe, stelle ich vielleicht den ORM Mapper hier vor.