Flash CS3, AJAX und PHP
Flash CS3, AJAX und PHP Uwe Mutz
ADDISON-WESLEY Ein Imprint von Pearson Education München • Boston • San Francisco • Harlow, England Don Mills, Ontario • Sydney • Mexico City Madrid • Amsterdam
Bibliografische Information Der Deutschen Bibliothek Die Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.ddb.de abrufbar. Die Informationen in diesem Produkt werden ohne Rücksicht auf einen eventuellen Patentschutz veröffentlicht. Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt. Bei der Zusammenstellung von Texten und Abbildungen wurde mit größter Sorgfalt vorgegangen. Trotzdem können Fehler nicht vollständig ausgeschlossen werden. Verlag, Herausgeber und Autoren können für fehlerhafte Angaben und deren Folgen weder eine juristische Verantwortung noch irgendeine Haftung übernehmen. Für Verbesserungsvorschläge und Hinweise auf Fehler sind Verlag und Herausgeber dankbar. Alle Rechte vorbehalten, auch die der fotomechanischen Wiedergabe und der Speicherung in elektronischen Medien. Die gewerbliche Nutzung der in diesem Produkt gezeigten Modelle und Arbeiten ist nicht zulässig. Fast alle Hardware- und Softwarebezeichnungen und weitere Stichworte und sonstige Angaben, die in diesem Buch verwendet werden, sind als eingetragene Marken geschützt. Da es nicht möglich ist, in allen Fällen zeitnah zu ermitteln, ob ein Markenschutz besteht, wird das Symbol in diesem Buch nicht verwendet.
®
Umwelthinweis: Dieses Buch wurde auf chlorfrei gebleichtem Papier gedruckt. Alle Rechte vorbehalten. Kein Teil des Buches darf ohne Erlaubnis der Pearson Education Inc. in fotomechanischer oder elektronischer Form reproduziert oder gespeichert werden.
10 9 8 7 6 5 4 3 2 1 09 08 07
ISBN 978-3-8273-2528-0
© 2007 Addison-Wesley Verlag, ein Imprint der PEARSON EDUCATION DEUTSCHLAND GmbH, Martin-Kollar-Str. 10-12, 81829 München/Germany Alle Rechte vorbehalten Lektorat: Brigitte Bauer-Schiewek,
[email protected] Fachlektorat: Matthias Kannengiesser Korrektorat: Petra Kienle Herstellung: Claudia Bäurle,
[email protected] Satz: Ulrich Borstelmann, Dortmund (www.borstelmann.de) Einbandgestaltung: Marco Lindenbeck, webwo GmbH,
[email protected] Druck und Verarbeitung: Kösel Druck, Krugzell (www.koeselBuch.de) Printed in Germany
I NHALTSVERZEICHNIS Sieh' einer an …
IX
Kapitel 1
Einleitung
1
Kapitel 2
Grundlagen der Programmierung
5
2.1
2.2
2.3
2.4
2.5
2.6
Programmierung in Flash 2.1.1 Anlehnung an JavaScript 2.1.2 Objektorientiertes Programmieren Kommentare 2.2.1 Einzeilige Kommentare 2.2.2 Mehrzeilige Kommentare 2.2.3 Verschachtelte Kommentare Variablen und Datentypen 2.3.1 Variablendeklaration 2.3.2 Variablennamen 2.3.3 Datentypen 2.3.4 Gültigkeitsbereiche von Variablen Operatoren 2.4.1 Arithmetische Operatoren 2.4.2 Zuweisungsoperatoren 2.4.3 Bitoperatoren 2.4.4 Logische Operatoren 2.4.5 Vergleichsoperatoren 2.4.6 Rangordnung der Operatoren Arrays 2.5.1 Indizierte Arrays 2.5.2 Assoziative Arrays Bedingungen 2.6.1 if-Bedingung 2.6.2 switch-Bedingung
V
6 6 6 7 7 7 8 8 8 9 10 13 17 17 18 21 21 22 22 24 24 25 28 28 30
2.7
2.8 2.9 2.10
2.11 2.12
Kapitel 3
31 31 37 39 40 41 47 47 50 51 51 53 53 53 56 56 60 62
Basiswissen
65
3.1 3.2
66 66 67 69 72 72 73 73
3.3
Kapitel 4
Schleifen 2.7.1 for-Schleife 2.7.2 for...each- oder for...in-Schleife 2.7.3 do..while-Schleife 2.7.4 while-Schleife Funktionen Cookies 2.9.1 Exkurs HTTP Sessions 2.10.1 session_start() 2.10.2 session_register() vs. $_SESSION 2.10.3 session_unregister() vs. $_SESSION 2.10.4 session_destroy() Caching XML auslesen und erstellen 2.12.1 Der Aufbau eines XML-Dokuments – Blitzeinführung 2.12.2 Auslesen einer XML-Struktur 2.12.3 XML-Dokumente erstellen
PHP JavaScript (AJAX) & DOM 3.2.1 „Kern-DOM“ 3.2.2 Alternativer Zugriff auf Objekte Flash 3.3.1 Sinnvolle Kombination von Flash und PHP 3.3.2 Weitere Verbindungsmöglichkeiten zur Serverseite 3.3.3 ActionScript 3.0 – die wichtigsten Änderungen
AJAX – Asynchronus JavaScript and XML
119
4.1 4.2 4.3
120 120 122 125 128
Was ist AJAX? Was ist AJAX nicht? Der XMLHttpRequest 4.3.1 Details zum XMLHttpRequest-Objekt 4.3.2 AJAX im Einsatz VI
4.4 4.5
Kapitel 5
167
5.1
168 168
5.4
Daten senden: Browser an Flash 5.1.1 Variante 1: JavaScript greift auf die SWF-Datei zu 5.1.2 Variante 2: Verwenden von HTML-Attributen zum Setzen von Variablen Daten senden: Flash an Browser 5.2.1 Kontaktaufnahme mit getURL 5.3 Die ExternalInterface-Klasse – Flash 8 und höher 5.3.1 ExternalInterface-Klasse mit ActionScript 1.0/2.0 5.3.2 ExternalInterface-Klasse mit ActionScript 3.0 Flash & AJAX 5.4.1 Parameterübergabe: Text 5.4.2 Parameterübergabe: XML
Serverseitiger Datenaustausch – Flash, PHP & Datenbank 6.1 6.2 6.3
6.4
Kapitel 7
164 165
Clientseitiger Datenaustausch – Flash & Javascript
5.2
Kapitel 6
Flash vs. AJAX Flash & AJAX
Drei Technologien im Einsatz Das LoadVars-Objekt Die Basis: das XML-Objekt & ActionScript 2.0 6.3.1 Grundlegende XML-Befehle 6.3.2 Einlesen von XML-Daten 6.3.3 Ausgeben von XML-Daten in eine PHP-Seite 6.3.4 Die XMLConnector-Komponente ActionScript 3.0: Neues und Änderungen 6.4.1 Das URLLoader- und URLRequest-Objekt 6.4.2 Der Aufbau: das XML-Objekt & ActionScript 3.0
179 181 181 184 185 207 208 209 233
239 240 241 266 266 266 286 298 309 309 325
Audio-Jukebox
337
7.1 7.2 7.3
338 338 338 338
Abfragen serverseitiger Informationen Multimediale Anwendungen Konzept der Jukebox 7.3.1 Playlist generieren VII
7.4
7.5 7.6
7.7
Kapitel 8
Jukebox in ActionScript 2.0 7.4.1 XML-Daten laden 7.4.2 Abspielen der Songs 7.4.3 ID3-Tags auslesen 7.4.4 Abspielsteuerung 7.4.5 Lautstärkeregler Der PHP-Part Jukebox in ActionScript 3.0 7.6.1 Allgemeine Änderungen 7.6.2 Änderungen beim Laden der XML-Daten 7.6.3 Änderungen im Soundobjekt 7.6.4 Änderungen in der Abspielsteuerung 7.6.5 Änderungen in der Lautstärkeregelung 7.6.6 Songs aus einer ComboBox abspielen Mögliche Erweiterungen
340 341 344 349 351 353 355 359 359 360 363 363 370 372 374
Videoplayer (ActionScript 3.0)
375
8.1 8.2 8.3
376 376 378 378 382
Das Konzept des Videoplayers Flash & Video Die Umsetzung 8.3.1 Flash und die FLVPlayback-Komponente 8.3.2 Videos im FLV-Format 8.3.3 Dynamisches Verknüpfen der FLVPlayback-Komponente mit einem Video 8.3.4 Schritt 1: Abspielen einer Liste von Videos (Array) 8.3.5 Schritt 2: Abspielen einer Liste von Videos (XML) 8.3.6 Arbeiten mit Cue-Points
Stichwortverzeichnis
392 394 401 426 429
VIII
SIEH’ EINER AN … Schön, Sie hier zu treffen! Ein Sprichwort sagt „Alles neu macht der Mai“ – nun, Flash erstrahlt in Version CS3, PHP läuft stabil in Version 5 und um AJAX müssen wir uns keine Sorgen machen, denn da setzen wir auf die bekannten (und bewährten) Technologien JavaScript und XML. Mit anderen Worten: Dieses Buch baut auf Bewährtem und Neuem auf. Lassen Sie sich überraschen! Aber alles der Reihe nach. Zunächst einmal freut es mich, dass Sie sich für dieses Buch entschieden haben. Es zeigt mir, dass die Kombination von Flash und PHP nach wie vor ein beliebtes Thema ist. Und mit „Web 2.0“ ist auch AJAX in aller Munde – und wie es scheint auch in Ihrem Interesse.
Meine geschätzte Leserschaft Bevor wir ans Eingemachte gehen, möchte ich ein paar Worte vorausschicken, für wen dieses Buch geschrieben ist und – vor allem! – für wen dieses Buch nicht geschrieben ist (ich denke, es ist wichtiger, solche „Nicht-Ziele“ zu definieren).
Das sind meine Leser! Dieses Buch ist für Einsteiger in die Thematik „Flash & PHP & AJAX“ geschrieben. Dabei gehe ich davon aus, dass meine Leser mit der Arbeitsweise von Flash, PHP & JavaScript vertraut sind, sie also den Umgang mit Folgendem im Schlaf beherrschen : u Flash: u Die „Zeit“: Der Umgang mit der Zeitleiste ist kein Problem, ebenso wissen Sie über
Schlüsselbilder, benannte Bilder und Szenen Bescheid. u Die „Elemente“: Formen, Symbole und Instanzen, grundlegende Komponenten stellen
für Sie in der Anwendung kein Problem dar, Benennung von Instanzen, Definieren von Instanz-Eigenschaften etc. erledigen Sie ohne nachzudenken. u .fla versus .swf: Selbstverständlich ist Ihnen der Unterschied zwischen der Flash- und der
SWF-Datei bekannt, auch haben Sie schon unzählige Male eine SWF-Datei in ein Webdokument eingebunden. Die Problematik verschiedener Browser-Systeme (Einbinden der SWF-Dateien mittels <embed> oder
) kennen Sie ebenso. u ActionScript: Dass hiermit die in Flash verwendete Programmiersprache gemeint ist,
wissen Sie. Dabei hatten Sie bereits ersten Kontakt mit grundlegenden Befehlen wie etwa stop(), play(), gotoAndPlay(), gotoAndStop() usw. – die Grundlagen der Programmierung sind Ihnen bekannt und ein wenig programmiert haben Sie auch schon. IX
u JavaScript: Sie sind eventuell (noch) kein Programmierprofi, jedoch wissen Sie, wie man mit dem <script>-Tag umgeht und dass man JavaScript-Code in einer externen Datei
ablegen kann, welche sich im Weiteren mit einem Webdokument verknüpfen lässt. Wahrscheinlich sind Sie sogar in der Lage, grundlegenden Code zu schreiben und auch kleinere Projekte zu verstehen – ansonsten helfen Ihnen das einleitende Kapitel „Grundlagen der Programmierung“ und die einschlägige Literatur weiter. u PHP und MySQL: u Server- versus Clientseite: PHP ist eine serverseitige, JavaScript eine clientseitige Pro-
grammiersprache – kein Thema, das wissen Sie. u Programmierung: Ein wenig Erfahrung haben Sie bereits gesammelt bzw. Sie haben
zumindest schon einmal PHP-Code geschrieben. Sollte dem nicht so sein – wie gesagt, dann ist das Einleitungskapitel für Sie gedacht. u Datenbanken: Die Grundlagen relationaler Datenbanken kennen Sie, ebenso haben Sie
bereits einmal mit MySQL in Zusammenhang mit einer datenbankbasierten Webanwendung gearbeitet. Das System PHPMyAdmin ist Ihnen auch ein Begriff und Tabellen können Sie anlegen, mit Daten befüllen und auch administrieren. Nein? Kapitel „Grundlagen der Programmierung“ … Die liebe Programmierung … Sollten Sie mit der Programmierung noch nicht so sehr vertraut sein, so ist Ihnen das Kapitel „Grundlagen der Programmierung“ gewidmet, in dem Sie das notwendige Rüstzeug vermittelt bekommen, um die folgenden Kapitel locker bewältigen zu können. Bedenken Sie jedoch bitte, dass es sich hierbei nicht um ein allumfassendes Werk zu den genannten Technologien handelt und deshalb im Abschnitt zu den Grundlagen der Programmierung auch nur die für die restlichen Kapitel notwendigen Themen behandelt werden.
Diese Leser werden nicht glücklich! Wie schon eingangs erwähnt, ist dieses Buch für Einsteiger geschrieben. Sollten Sie also bereits Programmierprofi sein, Hunderte Projekte in Flash realisiert und jegliche Arten von Datenbanksystemen realisiert haben, dann werden Sie die in diesem Buch beschriebenen Inhalte nicht befriedigen. Das Anwenden von Flash-Komponenten zur Kommunikation mit serverseitigen (Adobe-)Anwendungen ist zwar ein Teil des Buchs, spielt jedoch nur eine untergeordnete Rolle. Ich werde auch nicht den Versuch machen, den kürzest möglichen Programmcode zu schreiben, denn dies geht meist auf Kosten der Lesbarkeit und somit der Verständlichkeit des Programmierten. Ein perfekter Programmierer wird man nie, ein sehr guter Programmierer wird man durch das tägliche Programmieren – auf diesen Weg kann ich Sie führen, indem ich Ihnen den Einstieg so einfach wie möglich mache. X
Ein immerwährendes Problem in der Welt des Internets sind die Browser: verschiedene Generationen von Browsern, verschiedene Browser, verschiedene Plattformen – zumeist verhalten sie sich unterschiedlich und liefern unterschiedliche Resultate. Ich werde in diesem Buch nicht den Versuch anstellen, alle nur erdenkbaren Eventualitäten zu berücksichtigen, sondern vielmehr Rücksicht auf die gängigen Browser nehmen: u Microsoft Internet Explorer 6 unter Windows u Microsoft Internet Explorer 7 unter Windows u Firefox 2 unter Windows und Mac OS X u Opera 9.1 unter Windows und Mac OS X u Safari 2.0.4 unter Windows
Diese Browser stellen mit Sicherheit den repräsentativen Querschnitt über alle gängigen und im Einsatz befindlichen Browser weltweit dar – alle weiteren Browser lasse ich „links liegen“. Zusammengefasst: Profis werden in diesem Buch nicht die gewünschten Inhalte finden – dies ist ein Einsteigerbuch! Für Sie, meine lieben Experten, hält Addison-Wesley eine Reihe von Büchern bereit, die Ihren Ansprüchen gerecht werden und auch noch die letzte Frage beantworten.
Danke! An dieser Stelle wird es im Allgemeinen persönlich … Wohl nichts, das den Inhalt eines Buchs wesentlich beeinflussen würde, aber eine wunderbare Möglichkeit, sich zurückzulehnen, zu erfreuen an einem sonnigen Tag und die verstrichene Zeit Revue passieren zu lassen. Mit der Zeit tritt dann eine innere Dankbarkeit ein, die darauf wartet, nach außen zu treten und DANKE in die Welt zu schreien – danke all den Menschen, die mir wertvoll sind und mein tägliches Leben bereichern. Allen voran meiner geliebten Freundin Doris, die mir mein tägliches Maß an Freude und Spaß zu servieren weiß und mich mit Motivation und Lebensfreude versorgt – meine lieben Herren, ihr könnt euch glücklich schätzen, wenn auch ihr mit einer solch tollen Freundin gesegnet seid. Werte Damen – sorry, ich bin vergeben! Im selben Atemzug danke ich meiner Familie für eigentlich alles! Geburt (inklusive Zeugung), Erziehung, Ausbildung, Unterstützung, Liebe, Freundschaft, Rat und Tat – nichts blieb auf der Strecke. Und ganz nebenbei haben diese beiden auch dafür gesorgt, mir eine tolle Schwester zu schenken (die mir wiederum einen tollen Neffen geschenkt hat ...)! Alle meine Freunde, mit denen ich feiern und Spaß haben kann. Jungs, manchmal muss ich euch zwar motivieren, aus euren trauten Heimen zu kriechen, um etwas zu unternehmen, aber das erledige ich gerne. Caro, AIC, ToM, Gott, Chris, Clemens, Erik, Hari und viele mehr, die XI
mich sicherlich schimpfen werden, dass sie hier namentlich nicht erwähnt sind („… wie konntest du mich nur vergessen …“ usw.). Ein herzlicher Dank gebührt auch meinem Verlag und meinen Lektoren, die mich so nett in ihren Kreis aufgenommen haben und mir bei jeder Frage und jedem Anliegen mit Tipp und Tat zur Seite standen – ich freue mich auf jede Zusammenarbeit, die noch kommen wird! Zu guter Letzt danke ich Ducati für meine Monster, Metallica für die Art von Musik, die ich täglich brauche, und meinem Doktorvater Gü Blaschek für all die tollen Gespräche, die mich immer wieder über Gott und die Welt nachdenken lassen.
Me, myself and I …
Uwe Mutz
XII
1 EINLEITUNG
Flash, AJAX und PHP – das wird spannend! Vor kurzem ist die neueste Version von Flash in deutscher Version erschienen: Flash CS3. Viele Entwickler waren schon sehr auf die Neuerungen und Änderungen gespannt. Und wissen Sie was – sie wurden nicht enttäuscht! Sogar ganz im Gegenteil ... Was Flash speziell für Programmierer durch die Einführung von ActionScript 3.0 zu bieten hat, ist schon fast eine Sensation. Beinahe kein Stein blieb auf dem anderen, die hart erworbenen Kenntnisse in ActionScript 2.0 dienen mehr oder weniger nur noch dafür, dass man sich ein bisschen „zurechtfindet“. Angefangen von einfachen Änderungen in den Bezeichnungen von Eigenschaften bis hin zum kompletten Wegfall diverser Klassen (bzw. Verschieben in andere Pakete) ist alles gegeben. Da ich an dieser Stelle aber nicht davon ausgehen kann, dass ab jetzt sämtliche Entwicklungen in ActionScript 3.0 erfolgen (dies setzt nämlich den Flash9-Player voraus), gehe ich in diesem Buch sowohl auf die Version 2.0 als auch auf 3.0 von ActionScript ein. Gerade einmal das letzte Beispiel in diesem Buch – der Videoplayer – ist komplett in ActionScript 3.0 entwickelt worden. Gerade bei Videos bietet sich ActionScript 3.0 geradezu an. Der zweite große Workshop im Buch – der Audioplayer – ist sowohl in ActionScript 2.0 als auch 3.0 entwickelt. Ideal also, um einen Vergleich der beiden Versionen zu ziehen.
2
KAPITEL 1
Mein Tipp in Bezug auf die beiden Versionen (ActionScript 1.0 mal außer Acht gelassen): Sollten Sie sich in eine Version gezielt einarbeiten wollen, beschäftigen Sie sich primär mit der 3.0er Version, denn sie ist mit Sicherheit die Zukunft. Es wird nicht mehr lange dauern, bis die Mehrheit der Internet-User auf den Flash9-Player umgestellt hat. Dieses Buch wird sich nur sehr oberflächlich mit allen Komponenten und Möglichkeiten befassen, die im Rahmen der Entwicklungsumgebung auf der Bühne platziert werden. Umso mehr ist der Fokus auf die Programmierung gerichtet. Ein Flash Communication Server wird ebenso wenig ein Thema sein wie Elemente der FileReferenceKlasse usw. Primäres Ziel des Buchs ist es, die Möglichkeiten der Zusammenarbeit dreier Technologien zu zeigen und nicht jede Technologie für sich. PHP
Warum sich das Buch mit PHP beschäftigt, liegt auf der Hand: PHP hat sich zu der serverseitigen Programmiersprache entwickelt, um die man einfach nicht mehr herumkommt. Und das aus gutem Grunde, wurde sie doch speziell für den Einsatz im Web entwickelt. Und welche andere serverseitige Programmiersprache kann das schon von sich behaupten? Da sich die Syntax an die gängigen Standards anlehnt, ist das Erlernen nicht allzu aufwändig. Hat man den Unterschied zwischen Server- und Clientseite einmal verstanden, ist eigentlich alles klar. Alternativ könnte man genauso gut auf ASP, ASP.NET oder JSP zurückgreifen, aber warum eine weniger gängige Technologie einsetzen, wenn das Gute doch so nah liegt?
AJAX
Dass das Thema AJAX in diesem Buch aufgegriffen wird, mag schon etwas weniger auf der Hand liegen, denn im Grunde genommen ist Flash in der Lage, so gut wie alle Bereiche abzudecken, die uns AJAX auf Clientseite ermöglicht. Spannend wird die Sache jedoch, wenn man sich die Möglichkeiten überlegt, wie sich Flash und AJAX ergänzen können. Ein guter Webdesigner entwickelt nicht stur in eine Richtung, sondern kennt die User seiner Webanwendungen. Genau aus diesem Grund ist es manchmal notwendig, parallel in AJAX und Flash zu entwickeln. Sollte man dann nicht genau wissen, in welchen Bereichen sich AJAX und Flash überschneiden? Ich denke schon. Mindestens genauso spannend ist es, wenn „gemischte“ Webanwendungen mit AJAX und Flash entwickelt werden müssen. Flash interagiert mit AJAX, AJAX interagiert mit Flash. So läuft der Hase! Dass in diesem Buch nicht alle Anwendungsgebiete abgedeckt werden können, versteht sich von selbst. Aus diesem Grunde habe ich mich für multimediale Anwendungen mit Audio- und Videodaten entschieden. Das „Dahinter“ („Wie erhält ein Videoplayer seine Playlist?“ etc.) wird vor allem über XML-Daten realisiert, Interaktion mit dem Browser erfolgt zumeist über die ExternalInterface-Klasse.
EINLEITUNG
Besonders wichtig ist mir, dass Sie nach dem Lesen dieses Buchs ein Grundverständnis für die Arbeit mit Flash, AJAX und PHP als Paket entwickelt haben und einsetzen können. Kochrezepte werden Sie nur wenige finden. Aber Hand aufs Herz – ohne Denken läuft in unserem Business sowieso nichts mehr! Dann empfiehlt es sich, lieber ein gutes Verständnis einer Thematik zu haben, als Kochrezepte einzusetzen, die man nicht versteht! Abschließend: Sollten Sie Fragen zu den Inhalten oder Anregungen haben, so freue ich mich über eine Kontaktaufnahme per E-Mail: [email protected] .
3
2 GRUNDLAGEN DER PROGRAMMIERUNG Variablen, Arrays, Schleifen und Co. sind das Handwerkszeug eines Programmierers. In diesem Kapitel werden wir uns mit den theoretischen Grundlagen von Programmiersprachen befassen. Haben Sie diese Grundlagen einmal verstanden, steht Ihnen eigentlich die ganze Welt der Programmierung offen. Da dieses Buch dynamische Flash-Anwendungen durch den Einsatz von ActionScript und PHP zum Thema hat, zeigen wir Ihnen die Grundlagen der Programmierung auch gleich anhand dieser zwei Programmiersprachen. Des Weiteren erhalten Sie im Rahmen dieses Kapitels eine Blitzeinführung zum Thema XML. In vielen Fällen müssen wir dabei nicht zwischen PHP, JavaScript und ActionScript unterscheiden. Wo dies jedoch notwendig ist, finden Sie in der äußeren Spalte neben dem Text einen Hinweis für PHP, JavaScript bzw. für ActionScript.
6
KAPITEL 2
Kein allumfassendes Werk zu PHP, JavaScript und ActionScript!
Bitte beachten Sie jedoch, dass dieses Buch ein umfassendes Buch zu den Themen PHP, JavaScript und ActionScript weder ersetzen kann noch soll. Dieses Kapitel dient dazu, Ihnen die notwendigen Voraussetzungen mit auf den Weg zu geben – jedoch nur die notwendigen Voraussetzungen, die Sie für die weiteren Kapitel benötigen.
2.1
Programmierung in Flash
Anders als in gängigen Programmiersprachen muss in Flash – aufgrund seines Ursprungs als Animationsprogramm – die Zeitleiste berücksichtigt werden. Somit müssen wir mit dem Faktor „Zeit“ umgehen lernen. Wie Sie bereits gehört haben, ist die Programmierung in Flash auf drei verschiedene Arten möglich: MovieClips Bei der Programmierung mit MovieClips ist es von besonderer Bedeutung, den verwendeten MovieClips einen Namen zu geben.
1.
Programmierung in der Zeitleiste (egal, ob Zeitleiste der Bühne oder die eines MovieClip)
2.
Bei MovieClips über MovieClip-Ereignisse (diese werden Sie noch kennenlernen)
3.
Bei Schaltflächen über Schaltflächen-Ereignisse (sie werden ebenfalls noch vorgestellt)
2.1.1 Anlehnung an JavaScript ActionScript ist eine Programmiersprache, die sich an JavaScript (bekannt aus der Webprogrammierung) anlehnt, jedoch nicht genau deren Umfang hat. Detailliert soll auf diese Tatsache nicht eingegangen werden, nur eines sei noch erwähnt: Können Sie JavaScript programmieren, so ist es ein Leichtes, ActionScript zu programmieren.
2.1.2 Objektorientiertes Programmieren Oft ist die Rede von ActionScript 1.0, ActionScript 2.0 und ActionScript 3.0. Der wesentliche Unterschied zwischen den ersten beiden Versionen besteht darin, dass Version 2.0 im Gegensatz zu Version 1.0 objektorientiert ist. Ein weiteres Feature ist die Möglichkeit einer strikten Typisierung, auf die wir im Verlauf dieses Kapitels noch näher eingehen werden. Für unsere Anwendungen wird es nicht notwendig sein, objektorientiert zu programmieren, deshalb ist ein umfassendes Verständnis von ActionScript 2.0 nicht erforderlich. ActionScript 3.0 stellt eine beinahe vollkommene Neuentwicklung von ActionScript dar. Sämtliche Unterschiede und Änderungen finden Sie in der ActionScript-Referenz unter dem Schlagwort „ActionScript 2.0 Migration“, auf die wesentlichen Änderungen gehen wir im Weiteren noch genauer ein. Bitte beachten Sie jedoch, dass die einleitenden Kapitel dieses Buchs keinesfalls ein ActionScript-Buch und schon gar kein ActionScript 3.0-Buch ersetzen können!
GRUNDLAGEN DER PROGRAMMIERUNG
So weit zu den einfachen Dingen, nun zu den etwas schwierigeren: Wir müssen uns die Grundlagen der Programmierung aneignen und das bedeutet ein hartes Stück Arbeit. Es wäre viel zu trocken, diesen Part rein theoretisch zu halten, also werden wir begleitend dazu einige kleine Beispiele programmieren. Die folgenden Ausführungen können – wenn nicht anders vermerkt – für die Programmiersprachen JavaScript, ActionScript und PHP verstanden werden.
2.2
Kommentare
Gleich zu Beginn dieses Kapitels möchten wir Sie auf die Möglichkeit der Kommentierung Ihrer Scripte hinweisen. Dies ist natürlich nicht zwingend notwendig, jedoch sehr wichtig und hilfreich. Beim Erstellen Ihres Programms ist wahrscheinlich der Code noch verständlich und logisch. Ob dies nach ein oder zwei Monaten immer noch so ist, ist fraglich. Zusätzlich erleichtern Sie Kollegen die Arbeit mit Ihren Scripten, wenn diese gut kommentiert sind. Nutzen Sie Kommentare also so oft wie möglich.
2.2.1 Einzeilige Kommentare Zwei Schrägstriche // leiten einen Kommentar ein, und zwar einen zeilenweisen Kommentar. Alles, was Sie in dieser Zeile nach den Schrägstrichen schreiben, wird nicht als Befehl interpretiert, sondern nur als Anmerkung, also als Kommentar. //dies ist ein einzeiliger Kommentar
2.2.2 Mehrzeilige Kommentare Sollten Sie einen Kommentar benötigen, der über mehrere Zeilen geht, so können Sie ihn mit einem beginnenden /* und einem (in irgendeiner der darunterstehenden Zeilen) endenden */ einschließen, also z.B. so: /* dies ist ein mehrzeiliger Kommentar */
Im Allgemeinen werden Kommentare im Code verwendet, um die Ideen während der Entwicklung des Codes bzw. wichtige Informationen zu Variablen, Objekten etc. (etwa deren Bedeutung oder mögliche Werte) festzuhalten. Ein weiteres Anwendungsgebiet ist das „Auskommentieren„ von nicht verwendeten Codezeilen: Der Entwickler ist grundsätzlich immer versucht, den bereits geschriebenen Code bei Nichtverwendung keinesfalls einfach zu löschen, sondern ihn – sollte er wider Erwarten doch noch benötigt werden – auszukommentieren.
7
8
KAPITEL 2
Bitte beachten Sie, dass sowohl ein- als auch mehrzeilige Kommentare an derjenigen Stelle beginnen, an der die Kommentarzeichen gesetzt werden. Dabei werden einzeilige Kommentare oft verwendet, um am Ende einer Codezeile diverse Anmerkungen zu platzieren, wie etwa: var modus:Number = 1; //Nur die Werte 1 und 2 sind gueltig
Im obigen Beispiel wird so deutlich, dass bei Verwendung der Variablen modus nur die Werte 1 oder 2 zugewiesen werden dürfen. Beachten Sie bitte weiterhin, dass erklärende (ein- oder mehrzeilige) Kommentare besser vor den Codeblock geschrieben werden, wo diese Erklärung benötigt wird.
2.2.3 Verschachtelte Kommentare Verschachtelte Kommentare sind in PHP nicht erlaubt. Das Ausführen Ihres Programms wird in solch einem Fall abgebrochen.
2.3
Variablen und Datentypen
2.3.1 Variablendeklaration Wenn Sie ein Programm erstellen, müssen Sie bestimmte Werte für die spätere Verwendung sicher und eindeutig speichern. Denken Sie einfach an ein Spiel, in dem der User zu Beginn seinen Nickname nennt. Im weiteren Verlauf des Spiels werden wir diesen Spieler immer an diesem Namen erkennen und ihn auch mit diesem Namen ansprechen. Damit ist eine klare Identität gegeben. Eingegebene Werte sind dann unter diesem Namen jederzeit abrufbar. PHP
In diesem Fall würden wir zum Beispiel eine Variable namens plNickname anlegen und in ihr den eingegebenen Namen des Spielers speichern. $plNickname ; // Variablendeklaration $plNickname = "Uwe"; // der Variable $plNickname wird der Wert Uwe zugewiesen
Listing 2.1: PHP erkennt Variablen immer am $-Zeichen, das ohne Leerzeichen direkt vor dem Namen der Variable stehen muss. Variablendeklaration immer am Anfang
In sehr vielen anderen Programmiersprachen muss eine Variable vor ihrer Verwendung deklariert, d.h. ins Leben gerufen werden. Würde dies nicht erfolgen, könnte man mit der gewünschten Variable nicht arbeiten, da sie noch nicht existiert. Da wir PHP als serverseitige Programmiersprache verwenden, wäre es eigentlich nicht nötig, Variablen am Anfang eines Scripts zu deklarieren. Jedoch sollten Sie sich trotzdem angewöhnen, Variablen immer anzugeben, da Sie dadurch einen besseren Überblick über die verwendeten Variablen erhalten.
GRUNDLAGEN DER PROGRAMMIERUNG
Befehle abschließen Im obigen Fall finden Sie noch einen weiteren Punkt, der bei der Programmierung wichtig ist: Wie Sie sehen, ist jede Zeile mit einem Strichpunkt abgeschlossen. Dies ist in PHP zwingend notwendig, in Flash nicht.
Variablentypen
ActionScript
In Flash verhält es sich ähnlich, jedoch hat man seit der Einführung von ActionScript 2.0 die Möglichkeit, Variablen explizit zu deklarieren, wovon Sie auch Gebrauch machen sollten. Wie Sie gleich im nächsten Abschnitt sehen werden, sollte bei guter Programmierung in Flash neben dem „Erwähnen“ der Variable über deren Namen auch der Typ der Variable angegeben werden. Würden wir das Beispiel aus PHP von oben umsetzen, so würde das wie folgt aussehen: var plNickname:String; plNickname = "Uwe";
Listing 2.2: Variablendeklaration und anschließende Wertzuweisung in Flash
In der ersten Zeile wird eine Variable vom Typ String (das ist ein Text) angelegt. Dies bedeutet nichts anderes, als dass in dieser Variablen nur Textwerte gespeichert werden. In der zweiten Zeile wird dieser Variablen der Wert „Uwe“ zugewiesen. Bitte beachten Sie an dieser Stelle, dass String-Werte immer in Anführungszeichen stehen. Kürzt man die beiden Zeilen noch etwas ab, so erhält man nachfolgenden Code, in dem gleichzeitig mit der Variablendeklaration auch eine Wertzuweisung erfolgt: var plNickname:String = "Uwe";
Listing 2.3: Variablendeklaration und gleichzeitige Wertzuweisung
Somit wissen wir, wie man Variablen anlegt und ihnen einen Wert zuweist. Jetzt müssen wir uns kurz Gedanken darüber machen, welche Variablennamen gültig sind und welche nicht. In JavaScript wird wie in PHP bei der Variablendeklaration nicht zwischen verschiedenen Variablentypen unterschieden, deshalb erfolgt die Zuweisung wie folgt: var plNickname = "Uwe";
Listing 2.4: Variablendeklaration und anschließende Wertzuweisung in JavaScript
2.3.2 Variablennamen Bei der Namensgebung der Variablen in Flash, JavaScript und PHP müssen Sie einige Regeln strikt beachten:
JavaScript
9
10
KAPITEL 2
Variablen … u müssen in PHP mit einem Dollarzeichen „$“ beginnen (in Flash und JavaScript ist
dies nicht der Fall). u dürfen keine Leerzeichen enthalten. u dürfen nur aus Buchstaben und Ziffern bestehen, wobei das erste Zeichen nach
dem Dollarzeichen ein Buchstabe sein muss. u dürfen Groß- und Kleinbuchstaben enthalten. PHP und ActionScript (ab Version
2.0) sind Case-sensitive und erkennen die Unterschiede. u dürfen keine Umlaute wie ä, ö, ü und kein ß enthalten. u dürfen als einziges Sonderzeichen den Unterstrich „_“ enthalten. u dürfen nicht wie Befehle der Sprache PHP, JavaScript bzw. ActionScript benannt
sein (eine Auflistung aller Befehle entnehmen Sie bitte den jeweiligen Sprachreferenzen). Bitte gewöhnen Sie sich an, für die „Taufe“ der Variablen möglichst selbst erklärende Namen zu verwenden. Damit sind Sie (und auch andere Personen) in der Lage, Ihren Code auch später schnell und unmissverständlich zu lesen und zu erfassen. Originalität bei der Namensvergabe wäre hier völlig fehl am Platz.
2.3.3 Datentypen Der Typ der Daten legt verbindlich fest, welcher Inhalt in den Variablen gespeichert werden kann. Man kann auch sagen, dass der Datentyp die Art der Information beschreibt, die in der Variable gespeichert werden soll. PHP
In PHP gibt es folgende Datentypen: u Ganze Zahlen (Integer) u Zahlen mit Nachkommastellen (Float) u Zeichenketten (String) u Felder (Array) u Objekte
Zum Glück müssen wir uns in PHP und JavaScript über den Inhalt von Variablen wenig Gedanken machen. PHP und JavaScript entscheiden nämlich selbst, welcher Datentyp für welchen Inhalt verwendet werden soll. So kann es durchaus vorkommen, dass eine Variable im Laufe eines Programms ihren Datentyp selbstständig ändert.
GRUNDLAGEN DER PROGRAMMIERUNG
Ein kleines Beispiel in PHP: Uebung Variablen / Datentyp
Listing 2.5: PHP-Code in einer HTML-Seite
Die Variable $finalpoints hatte zu Beginn des Programms den Datentyp „Integer“. Nach der Neuberechnung des Endstands wurde in der Variable $final_points der Fließkommawert „34.3“ gespeichert. Somit hat sich der Datentyp von „Integer“ zu „Float“ geändert. In Flash sieht die Sachlage ähnlich, wenn auch etwas unterschiedlich aus. Flash unterscheidet zwischen „Grunddatentypen“ und „Referenzdatentypen“ (oder „integrierten Datentypen“). Des Weiteren existieren die speziellen Datentypen Null und undefined.
ActionScript
11
12
KAPITEL 2
Grunddatentypen sind: u Number: numerische Variablen (Zahlen) u String: Textvariablen u Boolean: Variablen, die nur die Werte true oder false speichern können
Diese Datentypen werden verwendet, um mit Variablen zu arbeiten. Die Referenzdatentypen (oder „integrierte Datentypen“) werden hingegen eingesetzt, um einerseits mit MovieClips zu arbeiten, und andererseits, um komplexere Objekte zu erstellen – auf die meisten Vertreter der Referenzdatentypen werden wir später noch zu sprechen kommen. Referenzdatentypen sind also unter anderem: u MovieClip u TextField u Date
Der Datentyp Null deutet an, dass hier kein Wert existiert bzw. keine Daten vorhanden sind. undefined kennzeichnet, dass einer Variable noch kein Wert zugewiesen wurde. ActionScript 3.0: int und uint
Seit ActionScript 3.0 existieren neben Number nun auch die numerischen Datentypen int (Integer) und uint, wobei uint für „unsigned integer“ (Ganzzahl ohne Vorzeichen) steht: u int: eine Ganzzahl (= Zahl ohne Kommastelle) u uint: eine Ganzzahl ohne Vorzeichen (somit können nur Zahlen größer oder
gleich 0 gespeichert werden)
Datentypen bei der Deklaration Um nun Variablen verschiedener Datentypen zu deklarieren, wird der Datentyp nach dem Variablennamen und einem (deklarierenden) Doppelpunkt geschrieben. Die Syntax lautet wie folgt: var Variablenname:Datentyp;
Listing 2.6: Variablendeklaration mit Datentyp
Wird der Datentyp angegeben (was nicht zwingend erforderlich ist – siehe hierzu auch die Info-Box „Automatische versus strikte Typisierung“), nennt man dies „Strikte Typisierung“. Angewandt auf einige Beispiele sieht das Ganze dann so aus: var myNumber:Number = 17; var myString:String = "Uwe";
GRUNDLAGEN DER PROGRAMMIERUNG
var myBoolean:Boolean = true; trace("Der Wert der (nicht existenten) Variable myNumber2="+myNumber2);
Listing 2.7: Beispiele einiger Variablendeklarationen inklusive Wertzuweisung Automatische versus strikte Typisierung (ActionScript 1.0 und 2.0) Grundsätzlich muss im Rahmen von Flash der Datentyp nicht explizit angegeben werden, denn Flash erzeugt bei der Wertzuweisung automatisch den korrekten Datentyp, wie Sie in der nachfolgenden Zeile sehen: var myNumber = 17;
Nachteilig an dieser sogenannten „Automatischen Typisierung“ ist, dass der Code fehleranfälliger wird, da man in solchen Fällen einer Variable vom (angedachten) Typ Number auch beispielsweise einen String-Wert zuweisen könnte. Im Fall der „Strikten Typisierung“ kann dies nicht geschehen und der Compiler von Flash würde beim Veröffentlichen eine entsprechende Fehlermeldung erzeugen. Deshalb der Tipp: Versuchen Sie immer, eine strikte Typisierung zu verwenden.
ActionScript 3.0 erfordert in jedem Fall eine strikte Typisierung. Es ist zwar eine Typumwandlung möglich, standardmäßig erfordert ActionScript 3.0 jedoch eine strikte Typisierung.
2.3.4 Gültigkeitsbereiche von Variablen Der Gültigkeitsbereich einer Variablen gibt an, in welchem Bereich des Codes eine Variable gültig ist. Anders gesprochen: Der Gültigkeitsbereich soll ausdrücken, wo im Code der Wert der Variable verfügbar ist und wo nicht. Außerhalb des Gültigkeitsbereichs existiert die Variable dann ganz einfach nicht (oder nicht mehr). Insbesondere im Rahmen von Funktionen und speziellen Codeblöcken (PHP, JavaScript und ActionScript) müssen wir uns um Gültigkeitsbereiche Gedanken machen. Grundlegend unterscheidet man zwischen zwei Bereichen (drei hingegen für ActionScript): u Lokale Variablen: Diese sind nur innerhalb eines gewissen Codeblocks gültig und
verlieren mit dem Ende des Codeblocks ihre Gültigkeit. Sie werden z.B. innerhalb von Funktionen und Schleifen eingesetzt. u Globale Variablen: Diese sind überall gültig und verlieren ihre Gültigkeit erst mit
Ende des Scripts. In ActionScript 3.0 wurden globale Variablen entfernt. u Zeitleistenvariablen (nur in ActionScript): Diese sind für alle Codeblöcke inner-
halb der Zeitleiste verfügbar. Im Rahmen der bisher erlernten Programmierung müssen Sie sich noch keine Gedanken über lokale, globale und Zeitleistenvariablen machen. Mit Einführung von Funktionen wird sich dies ändern, aber darauf werden wir Sie zu gegebenem Zeitpunkt noch konkret hinweisen.
ActionScript 3.0
13
14
KAPITEL 2
Flash: nicht deklarierte lokale Variablen in Codeblöcken In Flash unterscheiden wir zwischen deklarierten und nicht deklarierten Variablen innerhalb von Codeblöcken, beispielsweise Funktionen. Wird eine Variable implizit deklariert (d. h., es wird ihr ein Wert zugewiesen, ohne dass die Variable zuvor mit var deklariert wurde), verliert die Variable erst bei Ende des Scripts ihre Gültigkeit. Anders bei deklarierten Variablen: Diese verlieren mit Ende des Codeblocks ihre Gültigkeit!
Superglobale Variablen und Arrays PHP
Superglobale Arrays kennt nur PHP. In Flash (bis einschließlich ActionScript 2.0) existiert ein ähnliches Array namens _global. Anhand des Namens „superglobal“ erahnen Sie wahrscheinlich schon den Sinn dieser Variablen. Superglobale Variablen sind zu jeder Zeit und an jeder Stelle in einem Script bekannt und somit les- und veränderbar. Diese werden PHP-intern in einem Array gespeichert. Was genau ein Array ist und wozu man sie verwenden kann, können Sie in diesem Kapitel in Abschnitt 2.5 nachlesen. Der Name des Arrays lautet $GLOBALS[]. Den Einsatz von $GLOBALS[] sollten wir für ein leichteres Verständnis in einem Beispiel genauer betrachten. // Definition der Variable textstring $textstring = "Info in der Variable textstring"; // Eine Funktion zum Anzeigen des Variableninhalts function showData { echo("Der Inhalt der Variable lautet: $textstring"); } showData();
Listing 2.8: Der Inhalt der Variable $textstring soll ausgegeben werden.
Leider wird aber im Browser der Inhalt der Variable $textstring nicht angezeigt. Dies liegt einzig und allein daran, dass innerhalb einer Funktion Variablen nicht bekannt sind, die außerhalb dieser Funktion definiert wurden. Es existiert in der Funktion showData() keine Variable mit dem Namen $textstring. Um dieses Problem nun zu lösen, werden wir $GLOBALS[] einsetzen. // Definition der Variable textstring $textstring = "Info in der Variable textstring"; // Eine Funktion zum Anzeigen des Variableninhalts function showData { echo("Der Inhalt der Variable lautet: ".$GLOBALS[textstring]); } showData();
Listing 2.9: Mit dem Array $GLOBALS[] kann die Variable ausgelesen werden.
GRUNDLAGEN DER PROGRAMMIERUNG
Wie Sie erkennen, haben wir nicht sehr viel geändert. Innerhalb der Funktion greifen wir nun nicht mehr auf die Variable $textstring, sondern auf das Element textstring im Array $GLOBALS[] zu. Bitte beachten Sie, dass der Parameter des Arrays – also der Variablenname – ohne führendes $-Zeichen aufgerufen werden kann. PHP kennt noch weitere superglobale Arrays, die uns die Arbeit zum Beispiel mit Formulardaten sehr erleichtern: u $GLOBALS u $_SERVER u $_GET u $_POST u $_COOKIE u $_FILES u $_ENV u $_REQUEST u $_SESSION
Formulardaten versenden Im ersten Kapitel dieses Buchs hörten Sie bereits von GET und POST. Wenn Sie Formulardaten von einer Seite zu einer anderen Seite schicken und die gesendeten Daten weiterverarbeiten möchten, benötigen Sie die superglobalen Arrays $_GET oder $_POST, wenn in der php.ini die Einstellung register_globals auf off gesetzt ist. Angenommen, Sie haben ein Kontaktformular für Ihre User erstellt, in dem ein Textfeld mit dem Namen „Vorname“ existiert. Beim Absenden des Formulars wird der Inhalt dieses Textfelds an eine weitere PHP-Seite geschickt. Nun haben Sie zwei Möglichkeiten zum Auslesen des Textfelds, je nachdem, ob register_globals auf off oder on gesetzt ist. u Wenn off eingestellt ist, dann können Sie nur über das superglobale Array $_POST (oder $_GET) auf den Inhalt des Textfelds „Vorname“ zugreifen. u $_POST[‚Vorname']; u Im zweiten Fall (register_globals ist on) können Sie mit $Vorname direkt
auf den Inhalt des Textfelds zugreifen. Der Name der Variable ist automatisch der Name des Textfelds. Sollten Sie noch nähere Information über die restlichen superglobalen Arrays benötigen, bitten wir Sie, in der PHP-Referenz nachzuschlagen. Diese finden Sie auch im Internet unter www.php.net.
register_globals
15
16
KAPITEL 2
Tipp: Ich würde Ihnen in jedem Fall empfehlen, die Eigenschaft register_globals auf off zu belassen (oder zu setzen), auch wenn es scheinbar einfacher wäre, wenn sie on ist. register_globals stellt eine nicht zu unterschätzende Sicherheitslücke dar, da PHP keinen Unterschied zwischen einer GET- oder POST-Variable mit gleichem Namen machen kann. ActionScript bis inklusive 2.0
Globale Variablen (und Funktionen) sind Variablen, die in allen Zeitleisten und allen Hierarchiebereichen, also Gültigkeitsbereichen, verfügbar sind. Lokale Variablen haben dagegen nur einen eingeschränkten Gültigkeitsbereich. Um eine globale Variable zu erzeugen, wird der Variable der Bezeichner _global vorangestellt. Globale Variablen werden nicht mit var deklariert und ihnen werden auch keine Datentypen zugewiesen. _global.myNumberGlobal = 17;
Listing 2.10: Deklaration einer globalen Variable in ActionScript var myNumberLocal:Number = 17;
Listing 2.11: Deklaration einer lokalen Variable in ActionScript Globale versus lokale Variablen Der Sinn der globalen Variable ist, dass sie von überall aus zugänglich ist. Natürlich wäre es nett, wenn jede Variable von überall aus zugänglich wäre, frei nach dem Motto „Weg frei für die Globalisierung jeder Variable“ ... Ein guter Programmierer zeichnet sich aber auch dadurch aus, dass er weiß, wann eine Variable global sein muss und wann eine Variable lokal sein kann. Zumeist werden Variablen nur für gewisse Bereiche benötigt – deshalb die Regel: lokal vor global! ActionScript 3.0
In ActionScript 3.0 existiert das Array _globals nicht mehr. Vielmehr behandelt ActionScript 3.0 alle Variablen als global, die in der root-Ebene eines Clips (oder einer externen ActionScript-Datei) definiert wurden.
JavaScript
In JavaScript verhält es sich ähnlich wie in ActionScript – global sind Variablen dann, wenn sie auf äußerster Ebene erzeugt wurden. Beispiel: var global01 = 15; function showVariables() { var nichtglobal = 17; alert("INNERHALB: global01="+global01+"; nichtglobal="+nichtglobal); } showVariables(); alert("AUSSERHALB: global01="+global01+"; nichtglobal="+nichtglobal);
Listing 2.12: Ein Beispiel für globale und lokale Variablen
GRUNDLAGEN DER PROGRAMMIERUNG
Außerhalb der Funktion showVariables wird eine Variable global01 angelegt. Da diese Variable global ist, kann sie innerhalb der Funktion showVariables abgerufen werden: Wird die Funktion showVariables aufgerufen (vorletzte Zeile), so erhalten Sie eine funktionierende alert-Ausgabe. Innerhalb der Funktion wird zusätzlich noch die lokale Variable nichtglobal definiert. Greift man nun von „außen“ auf die lokale Variable nichtglobal zu, so erhält man einen Fehler, da diese Variable eben nur innerhalb der Funktion showVariables existiert.
2.4
Operatoren
Operatoren dienen dem Zweck, Variablenwerte miteinander zu kombinieren. Dies kann einerseits eine einfache arithmetische Addition sein, andererseits aber auch dazu dienen, logische Verknüpfungen von Zuständen zu erzeugen.
2.4.1 Arithmetische Operatoren Wie der Name schon sagt, handelt es sich hierbei um eine mathematische Verknüpfung von Werten. Im folgenden Beispiel sehen Sie die Anwendung der Operation „Addition“ oder „+“: $anzahl1 = 23;
PHP
$anzahl2 = 15; $anzahl3; //bis jetzt wurde anzahl3 noch kein Wert zugewiesen $anzahl3 = $anzahl1 + $anzahl2;
Listing 2.13: Eine Addition in PHP ... var anzahl1 = 23;
JavaScript
var anzahl2 = 15; var anzahl3; anzahl3 = anzahl1+anzahl2;
Listing 2.14: ... in JavaScript ... var anzahl1:Number = 23; var anzahl2:Number = 15; var anzahl3:Number; anzahl3 = anzahl1+anzahl2;
Listing 2.15: ... und in Flash
ActionScript
17
18
KAPITEL 2
Operatoren Numerische Werte kann man mithilfe von folgenden Operatoren miteinander verknüpfen: Nehmen wir für das Beispiel in der Tabelle an, die Variablen $a (bzw. a) und $b (bzw. b) erhalten die Werte $a=22 und $b=5. In $c (bzw. c) wird das Ergebnis der Berechnung gespeichert. Operator +
-
Operation Addition (dies gilt in JavaScript und Flash für numerische ebenso wie für String-Variablen) Subtraktion
*
Multiplikation
/
Division
%
Modulo-Rechnung (gibt den Rest einer Division zurück)
Beispiel $c=$a+$b; (PHP) bzw. c=a+b; (JavaScript, Flash) liefert $c=27 $c=$a-$b; (PHP) bzw. c=a-b; (JavaScript, Flash) liefert $c=17 $c=$a*$b; (PHP) bzw. c=a*b; (JavaScript, Flash) liefert $c=110 $c=$a/$b; (PHP) bzw. c=a/b; (JavaScript, Flash) liefert $c=4.4 $c=$a%$b; (PHP) bzw. c=a%b; (JavaScript, Flash) liefert $c=2
Tabelle 2.1: Arithmetische Operatoren
Inkrement und Dekrement Um Werte um eins zu erhöhen oder zu verringern, können Sie die Inkrement- und Dekrementoperatoren verwenden. PHP
$variable++; $variable--;
Listing 2.16: In PHP ... JavaScript und ActionScript
variable++; variable--;
Listing 2.17: ... und in JavaScript bzw. Flash
2.4.2 Zuweisungsoperatoren Ein Zuweisungsoperator ist Ihnen auf den vorigen Seiten bereits begegnet. Es handelt sich hierbei im einfachsten Fall um das Gleichheitszeichen „=“. Es ist dafür bestimmt, einer Variable einen Wert zuzuweisen. Neben dieser Art von Zuweisung existieren jedoch auch noch weitere Zuweisungsoperatoren, die Sie in Tabelle 2.2 aufgelistet sehen. Der verwendete Wert kann selbstverständlich auch eine Variable sein – in diesem Fall passiert nichts anderes, als dass der Inhalt, sprich der Wert der Variable, ausgelesen und dieser Inhalt für die Berechnung herangezogen wird. Die Zuweisungen gelten dabei immer von rechts nach links.
GRUNDLAGEN DER PROGRAMMIERUNG
Zuweisungsoperator variable = Wert variable += Wert variable -= Wert variable *= Wert variable /= Wert variable %= Wert
Operation Einer Variable wird ein Wert zugewiesen. Eine Variable wird um einen Wert erhöht Eine Variable wird um einen Wert verringert. Eine Variable wird mit einem Wert multipliziert. Eine Variable wird durch einen Wert dividiert. Einer Variable wird durch einen Wert dividiert und es wird ihr der Restwert der Division zugewiesen.
Tabelle 2.2: Mögliche Arten von arithmetischen Zuweisungsoperatoren. Wie Sie bereits wissen, muss eine PHP-Variable selbstverständlich ein führendes $-Zeichen besitzen.
Ein Beispiel für die Anwendung des Operators +=, der zu einer Variable den Wert einer zweiten Variable hinzuaddiert: $variable1 = 23; // variable1 bekommt den Wert 23
PHP
$variable2 = 20; // variable2 bekommt den Wert 20 $variable1 += $variable2; // variable2 wird zu variable1 addiert
Listing 2.18: Der Operator += in PHP … var variable1 = 23;
JavaScript
var variable2 = 20; variable1 += variable2;
Listing 2.19: ... in JavaScript ... var variable1:Number = 23;
ActionScript
var variable2:Number = 20; variable1 += variable2;
Listing 2.20: ... und in Flash
In unserem Beispiel hat die variable1 nach der Addition den Wert 43, variable2 dagegen weiterhin den Wert 20. Ein weiteres Beispiel für eine Anwendung des Modulo-Operators %, der den Restwert einer Division berechnet: $variable1 = 23; // variable1 bekommt den Wert 23
PHP
$variable2 = 20; // variable2 bekommt den Wert 20 $variable3 = variable1 % $variable2; //Ergebnis: 3
Der Modulo-Operator in PHP … var variable1 = 23; // variable1 bekommt den Wert 23 var variable2 = 20; // variable2 bekommt den Wert 20 var variable3 = variable1 % variable2; //Ergebnis: 3
Listing 2.21: ... in JavaScript ...
JavaScript
19
20
KAPITEL 2
ActionScript
var variable1:Number = 23; var variable2:Number = 20; var variable3:Number = variable1 % variable2; //Ergebnis: 3
Listing 2.22: ... und in Flash
Die Modulo-Rechnung ist prinzipiell einfach zu verstehen, denn die Berechnung folgt dem gleichen Prinzip, wie Sie es aus der Volksschule kennen: Möchte man eine Zahl durch eine andere dividieren, so versucht man zunächst zu erkennen, wie oft die eine Zahl in der zweiten Zahl vorkommt, bis man letztendlich zu den Kommazahlen der Division gelangt. In unserem Beispiel ist die erste Zahl 23 und die zweite Zahl 20. Rechnet man 23 dividiert durch 20, so ist leicht zu erkennen, dass 20 in 23 genau ein Mal vorkommt und der Wert 3 als Rest übrig bleibt, also: 23/20 = 1 Rest 3
Die Modulo-Rechnung gibt Ihnen genau diese Restza lt gefüllt. u Die Textfelder werden nicht vorab angelegt, sondern bei jedem Laden einer Video-
quelle neu erzeugt. u Sämtliche Informationen werden in einer TextArea-Komponente angezeigt.
Wir werden den dritten Weg einschlagen und eine TextArea-Komponente verwenden, die wir einerseits (videoplayer_01e.fla) direkt auf der Bühne platzieren und andererseits (videoplayer_02e.fla) per ActionScript generieren. Im Fall der direkten Platzierung der TextArea-Komponente auf der Bühne geben wir der Instanz den Namen „videoinfos“ und stellen folgende Eigenschaften um: u editable: false u horizontalScrollPolicy: off
V I D E O P L AY E R ( A C T I O N S C R I P T 3 . 0 )
409
u Breite: 300 Pixel u Höhe: 40 Pixel u Position (x/y): (256/436)
ABBILDUNG 8.21 Eine Instanz der TextAreaKomponente wurde auf der Bühne in der Elementeebene eingefügt.
Die Funktion loadVideo in Bild 2 der Funktionenebene erweitern wir entsprechend um die Zeile function loadVideo(increaseIndex:uint, playVideo:Boolean):void { videoIndex+=increaseIndex; if(videoIndex==myXML.File.length()) { if(loopAtEnd) { videoIndex = 0; } else { mcFinished.visible = true; return; } } videoinfos.text = "Author: "+myXML.File[videoIndex].Author+"\ nAufnahmedatum: "+myXML.File[videoIndex].Date; myVideoplayer.source = myXML.@rootDir+"/"+myXML.File[videoIndex].@src; if(playVideo) { myVideoplayer.play(); } }
Listing 8.21: In die TextArea-Instanz „videoinfos“ werden Autor und Aufnahmedatum geschrieben.
Würden wir die TextArea-Komponente hingegen per ActionScript einbinden, müssten wir folgendermaßen vorgehen:
410
KAPITEL 8
u TextArea-Komponente in die Bibliothek ziehen u Folgenden ActionScript-Code in das zweite Bild der Aktionenebene einbauen: ... // ---- TextArea-Komponente: ---import fl.controls.TextArea; import fl.controls.ScrollPolicy;
var videoinfos:TextArea = new TextArea(); videoinfos.editable = false; videoinfos.horizontalScrollPolicy = ScrollPolicy.OFF; videoinfos.width = 300; videoinfos.height = 40; videoinfos.move(256,436); addChild(videoinfos); // ENDE TextArea-Komponente: ----
loadVideo(0,false);
Listing 8.22: Die zwischen den Kommentaren gelisteten Zeilen sind in der Aktionenebene in Bild 2 hinzugefügt worden.
Zunächst werden die Klassen TextArea und ScrollPolicy aus der Klasse fl.controls hinzugeladen, wobei die erste für das Ansprechen der TextArea und die zweite für das Setzen von Scrollparametern für eine eventuelle Scrollbar zuständig ist. Danach wird eine Instanz der TextArea-Komponente erzeugt (videoinfos) und die benötigten Eigenschaften und Parameter werden gesetzt. Abschließend fügt man die Instanz noch dem DisplayObject zu (addChild(videoinfos);) und hat es auch schon wieder geschafft! Die entsprechenden Dateien finden Sie wie üblich auf der Buch-CD unter den Namen videoplayer_01e.fla und videoplayer_02e.fla.
XML-Datei serverseitig aus einer Datenbank generieren Nehmen wir folgenden Fall an: In einer Datenbank wurde Ihnen eine Playlist zugewiesen, welcher wiederum eine Liste an Videos angehören. Ein PHP-Script erzeugt bei Übergabe einer Playlist-ID (die Übergabe erfolgt per GET) ein XML-File laut dem bisherigen Aufbau unserer verwendeten XML-Datei (siehe Listing 8.11). Nehmen wir folgende Struktur der Tabellen an:
V I D E O P L AY E R ( A C T I O N S C R I P T 3 . 0 )
Tabelle tbl_08playlist
tbl_08videos
Feld idP_Playlist
Typ int(11)
vcP_Bezeichnung
varchar(128)
vcP_Rootdir
varchar(128)
bitP_chk_autostart
tinyint(1)
idP_video
int(11)
fidP_select_ Bezeichnung_Playlist
int(11)
vcP_Src vcP_Content vc_Author
varchar(128) varchar(128) varchar(64)
dt_Date
date
tmP_Uploadtimestamp
timestamp
Details Beschreibung auto-increment, ID der Playlist Primary Key, not null not null Eine interne PlaylistBezeichnung, die innerhalb der XML-Struktur nicht verwendet wird not null URL zum Root-Verzeichnis der Videos in der Playlist not null, Kennzeichnung, ob Standard = 1 Autostart der Playlist an (1) oder aus (0) ist auto-increment, ID des Videos Primary Key, not null not null Ein Feld, das als Foreign Key zur Tabelle tbl_08playlist verwendet wird not null URL zur Videoquelle not null Name des Videos null Name des Autors (sofern vorhanden) null Aufnahmedatum (sofern vorhanden) not null, Timestamp des Eintrags CURRENT_ des Videos in die Tabelle TIMESTAMP
Tabelle 8.1: Aufbau der beiden Tabellen für unser Beispiel
Eine solche PHP-Datei zum Generieren von XML-Content aus den beiden oben definierten Tabellen könnte folgendermaßen aussehen: function createXML($idP_Playlist) { $dbData = array( "dbServer" => "mysql.syneweb.com", "dbUser" => "usr_mysql2", "dbPWD" => "456mysql!", "dbName" => "db_flashphpajax" );
if(!$conn = mysql_connect($dbData["dbServer"],$dbData["dbUser"],$dbDat a["dbPWD"])) { die('Der Datenbankserver konnte nicht erreicht werden. ERROR='.mysql_error().'
'); }
411
412
KAPITEL 8
if(!mysql_select_db($dbData["dbName"])) { die('Die Datenbank konnte nicht ausgewaehlt werden. ERROR='.mysql_error().'
'); }
$sql = "SELECT * FROM tbl_08playlist WHERE(idP_Playlist=$idP_Playlist)"; $query = mysql_query($sql) or die('Die Query konnte nicht abgesetzt werden. ERROR='.mysql_error().'
'); $data = mysql_fetch_array($query); $msg = ‚'; $msg.= ‚';
$sql = "SELECT * FROM tbl_08videos WHERE(fidP_select_Bezeichnung_ Playlist=$idP_Playlist)"; $query = mysql_query($sql) or die('Die Query konnte nicht abgesetzt werden. ERROR='.mysql_error().'
');
while($data = mysql_fetch_array($query)) { $msg.= ' '.$data["vc_Author"].' '.$data["vcP_Content"].' '.$data["dt_Date"].' '; }
$msg.= ' '; return $msg; }
if(count($_GET)>0 && isset($_GET["idP_Playlist"])) { echo(createXML($_ GET["idP_Playlist"])); } else { echo('Sie haben keine Berechtigung für diese Site.
'); }
Listing 8.23: Eine PHP-Datei namens playlist.php erzeugt aus einer Datenbank mit den Tabellen tbl_ 08playlist und tbl_08videos eine XML-Struktur laut den bisherigen Vorgaben.
V I D E O P L AY E R ( A C T I O N S C R I P T 3 . 0 )
Betrachtet man das Script Schritt für Schritt, so sind folgende Punkte von besonderem Interesse: 1.
Sofern an das Script GET-Variablen und im Speziellen die GET-Variable idP_ Playlist übergeben wurden, wird die Funktion createXML mit dieser Variable als Parameter aufgerufen und deren Rückgabewert per echo ausgegeben. Sollte nichts an die Datei übergeben worden sein, so wird eine entsprechende Fehlermeldung ausgegeben.
2.
Die Funktion createXML definiert zunächst die für den Connect zu einer Datenbank notwendigen Informationen in dem Array $dbData, stellt danach die Verbindung zum Datenbankserver her und wählt zuletzt die Datenbank aus. Sollte einer dieser Befehle misslingen, endet das Script mit einem die.
3.
Danach wird erst einmal aus der Tabelle tbl_08playlist alles ausgelesen, was zur übergebenen Playlist-ID gehört. Dies umfasst neben dem Playlist-Namen (der für unsere Zwecke irrelevant ist) auch das Root-Verzeichnis der Videos (vcP_Rootdir) und die Information zu einem Autostart der Playlist (bitP_chk_autostart). Aus diesen Informationen wird der erste Teil der XML-Struktur erzeugt (dieser wird vollständig in der Variablen $msg gespeichert): $msg = ‚'; $msg.= ‚';
4.
Ist dies erfolgt, werden in einem zweiten SQL-Statement aus tbl_08videos sämtliche Videoinformationen zur gegebenen Playlist geladen. Aus diesen Informationen wird in einer while-Schleife der weitere XML-Baum aufgebaut: $msg.= ‚ '.$data["vc_Author"].' '.$data["vcP_Content"].' '.$data["dt_Date"].' ‚;
5.
Zuletzt wird noch das geöffnete Tag geschlossen und der gesamte String $msg von der Funktion an den Aufrufer zurückgegeben.
Das Ergebnis für beispielsweise idP_Playlist=1 sieht dann folgendermaßen aus:
413
414
KAPITEL 8
ABBILDUNG 8.22 Nun wurde die XML-Datei nicht mehr „von Hand“ geschrieben, sondern per PHP aus einer Datenbank und zwei Tabellen erzeugt.
Flash muss demnach eine XML-basierte PHP-Datei playlist.php einlesen, die über einen GET-Parameter die korrekten Daten aus einer Datenbank ausliest. Nun offenbaren sich zwei Wege: 1.
Unser Flash-Beispiel wird so aufgebaut, dass immer dieselbe Playlist ausgelesen wird. Das bedeutet, jeder User ruft dieselben Videos ab.
2.
Es soll für jeden User eine individuelle Playlist existieren. Daher muss die FlashDatei so aufgebaut sein, dass sie zunächst auf den Playlist-Parameter wartet (die Flash-Datei muss ja unabhängig von einem User sein) und danach basierend auf diesem Parameter die XML-Daten anfordert.
Wir werden zunächst den ersten Teil entwickeln (das ist sehr einfach, da wir nur die URL zur einzulesenden Datei ändern müssen) und uns danach den zweiten Teil vornehmen. Fixe Playlist für alle User Dieser Fall ist sehr einfach, denn es macht keinen Unterschied, ob wir eine Textdatei mit XML als Inhalt oder eine PHP-Datei mit XML als Inhalt einlesen. Einzig die Tatsache, dass wir ab nun eine Server-Umgebung benötigen (PHP ist im Spiel ...), macht die Sache ein wenig aufwändiger. Bauen wir auf der Datei videoplayer_01e.fla auf, so muss lediglich in der Aktionenebene in Bild 1 die Zeile var theURL:String = "playlist.txt";
V I D E O P L AY E R ( A C T I O N S C R I P T 3 . 0 )
415
in var theURL:String = "playlist.php?idP_Playlist=1";
geändert werden. Testen Sie online und Sie werden sehen, dass sich nichts geändert hat: ABBILDUNG 8.23 Auch mit dynamisch erzeugten XML-Daten und online funktioniert der Video-Player prächtig.
Die Datei finden Sie unter dem Namen videoplayer_01f.fla (bzw. videoplayer_02f.fla) auf der Buch-CD. Variable Playlist für jeden User individuell Jetzt wird die Sache etwas komplizierter, denn nun muss das umgebende Webdokument zunächst die ID der Playlist an Flash übergeben – erst dann kann Flash die XMLDaten anfordern. Somit muss Flash beigebracht werden, dass es auf das Setzen der Playlist-ID warten muss, bevor die Daten geladen werden. Aus den vorigen Kapiteln wissen wir, dass sich das über das ExternalInterface sehr einfach lösen lässt: Erst wird eine Funktion definiert, die als eine Art „JavaScript-Handler“ dient und danach wird diese Funktion für JavaScript freigegeben. Ebenso muss dafür gesorgt werden, dass erst nach dem Funktionsaufruf auf die XML-Quelle zugegriffen wird. Zunächst die „JavaScript-Handler“-Funktion: function loadXMLVideodata(PlaylistID:Number):void { idP_Playlist = PlaylistID;
416
KAPITEL 8
nextFrame(); }
Listing 8.24: Die Funktion loadXLMVideodata erhält als Übergabeparameter die Playlist-ID von JavaScript.
JavaScript wird später auf diese Funktion zugreifen und ihr als Übergabeparameter die zu ladende Playlist-ID übergeben. Diese Übergabevariable wird in der globalen Variablen idP_Playlist gespeichert und danach erfolgt ein Sprung in den nächsten Frame, wo das Laden der XML-Datei erfolgt (an der Stelle, wo die URL zur XML-Datei definiert ist, müssen wir dann noch eine Änderung vornehmen). Die obige Funktion wird mittels des nachfolgenden Codes für JavaScript registriert: import flash.external.*; var idP_Playlist:Number;
if(ExternalInterface.available) { try { ExternalInterface.addCallback("loadXMLVideodata",loadXMLVideodata); } catch(myError:Error) { trace("Error: "+myError); } } stop();
Listing 8.25: Die zuvor definierte Funktion loadXMLVideodata wird als sogenannte „Callback-Funktion“ für JavaScript registriert. Die Flash-Datei finden Sie auf der Buch-CD unter dem Namen videoplayer_01g.fla.
Um mit der ExternalInterface-Klasse zu arbeiten, muss die entsprechende Klasse flash.external.* importiert werden. Danach wird eine (globale) Variable namens idP_Playlist definiert, der im Weiteren der Übergabewert von JavaScript zugewiesen wird. Sollte das ExternalInterface verfügbar sein, wird versucht, die Callback-Funktion zu registrieren. Schlägt dies fehl, wird per trace eine Fehlermeldung ausgegeben. Danach wird das Script noch abgestoppt, da die Flash-Anwendung so lange mit dem Laden der XML-Daten warten soll, bis es eine Playlist-ID zugewiesen bekommt. Weiter gesprungen und geladen wird im nächsten Frame. Zuletzt muss in Bild 2 in der Aktionenebene noch angegeben werden, wie Flash zu den korrekten Playlist-Daten gelangt: var theURL:String = "playlist.php?idP_Playlist="+idP_Playlist;
Listing 8.26: Die korrekte Playlist wird über die Variable idP_Playlist definiert, die beim Laden der XMLDaten an das entsprechende PHP-Script angehängt wird.
V I D E O P L AY E R ( A C T I O N S C R I P T 3 . 0 )
Damit wäre der Flash-Teil abgeschlossen und wir können uns der XHTML-Aufgabe widmen. Es ist relativ wenig JavaScript-Code notwendig, um die Playlist-ID an Flash zu übergeben. Grundsätzlich gehen wir davon aus, dass die Playlist-ID bereits an die XHTML-Datei per GET übergeben wurde: function sendDataToFlash(idP_Playlist) { var myswf = getFlashElement("myswf"); myswf.loadXMLVideodata(idP_Playlist); }
window.onload = function() { sendDataToFlash(); }
Listing 8.27: Übergabe der per GET definierten Variable idP_Playlist an Flash. Die entsprechende XHTML-Datei hört auf den Namen videoplayer_01g.php.
Nachdem die XHMTL-Seite vollständig geladen wurde (window.onload) wird die Funktion sendDataToFlash mit der GET-Variable idP_Playlist als Übergabeparameter aufgerufen. Diese Funktion sucht sich zunächst die korrekte Referenz auf die eingebundene SWF-Datei myswf über die Funktion getFlashElement (die Erklärung dazu finden Sie im Kapitel zu AJAX bzw. clientseitigem Datenaustausch) und ruft in dieser SWF-Datei danach die Callback-Funktion loadXMLVideodata mit wiederum idP_Playlist als Übergabeparameter auf. Somit schließt sich der Kreis und Flash hat, was es braucht: die Playlist-ID. Der Vollständigkeit halber hier noch einmal die Funktion getFlashElement: function getFlashElement(elem) { var app = navigator.appName.toLowerCase(); var nav = navigator.userAgent.toLowerCase(); if((app.indexOf("microsoft") != -1 || nav.indexOf("microsoft") != -1) && !Boolean(window["opera"])) { return document.all[elem]; } else { return document[elem]; } }
Listing 8.28: Die Funktion getFlashElement findet den korrekten Verweis auf die Flash-Datei – egal, welcher Browser verwendet wird.
Alternativ zum Setzen der Playlist-ID basierend auf GET-Variablen könnten wir dem User auch die Möglichkeit geben, die Playlist-ID selbst einzugeben oder aus einer Select-Box selbst zu wählen. Diese Variante ist in der Datei videoplayer_01h.php zu finden. Hierzu entfernen Sie zunächst den window.onload-Teil aus Listing 8.27 und fügen stattdessen den nachfolgenden Code ein:
417
418
KAPITEL 8
function setPlaylistID() { var idP_Playlist = document.forms["frmVideoplayer"]. elements["selPlaylist"].value; if(idP_Playlist!=-1) { sendDataToFlash(idP_Playlist); } }
Listing 8.29: Setzen der PlaylistID
Die Funktion setPlaylistID wird bei einer Auswahl eines Videos aus einer SelectBox aufgerufen. Sofern die Auswahl mit einem Wert ungleich -1 endet (der Wert -1 ist dem Eintrag „Bitte wählen Sie aus:“ zugewiesen), wird die Auswahl an sendDataToFlash übergeben. Die Select-Box wird per PHP aus der Datenbank erzeugt, indem wir die Tabelle tbl_08playlist auslesen: ... $sql = "SELECT * FROM tbl_08playlist"; $query = mysql_query($sql) or die('Fehler beim Absetzen der Query. ERROR='.mysql_error().'
'); if(mysql_num_rows($query)>0) { $returner = ' <select name="selPlaylist" id="selPlaylist" onchange="setPlaylistI D();"> Bitte wählen Sie aus: ‚; while($data = mysql_fetch_array($query)) { $returner.= ' '.$data["vcP_ Bezeichnung"].' '; } $returner.= ''; } else { $returner = '(kein Zugriff auf die Playlists)'; } echo($returner);
Listing 8.30: Auszug aus dem Script zum Auslesen der Tabelle tbl_08playlist, um alle Playlists in eine Select-Box zu schreiben. Der Teil für die Verbindung zur Datenbank wurde weggelassen, da dieses Prozedere hinlänglich bekannt ist. Die Datei finden Sie auf der Buch-CD unter videoplayer_01h.php.
V I D E O P L AY E R ( A C T I O N S C R I P T 3 . 0 )
419
Sollten in der Tabelle Playlists vorhanden sein, wird eine Select-Box selPlaylist mit einem Eintrag „Bitte wählen Sie aus:“ und den restlichen Einträgen aus der Tabelle generiert. Die Werte der Einträge entsprechen den IDs der Playlists (idP_Playlist). Sobald sich eine Änderung in der Auswahl ergibt, wird das Ereignis onchange ausgelöst, das die Funktion setPlaylistID aufruft. Das Ergebnis ist wie folgt: ABBILDUNG 8.24 Flash wartet auf eine Auswahl aus der Select-Box.
Sobald eine Auswahl getroffen wurde, lädt Flash die entsprechende Playlist: ABBILDUNG 8.25 Wurde eine Auswahl getroffen, lädt Flash die Videos zur Playlist und stellt diese in der ComboBox dar.
420
KAPITEL 8
AJAX zum Nachladen der Videos Bis zu diesem Zeitpunkt haben wir alle Ziele erreicht, die wir uns gesetzt hatten. Nun wollen wir folgende Erweiterung programmieren: Angenommen, es wurde ein weiteres Video zur Playlist hinzugefügt, während der User gerade die Animation offen hat. Ist dies der Fall, würde der User genau das neue Video nicht in der Playlist sehen, da es ja gerade hinzugekommen ist. Per AJAX hätten wir jedoch sehr einfach die Möglichkeit, Flash mitzuteilen, dass ein neues Video der Playlist hinzugefügt wurde – wir müssen nur per AJAX in regelmäßigen Abständen nachsehen, ob sich etwas an der Playlist geändert hat, und übergeben in diesem Fall die Änderungen an Flash. Die Idee ist, dass bei einem Eintrag eines Videos in die Datenbank ein Timestamp gespeichert wird. Beim Öffnen des Dokuments videoplayer_01i.php wird der neueste Timestamp ausgelesen und clientseitig gespeichert. In regelmäßigen Abständen wird die Tabelle per AJAX abgefragt und nachgesehen, ob es ein aktuelleres Video gibt. Sollte dies der Fall sein, wird eine entsprechende Meldung an Flash übergeben. In den folgenden Abbildungen sehen Sie die Anwendung. Schritt 1: Der User hat eine Playlist („Uwes Playlist 1“) ausgewählt, die derzeit noch vier Videos enthält (Abbildung 8.26). ABBILDUNG 8.26 Es wurde die Playlist „Uwes Playlist 1“ ausgewählt – sie enthält derzeit noch vier Videos.
Schritt 2: Zwischenzeitlich wurde in die Datenbank ein neues Video eingetragen. Nach spätestens 60 Sekunden (alle 60 Sekunden fragt AJAX die Datenbank ab) erhält der User eine Meldung innerhalb der Flash-Anwendung, dass ein neues Video zum Abruf bereitsteht (Abbildung 8.27).
V I D E O P L AY E R ( A C T I O N S C R I P T 3 . 0 )
421
ABBILDUNG 8.27 Ein neues Video wurde in der Datenbank gespeichert. Der User hat nun die Möglichkeit zu entscheiden, ob er es in seine Playlist (ComboBox) aufnehmen möchte.
Schritt 3: Hat sich der User dafür entschieden, das Video in seine Abspielliste zu übernehmen, wird die Abspielliste entsprechend erweitert (Abbildung 8.28). ABBILDUNG 8.28 Das neue Video („Düringer ab 4,99“) wurde in die Abspielliste aufgenommen.
Damit AJAX das aktuellste Video ermitteln kann, benötigt es auf Serverseite ein Script, das genau die benötigten Informationen liefert:
422
KAPITEL 8
... $sql = "SELECT tmP_Uploaddatum FROM tbl_08videos WHERE(fidP_select_ Bezeichnung_Playlist=".$_GET["idP_Playlist"].") ORDER BY tmP_Uploaddatum DESC LIMIT 1"; $query = mysql_query($sql) or die('ERROR='.mysql_ error().'
'); $data = mysql_fetch_array($query); echo(strtotime($data["tmP_Uploaddatum"])); ...
Listing 8.31: Auszug aus der Datei getnewestvideo.php, der die ID der aktuellen Playlist als GET-Parameter übergibt.
Ein geeignetes SQL-Statement ruft das neueste Video ab, indem es einen Eintrag (LIMIT 1) aus der Tabelle tbl_08videos abruft, wobei die Ergebnisliste absteigend (also das neueste zuerst: ORDER BY tmP_Uploaddatum DESC) sortiert ist. Es werden nur Videos abgerufen, die einer gegebenen Playlist angehören (fidP_select_Bezeichnung_ Playlist=".$_GET["idP_Playlist"]). Das Ergebnis wird in einen Timestamp umgewandelt (strtotime($data["tmP_Uploaddatum"])) und ausgegeben. Der JavaScript-Part aus Listing 8.29 wird zunächst um eine Variable firstShow erweitert: var firstShow = true; var itv; function setPlaylistID() { var idP_Playlist = document.forms["frmVideoplayer"]. elements["selPlaylist"].value; if(idP_Playlist!=-1) { if(firstShow) { itv = setInterval("sendRequest("+idP_ Playlist+")",60000); } sendDataToFlash(idP_Playlist); } }
Listing 8.32: Erweiterung von Listing 8.29 um die Variablen firstShow und itv
Die Variable firstShow definiert, ob die Playlist das erste Mal geladen wird oder nicht. Wir benötigen diese Info, damit der Timer (setInterval) für die AJAXAbfrage gestartet wird, denn bevor eine Playlist das erste Mal gewählt wurde, bringt eine AJAX-Anfrage an den Server zum Überprüfen eventuell neu hinzugekommener Videos nichts. Wurde also eine Playlist ausgewählt, wird ein Intervall (itv) gestartet, das alle 60 Sekunden eine Funktion sendRequest mit dem Übergabeparameter
V I D E O P L AY E R ( A C T I O N S C R I P T 3 . 0 )
idP_Playlist aufruft. Diese Funktion erzeugt eine Anfrage an die Datenbank über
das im folgenden Listing dargestellte Script: var myXMLHttpRequest = createRequestObject(); function sendRequest(idP_Playlist) { myXMLHttpRequest.open("GET", "getnewestvideo.php?idP_Playlist="+idP_ Playlist, true); myXMLHttpRequest.onreadystatechange = handleRequest; myXMLHttpRequest.send(null); }
Listing 8.33: Anfrage an die Datenbank über die Datei getnewestvideo.php, die als GET-Parameter idP_Playlist übermittelt bekommt.
Nachdem eine XMLHttpRequest-Instanz erzeugt wurde (die dafür verantwortliche Funktion createRequestObject wurde im Kapitel zu AJAX hinlänglich beschrieben, deshalb verzichte ich an dieser Stelle auf die Erklärung der Funktion), kann die Verbindung zur Datei getnewestvideo.php geöffnet (myXMLHttpRequest.open), der Instanz ein Eventhandler zugewiesen (myXMLHttpRequest.onreadystatechange) und die Anfrage versandt werden (myXMLHttpRequest.send). Der Eventhandler handleRequest, der bei jeder Änderung des Status der AJAX-Anfrage aufgerufen wird, stellt sich folgendermaßen dar: function handleRequest() { if(myXMLHttpRequest.readyState==4) { if(firstShow) { firstShow = false; newestVideo = parseInt(myXMLHttpRequest.responseText); } else { proveReturner(myXMLHttpRequest.responseText); } } }
Listing 8.34: Der Eventhandler sorgt für den korrekten Aufruf der Funktion proveReturner.
Sollte der Eventhandler erkennen, dass die Eigenschaft readyState den Wert 4 hat (Übermittlung der Daten vom Server zur XMLHttpRequest-Instanz abgeschlossen), wird zunächst überprüft, ob diese Anfrage das erste Mal stattgefunden hat (firstShow==true). In diesem Fall wird zunächst firstShow=false gesetzt und die Variable newestVideo auf den Rückgabewert von getnewestvideo.php gesetzt (dies ist wie oben beschrieben der Timestamp des neuesten Videos in der Playlist). Da es sich in diesem Fall um den ersten Aufruf der AJAX-Anwendung gehandelt hat, muss auch noch nicht überprüft werden, ob ein neueres Video vorhanden ist (die Videos zur Play-
423
424
KAPITEL 8
list wurden gerade zuvor das erste Mal geladen). Sollte hingegen firstShow==false sein, wird die Funktion proveReturner aufgerufen, die als Übergabeparameter den Wert responseText erhält: function proveReturner(timestamp) { if(newestVideo<parseInt(timestamp)) { newestVideo = parseInt(timestamp); var myswf = getFlashElement("myswf"); myswf.newVideoAvailable(); } }
Listing 8.35: Die Funktion proveReturner überprüft, ob das neueste Video bereits Bestandteil der schon geladenen Playlist ist.
Bei Aufruf von proveReturner wird verglichen, ob der Timestamp des ermittelten Videos größer als der Timestamp des zuletzt (vor 60 Sekunden) ermittelten Videos ist. Ist dies der Fall, wurde also zwischenzeitlich ein neues Video in die Datenbank geschrieben – somit muss Folgendes getan werden: 1.
Der Timestamp des somit „neuesten“ Videos muss gespeichert werden, damit man in 60 Sekunden mit diesem Timestamp vergleichen kann: newestVideo = parseInt(timestamp);.
2.
Es muss Flash mitgeteilt werden, dass (zumindest) ein neues Video vorhanden ist: myswf.newVideoAvailable();.
Ob in den letzten 60 Sekunden ein oder mehrere neue Videos hinzugekommen sind, ist letztlich egal, denn Flash wird seinerseits die komplette Playlist neu laden und erhält somit alle neuen Videos. Der Flash-Teil ist nicht wesentlich aufwändiger, jedoch mussten einige Änderungen in der Struktur vorgenommen werden: 1.
Sämtlicher Code befindet sich nun in einem einzigen Bild der Zeitleiste.
2.
Der Aufbau der Bühne erfolgt ereignisorientiert: 1.
Die Funktion loadXMLVideodata (diese wird von JavaScript aufgerufen) steuert den Aufbau. Sobald sie aufgerufen wird, wird die Funktion loadXML aufgerufen.
2.
Sobald für loadXML das Ereignis COMPLETE auftritt („XML-Daten geladen“), wird die Bühne aufgebaut. Da die Funktion loadXML öfter als nur einmal aufgerufen wird (sobald ein neues Video entdeckt wurde und der User dieses neue Video in die Abspielliste aufgenommen hat, wird diese Funktion erneut
V I D E O P L AY E R ( A C T I O N S C R I P T 3 . 0 )
aufgerufen), müssen wir zwischen dem ersten und allen folgenden Aufrufen unterscheiden: Im Fall des ersten Aufrufs generieren wir eine TextArea-, eine ComboBox- und eine FLVPlayback-Komponente und danach den Inhalt der ComboBox für die Abspielliste. Für alle weiteren Aufrufe wird nur der Inhalt der ComboBox neu generiert. 3.
Bei Aufruf der Funktion newVideoAvailable durch JavaScript und positiver Bestätigung der Aufnahme des Videos durch den User wird die Funktion loadXML erneut ausgeführt und das oben beschriebene Prozedere geschieht von neuem.
Die Funktion newVideoAvailable setzt zunächst das Infofenster in den Vordergrund (setChildIndex) und blendet es dann ein: function newVideoAvailable():void { var topPosition:uint = numChildren - 1; setChildIndex(mcNewVideoInfo, topPosition); mcNewVideoInfo.visible = true; }
Kurz zum Infofenster, sobald ein neues Video von AJAX entdeckt wurde: Der Einfachheit halber wurde das Infofenster „Ein neues Video ist vorhanden...“ als MovieClip in Flash ausgeführt und nicht per ActionScript erzeugt. Der Code zu den beiden Buttons „Nein“ und „Ja“ ist wie folgt: function cancelNewVideolist(myEvent:MouseEvent):void { mcNewVideoInfo.visible = false; } function loadNewVideolist(myEvent:MouseEvent):void { mcNewVideoInfo.visible = false; loadXML(idP_Playlist); } mcNewVideoInfo.btnNein.addEventListener(MouseEvent.MOUSE_ UP,cancelNewVideolist); mcNewVideoInfo.btnJa.addEventListener(MouseEvent.MOUSE_UP,loadNewVideolist);
Listing 8.36: Die Eventlistener der Buttons „Nein“ und „Ja“ für die Aufnahme eines neuen Videos in die Abspielliste
Im Fall eines Klicks auf den „Nein“-Button wird lediglich das Infofenster (mcNewVideoInfo) wieder ausgeblendet, im Fall eines Klicks auf den „Ja“-Button wird zusätzlich (wie oben beschrieben) die Funktion loadXML aufgerufen. Die Variable idP_Playlist ist eine Variable auf root-Ebene und somit „global“. Und dann geht alles seinen Lauf ...
425
426
KAPITEL 8
XML im Cache?
Einen wichtigen Punkt sollte man nicht außer Acht lassen: Browser wie Server neigen dazu, XML-Daten (auch solche, die von PHP erzeugt wurden) im Cache abzulegen. Um dies sehr einfach zu umgehen, hängt man an die XML-Anfrage einen zufälligen String an, sodass dem Server (wie Browser) eine neue Anfrage mit neuen GET-Variablen vorgegaukelt wird: var dStr:String = "×tamp="+new Date().getTime(); var theURL:String = "playlist.php?idP_Playlist="+PlaylistID+"&CacheBuste r="+Math.random()+dStr;
Listing 8.37: Ein sehr zufälliger String wird an die Anfrage angehängt.
Der Zufallsstring setzt sich aus dem aktuellen Datum, der aktuellen Zeit und einer Zufallszahl zwischen 0 und 1 zusammen – das sollte Zufall genug sein ... Die entsprechenden Dateien finden Sie auf der Buch-CD unter folgenden Namen: u Flash-Datei: videoplayer_03.fla u XHTML-Datei: videoplayer_01i.php u XML-basierte PHP-Datei (Playlist): playlist.php u Ermitteln neuer Videos in der Datenbank: getnewestvideo.php u Include-Datei zum Verbindungsaufbau mit der Datenbank: includes/connectdb.inc.
php
8.3.6 Arbeiten mit Cue-Points Hierzu erweitern wir die zuvor entwickelte Flash-Anwendung videoplayer_03.fla und speichern sie unter dem Namen videoplayer_04.fla. Um mit in FLV-Dateien eingebetteten CuePoints zu arbeiten, stellt uns Flash folgende wichtige Eigenschaften, Methoden und Ereignisse zur Seite: u MetadataEvent.METADATA_RECEIVED: Dieses Ereignis tritt auf, sobald Meta-
daten (dazu gehören auch CuePoints) von der FLV-Datei gelesen werden konnten – dies gilt es abzuwarten. u Aus dem Array FLVPlayback.metadata.cuePoints können sämtliche Cue-
Points ausgelesen werden. Diese sind darin als Objekte abgelegt: u type:String: Typ des CuePoint. Mögliche Werte sind „event“ oder „navigati-
on“. Siehe hierzu auch die Ausführungen im Abschnitt 8.3.2. u name:String: Name des CuePoint u time:Number: Eine auf drei Kommastellen genaue Zahl, die den Zeitpunkt des
CuePoint angibt
V I D E O P L AY E R ( A C T I O N S C R I P T 3 . 0 )
u parameters:Object: Ein optionales Objekt (beinhaltet Name-Wert-Paare),
das beim Erstellen der CuePoints mit beispielsweise dem Flash Video Encoder erstellt wurde Die wichtigen Parameter sind name und time, sofern man sich über den Typ des CuePoint im Klaren ist. In Flash fügen wir der FLVPlayback-Instanz zunächst einen Eventhandler für das Ereignis METADATA_RECEIVED zu: myVideoplayer.addEventListener(MetadataEvent.METADATA_RECEIVED, EMetadata);´ function EMetadata(myEvent:MetadataEvent):void { loadCuePoints(myVideoplayer.metadata.cuePoints); }
Sobald Metadaten vorhanden sind, wird die Funktion loadCuePoints aufgerufen: function loadCuePoints(myData:Array):void { myCombobox2.removeAll(); for(var i:Number = 0; i<myData.length; i++) { myCombobox2.addItem({ label:myData[i].name, data:myData[i].time }); } }
Listing 8.38: Laden der CuePoint-Informationen in eine ComboBox
In einer for-Schleife werden alle CuePoints durchlaufen, wobei die Beschriftung der ComboBox den Namen des CuePoint (myData[i].name) und der Wert der ComboBox den Zeitpunkt des CuePoint (myData[i].time) erhält. Um mit dieser ComboBox myCombobox2 überhaupt arbeiten zu können, muss sie natürlich zuvor angelegt werden: var myCombobox2:ComboBox; function createComboBoxCuePoints():void { myCombobox2 = new ComboBox(); myCombobox2.move(44,460); myCombobox2.width = 200; addChild(myCombobox2); myCombobox2.addEventListener(Event.CHANGE, EChange2); }
Listing 8.39: Erzeugen der zweiten ComboBox unterhalb der bestehenden ComboBox für die Abspielliste
427
428
KAPITEL 8
Die Funktion createComboBoxCuePoints wird beim Auftreten des COMPLETE-Ereignisses beim Laden einer XML-Datei aus der Funktion EXMLComplete aufgerufen: function EXMLComplete(myEvent:Event):void { mcLade.visible = false; myXML = new XML(myEvent.target.data); myXML.ignoreWhitespace = true; if(firstShow) { firstShow = false; createTextArea(); createFLVPlayback(); createComboBox(); createComboBoxCuePoints(); } loadComboBoxData(); }
Das Ergebnis spricht wie immer für sich: ABBILDUNG 8.29 Die geladenen CuePoints, über die man direkt Abschnitte in der FLV-Datei anspringen kann
Viel Spaß beim Umsetzen!
Stichwortverzeichnis Symbole $-Zeichen 8 $_GET 261 $HTTP_GET_VARS 262 $HTTP_POST_VARS 262
A AC_FL_RunContent 178 ActionScript 1.0 6 ActionScript 2.0 6 ActionScript-Referenz 349 addEventListener 362 Addition 18 Aktionen auslösen 172 all 170 appendChild 290 Array 10, 24 assoziatives 25, 257 attributes 282 auslesen 257 Elementanzahl 36 erstellen 24, 25 indiziertes 24 in Flash 282 Länge 36 superglobales 14 übergeben 45 Attribute 282 Ausgeben von XML-Daten 286 Auskommentieren 7 Automatische Typisierung 13
B Bedingungen 28 break 41
C Cache 426 Caching 53 verhindern 54
Case-sensitive 10 Child 272 childNodes 273 classid 169 clearInterval 351 closdir() 356 codebase 169 contentType 289 continue 41 Cookies 47 Gültigkeit 49 Session 50 setzen 48 Verfallsdatum 49 count () 261 createElement 290
D data 314 Daten an Browser 181 an Flash 168 an Flash senden 172 aus Datenbank 253 Datenbank speichern 295 schreiben 260 übergeben 260 verschicken 241 versenden, GET 260 versenden, POST 262 von Flash auslesen 295 Datenbank auswählen 255 Verbindungsaufbau 255 Datentypen 8, 10 Flash 11 PHP 10 Datum 54 Dekrement 18 die 255 do..while-Schleife 39
Document Object Model 170 DOM 56, 170
E Ebenen Bildnamen 172 embeds 171 Endlosschleife 32 Entwicklung Anforderungen 338 Ereignisbehandlungsroutine 245 Ereignisparameter 245 Ereignisprozedur 245, 250, 341 Ereignisroutinen 341 ExternalInterface 184 available 187 Rekursion 202
F firstChild 273 Flash Datenübergabe 294 JavaScript aufrufen 182 Flash Video Encoder 385 FlashVars 179 FLV-Format 377 FLVPlayback 378 for-Schleife 31 Abbruchbedingung 32 Syntax 33 for...each-Schleife 37 Syntax 37 for...in-Schleife 37, 342 Formulardaten versenden 15 Formulare 176 Daten verschicken 260 function 42
STICHWORTVERZEICHNIS
430
Funktionen 41 Arrays 45 aufrufen 44 deklarieren 42 lokale Variablen 45
J
N
JavaScript 6, 158, 167 Flash ansprechen 172 Flash-Aktion auslösen 172 Wert übergeben 172
navigateToURL 323 nodeValue 274 Null 12
G
K
GET 15, 260 getElementById 170 getURL 181 getURL() 260 GET 261 POST 263 Gleichheit strikte 22 Grafiken hochladen 265 Grunddatentypen 11
Klammern geschweifte 30 Kommentare 7, 58 einzeilige 7 mehrzeilige 7 Komponente XMLConnector 298
On2VP6 376 onLoad 243, 341 opendir() 356 Operatoren 17, 18 arithmetisch 17 Bit 21 logische 21 Rangordnung 21, 22 Vergleich 22 Zuweisung 18 Ordner öffnen 356
H hasChildNodes () 274 Header 53 header() 53 HTML JavaScript ausführen 181 HTTP 47 https 49
I id3-Objekt 349 ID3-Tag 338 auslesen 349 if Syntax 28 if-Bedingungen 28 ignoreComments 329 ignoreProcessingInstructions 329 ignoreWhite 271 ignoreWhitespace 329 Inkrement 18 innerHTML 150 int 12 Integer 10 is_dir() 357
L Ladevorgang fehlgeschlagen 251 wiederholen 244 Lautstärkeregler 353 length 334 list 261 loaded 243, 341 loadVariables 72 LoadVars 72, 165, 225, 241, 243, 263 Daten versenden 264 LoadVars-Klasse 72 LoadVars-Objekt anlegen 263 Variablen anlegen 263
M Modulo 19 MP3 338, 376 streamen 346 Multimedia 338 mysql_fetch_array 257 mysql_pconnect 255 mysql_query 256 mysql_select_db 255
O
P parsen 266 PDF-Datei hochladen 265 PHP XML generieren 283 PHP-Referenz 15 POST 15, 262 Programmieren objektorientiert 6
R readdir() 356 readyState 127 Referenzdatentypen 11, 12 register_globals 15 Regular Expression 160 responseText 127, 234 responseXML 127, 234 return 43, 45 RSS 72
S Schleifen 31 break 41
STICHWORTVERZEICHNIS
continue 41 Durchläufe 31 send 294 send() 260, 263 sendAndLoad() 264 sendToURL 320 Server Verbindung abgebrochen 244 Session 50 initialisieren 51 löschen 53 Variablen entfernen 53 Variablen speichern 51 Session-ID 50 setInterval 350 setRequestHeader 136 SetVariable 170 SGML 168 Sibling 272 SimpleXML 56 Skins 379 Sonderzeichen 242 Soundobjekt 345 loadSound 346 onSoundComplete 348 SoundTransform 372 Streaming 346 String 9, 10, 262 verketten 261 verknüpfen 20 substr 357 substr() 357 Subtraktion 18 switch Syntax 30 switch-Bedingungen 30 switch-case 30
T TEXT URLLoaderDataFormat 315 text 334 TextArea 175
Textdatei Daten einlesen 241 einlesen 267 toString 270
U uint 12 undefined 12 Ungleichheit strikte 22 URL-Codierung 241, 242 URLLoader 309 URLRequest 309 Usability 253
V Variablen 8 einlesen 241 globale 13 Gültigkeitsbereiche 13 in Arrays 280 lokale 13 nicht deklarierte 14 superglobale 14 Variablendeklaration 8 explizit 9 globale 16 implizit 14 lokale 16 Variablennamen 9 dynamisch erzeugen 277 Variablentypen 9 VARIABLES URLLoaderDataFormat 315 Verzeichnisse auslesen 356 volume 372
W Werte zuweisen 19 WHILE-Schleife 40 Wurzelelement 58, 272
X XHTML 167 XML 56, 168, 233, 266, 325 Arrays auslesen 273 Attribute 339 Attribute auslesen 61 auf Elemente zugreifen 272 auswerten 275 Befehle 266 Child 272 Dokumente 56 einlesen 266 encoding 57 erstellen 62 Gültigkeit 57 Inhalt 57 in String umwandeln 270 Knoten 273, 274 Knoten auslesen 62 Prolog 57 Sibling 272 standalone 57 Syntax 59 versenden 294 version 57 Wohlgeformtheit 57 XML-Attribute speichern 342 XML-Baum 270 in Flash erzeugen 287 XMLConnector 298 xmlDecl 289 XML-Header 287 XMLHttpRequest 125 XML-Klasse 72 XML-konform 268 XML-Objekt 266, 325, 341 XML-Struktur 339
Z Zählvariable 31, 257 Zeitleistenvariablen 13 Zustände 21
431
Copyright Daten, Texte, Design und Grafiken dieses eBooks, sowie die eventuell angebotenen eBook-Zusatzdaten sind urheberrechtlich geschützt. Dieses eBook stellen wir lediglich als persönliche Einzelplatz-Lizenz zur Verfügung! Jede andere Verwendung dieses eBooks oder zugehöriger Materialien und Informationen, einschliesslich •
der Reproduktion,
•
der Weitergabe,
•
des Weitervertriebs,
•
der Platzierung im Internet, in Intranets, in Extranets,
•
der Veränderung,
•
des Weiterverkaufs
•
und der Veröffentlichung
bedarf der schriftlichen Genehmigung des Verlags. Insbesondere ist die Entfernung oder Änderung des vom Verlag vergebenen Passwortschutzes ausdrücklich untersagt! Bei Fragen zu diesem Thema wenden Sie sich bitte an: [email protected] Zusatzdaten Möglicherweise liegt dem gedruckten Buch eine CD-ROM mit Zusatzdaten bei. Die Zurverfügungstellung dieser Daten auf unseren Websites ist eine freiwillige Leistung des Verlags. Der Rechtsweg ist ausgeschlossen. Hinweis Dieses und viele weitere eBooks können Sie rund um die Uhr und legal auf unserer Website
http://www.informit.de herunterladen