Flash cs3, ajax und php

445

Transcript of Flash cs3, ajax und php

Page 2: Flash cs3, ajax und php

Flash CS3, AJAX und PHP

Page 3: Flash cs3, ajax und php
Page 4: Flash cs3, ajax und php

Flash CS3, AJAX und PHP

Ein Imprint von Pearson Education

München • Boston • San Francisco • Harlow, EnglandDon Mills, Ontario • Sydney • Mexico City

Madrid • Amsterdam

ADDISON-WESLEY

Uwe Mutz

Addison-Wesley Verlag
© Copyright-Hinweis
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.
praktit01
Notiz
Completed festgelegt von praktit01
praktit01
Notiz
MigrationConfirmed festgelegt von praktit01
Page 5: Flash cs3, ajax und php

Bibliografische Information Der Deutschen BibliothekDie 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/GermanyAlle Rechte vorbehaltenLektorat: Brigitte Bauer-Schiewek, [email protected]: Matthias KannengiesserKorrektorat: Petra KienleHerstellung: Claudia Bäurle, [email protected]: Ulrich Borstelmann, Dortmund (www.borstelmann.de)Einbandgestaltung: Marco Lindenbeck, webwo GmbH, [email protected] und Verarbeitung: Kösel Druck, Krugzell (www.koeselBuch.de)Printed in Germany

Page 6: Flash cs3, ajax und php

V

INHALTSVERZEICHNIS

Sieh' einer an … IX

Kapitel 1 Einleitung 1

Kapitel 2 Grundlagen der Programmierung 5

2.1 Programmierung in Flash 6

2.1.1 Anlehnung an JavaScript 6

2.1.2 Objektorientiertes Programmieren 6

2.2 Kommentare 7

2.2.1 Einzeilige Kommentare 7

2.2.2 Mehrzeilige Kommentare 7

2.2.3 Verschachtelte Kommentare 8

2.3 Variablen und Datentypen 8

2.3.1 Variablendeklaration 8

2.3.2 Variablennamen 9

2.3.3 Datentypen 10

2.3.4 Gültigkeitsbereiche von Variablen 13

2.4 Operatoren 17

2.4.1 Arithmetische Operatoren 17

2.4.2 Zuweisungsoperatoren 18

2.4.3 Bitoperatoren 21

2.4.4 Logische Operatoren 21

2.4.5 Vergleichsoperatoren 22

2.4.6 Rangordnung der Operatoren 22

2.5 Arrays 24

2.5.1 Indizierte Arrays 24

2.5.2 Assoziative Arrays 25

2.6 Bedingungen 28

2.6.1 if-Bedingung 28

2.6.2 switch-Bedingung 30

Page 7: Flash cs3, ajax und php

VI

2.7 Schleifen 31

2.7.1 for-Schleife 31

2.7.2 for...each- oder for...in-Schleife 37

2.7.3 do..while-Schleife 39

2.7.4 while-Schleife 40

2.8 Funktionen 41

2.9 Cookies 47

2.9.1 Exkurs HTTP 47

2.10 Sessions 50

2.10.1 session_start() 51

2.10.2 session_register() vs. $_SESSION 51

2.10.3 session_unregister() vs. $_SESSION 53

2.10.4 session_destroy() 53

2.11 Caching 53

2.12 XML auslesen und erstellen 56

2.12.1 Der Aufbau eines XML-Dokuments – Blitzeinführung 56

2.12.2 Auslesen einer XML-Struktur 60

2.12.3 XML-Dokumente erstellen 62

Kapitel 3 Basiswissen 65

3.1 PHP 66

3.2 JavaScript (AJAX) & DOM 66

3.2.1 „Kern-DOM“ 67

3.2.2 Alternativer Zugriff auf Objekte 69

3.3 Flash 72

3.3.1 Sinnvolle Kombination von Flash und PHP 72

3.3.2 Weitere Verbindungsmöglichkeiten zur Serverseite 73

3.3.3 ActionScript 3.0 – die wichtigsten Änderungen 73

Kapitel 4 AJAX – Asynchronus JavaScript and XML 119

4.1 Was ist AJAX? 120

4.2 Was ist AJAX nicht? 120

4.3 Der XMLHttpRequest 122

4.3.1 Details zum XMLHttpRequest-Objekt 125

4.3.2 AJAX im Einsatz 128

Page 8: Flash cs3, ajax und php

VII

4.4 Flash vs. AJAX 164

4.5 Flash & AJAX 165

Kapitel 5 Clientseitiger Datenaustausch – Flash & Javascript 167

5.1 Daten senden: Browser an Flash 168

5.1.1 Variante 1: JavaScript greift auf die SWF-Datei zu 168

5.1.2 Variante 2: Verwenden von HTML-Attributen zum Setzen von Variablen 179

5.2 Daten senden: Flash an Browser 181

5.2.1 Kontaktaufnahme mit getURL 181

5.3 Die ExternalInterface-Klasse – Flash 8 und höher 184

5.3.1 ExternalInterface-Klasse mit ActionScript 1.0/2.0 185

5.3.2 ExternalInterface-Klasse mit ActionScript 3.0 207

5.4 Flash & AJAX 208

5.4.1 Parameterübergabe: Text 209

5.4.2 Parameterübergabe: XML 233

Kapitel 6 Serverseitiger Daten austausch – Flash, PHP & Datenbank 239

6.1 Drei Technologien im Einsatz 240

6.2 Das LoadVars-Objekt 241

6.3 Die Basis: das XML-Objekt & ActionScript 2.0 266

6.3.1 Grundlegende XML-Befehle 266

6.3.2 Einlesen von XML-Daten 266

6.3.3 Ausgeben von XML-Daten in eine PHP-Seite 286

6.3.4 Die XMLConnector-Komponente 298

6.4 ActionScript 3.0: Neues und Änderungen 309

6.4.1 Das URLLoader- und URLRequest-Objekt 309

6.4.2 Der Aufbau: das XML-Objekt & ActionScript 3.0 325

Kapitel 7 Audio-Jukebox 337

7.1 Abfragen serverseitiger Informationen 338

7.2 Multimediale Anwendungen 338

7.3 Konzept der Jukebox 338

7.3.1 Playlist generieren 338

Page 9: Flash cs3, ajax und php

VIII

7.4 Jukebox in ActionScript 2.0 340

7.4.1 XML-Daten laden 341

7.4.2 Abspielen der Songs 344

7.4.3 ID3-Tags auslesen 349

7.4.4 Abspielsteuerung 351

7.4.5 Lautstärkeregler 353

7.5 Der PHP-Part 355

7.6 Jukebox in ActionScript 3.0 359

7.6.1 Allgemeine Änderungen 359

7.6.2 Änderungen beim Laden der XML-Daten 360

7.6.3 Änderungen im Soundobjekt 363

7.6.4 Änderungen in der Abspielsteuerung 363

7.6.5 Änderungen in der Lautstärkeregelung 370

7.6.6 Songs aus einer ComboBox abspielen 372

7.7 Mögliche Erweiterungen 374

Kapitel 8 Videoplayer (ActionScript 3.0) 375

8.1 Das Konzept des Videoplayers 376

8.2 Flash & Video 376

8.3 Die Umsetzung 378

8.3.1 Flash und die FLVPlayback-Komponente 378

8.3.2 Videos im FLV-Format 382

8.3.3 Dynamisches Verknüpfen der FLVPlayback-Komponente mit einem Video 392

8.3.4 Schritt 1: Abspielen einer Liste von Videos (Array) 394

8.3.5 Schritt 2: Abspielen einer Liste von Videos (XML) 401

8.3.6 Arbeiten mit Cue-Points 426

Stichwortverzeichnis 429

Page 10: Flash cs3, ajax und php

IX

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 entschie-den 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 LeserschaftBevor 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 :

Flash:

Die „Zeit“: Der Umgang mit der Zeitleiste ist kein Problem, ebenso wissen Sie über Schlüsselbilder, benannte Bilder und Szenen Bescheid.

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.

.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 Web-dokument eingebunden. Die Problematik verschiedener Browser-Systeme (Einbinden der SWF-Dateien mittels <embed> oder <object>) kennen Sie ebenso.

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 Pro-grammierung sind Ihnen bekannt und ein wenig programmiert haben Sie auch schon.

u

u

u

u

u

Page 11: Flash cs3, ajax und php

X

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. Wahr-scheinlich 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.

PHP und MySQL:

Server- versus Clientseite: PHP ist eine serverseitige, JavaScript eine clientseitige Pro-grammiersprache – kein Thema, das wissen Sie.

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.

Datenbanken: Die Grundlagen relationaler Datenbanken kennen Sie, ebenso haben Sie bereits einmal mit MySQL in Zusammenhang mit einer datenbankbasierten Weban-wendung gearbeitet. Das System PHPMyAdmin ist Ihnen auch ein Begriff und Tabel-len 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 fol-genden 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 Daten-banksystemen realisiert haben, dann werden Sie die in diesem Buch beschriebenen Inhalte nicht befriedigen. Das Anwenden von Flash-Komponenten zur Kommunikation mit serversei-tigen (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 schrei-ben, denn dies geht meist auf Kosten der Lesbarkeit und somit der Verständlichkeit des Pro-grammierten. 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.

u

u

u

u

u

Page 12: Flash cs3, ajax und php

XI

Ein immerwährendes Problem in der Welt des Internets sind die Browser: verschiedene Gene-rationen 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 viel-mehr Rücksicht auf die gängigen Browser nehmen:

Microsoft Internet Explorer 6 unter Windows

Microsoft Internet Explorer 7 unter Windows

Firefox 2 unter Windows und Mac OS X

Opera 9.1 unter Windows und Mac OS X

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 beant-worten.

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

u

u

u

u

u

Page 13: Flash cs3, ajax und php

XII

mich sicherlich schimpfen werden, dass sie hier namentlich nicht erwähnt sind („… wie konn-test 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

Page 14: Flash cs3, ajax und php

1EINLEITUNG

Flash, AJAX und PHP – das wird spannend!

Vor kurzem ist die neueste Version von Flash in deutscher Ver-sion 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“. Ange-fangen 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 ent-wickelt worden. Gerade bei Videos bietet sich ActionScript 3.0 geradezu an. Der zweite große Workshop im Buch – der Audio-player – ist sowohl in ActionScript 2.0 als auch 3.0 entwickelt. Ideal also, um einen Vergleich der beiden Versionen zu ziehen.

Page 15: Flash cs3, ajax und php

K A P I T E L 12

Mein Tipp in Bezug auf die beiden Versionen (ActionScript 1.0 mal außer Acht gelas-sen): 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 umge-stellt hat.

Dieses Buch wird sich nur sehr oberflächlich mit allen Komponenten und Möglich-keiten befassen, die im Rahmen der Entwicklungsumgebung auf der Bühne platziert werden. Umso mehr ist der Fokus auf die Programmierung gerichtet. Ein Flash Com-munication Server wird ebenso wenig ein Thema sein wie Elemente der FileReference-Klasse usw. Primäres Ziel des Buchs ist es, die Möglichkeiten der Zusammenarbeit dreier Technologien zu zeigen und nicht jede Technologie für sich.

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?

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, son-dern kennt die User seiner Webanwendungen. Genau aus diesem Grund ist es manch-mal 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.

PHPPHP

AJAXAJAX

Page 16: Flash cs3, ajax und php

E I N L E I T U N G 3

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].

Page 17: Flash cs3, ajax und php
Page 18: Flash cs3, ajax und php

2GRUNDLAGEN 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 erhal-ten 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.

Page 19: Flash cs3, ajax und php

K A P I T E L 26

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 FlashAnders 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:

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 fin-den Sie in der ActionScript-Referenz unter dem Schlagwort „ActionScript 2.0 Migra-tion“, auf die wesentlichen Änderungen gehen wir im Weiteren noch genauer ein. Bitte beachten Sie jedoch, dass die einleitenden Kapitel dieses Buchs keinesfalls ein Action-Script-Buch und schon gar kein ActionScript 3.0-Buch ersetzen können!

Kein allumfas-sendes Werk zu PHP, JavaScript

und ActionScript!

Kein allumfas-sendes Werk zu PHP, JavaScript

und ActionScript!

MovieClipsBei der Programmierung

mit MovieClips ist es von besonderer Bedeutung, den

verwendeten MovieClips einen Namen zu geben.

Page 20: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 7

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 beglei-tend dazu einige kleine Beispiele programmieren.

Die folgenden Ausführungen können – wenn nicht anders vermerkt – für die Pro-grammiersprachen JavaScript, ActionScript und PHP verstanden werden.

2.2 Kommentare Gleich zu Beginn dieses Kapitels möchten wir Sie auf die Möglichkeit der Kommentie-rung 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 Kom-mentar. 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.

Page 21: Flash cs3, ajax und php

K A P I T E L 28

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 KommentareVerschachtelte Kommentare sind in PHP nicht erlaubt. Das Ausführen Ihres Pro-gramms 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 Ver-wendung 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.

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.

In sehr vielen anderen Programmiersprachen muss eine Variable vor ihrer Verwen-dung 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.

PHPPHP

Variablen -deklaration

immer am Anfang

Variablen -deklaration

immer am Anfang

Page 22: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 9

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

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üs-sen 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 verschie-denen 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:

ActionScriptActionScript

JavaScriptJavaScript

Page 23: Flash cs3, ajax und php

K A P I T E L 210

Variablen …

müssen in PHP mit einem Dollarzeichen „$“ beginnen (in Flash und JavaScript ist dies nicht der Fall).

dürfen keine Leerzeichen enthalten.

dürfen nur aus Buchstaben und Ziffern bestehen, wobei das erste Zeichen nach dem Dollarzeichen ein Buchstabe sein muss.

dürfen Groß- und Kleinbuchstaben enthalten. PHP und ActionScript (ab Version 2.0) sind Case-sensitive und erkennen die Unterschiede.

dürfen keine Umlaute wie ä, ö, ü und kein ß enthalten.

dürfen als einziges Sonderzeichen den Unterstrich „_“ enthalten.

dürfen nicht wie Befehle der Sprache PHP, JavaScript bzw. ActionScript benannt sein (eine Auflistung aller Befehle entnehmen Sie bitte den jeweiligen Sprachrefe-renzen).

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. Originali-tä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.

In PHP gibt es folgende Datentypen :

Ganze Zahlen (Integer )

Zahlen mit Nachkommastellen (Float)

Zeichenketten (String )

Felder (Array )

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.

u

u

u

u

u

u

u

u

u

u

u

u

PHPPHP

Page 24: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 11

Ein kleines Beispiel in PHP:

<?php

//Anlegen der Variablen

$plNickname = "Uwe"; // Uwe wird in der Variable $plNickname gespeichert. (Typ: String)

$pointsUwe = 24.3; // Variable $pointsUwe bekommt den Wert 24,3 (Typ: Float)

$bonuspoints = 10; // Variable $bonuspoints bekommt den Wert 10 (Typ: Integer)

$fi nal_points = 15; // Variable $fi nal_points hat den Wert 15 (Typ: Integer)

//Berechnung der neuen fi nal_points

$fi nal_points = $pointsUwe + $bonuspoints;

?>

<html>

<head><title>Uebung Variablen / Datentyp</title></head>

<body>

<?php

echo("Endstand von ");

echo($plNickname);

echo(": ");

echo($fi nal_points;)

?>

</body>

</html>

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 unter-scheidet zwischen „Grunddatentypen“ und „Referenzdatentypen“ (oder „integrierten Datentypen “). Des Weiteren existieren die speziellen Datentypen Null und undefi-ned.

ActionScriptActionScript

Page 25: Flash cs3, ajax und php

K A P I T E L 212

Grunddatentypen sind:

Number: numerische Variablen (Zahlen)

String: Textvariablen

Boolean: Variablen, die nur die Werte true oder false speichern können

Diese Datentypen werden verwendet, um mit Variablen zu arbeiten. Die Referenzda-tentypen (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 spre-chen kommen.

Referenzdatentypen sind also unter anderem:

MovieClip

TextField

Date

Der Datentyp Null deutet an, dass hier kein Wert existiert bzw. keine Daten vorhan-den sind. undefined kennzeichnet, dass einer Variable noch kein Wert zugewiesen wurde.

Seit ActionScript 3.0 existieren neben Number nun auch die numerischen Datentypen int (Integer) und uint , wobei uint für „unsigned integer“ (Ganzzahl ohne Vorzei-chen) steht:

int: eine Ganzzahl (= Zahl ohne Kommastelle)

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";

u

u

u

u

u

u

u

u

ActionScript 3.0: int und uint

ActionScript 3.0: int und uint

Page 26: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 13

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 nach-folgenden 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 beispiels-weise 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 Typ-umwandlung 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ültigkeits-bereichs existiert die Variable dann ganz einfach nicht (oder nicht mehr). Insbeson-dere 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 Action-Script):

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.

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.

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 Gedan-ken über lokale, globale und Zeitleistenvariablen machen. Mit Einführung von Funk-tionen wird sich dies ändern, aber darauf werden wir Sie zu gegebenem Zeitpunkt noch konkret hinweisen.

u

u

u

ActionScript 3.0ActionScript 3.0

Page 27: Flash cs3, ajax und php

K A P I T E L 214

Flash: nicht deklarierte lokale Variablen in CodeblöckenIn 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

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.

// Defi nition 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 Funk-tion showData() keine Variable mit dem Namen $textstring. Um dieses Problem nun zu lösen, werden wir $GLOBALS[] einsetzen.

// Defi nition 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.

PHPPHP

Page 28: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 15

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 text-string 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 For-mulardaten sehr erleichtern:

$GLOBALS

$_SERVER

$_GET

$_POST

$_COOKIE

$_FILES

$_ENV

$_REQUEST

$_SESSION

Formulardaten versenden

Im ersten Kapitel dieses Buchs hörten Sie bereits von GET und POST . Wenn Sie Formu-lardaten von einer Seite zu einer anderen Seite schicken und die gesendeten Daten wei-terverarbeiten 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 Text-feld 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ög-lichkeiten zum Auslesen des Textfelds, je nachdem, ob register_globals auf off oder on gesetzt ist.

Wenn off eingestellt ist, dann können Sie nur über das superglobale Array $_POST (oder $_GET) auf den Inhalt des Textfelds „Vorname“ zugreifen.

$_POST[‚Vorname'];

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.

u

u

u

u

u

u

u

u

u

u

u

u

register_globalsregister_globals

Page 29: Flash cs3, ajax und php

K A P I T E L 216

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.

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 VariablenDer 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!

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.

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

ActionScript bis inklusive 2.0

ActionScript bis inklusive 2.0

ActionScript 3.0ActionScript 3.0

JavaScriptJavaScript

Page 30: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 17

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 loka-le 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 „Addi-tion“ oder „+“:

$anzahl1 = 23;

$anzahl2 = 15;

$anzahl3; //bis jetzt wurde anzahl3 noch kein Wert zugewiesen

$anzahl3 = $anzahl1 + $anzahl2;

Listing 2.13: Eine Addition in PHP ...

var anzahl1 = 23;

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

PHPPHP

JavaScriptJavaScript

ActionScriptActionScript

Page 31: Flash cs3, ajax und php

K A P I T E L 218

Operatoren

Numerische Werte kann man mithilfe von folgenden Operatoren miteinander ver-knü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 Beispiel

+ Addition (dies gilt in JavaScript und Flash für numerische ebenso wie für String-Variablen)

$c=$a+$b; (PHP) bzw. c=a+b; (JavaScript, Flash) liefert $c=27

- Subtraktion $c=$a-$b; (PHP) bzw. c=a-b; (JavaScript, Flash) liefert $c=17

* Multiplikation $c=$a*$b; (PHP) bzw. c=a*b; (JavaScript, Flash) liefert $c=110

/ Division $c=$a/$b; (PHP) bzw. c=a/b; (JavaScript, Flash) liefert $c=4.4

% Modulo-Rechnung (gibt den Rest einer Division zurück)

$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 Dekrement operatoren verwenden.

$variable++;

$variable--;

Listing 2.16: In PHP ...

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 Zuweisungsope-ratoren, die Sie in Tabelle 2.2 aufgelistet sehen. Der verwendete Wert kann selbstver-stä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.

PHPPHP

JavaScript und ActionScript

JavaScript und ActionScript

Page 32: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 19

Zuweisungsoperator Operation

variable = Wert Einer Variable wird ein Wert zugewiesen .

variable += Wert Eine Variable wird um einen Wert erhöht

variable -= Wert Eine Variable wird um einen Wert verringert.

variable *= Wert Eine Variable wird mit einem Wert multipliziert.

variable /= Wert Eine Variable wird durch einen Wert dividiert.

variable %= Wert 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

$variable2 = 20; // variable2 bekommt den Wert 20

$variable1 += $variable2; // variable2 wird zu variable1 addiert

Listing 2.18: Der Operator += in PHP …

var variable1 = 23;

var variable2 = 20;

variable1 += variable2;

Listing 2.19: ... in JavaScript ...

var variable1:Number = 23;

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

$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 ...

PHPPHP

JavaScriptJavaScript

ActionScriptActionScript

PHPPHP

JavaScriptJavaScript

Page 33: Flash cs3, ajax und php

K A P I T E L 220

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 Restzahl als Ergebnis zurück, also:

23%20 = 3

Einige weitere Beispiele zur Modulo-Rechnung:

23%5 = 3

23%6 = 5

23%23 = 0

8%2 = 0

Verknüpfung von Strings

Ein weiterer wichtiger Operator dient zur Verknüpfung von Strings .

In PHP wird dafür der Operator .= verwendet. In unserem Beispiel aus Listing 2.23 würde die Variable text nach der Zuweisung den Text „Name = Uwe“ im Browser ausgeben.

$text = "Name = ";

$text .= "Uwe";

Listing 2.23: Verknüpfung von Texten in PHP

In JavaScript und ActionScript erfolgt die Verknüpfung von Texten mithilfe des Addi-tions-Operators +=. Die Ausgabe würde hier „Name = Uwe“ lauten.

var myText = "Name = ";

myText += "Uwe";

Listing 2.24: Verknüpfung von Texten in JavaScript ...

ActionScriptActionScript

PHPPHP

JavaScript und ActionScript

JavaScript und ActionScript

Page 34: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 21

var myText:String = "Name = ";

myText += "Uwe";

Listing 2.25: ... und in ActionScript

2.4.3 Bitoperatoren Bitoperatoren sind hier nur der Vollständigkeit halber erwähnt. Sie werden bei Variab-len mit Werten in Bit- oder Byteform eingesetzt. Nähere Informationen dazu entneh-men Sie bitte der jeweiligen Sprachreferenz.

2.4.4 Logische Operatoren Logische Operatoren zählen sicher zu den wichtigsten Bestandteilen einer Program-miersprache. Sie werden dafür verwendet, um Zustände (true oder false) mitein-ander zu verknüpfen. Beispielsweise könnte man bei einer elektrischen Wechselschal-tung entweder den einen oder den anderen Lichtschalter betätigen, damit das Licht aufleuchtet – in diesem Fall würde man die beiden Lichtschalter gedanklich mit einem „oder“ verknüpfen.

Logische Operatoren Operation

and logische UND-Verknüpfung (in Flash veraltet)

&& logische UND-Verknüpfung

or logische ODER-Verknüpfung (in Flash veraltet)

xor logische Entweder-oder-Verknüpfung (gilt nur für PHP)

|| logische ODER-Verknüpfung

! logisches NICHT

Tabelle 2.3: Die wichtigsten logischen Operatoren

Punkt vor Strich

Wichtig ist immer die Rangordnung der Operatoren : Ähnlich wie in der Mathematik-stunde in der Schule gilt die Punkt-vor-Strich-Regel, wobei && der Punkt- und || der Strichrechnung zuzuweisen ist. Sollte ein Rechenvorgang allein mit Punkt- und Strich-rechnung nicht ausführbar sein, stehen Ihnen genau wie in der Algebra Klammern zur Verfügung, wobei dieselben Klammersetzungsregeln gelten.

Werte prüfenMit den logischen Operatoren ist es weiterhin möglich, in Kombination mit Bedingungen Werte auf „Richtig“ (true) oder „Falsch“ (false) zu prüfen. Beispiele finden Sie etwas später bei den Bedingungen im Abschnitt 2.6.

Der Grund für jeweils zwei logische UND- und ODER-Verknüpfungen in PHP liegt einzig in der Rangordnung der Operatoren: && ist „stärker“ als and und wird deshalb zuerst ausgeführt; Gleiches gilt für || vor or.

Page 35: Flash cs3, ajax und php

K A P I T E L 222

Die Wirkungsweise der einzelnen Operationen sehen Sie in der nachfolgenden Tabelle.

Variable 1 Variable 2 AND- (&&-) Verknüpfung OR- (||-) Verknüpfung XOR-Verknüpfung (nur PHP)

false false false false falsefalse true false true truetrue false false true truetrue true true true false

Tabelle 2.4: Verschiedene Verknüpfungsoperatoren angewandt auf zwei Variablen

2.4.5 Vergleichsoperatoren Um Werte miteinander zu vergleichen, benötigen wir Vergleichsoperatoren. Folgende Möglichkeiten stehen uns dabei zur Verfügung:

Vergleichsoperatoren Operation

== Gleichheit der Werte

!= Ungleichheit der Werte

=== Gleichheit der Werte und des Datentyps („Strikte Gleichheit“ )

!== Ungleichheit der Werte oder des Datentyps („Strikte Ungleichheit “)

> größer als

< kleiner als

>= größer als oder gleich

<= kleiner als oder gleich

Tabelle 2.5: Vergleichsoperatoren

Das Resultat eines Vergleiches ist immer ein boolescher Wert, denn einem Vergleich geht stets eine „Frage“ voran, wobei die Antwort auf diese Frage immer entweder „ja“ (true) oder „nein“ (false) lautet. Der Vergleich selbst ist nichts anderes als beispiels-weise die Frage, ob ein Wert kleiner gleich einem anderen Wert ist.

2.4.6 Rangordnung der Operatoren Nachfolgend finden Sie die Rangordnung der Operatoren, wobei diejenigen, die in derselben Zeile aufgeführt sind, gleichberechtigt sind. Am stärksten sind demnach die Operatoren !, ~, ++ und --, am schwächsten das or (die bitweisen Operatoren haben wir in diese Liste ebenso mit aufgenommen):

1. ! , ~, ++, --

2. *, /, %

3. +, -, .

4. <<, >>

5. <, <=, >, >=

Page 36: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 23

6. ==, != , ===, !==

7. &

8. |

9. &&

10. ||

11. ?, :

12. =, +=, -=, *=, /=, .= , %=, &=, |=, <<=, >>=

13. and

14. or

In folgendem Beispiel wird mit diesen Rangordnungen gearbeitet.

var a:Number = 17, b:Number = -3, c:Number = 11;

var d:Number = 200, ergB:Boolean, ergN:Number;

var bool1:Boolean = true, bool2:Boolean = false;

ergN = ++a*17-d; //(1+17)*17-200=106; a hat sich von 17 auf 18 erhöht

ergB = ergN==89 //false

ergN = (a*d+b)%5-c*d; // (18*200-3)%5-11*200 = 3597%5-2200 = 2-2200 = -2198

ergB = ergN !=-250 && bool2;

/* Erklärung:

Zunächst wird überprüft, ob der Inhalt von ergN ungleich (!=) -250 ist. Nachdem dies der Fall ist, ergibt der Vergleich den Wert true. Dieser wird danach mit dem Inhalt von bool2 mit UND verknüpft. Da bool2 den Wert false aufweist, ist das Ergebnis der UND-Verknüpfung ebenfalls false. Somit wird der Variable ergB der Wert false zugewiesen. Beachten Sie bitte, dass sich a durch die Operation ++a von 17 auf 18 erhöht hat!

-2198!=250 && false = true && false = false

*/

Listing 2.26: Einige Beispiele zur Reihenfolge von Operationen

Page 37: Flash cs3, ajax und php

K A P I T E L 224

2.5 Arrays Arrays sind für die Arbeit eines jeden Programmierers von großer Bedeutung. Sie können sich einen Array als einen Datenpool oder – einfacher – als Tabelle vorstellen. Jeder dieser Werte des Datenpools ist in einem eigenen Bereich gespeichert. Arrays könnte man auch mit einem Setzkasten vergleichen, in dem jede Figur einen eigenen Platz hat.

Am Anfang dieses Kapitels haben wir für ein Online-Spiel den Nicknamen des Users benötigt. Wenn wir nun dieses Beispiel erweitern und pro User zusätzliche Daten wie Vorname, Nachname, Adresse und Wohnort speichern möchten, benötigten wir sehr viele Variablen, vor allem wenn mehrere User an unserem Online-Spiel teilnehmen. Dieses Problem können wir mit Arrays in den Griff bekommen.

Zunächst einmal die Syntax zur Array-Erstellung:

$myArray = array();

Listing 2.27: In PHP ...

var myArray = new Array();

Listing 2.28: ... in JavaScript ...

var myArray:Array = new Array();

Listing 2.29: ... und in Flash

Arrays in Flash und JavaScriptIn JavaScript und Flash spricht man im Fall von Arrays von „Objekten“ (man spricht auch von der „Klasse der Arrays“), in PHP gehören sie zu den „komplexen Datentypen“. Bei der Verwendung in JavaScript und Flash ist daher darauf zu achten, dass beim Erzeugen der Konstruktor new Array() verwendet wird.

Es gibt unterschiedliche Arten, Werte in den Arrays zu speichern: Unterschieden wird dabei zwischen indizierten und assoziativen Arrays.

2.5.1 Indizierte Arrays Die Werte eines Arrays werden immer durch eine fortlaufende Nummer gekennzeich-net. Indizierte Arrays beginnen immer bei 0, deshalb spricht man gern von „zero-based“ Elementen. Das zweite Element des Arrays bekommt die Nummer 1, das dritte die Nummer 2 zugewiesen usw. Das letzte Element eines Arrays mit fünf Elementen hat also die Nummer 4.

$arrUser = array("Uwe", "Uwe", "Mutz");

Listing 2.30: In PHP ...

Arrays erstellenArrays erstellen

Werte in Arrays speichern

Werte in Arrays speichern

Page 38: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 25

var arrUser = new Array("Uwe", "Uwe", "Mutz");

Listing 2.31: ... in JavaScript ...

var arrUser:Array = new Array("Uwe", "Uwe", "Mutz");

Listing 2.32: ... und in Flash

Möchten wir nun den Usernamen des Users aus dem Array $arrUser/arrUser aus-geben, müssten wir folgenden Code schreiben.

echo($arrUser[0]); //Ausgabe in den Browser

Listing 2.33: In PHP ...

alert(arrUser[0]); //Ausgabe in einer Alert-Box

Listing 2.34: ... in JavaScript ...

trace(arrUser[0]); //Ausgabe in das Ausgabefenster

Listing 2.35: ... und in Flash

Elementname Nummer (Index) des Elements Wert

$arrUser[0] 0 Uwe

$arrUser[1] 1 Uwe

$arrUser[2] 2 Mutz

Tabelle 2.6: Inhalte des indizierten Arrays $arrUser (gleichermaßen gültig für arrUser in JavaScript und Flash)

2.5.2 Assoziative Arrays Bei einem assoziativen Array („Hash-Table“) werden die Werte nicht durch fortlau-fende Nummern gekennzeichnet, sondern durch eine eindeutige Bezeichnung wie bei Variablen.

Arrays erstellen

Das Erzeugen „echter“ assoziativer Arrays ist nur in PHP möglich – in JavaScript und ActionScript läuft die Sache etwas anders, denn hier müsste man Objekte in Arrays verschachteln – sollten Sie „um die Burg“ assoziative Arrays in Flash oder JavaScript benötigen, so empfehle ich Ihnen die ActionScript- bzw. JavaScript-Referenz.

Werfen wir zunächst einen Blick auf PHP. Um diesen Array-Typ zu erstellen, benötigen wir den Operator =>.

$arrUser = array(

"Nickname" => "Uwe",

"Vorname" => "Uwe",

PHPPHP

Page 39: Flash cs3, ajax und php

K A P I T E L 226

"Nachname" => "Mutz"

);

Jetzt hat jeder Wert des Arrays eine eindeutige Bezeichnung erhalten. Man spricht hier auch vom „Key“ und dessen „Value“.

Elementname Key Value

$arrUser["Nickname"] Nickname Uwe

$arrUser["Vorname"] Vorname Uwe

$arrUser["Nachname"] Nachname Mutz

Tabelle 2.7: Inhalte des assoziativen Arrays $arrUser

Mehrdimensionale Arrays

Im Moment haben wir nur eindimensionale Arrays erzeugt, die man mit einzeiligen Tabellen vergleichen kann, bei denen alle Werte hintereinander in den Zellen der Tabelle gespeichert werden. Möglich ist aber auch der Einsatz von mehrdimensionalen Arrays.

Angenommen, wir möchten alle User unseres Online-Spiels mit deren Nicknamen, Vornamen und Nachnamen speichern, so wäre der Einsatz eines mehrdimensionalen Arrays denkbar und sinnvoll:

$arrUser = array("User1" => array("Uwe", "Uwe", "Mutz"), "User2" => array("Uwe", "Uwe", "Mutz"));

Das Array $arrUser hat zwei Elemente User1 und User2. Diese Elemente sind wie-derum selbst Arrays, in denen dann die eigentlichen Werte gespeichert werden. Möch-ten wir nun den Nachnamen des Users 2 ausgeben, schreiben wir folgenden Code:

echo($arrUser["User2"][2]);

Bei der Ausgabe müssen wir nur Schritt für Schritt vom äußersten Array in das gewünschte Array wandern. Unser Array $arrUser beinhaltet ein assoziatives Array namens User2 und dieses beinhaltet wiederum ein „normales“ Array. Mit [2] geben wir somit nur die Stelle im Array User2 an, an der der Nachname gespeichert wurde.

Natürlich könnten wir das zweite Array auch assoziativ aufbauen:

$arrUser = array("User1" => array("Nickname" => "Uwe", "Vorname" => "Uwe", "Nachname" => "Mutz"), "User2" => array("Nickname" => "Uwe", "Vorname" => "Uwe", "Nachname" => "Mutz"));

Um wieder den Nachnamen des zweiten Users auszugeben, schreiben wir nun:

echo($arrUser["User2"]["Nachname"]);

Äquivalent können wir dieses Beispiel in JavaScript und ActionScript nicht umsetzen, da es wie erwähnt in JavaScript und ActionScript keine assoziativen Arrays gibt. Der Ausweg hier führt über Objekte, die innerhalb von Arrays angelegt werden.

JavaScript und ActionScript

JavaScript und ActionScript

Page 40: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 27

Mehrdimensionale Arrays (jedoch nicht assoziativ) anzulegen, ist jedoch auch in JavaScript und ActionScript kein Problem:

var arrUser = new Array("User1", "User2"); //macht keinen Sinn!

arrUser[0] = new Array("Uwe", "Uwe", "Mutz");

arrUser[1] = new Array("Alex", "Alexander", "Grasser");

alert("Bezeichnung des ersten Eintrags der User-Tabelle: "+arrUser[0]);

alert("Nachname des zweiten Users: "+arrUser[1][2]);

Listing 2.36: Ein mehrdimensionales Array, wobei die erste Zeile in dieser Form wenig Sinn macht

Mehrdimensionale Arrays werden nach dem Muster:

var myArray = new Array();

myArray[n] = new Array();

angelegt, wobei n eine beliebige Stelle im Array ist. Sollte an Stelle n des Arrays myAr-ray bereits ein Inhalt vorhanden sein, so wird dieser überschrieben. Aus diesem Grund ergibt die erste Zeile in Listing 2.36 keinen Sinn, da die Einträge „User1“ und „User2“ in den nächsten Zeilen gleich wieder überschrieben werden. Sinnvoll ist daher anstatt dieser Zeile die folgende:

var arrUser = new Array();

Selbiges gilt in Flash, wobei in diesem Fall noch die Typisierung hinzukommt:

var arrUser:Array = new Array();

arrUser[0] = new Array("Uwe", "Uwe", "Mutz");

arrUser[1] = new Array("Alex", "Alexander", "Grasser");

trace("Bezeichnung des ersten Eintrags der User-Tabelle: "+arrUser[0]);

trace("Nachname des zweiten Users: "+arrUser[1][2]);

Listing 2.37: Mehrdimensionale Arrays in Flash nach demselben Muster wie in JavaScript, nur mit zusätzli-cher strikter Typisierung

Vielleicht haben Sie sich schon die Frage gestellt, ob es nicht eigentlich

var myArray = new Array();

var myArray[0] = new Array();

heißen müsste – also mit einem zusätzlichen var in der zweiten Zeile. Nun, diese Art der Schreibweise ist aufgrund des inneren Aufbaus der Arrays als Objekte nicht zuläs-sig – Details dazu finden Sie in der Objektorientierten Programmierung (OOP).

JavaScriptJavaScript

Page 41: Flash cs3, ajax und php

K A P I T E L 228

2.6 Bedingungen In der Programmierung gibt es oft Situationen, in denen ein Programmblock nur unter einer gewissen Bedingung ausgeführt werden soll. Diese Bedingung muss geprüft und daraufhin eine Entscheidung getroffen werden, wie das Script weiterverarbeitet wer-den soll. Fällt die Entscheidung positiv aus, wird der Programmblock ausgeführt, ist sie negativ, kann an dieser Stelle beispielsweise abgebrochen werden.

2.6.1 if-Bedingung Die gültige Syntax ist:

if(Bedingung) {

Programmblock, falls die Bedingung zutrifft

}

else {

Programmblock, falls die Bedingung nicht zutrifft

}

Listing 2.38: Syntax für if-Bedingungen

Was genau ist nun eine Bedingung und was liefert sie für Resultate? Nun, eine Bedin-gung ist in den meisten Fällen ein Vergleich zweier (oder mehrerer) Werte. Man kann Vergleiche in Bezug auf „gleich (==)“, „kleiner (<)“, „größer (>)“ usw. anstellen – das haben Sie im letzten Abschnitt bereits erfahren. Das Resultat ist dann immer eine Antwort des Systems, das sagt: „Wert 1 ist gleich Wert 2“ oder „Wert 1 ist nicht gleich Wert 2“, wenn man mit == auf Gleichheit prüft. Der Programmcode für dieses Beispiel würde folgendermaßen aussehen:

if (Wert1 == Wert2) {

//Wert1 ist gleich Wert2

}

else {

//Wert1 ist nicht gleich Wert2

}

Page 42: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 29

Ein einfaches Beispiel vergleicht die Variablen a und b miteinander und ermittelt, wel-che der beiden Variablen den größeren Wert beinhaltet:

$a = 23; //einen fi ktiven Wert eingeben, wie z.B. 23

$b = 17;

if ($a > $b) {

echo("$a ist groesser als $b");

}

else {

echo("$b ist groesser oder gleich $a");

}

Listing 2.39: In PHP ...

var a = 23;

var b = 17;

if(a>b) {

alert("a ist groesser als b");

}

else {

alert("b ist groesser oder gleich a");

}

Listing 2.40: ... in JavaScript ...

ABBILDUNG 2.1

Schematische Darstellung einer if-Bedingung

Page 43: Flash cs3, ajax und php

K A P I T E L 230

var a:Number = 23;

var b:Number = 17;

if(a>b) {

trace("a ist groesser als b");

}

else {

trace("b ist groesser oder gleich a");

}

Listing 2.41: ... und in ActionScript

Geschweifte Klammern bei Programmblöcken

Vielleicht ist Ihnen in der Syntax des obigen Beispiels aufgefallen, dass nach der Über-prüfung der Bedingung (die übrigens immer in runden Klammern stehen muss) eine geschweifte Klammer „{„ geöffnet wird. Dies deutet an, dass die nachfolgenden Code-zeilen zum if-Befehl gehören. Gleiches gilt für den else-Teil.

2.6.2 switch -Bedingung Das Problem der if-Bedingung ist, dass diese Bedingung immer nur auf einen Wert überprüft, also eine Fallunterscheidung nur durch Verschachtelung möglich ist. Muss auf sehr viele verschiedene Werte überprüft werden, so wird eine solche Fallunterschei-dung mit verschachtelten if-Bedingungen sehr schnell sehr unübersichtlich. Abhilfe schafft hier die switch-Bedingung, die eine Variable auf beliebig viele verschiedene Werte überprüft und je nachdem verschiedene Programmblöcke ausführt. Werfen wir einen Blick auf die Syntax :

switch (Variable) {

case Wert 1:

//Programmblock 1

break;

case Wert 2:

//Programmblock 2

break;

...

case Wert n:

//Programmblock n

break;

default:

Zeichenketten vergleichen

Wenn Sie Zeichenketten vergleichen, benutzen Sie

=== oder !==, da hier auch der Datentyp verglichen

wird.

Einzeiliger Programmcode

Sollte der Programmblock aus nur einer einzigen Zeile bestehen, könnte man die geschweiften Klammern weglassen. In Hinblick auf andere

Programmiersprachen sollte man sie aber auch bei nur

einer Zeile setzen.

Page 44: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 31

//Programmblock, falls keiner der Werte auf die Variable zutrifft

}

Listing 2.42: Syntax für switch-Bedingungen

Die Variable wird Schritt für Schritt auf die Werte überprüft. Trifft einer der innerhalb des switch-Blocks aufgelisteten Werte auf die Variable zu, so wird der zugehörige Programmblock ausgeführt; trifft keiner der Werte auf die Variable zu, so wird der Programmblock im default-Teil ausgeführt. Dieser default-Teil kann aber auch gänzlich wegfallen – sollte also kein Wert auf den Inhalt der Variable zutreffen, würde einfach gar nichts geschehen. Die break-Anweisung sorgt dafür, dass der nachfolgende Code innerhalb der switch-Anweisung nicht mehr ausgeführt wird – hierdurch wird das Abarbeiten des Codes schneller.

2.7 Schleifen Ein weiterer wichtiger Bestandteil in der Programmierung sind Schleifen. Sie kommen immer dann zum Einsatz, wenn ein Block von Befehlen mehrmals hintereinander ablaufen soll.

Grundsätzlich unterscheidet man zwischen Schleifen mit einer festen Anzahl von Durchläufen und solchen mit einer variablen Anzahl von Durchläufen .

2.7.1 for-Schleife Beginnen wir bei einer Schleife mit einer festen Anzahl von Durchläufen, der for-Schleife. Die for-Schleife benötigt drei Werte, die gesetzt werden müssen:

Startwert einer sogenannten Zähl- oder Schleifenvariable

Abbruch- oder Ende-Bedingung

Zählvariablen-Inkrement

Zählvariable

Die Zählvariable ist die Variable, die die Anzahl der Schleifendurchläufe zählt. In der obigen Auflistung steht „Startwert einer Zählvariablen“. Dies bedeutet, dass dieser Variablen ein Anfangswert zugewiesen wird. Oftmals wird als Startwert der Wert „0“ verwendet; es muss aber nicht so sein.

Sie sollten sich dies aber nicht so vorstellen, dass pro Schleifendurchlauf die Variable um eins erhöht wird (was als Spezialfall natürlich möglich ist und oft verwendet wird), sondern die Zählvariable wird um den Wert des Zählvariablen-Inkrements verändert. Wir schreiben an dieser Stelle bewusst „verändert“ und nicht „erhöht“, weil die Vari-

u

u

u

Page 45: Flash cs3, ajax und php

K A P I T E L 232

able genauso um einen gewissen Wert verringert werden könnte, je nachdem, was im Zählvariablen-Inkrement angegeben ist.

Abbruchbedingung

Die Abbruchbedingung überprüft die Zählvariable pro Schleifendurchlauf auf einen gewissen Wert. Sollte dieser Wert (je nach Art der Bedingung) über- oder unterschrit-ten werden, wird die Schleife abgebrochen, sprich, sie wird nicht mehr ausgeführt.

Endlosschleife

Wichtig hierbei ist, dass die Abbruchbedingung auch wirklich irgendwann erreicht werden kann, ansonsten haben Sie eine sogenannte Endlosschleife programmiert. Dies führt zu einer Überlastung des Prozessors und wird im Allgemeinen vom Betriebssys-tem nach einer gewissen Zeit automatisch abgebrochen, was logischerweise zur Folge

ABBILDUNG 2.2

Schematische Darstellung einer for-Schleife

Page 46: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 33

hat, dass die PHP- oder Flash-Datei bzw. JavaScript-Anwendung nicht mehr weiter ausgeführt wird.

Warum all der Aufwand mit der Zählvariable? Wenn sie nur dafür da ist, dass man die Anzahl der Durchläufe auf alle möglichen Arten abprüft, hätte sich der Aufwand nicht gelohnt. Der Grund dafür ist, dass die Variable selbst im Programmblock der Schleife sehr oft als ganz normale Variable verwendet wird.

Die korrekte Syntax der for-Schleife lautet:

for(Initialisierung der Zählvariablen; Abbruchbedingung; Inkrement) {

Programmblock

}

Listing 2.43: Syntax für for-Schleifen

Initialisierung der Schleife

Die Initialisierung kann z.B. wie folgt aussehen:

for($i = 0; …) //Zählvariable $i mit Startwert 0

for($a = 23; …) //Zählvariable $a mit Startwert 23

for($i = -17; …) //Zählvariable $i mit Startwert -17

Listing 2.44: In PHP ...

for(var i:Number = 0; ...) //Zählvariable i mit Startwert 0

for(var a:Number = 23; ...) //Zählvariable a mit Startwert 23

for(var i:Number = -17; ...) //Zählvariable i mit Startwert -17

Listing 2.45: ... in JavaScript ...

for(var i = 0; ...) //Zählvariable i mit Startwert 0

for(var a = 23; ...) //Zählvariable a mit Startwert 23

for(var i = -17; ...) //Zählvariable i mit Startwert -17

Listing 2.46: ... und in Flash

Typischerweise werden als Variablennamen für Zählvariablen die Buchstaben i, j, k usw. verwendet, einen besonderen Grund gibt es dafür wohl nicht.

Typische Abbruchbedingungen

Typische Abbruchbedingungen sind:

for($i = 0; $i<15; ...)

for($a = 23; $a>15; ...)

Page 47: Flash cs3, ajax und php

K A P I T E L 234

/* falls $a pro Schleifendurchlauf erhöht wird, ist die obige Schleife eine Endlosschleife; falls $a verringert wird, wird die Abbruchbedingung erreicht */

for(var $i = -17; $i<0; ...)

Listing 2.47: In PHP ...

for(var i = 0; i<15; ...)

for(var a = 23;a>15; ...)

for(var i = -17; i<0; ...)

Listing 2.48: ... in JavaScript ...

for(var i:Number = 0; i<15; ...)

for(var a:Number = 23;a>15; ...)

for(var i:Number = -17; i<0; ...)

Listing 2.49: ... und in Flash

Inkrement

Nun müssen wir uns noch um das Zählvariablen-Inkrement kümmern. Wir können die Zählvariable pro Durchlauf entweder verringern oder erhöhen, die Frage ist nur, um welchen Wert wir verringern oder erhöhen. Oft wird die Variable pro Schleifen-durchlauf um eins erhöht, das muss aber eben nicht so sein. Möchte man um eins erhöhen, würde man schreiben:

$i = $i+1; //erhöht die Variable i um eins

Dies bedeutet, dass der neue Wert der Variablen i 1 aus dem alten Wert 2 plus eins 3 errechnet wird. Diese Schreibweise ist speziell in diesem Fall nicht besonders üblich, vielmehr schreibt man:

$i++; //erhöht die Variable i um eins

Listing 2.50: in PHP ...

i++; //erhöht die Variable i um eins

Listing 2.51: ... und in JavaScript bzw. Flash

Eine weitere allgemeinere Schreibweise ist:

$i += 1; //erhöht die Variable i um eins

$i += 3; //erhöht die Variable i um drei

$i -= 1; //verringert die Variable i um eins

Listing 2.52: In PHP ...

Page 48: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 35

i += 1; //erhöht die Variable i um eins

i += 3; //erhöht die Variable i um drei

i -= 1; //verringert die Variable i um eins

Listing 2.53: ... und in JavaScript bzw. Flash

Beispiele von for-Schleifen

Damit sind wir in der Lage, komplette Schleifen zu programmieren. Sehen wir uns nun einige Beispiele von for-Schleifen an:

for($i=0; $i<10; $i++) {

echo("i = $i");

/* Diese Schleife beginnt mit $i = 0; $i wird pro Schleifendurchlauf um eins erhöht und es wird pro Durchlauf abgeprüft, ob $i immer noch kleiner als 10 ist; ist das irgendwann nicht mehr der Fall, wird die Schleife abgebrochen. Insgesamt sind es 10 Schleifendurchläufe */

}

for($i = -17; $i<30; $i+= 3) {

echo("i = $i");

//16 Durchläufe

}

Listing 2.54: In PHP ...

for(var i =0; i<10; i++) {

alert("i = "+i);

}

for(var i = -17; i<30; i+= 3) {

alert("i= "+i);

//16 Durchläufe

}

Listing 2.55: ... in JavaScript ...

for(var i:Number=0; i<10; i++) {

trace("i = "+i);

}

for(var i:Number = -17; i<30; i+= 3) {

trace("i= "+i);

//16 Durchläufe

}

Listing 2.56: ... und in Flash

Page 49: Flash cs3, ajax und php

K A P I T E L 236

Jetzt ein praktisches Beispiel. Sie erinnern sich sicher noch an unser Array mit den Userdaten.

Mit echo($arrUser[0]) haben wir den Nicknamen ausgegeben. Nun möchten wir alle Daten des Users ausgeben.

// Erstellen des Arrays

$arrUser = array("Uwe", "Uwe", "Mutz");

//Ausgabe des Arrays mit einer for-Schleife

for($i=0; $i<3; $i++){

echo($arrUser[$i]."<br />");

}

Mit diesen paar Zeilen werden alle Daten des Arrays durch Zeilenumbrüche getrennt ausgegeben: Die verwendete for-Schleife wird dreimal durchlaufen, weil wir als Start-wert 0 und als maximalen Wert 2 (< 3) definiert haben. Somit hat $i beim ersten Durchlauf der Schleife den Wert 0 und holt den Wert an der Stelle 0 aus unserem Array $arrUser[]. Beim nächsten Durchlauf hat $i den Wert 1 und wir lesen den Wert an der Stelle 1 aus unserem Array aus usw.

Anzahl der Elemente eines Arrays

Wir haben nur ein Problem, denn die for-Schleife läuft im Moment nur von Index 0 bis Index 2. Sobald mehr Daten in das Array gespeichert werden, würde ein Wert mit zum Beispiel Index 3 oder Index 4 nicht ausgegeben werden. Zu lösen ist das Problem über eine PHP-Funktion, die die Anzahl der Werte eines Arrays zurückgibt.

Hier können wir zwischen der Funktion count() und sizeOf() wählen. Welche Funktion Sie nutzen, ist egal. Beide geben die Anzahl der Elemente eines Arrays zurück.

for($i=0; $i<sizeof($arrUser); $i++){

echo($arrUser[$i]."<br />");

}

In ActionScript sähe der Code wie folgt aus, die Erklärung kann im Wesentlichen von oben übernommen werden:

var arrUser:Array = new Array("Uwe","Uwe","Mutz");

for(var i:Number=0; i<arrUser.length; i++) {

trace("arrUser["+i+"] = "+arrUser[i]);

}

Entgegen der Beschreibung von oben wird in Flash zur Ermittlung der Anzahl der Einträge in einem Array die Eigenschaft length des Arrays verwendet.

PHPPHP

ActionScriptActionScript

Page 50: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 37

var arrUser = new Array("Uwe","Uwe","Mutz");

for(var i =0; i<arrUser.length; i++) {

alert("arrUser["+i+"] = "+arrUser[i]);

}

JavaScript ist – wie Sie ja wissen – sehr ähnlich wie ActionScript aufgebaut (nachdem beide demselben Standard angehören, ist das auch nicht wirklich schwer ...) – einzig die strikte Typisierung fehlt uns in JavaScript.

2.7.2 for...each- oder for...in-Schleife Die for...each-Schleife steht uns in PHP speziell für Arrays zur Verfügung, in JavaScript und Flash verwendet man sie auch gern zum Auslesen aller Eigenschaften und Methoden eines Objekts. Dort ist sie als for...in-Schleife bekannt. Diese Schleife löst unser Problem der for-Schleife, dass die Anzahl der Einträge des Arrays nicht bekannt ist, denn mit einer for...each-Schleife werden alle Felder des Arrays durchlaufen.

Hier zunächst die Syntax der for...each-Schleife :

foreach($array as element) {

Programmblock;

}

Listing 2.57: In PHP ...

for(element in myArray) {

Programmblock;

}

Listing 2.58: ... und in JavaScript bzw. Flash

Unser voriges Beispiel mit einer for...each-Schleife würde demnach wie folgt aus-sehen:

// Erstellen des Arrays

$arrUser = array("Uwe", "Uwe", "Mutz");

//Ausgabe des Arrays mit einer for...each-Schleife

foreach($arrUser as $userdaten){

echo($userdaten."<br />");

}

Listing 2.59: In PHP ...

JavaScriptJavaScript

Page 51: Flash cs3, ajax und php

K A P I T E L 238

var arrUser:Array = new Array("Uwe","Uwe","Mutz");

for(element in arrUser) {

trace("arrUser["+element+"] = "+arrUser[element]);

}

Listing 2.60: ... in JavaScript ...

var arrUser = new Array("Uwe","Uwe","Mutz");

for(element in arrUser) {

alert("arrUser["+element+"] = "+arrUser[element]);

}

Listing 2.61: ... und in Flash

Für die Verarbeitung eines assoziativen Arrays müssen wir die for...each-Schleife noch etwas erweitern. Die Syntax für das Durchlaufen eines assoziativen Arrays lau-tet:

foreach($array as key => value){

Programmblock;

}

Listing 2.62: Syntax für eine for...each-Schleife in einem assoziativen Array

Wie schon bei der Erstellung eines assoziativen Arrays benötigen wir den Operator =>.

// Erstellen des Arrays

$arrUser = array(

"Nickname" => "Uwe",

"Vorname" => "Uwe",

"Nachname" => "Mutz"

);

// Ausgabe des assoziativen Arrays mit einer for...each-Schleife

foreach($arrUser as $key => $value){

echo("$key: <b>$value</b><br />");

}

Wissenswertes zur for...in-Schleife in FlashMithilfe der for...in-Schleife in Flash können zwar beinahe, jedoch nicht alle Eigenschaften und Methoden von Objekten ermittelt werden. Hierzu verweise ich auf die ActionScript-Referenz, die Sie auf der Site von Macromedia (www.macromedia.com) im Menüpunkt SUPPORT > DOKUMENTATION finden.Des Weiteren listet die for...in-Schleife die eingetragenen Elemente nicht in der Reihenfolge des Vorkommens auf. Dies wird speziell im Fall des Auslesens von Array-Elementen interessant.

PHPPHP

Page 52: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 39

Seit ActionScript 3.0 existiert in Flash nun auch eine for each..in-Schleife, die primär zum Durchlaufen von Objekten eines bestimmten Typs verwendet wird. Sol-che Objekte sind beispielsweise XML- oder XMLList-Objekte. Im Gegensatz zu einer for...in-Schleife wird über den Iterator der Schleife der Wert und nicht der Name der jeweiligen Eigenschaft ermittelt.

Als Beispiel arbeiten wir uns durch ein XML-Objekt, um alle Werte auszugeben:

var myXML:XML =

<Playliste>

<song src="BeAWarrior.mp3">Be a Warrior</song>

<song src="WarriorsOfTheWasteland.mp3">Warriors of the Wasteland</song>

</Playliste>;

for each (var item in myXML.song) { trace("item="+item); }

Als Ausgabe erhalten wir „Be A Warrior“ und „Warriors of the Wasteland“.

2.7.3 do..while-Schleife Diese und die nächste Schleife sind Vertreter von Schleifen mit einer variablen Anzahl von Durchläufen. Damit kommen wir mehr denn je in die Situation, dass wir selbst überprüfen müssen, dass die Schleife auch wirklich jemals abbricht. Sorgen wir pro-grammiertechnisch nicht für die Möglichkeit des Schleifenendes, erzeugen wir die schon bei der for-Schleife angesprochene Endlosschleife.

Mindestens einmal durchlaufen

Bei der do..while-Schleife wird der Programmblock, der sich in ihr befindet, auf jeden Fall einmal durchlaufen. Die Bedingung, ob die Schleife ein weiteres Mal durch-laufen wird, hängt von der Abbruchbedingung ab, die aber erst am Ende der Schleife überprüft wird.

Boolesche Werte

Genauso wie bei der for-Schleife (und jeder anderen Situation, in der Bedingungen gefordert sind) liefert die Bedingung einen booleschen Wert. Oft wird anstatt der Bedingung selbst einfach eine boolesche Variable verwendet, deren Wert dann für einen weiteren Schleifendurchlauf oder einen Schleifenabbruch entsprechend gesetzt wird. Der Variable wird dann z.B. innerhalb der Schleife ein Wert zugewiesen, damit die Schleife abbrechen kann.

Werfen wir einen Blick auf die Syntax:

for each..in in ActionScript 3.0for each..in in ActionScript 3.0

Page 53: Flash cs3, ajax und php

K A P I T E L 240

do{

//Programmblock

} while(Bedingung);

Listing 2.63: Syntax für do..while-Schleifen

Die do..while- und die while-Schleife werden dann verwendet, wenn man nicht sicher ist, wie oft die Schleife durchlaufen werden soll.

2.7.4 while-Schleife Entgegen der oben beschriebenen do..while-Schleife läuft die while-Schleife nicht notwendigerweise durch. Trifft die Bedingung schon von Beginn an nicht zu, führt kein Weg in das Innere der Schleife.

Die korrekte Syntax ist:

while(Bedingung) {

//Programmblock

}

Listing 2.64: Syntax für while-Schleifen

ABBILDUNG 2.3

Schematische Darstellung einer do..while-Schleife

Page 54: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 41

Die Anmerkungen zur Abbruchbedingung bei der do..while-Schleife gelten hier natürlich entsprechend.

Hilfreiches bei Schleifen: break und continue Zwei Befehle sind im Zusammenhang mit Schleifen oft hilfreich:

break: veranlasst den Interpreter, zum Beispiel den Flash-Player, die Schleife zu verlassen, ohne dass die Bedingung noch weiter geprüft wird.

continue: veranlasst den Interpreter, zur Bedingungsprüfung zu springen, ohne dass die restli-chen Zeilen des Programmblocks weiter ausgeführt werden.

2.8 Funktionen Bisher haben wir die notwendigen Grundlagen der Programmierung betrachtet. Sie sind bereits jetzt in der Lage, einfachere Programme zu schreiben. Auf den nächs-ten Seiten lernen Sie die Möglichkeit kennen, Programmteile erst bei Bedarf auszu-führen.

u

u

ABBILDUNG 2.1

Schematische Abbildung einer while-Schleife

Page 55: Flash cs3, ajax und php

K A P I T E L 242

Funktionen bieten uns bei der Programmierung zwei entscheidende Vorteile:

Funktionen können bei Bedarf – also erst dann, wenn man diesen Programmblock wirklich braucht – aufgerufen werden.

Funktionen lassen sich beliebig oft aufrufen.

Funktionen können Ergebnisse an das Hauptprogramm zurückgeben.

Stellen Sie sich zum Beispiel ein Computerspiel vor: Jedes Mal, wenn der Spieler mit seinem Raumschiff abgeschossen wird, soll die Anzahl seiner „Leben“ um eins redu-ziert werden. Das wäre ein Beispiel dafür, dass ein Programmblock nur bei Bedarf und so oft man will abgerufen werden kann.

Funktionsdeklaration

Sehen wir uns die korrekte Syntax der Funktionsdeklaration für verschiedene Anwen-dungsmöglichkeiten einmal an. Funktionen werden dabei immer durch das Schlüssel-wort function eingeleitet.

1. Funktion, an die weder Daten übergeben noch von der Daten zurückgegeben werden:

function Funktionsname() {

Programmblock

}

2. Funktion, an die Daten übergeben, von der jedoch keine Daten zurückgegeben werden:

function Funktionsname(Variablensatz) {

Programmblock

}

3. Funktion, an die keine Daten übergeben, von der jedoch Daten zurückgegeben werden:

function Funktionsname() {

Programmblock

return Variable / Wert;

}

4. Funktion, an die sowohl Daten übergeben als auch Daten von ihr zurückgegeben werden:

function Funktionsname(Variablensatz) {

Programmblock

u

u

u

Page 56: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 43

return Variable / Wert;

}

Übergabe von Daten und Rückgabe

In dieser Syntax sehen Sie Dinge, von denen bis jetzt noch gar nicht die Rede war. Dar-auf müssen wir genauer eingehen. Machen wir dies aber lieber anhand eines Beispiels: Wir programmieren eine Funktion, welche zwei Zahlen zusammenzählt (diese beiden Zahlen werden an die Funktion übergeben) und das Ergebnis an das Hauptprogramm zurückliefert.

function Addiere($zahl1,$zahl2) {

$ergebnis = $zahl1 + $zahl2;

return $ergebnis;

}

Listing 2.65: In PHP ...

function Addiere(zahl1,zahl2) {

var ergebnis = zahl1 + zahl2;

return ergebnis;

}

Listing 2.66: ... in JavaScript ...

function Addiere(zahl1:Number,zahl2:Number) {

var ergebnis:Number = zahl1 + zahl2;

return ergebnis;

}

Listing 2.67: ... und in Flash

Lesen wir diese Funktion einmal in Worten: Erzeugt wurde eine Funktion mit dem Namen Addiere. An die Funktion werden zwei Werte übergeben, welche innerhalb der Funktion über die Variablennamen $zahl1 (bzw. zahl1) und $zahl2 (bzw. zahl2) angesprochen werden können. Die Übergabe der Werte erfolgt in runden Klammern direkt hinter dem Funktionsnamen. Innerhalb der Funktion legen wir eine Variable $ergebnis/ergebnis an, der wir das Ergebnis der Addition der Zahlen $zahl1/zahl1 und $zahl2/zahl2 zuweisen. Der Inhalt der Variable wird dann über return an das aufgerufene Programm zurückgegeben.

Page 57: Flash cs3, ajax und php

K A P I T E L 244

Funktionsaufruf

Aufgerufen wird eine Funktion über den Namen der Funktion, wie z.B.:

Addiere(1,3); //wenn kein Wert zurückgegeben wird

$ergebnis = Addiere(1,3) // mit einem Rückgabewert

Listing 2.68: In PHP …

Addiere(1,3); // wenn kein Wert zurückgegeben wird

var ergebnis = Addiere(1,3); mit einem Rückgabewert

Listing 2.69: … in JavaScript …

Addiere(1,3); // wenn kein Wert zurückgegeben wird

var ergebnis:Number = Addiere(1,3); mit einem Rückgabewert

Listing 2.70: … und in Flash

Hier wird die Funktion Addiere mit den Zahlen 1 und 3 aufgerufen. Der Rückgabe-wert $ergebnis (bzw. ergebnis in JavaScript/Flash) sollte 4 sein.

Funktionen ohne Rückgabewert

Oft ist es nicht notwendig, einen Wert aus der Funktion zurückzugeben, da die Daten schon innerhalb der Funktion entweder ausgegeben oder anderweitig verwendet wer-den. Sie werden sogar sehr oft auf Funktionen treffen, an die weder Daten übergeben noch Daten von ihr zurückgegeben werden. Sollte jedoch ein Wert von der Funktion an den „Aufrufer“ zurückgegeben werden, wird dieser im Allgemeinen im aufrufenden Programmblock benötigt. Aus diesem Grund werden die Rückgabewerte gerne im aufrufenden Teil als Variablen gespeichert. Eine andere Variante ist das Ausgeben des Variablenwerts per echo (PHP), alert (JavaScript) oder trace (Flash).

Hier ein Beispiel für eine Funktion, die keinen Wert zurückliefert, da ein etwaig errech-neter Wert bereits innerhalb der Funktion ausgegeben wird:

function Addiere2($zahl1,$zahl2) {

$ergebnis = $zahl1 + $zahl2;

echo($ergebnis);

//Rückgabe ist nicht notwendig, da Ergebnis im Browser angezeigt wird

}

Addiere2(10,340);

Listing 2.71: Der Wert der Variable (350) wird in PHP per echo im Browser ausgegeben.

function Addiere2(zahl1,zahl2) {

var ergebnis = zahl1 + zahl2;

Page 58: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 45

alert(ergebnis);

}

Addiere2(10,340);

Listing 2.72: JavaScript gibt das Ergebnis in einer Alert-Box aus.

function Addiere2(zahl1:Number,zahl2:Number) {

var ergebnis:Number = zahl1 + zahl2;

trace(ergebnis);

}

Addiere2(10,340);

Listing 2.73: In Flash benutzt man trace für eine Ausgabe im Ausgabefenster.

Arrays übergeben

Wenn an eine Funktion Variablen übergeben werden, die in der Funktionsdeklaration explizit aufgeführt sind, so können diese Werte eben über diese Variablennamen (hier: $zahl1 / zahl1 und $zahl2 / zahl2) angesprochen werden. Ist von vorneherein nicht eindeutig klar, wie viele Werte man an eine Funktion übergeben möchte, dekla-riert man diese nicht explizit, sondern greift auf die Verwendung eines Arrays zurück.

Alles, was wir dazu wissen müssen, ist:

1. Wie erstelle ich ein Array? (nur PHP)

2. Wie erhalte ich die Anzahl der Werte eines Arrays?

3. Wie kann ich diese Werte in einer Schleife auslesen?

Ein Beispiel:

// Funktion deklarieren

function Addiere3($arr){

//Anzahl der Elemente des Arrays $arr in $anzParams speichern

$anzParams = count($arr);

$ergebnis = 0;

for($i=0; $i < $anzParams; $i++){

// Addieren aller Parameter

$ergebnis = $ergebnis + $arr[$i];

// $ergebnis += $ergebnis wäre auch richtig

}

// Ergebnis zurückgeben

PHPPHP

Lokale Variablen in FunktionenGrundsätzlich sind Variablen, die innerhalb einer Funktion angelegt werden, nicht außerhalb der Funktion bekannt. Aus diesem Grund gibt es return , um Werte außer-halb der Funktion weit-erverwenden zu können.

Page 59: Flash cs3, ajax und php

K A P I T E L 246

return $ergebnis;

}

//Array der Parameter erzeugen

$params = array(1,3,5,2,8);

//Aufruf der Funktion Addiere3 und Übergabe des Arrays $params

$resultat = Addiere3($params);

echo($resultat);

Listing 2.74: Auswerten einer beliebigen Anzahl von Übergabeparametern an eine PHP-Funktion

Insgesamt wird also in unserer Funktion Addiere3 die for-Schleife fünfmal durch-laufen. Bei jedem Durchlauf wird $ergebnis um den gerade aktuellen Wert aus dem Array $params erhöht. Das Endergebnis ist somit 18.

In JavaScript und Flash stellt sich die Sachlage etwas differenzierter dar, denn hier kann man innerhalb einer Funktion auf ein Array namens „arguments“ zurückgreifen, das alle an die Funktion übergebenen Werte beinhaltet – dieses Array muss somit nur noch ausgelesen werden. Der Aufruf der Funktion gleicht dem vorherigen:

function Addiere3() {

var args = Addiere3.arguments;

var ergebnis = 0;

for(var i =0; i<args.length; i++) {

ergebnis += args[i];

}

return ergebnis;

}

Addiere3(1,3,5,2,8);

Listing 2.75: JavaScript erhält eine beliebige Anzahl an Parametern übergeben.

function Addiere3() {

var args:Array = arguments;

var ergebnis:Number = 0;

for(var i:Number=0; i<args.length; i++) {

ergebnis += args[i];

}

return ergebnis;

JavaScript und ActionScript

JavaScript und ActionScript

Page 60: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 47

}

Addiere3(1,3,5,2,8);

Listing 2.76: Auswerten einer beliebigen Anzahl von Übergabeparametern an eine Flash-Funktion. Möch-ten Sie das Ergebnis der Addition ausgeben, so ersetzen Sie die letzte Zeile mit trace(Addiere3(1,3,5,2,8));.

Im Gegensatz zu Flash (es wird lediglich auf das Array arguments zugegriffen) erfolgt in JavaScript der Zugriff über: Funktionsname.arguments.

2.9 Cookies Im Internet würde nur sehr wenig ohne Cookies funktionieren. Jeder Webshop und jedes Forum arbeiten im Grunde mit Cookies. Diese ermöglichen es, User bei einem Wiederaufruf einer Website zu erkennen und persönlich zu begrüßen oder, wie es bei einem Webshop üblich ist, ihnen ihren Warenkorb anzuzeigen.

Einige User haben leider das Setzen von Cookies deaktiviert. Meist geschieht dies aus Angst, dass fremde Personen Zugriff auf die eigenen Daten bekommen. Diese Angst ist aber unbegründet, da nicht der Server Cookies am User-PC ausliest, sondern der Client, also der Browser des Users, sendet die Cookie-Daten an die URL zurück.

Unterscheiden kann man zwischen persistenten Cookies und Session-Cookies. Letzte-re werden wir im nächsten Abschnitt behandeln.

2.9.1 Exkurs HTTPWahrscheinlich ist Ihnen der Begriff HTTP schon öfter bei der Eingabe eines Links oder einer Webadresse aufgefallen. Doch was ist dieses HTTP eigentlich und wozu dient es?

HTTP ist eine Abkürzung für „HyperText Transfer Protocol“ und ist ein Grundstein des Internets. Mittels HTTP wird die Verständigung des Clients mit dem Server erst möglich. Bei dem Aufruf einer Website geschieht immer dasselbe.

1. Request – der Client (Browser) stellt eine Verbindung mit dem Server her und fragt nach der gewünschten Webseite.

2. Response – Antwort des Webservers mit den Daten oder einer Fehlermeldung, falls die gewünschten Daten nicht vorhanden sind

3. Der Client empfängt die Antwort des Servers und stellt die gewünschten Daten dar.

4. Anschließend wird die Verbindung zwischen Client und Browser geschlossen.

Definition von CookiesCookies sind ein Mecha-nismus, um clientseitige Informationen zu speichern und wieder auszulesen. Diesen Mechanismus nutzen serverseitige Verbindungen.

Page 61: Flash cs3, ajax und php

K A P I T E L 248

HTTP und Cookies

So weit, so gut, aber wahrscheinlich stellen Sie sich nun die Frage: „Was hat jetzt HTTP mit Cookies zu tun?“ Im Grunde haben sie nichts miteinander zu tun. Wichtig für uns ist einzig die Tatsache, dass eine Verbindung zwischen Client und Server immer nach Übergabe der gewünschten Daten geschlossen wird. Dies ist auch nicht weiter schlimm, solange Sie nicht gewisse Daten zu einem späteren Zeitpunkt auf einer weiteren Seite benötigen. Denken wir zum Beispiel an einen Warenkorb bei einem Online-Shop. User können nach Auswahl eines Artikels nach weiteren Produkten suchen und diese dann dem eigenen Warenkorb hinzufügen. Jedoch müssen wir dazu immer wissen, welcher User gerade in unserem Webshop surft. Ansonsten könnte es ja passieren, dass der gewünschte Artikel im Warenkorb eines falschen Kunden gespeichert wird.

Genau hier liegt das Problem von HTTP, da sofort nach Übergabe der gewünschten Daten die Verbindung zwischen Browser und Client geschlossen wird. Somit wissen wir zu keiner Zeit, dass der User X vorher auf der Seite Y gesurft hat. Um dieses Problem in den Griff zu bekommen, können wir auf Cookies oder Sessions zurückgreifen.

Cookies setzen

In PHP steht uns nur eine Funktion zur Verfügung, die es ermöglicht, Cookies zu set-zen und diese auch wieder auszulesen:

setcookie();

Die setcookie()-Funktion muss unbedingt vor dem ersten Ausgeben von Zeichen im Browser gesetzt werden. Sie erwartet sechs Parameter, wobei alle außer dem ersten optional sind. Die Parameter sind:

1. Name

2. Inhalt

3. Verfallsdatum

4. Pfad

5. Domain

6. secure

Optionale ParameterAuch wenn der Name-Parameter als einziger Pflicht ist, müssen Sie die Angaben zu Pfad und Domain durch eine leere Zeichenkette „“ und das Verfallsdatum und secure durch die Ziffer 0 ersetzen. Die Funktion sähe dann wie folgt aus:

setcookie (cookie1, "", 0, "", "", 0);

Page 62: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 49

Sehen wir uns die einzelnen Parameter genauer an:

Name: Der Name des Cookies darf keine Leerzeichen, Kommas und Semikolons beinhalten. Alles andere ist erlaubt.

Inhalt: Der Inhalt des Cookies kann ein Text sein. Meist werden Sie als Inhalt aber eine Variable speichern, deren Inhalt Text ist. Denkbar wäre der Username oder die ID des Users in der Datenbank. Der Inhalt wird auch automatisch über die Funk-tion urlencode() für die URL kodiert.

Verfallsdatum : Das Verfallsdatum gibt an, ab wann ein Cookie nicht mehr gültig ist. Geben Sie als Verfallsdatum 0 an, wird das Cookie sofort nach Ende der Sitzung gelöscht. Das Verfallsdatum muss in Sekunden angegeben werden.

Angenommen, Ihr Cookie soll nach fünf Minuten verfallen, so müssen Sie folgenden Code für das Verfallsdatum eingeben: time()+300. Mit der Funktion time() bekommt man die aktuelle Uhrzeit. Zu dieser rechnen Sie einfach 300 Sekunden dazu. Um ein bestehendes Cookie früher zu löschen als geplant, geben Sie einfach für das Cookie mit demselben Namen ein Verfallsdatum in der Vergangenheit an. Zum Beispiel time()-300.

Domain: Wir haben hier ganz bewusst den Parameter für die Domain vorgezogen, da erst dann der Sinn des Pfad-Parameters erkennbar wird.

Ein Browser sucht in der kompletten Liste der Cookies des Users nach einer Übereinstimmung des Domain-Parameters mit dem Internet-Domainnamen des Servers, der die Seite aufgerufen hat. Berücksichtigt werden auch Teile einer Domain.

Angenommen, Ihr Domain-Parameter lautet syne.at. Dann ist auch der Aufruf über test.syne.at richtig und das Cookie wird zum Auslesen erkannt. Wenn Sie keine Domain angeben, wird der Name des Servers (hostname) verwendet.

Pfad: Mit dem Pfad-Parameter können Sie zur Domain noch einen eigenen Pfad angeben. Erst wenn Domainname und Pfad übereinstimmen, wird das Cookie zum Auslesen bereitgestellt.

secure: Mit secure können Sie einstellen, dass ein Cookie nur gesetzt wird, wenn eine sichere Verbindung vorhanden ist. Eine sichere Verbindung erkennt man am https (statt http) in der Adresszeile des Browsers und zusätzlich an einem Schloss-Symbol, dass sich meist in der rechten unteren Ecke befindet.

User-ID speichern

Nun Schluss mit der Theorie, sehen wir uns ein kleines Beispiel an. Angenommen, wir haben einen Login-Bereich für unsere User erstellt. Um dem User das lästige Anmel-den bei einem erneuten Besuch unserer Website zu ersparen, speichern wir seine User-ID in einem Cookie ab. Durch diese User-ID können wir dann ganz einfach die Daten des Users aus unserer Datenbank laden und den User mit seinem Namen begrüßen.

u

u

u

u

u

u

Page 63: Flash cs3, ajax und php

K A P I T E L 250

Für unser Beispiel nehmen wir eine fiktive User-ID von 4 an. Diese ID speichern wir in der Variable $idUser ab. Nun können wir ein Cookie für den User definieren.

setcookie("user",$idUser, time+300(), "","syne.at",0);

Sofern der User das Setzen von Cookies akzeptiert, wird mit obigem Code ein Coo-kie mit dem Namen user und seiner User-ID gespeichert. Dieses Cookie ist für fünf Minuten gültig und bezieht sich auf die Domain syne.at.

Nun müssen wir uns überlegen, wie wir beim nächsten Besuch unseres Users kontrol-lieren können, ob ein Cookie existiert, um diesen begrüßen zu können. Dazu nutzen wir das superglobale Array $_COOKIE[].

if(isset($_COOKIE[‚user']))

Mit diesem Code überprüfen wir, ob das Cookie mit dem Namen user bei unserem User in der Cookieliste existiert. Wenn es nicht gefunden ist, wird false zurückgege-ben. Wenn das Cookie gefunden wird, ist unsere Bedingung true und wir könnten dann die Daten unseres Users aus der Datenbank laden.

2.10 Sessions Sessions helfen uns wie Cookies beim Identifizieren des Users, um auch wirklich die richtigen Daten anzuzeigen.

Lebensdauer von Session-Cookies : Der große Unterschied von persistenten Coo-kies zu Session-Cookies liegt allein in der Lebensdauer. Session-Cookies werden sofort nach Ablauf der Session, also nach Schließen des Browser-Fensters, zerstört.

Session-ID : Beim Erstellen einer Session erhält man eine ID zurück. PHP speichert dann alle Daten, die unter dieser ID anfallen, zentral und abrufbereit auf dem Ser-ver. Der Browser hingegen merkt sich bloß die ID der Session. Meist wird diese in einem Session-Cookie gespeichert.

Sessions ohne Cookies: Probleme gibt es hier, wenn der User in seinem Browser keine temporären Cookies akzeptiert. Doch das Gute an Sessions ist, dass wir hier mehrere Möglichkeiten ohne Cookies nutzen können. Denkbar wäre der Einsatz von versteckten Formularfeldern, die die Daten des Users aufnehmen. Dies ist aber eine eher aufwändige und umständliche Variante. Eine bessere Möglichkeit ist, die Session-ID direkt an die Links anzuhängen und auf jeder Seite zu kontrollieren, ob diese Session-ID mit der der aktuellen Sitzung des Browsers übereinstimmt. Nur dann darf der User die jeweilige Seite betrachten. Trotz allem bleibt die Variante mit temporären Cookies am sichersten.

Name und ID speichern: In einem dieser Cookies werden nur die Session-ID und der frei wählbare Name der Session gespeichert. Wenn Sie keinen Namen angeben, wird automatisch der Name PHPSESSID genutzt. In der php.ini können Sie den

u

u

u

u

Page 64: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 51

voreingestellten Namen einer Session ändern, indem Sie für session.name einen eigenen String angeben.

Die wichtigsten Session-Funktionen sind:

session_start()

session_register()

session_unregister()

session_destroy()

2.10.1 session_start()Mittels session_start() wird eine Session initialisiert und das Session-Cookie erstellt.

<?php

// Session initialisieren

session_start();

// Ausgabe der erzeugten Session-ID

echo(session_id());

?>

Vor dem Erzeugen einer Session dürfen auf keinen Fall Zeichen an den Browser gesen-det werden. Aus diesem Grund sollten Sie eine Session immer am Beginn eines Scripts initialisieren.

Automatische Initialisierung

In der php.ini gibt es eine Einstellung session_autostart. Wenn diese auf 1 gestellt ist, können Sie sich den Aufruf von session_start() ersparen. Trotzdem rate ich Ihnen, die Session immer explizit zu initialisieren, da Sie nicht darauf vertrauen kön-nen, dass diese Einstellung bei Ihrem Provider auch in Zukunft so bleibt.

2.10.2 session_register() vs. $_SESSIONBei der Verwendung von Sessions haben Sie auch die Möglichkeit, Variablen in der Ses-sion zu speichern . Denkbar wäre der Username oder dessen Kundennummer. Dem Auf-ruf von session_register() muss ein Aufruf von session_start() vorangehen.

<?php

// Variablen

$username = "Uwe";

$kundennummer = 1234;

u

u

u

u

Page 65: Flash cs3, ajax und php

K A P I T E L 252

// Session initialisieren

session_start();

// register_globals = ON

session_register(‚username','kundennummer');

?>

Listing 2.77: Verwendung bei register_globals=on. Nicht ideal!

Bitte beachten Sie, dass es sich bei den Parametern von session_register() nicht um die Variablen, sondern um deren Namen handelt. Somit müssen Sie das $-Zeichen weglassen.

Array bei register_globals = OFFWenn in der php.ini register_globals auf OFF steht, sollten Sie das superglobalen Array $_SESSION anstelle von session_register() verwenden:

//register_globals = OFF

$_SESSION[‚username'];

$_SESSION[‚kdnr'];

Mein Tipp ist, dass Sie sich von vorneherein angewöhnen, auf die superglobalen Arrays zurück-zugreifen, denn diese werden in jedem Fall funktionieren. Bei Einstellungen, die register_globals betreffen, sollte man generell vorsichtig sein. Auch gehen fast alle gängigen Provider aus Sicherheitsgründen weg von register_globals=on.

Wichtig ist, dass die gewünschten Variablen erst zum Ende des Scripts in die Session gespeichert werden. Dadurch ist es möglich, dass Sie den Wert der Variablen im Laufe des kompletten Scripts ändern, da ja erst der Endwert in die Session geschrieben wird. Als Folge daraus können wir auf die Sessionvariablen frühestens nach Beendigung des aktuellen Scripts und beim nächsten session_start() zugreifen.

<?php

// Variablen

$username = "Uwe";

$kundennummer = 1234;

// Session initialisieren

session_start();

// register_globals = OFF

$_SESSION["username"] = $username;

$_SESSION["kundennummer"] = $kundennummer;

?>

Listing 2.78: Verwendung bei register_globals=off. Ideal!

Page 66: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 53

2.10.3 session_unregister() vs. $_SESSIONsession_unregister() ist das genaue Gegenteil von session_register(). Es dient dazu, eine oder mehrere Variablen aus der Session zu verwerfen.

<?php

session_start();

// register_globals = ON

session_unregister('username');

?>

unset() bei register_globals = OFFIst register_globals auf OFF gestellt, dürfen wir session_unregister() nicht verwen-den, da man bei dieser Einstellung nicht auf diese Funktion zurückgreifen darf. Wir nutzen zum Löschen einer Sessionvariable dann die PHP-Funktion unset():

// register_globals_ OFF

unset($_SESSION['username']);

Heben Sie aber nicht $_SESSION selbst mit unset() auf, weil dies die besondere Funktion des superglobalen Arrays $_SESSION deaktivieren würde.

2.10.4 session_destroy()Die Funktion session_destroy() veranlasst PHP, alle Variablen einer Session zu verwerfen und die Session zu löschen . Dem Aufruf von session_destroy() muss ein Aufruf von session_start() vorangehen.

<?php

session_start();

// Session zerstören

session_destroy();

?>

2.11 Caching Caching ist das Zwischenspeichern von Daten einer Webseite im Cache (Speicher) des Browsers, um diese beim nächsten Aufruf schneller darstellen zu können. Dies ist im Grunde von Vorteil für den User. Wenn Flash mit PHP zusammenarbeitet, kann dies aber hinderlich sein, da der User möglicherweise veraltete Daten angezeigt bekommt.

Um das Caching zu beeinflussen oder auch zu verhindern, nutzen wir die Funktion header() von PHP. Der Header einer Webseite beinhaltet Anfangsinformationen, wie

Caching in PHPCaching in PHP

Page 67: Flash cs3, ajax und php

K A P I T E L 254

zum Beispiel den Typ des Dokuments und eben auch, wie lange eine Seite im Cache des Browsers gespeichert werden soll.

Um einem Browser mitzuteilen, dass eine Seite nicht zwischengespeichert werden soll, müssen wir drei Dinge einstellen.

1. Wann soll die Webseite aus dem Cache gelöscht werden?

2. Wann wurde die Webseite modifi ziert?

3. Die Webseite soll nicht gecacht werden.

Für die Einstellung, wann die Webseite aus dem Cache gelöscht werden soll, geben wir einfach ein Datum in der Vergangenheit an. Wichtig ist die Formatierung des Datums selbst und die Zeitzone.

// Datum aus der Vergangenheit

header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

Um zu bestimmen, wann die Webseite zum letzten Mal modifiziert wurde, geben wir auch wieder ein Datum ein. Hier soll logischerweise kein Datum in der Vergan-genheit angegeben werden, sondern immer das aktuelle. Dies können wir über die PHP-Datumsfunktion gmdate() realisieren. Mit dieser Funktion können wir immer das Datum mit der Zeitangabe von Greenwich Mean Time (GMT) auslesen. Wie wir dieses Datum und die Uhrzeit formatieren möchten, können wir in den Parametern von gmdate() angeben.

a – am/pm

A – AM/PM

B – Swatch-Internetzeit (Internetzeit, die überall auf der Welt gleich ist)

d – Tag des Monats mit zwei Stellen und führender Null (01-31)

D – Tag der Woche als Abkürzung mit drei Buchstaben

F – Monat, ausgeschrieben

h – Stunde im 12-Stunden-Format

H – Stunde im 24-Stunden-Format

g – Stunde im 12-Stunden-Format ohne führende Null

G – Stunde im 24-Stunden-Format ohne führende Null

i – Minuten von 0 bis 59

I – 1 bei Sommerzeit, 0 bei Winterzeit

j – Tag des Monats ohne führende Null (1-31)

l – Wochentag, voll ausgeschrieben

u

u

u

u

u

u

u

u

u

u

u

u

u

u

Caching verhindern

Caching verhindern

Datum angeben Datum angeben

Page 68: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 55

L – boolescher Wert, ob das Datum in einem Schaltjahr liegt

m – Monat mit führender Null

n – Monat ohne führende Null

M – Monat als Abkürzung

s – Sekunden mit führender Null (00-59)

S – Suffix der englischen Ordnungszahlen (bei 1 = 1st (first), bei 2 = 2nd (second) usw.)

T – Einstellung der Zeitzone des Servers (GMT oder MET ...)

t – Anzahl der Tage in einem Monat

U – Sekunden seit Beginn der UNIX-Zeitepoche (Beginn der UNIX-Zeitepoche ist der 1.1.1970, 00 Uhr)

w – numerische Darstellung des Wochentags (beginnend bei 0 für Sonntag)

Y – vierstellige Ausgabe des Jahres

y – zweistellige Ausgabe des Jahres

z – Tag im Jahr (0-365)

Z – Differenz von UTC zur benannten Zeitzone in Sekunden. Der Offset für die Zeitzone West nach UTC ist immer negativ und für die Zeitzone Ost nach UTC immer positiv (-43200 bis 43200).

Somit könnte die Header-Angabe für die letzte Modifizierung der Seite zum Beispiel folgendermaßen aussehen:

// immer geändert

header("Last-Modifi ed: " . gmdate("D, d M Y H:i:s") . " GMT");

Zu guter Letzt müssen wir noch einstellen, dass die Webseite generell nicht zwischen-gespeichert werden soll. Hier müssen wir aber die Einstellung für die verschiedenen HTTP-Versionen, welche Browser verwenden, definieren.

// für HTTP 1.1

header("Cache-Control: no-store, no-cache, must-revalidate");

header("Cache-Control: post-check=0, pre-check=0", false);

// für HTTP 1.0header("Pragma: no-cache");

Bei der Verwendung der header-Funktion sollten Sie immer beachten, dass vor deren Aufruf kein Zeichen an den Browser gesendet werden darf. Um keine Fehlermeldungen zu bekommen, geben Sie die header-Funktionen immer am Beginn einer PHP-Seite an. Achten Sie auch darauf, dass kein Leerzeichen davorsteht.

u

u

u

u

u

u

u

u

u

u

u

u

u

u

header()-Funktion immer zuerst

header()-Funktion immer zuerst

Page 69: Flash cs3, ajax und php

K A P I T E L 256

2.12 XML auslesen und erstellenIn PHP 4 war das Arbeiten mit XML noch sehr mühsam. Zum Glück hat sich das in PHP 5 grundlegend geändert. Nun ist die Grundlage von XML in PHP das Docu-ment Object Model, kurz DOM . Wenn Sie JavaScript kennen, wird Ihnen das DOM mit Sicherheit etwas sagen. Das DOM ist ein vom W3C verabschiedeter Standard für XML-Programmierschnittstellen.

Zusätzlich gibt es seit PHP 5 die Erweiterung SimpleXML , mit der es sehr einfach ist, mit XML-Daten zu arbeiten.

2.12.1 Der Aufbau eines XML-Dokuments – BlitzeinführungXML ist wie HTML und XHTML eine Bezeichnungssprache, die von der überge-ordneten Bezeichnungssprache SGML („Standard Generalized Markup Language“) abstammt. Man spricht auch gerne davon, dass XML eine „Teilmenge von SGML“ ist. XML für sich bildet wiederum die Basis für weitere Bezeichnungssprachen wie XHTML, RSS usw.

Entgegen HTML existieren in XML keine vorgefertigten Tags und aus diesem Grund sollte man auch XML nicht mit HTML vergleichen. XML stellt – für unsere Zwecke – lediglich ein Modell zur Verfügung, mit dem wir auf einfache Art und Weise struk-turierte Daten darstellen können.

ABBILDUNG 2.5

XML stammt von SGML ab.

Page 70: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 57

Ein XML-Dokument besteht aus zwei Teilen:

1. Prolog: Hierin werden der SGML-Typ deklariert (in unserem Fall also XML), Informationen zum Dokumenttyp dargestellt und etwaige Kommentare eingefügt.

2. Inhalt: Dieser Teil beinhaltet die darzustellenden Informationen, die durch das sogenannte „Wurzelelement“ umhüllt werden.

Der Prolog

Der Prolog beginnt mit der Deklaration des Dokuments, es wird also festgelegt, dass es sich hierbei um ein XML-Dokument handelt. Als Attribute dienen die Version (version), Informationen zum Zeichensatz (encoding) und zur Eigenständigkeit (standalone) des Dokuments:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

Werfen wir einen Blick auf die einzelnen Attribute:

version : Gibt die verwendete Version von XML an, wobei derzeit die Version 1.0 aktuell ist.

encoding : Gibt Informationen zum verwendeten Zeichensatz an. Typische Zei-chensätze sind der (eingeschränkte) Zeichensatz UTF-8 sowie der (westliche) Zei-chensatz ISO-8859-1.

standalone : Kann die Werte no oder yes annehmen, die ausdrücken sollen, ob zusätzlich zu diesem Dokument noch ein weiteres Dokument (wie beispielsweise eine externe DTD – Document Type Definition) benötigt wird (standalone="no") oder nicht (standalone="yes"). Da XML in diesem Buch als „Datenschnittstelle“ zwischen PHP und Flash dienen soll, wird zumeist standalone="yes" verwendet. In den meisten anderen Anwendungen (bei denen beispielsweise XML zur Dar-stellung von Daten in einem Browser-Fenster verwendet wird) benötigt man eine zusätzliche DTD und somit muss es dort standalone="no" heißen.

Auf den Prolog folgt bei Bedarf eine Dokumenttyp-Definition, damit ein Browser neben der Wohlgeformtheit auch die Gültigkeit des Dokuments überprüfen kann. In gewissen Fällen kann dies notwendig sein. Wir gehen jedoch davon aus, dass unsere (geringen Mengen an) Daten korrekt sind. Als Beispiel könnte die DTD wie folgt aus-sehen:

<!DOCTYPE Kundendaten SYSTEM "http://www.syne.at/xml/kunden.dtd">

u

u

u

Page 71: Flash cs3, ajax und php

K A P I T E L 258

Wohlgeformtheit und GültigkeitWohlgeformtheit deutet an, dass eine XML-Datei die Regeln von XML korrekt einhält. Diese sind:

Am Beginn der XML-Datei steht die XML-Deklaration: <?xml version="…">.

Das Dokument enthält zumindest ein Datenelement.

Es existiert ein Datenelement, das alle weiteren Datenelemente umfasst.

Ein gültiges XML-Dokument enthält neben der XML-Deklaration zusätzlich eine anschließende Dokumenttyp-Deklaration (DTD), die entweder auf eine externe DTD-Datei verweist oder die not-wendigen DTD-Regeln beinhaltet.

Eine gute Übersicht zu Wohlgeformtheit und Gültigkeit finden Sie auf der Website SelfHTML.de (http://de.selfhtml.org/xml).

Sollen im Prolog noch Kommentare eingefügt werden, so kann dies mithilfe der aus HTML ebenfalls bekannten Kommentarzeichen <!-- (Beginn des ein- oder mehrzei-ligen Kommentars) und --> (Kommentarende) geschehen.

Der Inhaltsbereich

Dieser Bereich des Dokuments beinhaltet sämtliche Daten. Besonders zu beachten ist, dass ein einziges Tag (das „Wurzelelement“) sämtliche weiteren Tags umschließt. Wie das Wurzelelement benannt wird, spielt keine Rolle und ist vollkommen Ihnen überlassen. Auch sind der Verwendung von Verschachtelungen beliebigen Ausmaßes sowie von Attributen keine Grenzen gesetzt. Im Allgemeinen achtet man darauf, dass bei beispielsweise einer Datenbankabfrage die Struktur der verwendete(n) Tabelle(n) widergespiegelt wird. Letztendlich ist es nur wichtig, dass die Struktur zum Auslesen der Daten bekannt und vereinbart ist.

Nachfolgend finden Sie ein Beispiel eines XML-Dokuments, bei dem Daten aus einem Verzeichnis auf dem Webserver ausgelesen werden. Beide Dokumentstrukturen sind gültig – Sie entscheiden, wie das XML-Dokument aufgebaut wird:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

<Playlist rootDir="songs" autostart="0">

<song src="01_GuentherStraub_Demo-CD_KeepOnGwine.mp3" Interpret="Guenther Straub"/>

<song src="02_GuentherStraub_Demo-CD_RockingNightExpress.mp3" Interpret="Guenther Straub"/>

<song src="03_GuentherStraub_Demo-CD_DizzyFingers.mp3" Interpret="Guenther Straub"/>

<song src="04_GuentherStraub_Demo-CD_ArkansasBlues.mp3" Interpret="Guenther Straub"/>

</Playlist>

Listing 2.79: Eine Möglichkeit des Aufbaus eines XML-Dokuments

u

u

u

Das Wurzelelement eines XML-DokumentsBitte achten Sie darauf,

dass sämtliche Daten von einem Wurzelelement

eingeschlossen werden müssen, wobei die

Betonung auf „einem“ liegt.

Page 72: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 59

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

<Playlist rootDir="songs" autostart="0">

<song>

<src>01_GuentherStraub_Demo-CD_KeepOnGwine.mp3</src>

<Interpret>Guenther Straub</Interpret>

</song>

<song>

<src>02_GuentherStraub_Demo-CD_RockingNightExpress.mp3</src>

<Interpret>Guenther Straub</Interpret>

</song>

<song>

<src>03_GuentherStraub_Demo-CD_DizzyFingers.mp3</src>

<Interpret>Guenther Straub</Interpret>

</song>

<song>

<src>04_GuentherStraub_Demo-CD_ArkansasBlues.mp3</src>

<Interpret>Guenther Straub</Interpret>

</song>

</Playlist>

Listing 2.80: Auch so kann ein XML-Dokument aufgebaut werden.

Strenge Syntax von XML -DokumentenEntgegen der Tag-Schreibweise von HTML-Dokumenten muss man bei XML-Dokumenten unter anderem folgende Punkte beachten:

Jedes geöffnete Tag muss auch wieder geschlossen werden. Tags, die sofort geöffnet und wieder geschlossen werden, unterliegen der Schreibweise <Tagname [Attribut="Wert" ...] />.

Es wird auf Groß- und Kleinschreibung der Tag-Namen geachtet.

Alle Werte von Attributen stehen in Anführungszeichen.

XML-Dokumente sind selbstverständlich in einem wesentlich größeren Umfang ver-wendbar. Es ist jedoch nicht sinnvoll, Sie mit sämtlichen Informationen hinsichtlich XML „vollzufüttern“, wenn wir im Rahmen dieses Buchs nur einen Bruchteil davon benötigen. Sollten Sie an weiterführenden Informationen interessiert sein, so finden Sie diese beispielsweise auf der XML-Website des W3-Konsortiums (http://www.w3.org/XML).

u

u

u

Tags, Attribute, Knoten & Co.Eine ausführliche Dokumentation zu XML finden Sie unter anderem auf der Website SelfHTML.de (http://de.selfhtml.org/xml).

Page 73: Flash cs3, ajax und php

K A P I T E L 260

2.12.2 Auslesen einer XML-StrukturSimpleXML bietet uns ein Objekt, mit dem wir XML-Daten einlesen können und dessen Daten in einer Objektstruktur dargestellt werden. Um XML-Daten in PHP einzulesen, stehen uns zwei Funktionen zur Verfügung:

Wenn Sie eine XML-Datei einlesen, können Sie simplexml_load_file() nutzen. Als Parameter wird allein der Dateiname mit der Pfadangabe benötigt.

Um einen XML-String weiterverarbeiten zu können, müssen wir diesen mit simplexml_load_string() einlesen. Hier ist logischerweise als Parameter die Variable des XML-Strings erforderlich. In unseren Workshops werden wir später mit dieser Funktion die XML-Daten auslesen, die Flash an PHP gesendet hat.

Sehen wir uns ein kleines Beispiel an. Erstellen Sie in einem Editor eine XML-Datei und geben Sie ihr den Namen bb_players.xml. Der Inhalt dieser Datei sollte folgender-maßen aussehen:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

<basketball>

<spieler>

<name>Michael Jordan</name>

<team>Chicago Bulls</team>

</spieler>

<spieler>

<name>Allen Iverson</name>

<team>Philadelphia 76ers</team>

</spieler>

</basketball>

Listing 2.81: Eine einfache XML-Datei

Angenommen, wir möchten nun den Namen des ersten Spielereintrags in der XML-Datei bb_players.xml ausgeben, so müssen wir zuerst einmal das XML-File einlesen:

// Einlesen der XML-Datei, die im gleichen Ordner des Scripts liegt

$xmlData = simplexml_load_string("bb_players.xml");

Als Nächstes geht es nun ans Auslesen des ersten Spielereintrags:

// Ausgabe des Spielernamens

echo($xmlData->spieler[0]->name);

Um das Team des ersten Spielers zu erfahren, müssen wir nur den folgenden Code eingeben:

echo($xmlData->spieler[0]->team);

u

u

Page 74: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 61

Das Auslesen der Daten eines XML-Knotens ist denkbar einfach. Es funktioniert im Grunde wie bei einem Array. Um den ersten Eintrag auslesen zu können, müssen wir im Fall eines Arrays an der Stelle 0 beginnen und bei einem XML-Knoten ist es genau-so. Will man die Daten des zweiten Spielers unserer XML-Datei ausgeben, müssen wir nur den zweiten Spielereintrag mit spieler[1] aufrufen.

// Ausgabe der zweiten Spielerdaten

echo($xmlData->spieler[1]->name);

echo($xmlData->spieler[1]->team);

Um alle Knoten der XML-Datei auszugeben, können wir eine for...each-Schleife nutzen.

foreach($xmlData->spieler as $mySpieler){

echo($mySpieler -> name);

echo(" – ");

echo($mySpieler->team."<br />");

}

Attribute auslesen

Das Auslesen von Attributen in XML-Tags ist auch denkbar einfach. Diese können wie assoziative Array-Einträge behandelt werden. Um dies zu testen, erweitern wir unsere XML-Datei um ein Attribut mit dem Namen nickname im Tag name.

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

<basketball>

<spieler>

<name nickname="Air Jordan">Michael Jordan</name>

<team>Chicago Bulls</team>

</spieler>

<spieler>

<name nickname="The Answer">Allen Iverson</name>

<team>Philadelphia 76ers</team>

</spieler>

</basketball>

Listing 2.82: Das Tag name wurde um ein Attribut erweitert.

Unsere angepasste for...each-Schleife sieht demnach so aus:

foreach($xmlData->spieler as $mySpieler){

echo($mySpieler -> name);

Page 75: Flash cs3, ajax und php

K A P I T E L 262

echo(" – ");

echo($mySpieler -> name[‚nickname']);

echo(" – ");

echo($mySpieler -> team."<br />");

}

Untergeordnete Knoten auslesen

Interessant ist noch, wie wir XML-Knoten auslesen können, deren Bezeichnung wir nicht kennen. Dazu steht uns eine Funktion mit dem Namen children zur Verfü-gung. Diese Funktion liest alle einem Knoten untergeordneten Knoten aus und spei-chert diese in einem Array.

$arrKnoten = $xmlData->children();

foreach($arrKnoten as $arrMyKnoten){

$arrChildren = $arrMyKnoten->children();

foreach($arrChildren as $strKnoten => $varValue) {

echo("Knoten ".$strKnoten." hat den Wert ".$varValue."<br />");

}

}

Zuerst holen wir mit $arrKnoten = $xmlData->children(); alle Kindelemente des obersten Elements <basketball> aus dem XML-Objekt $xmlData und speichern diese in dem Array $arrKnoten.

Dann verarbeiten wir dieses Array mit einer for...each-Schleife. In dieser Schleife werden alle Kinder des zweiten XML-Knotens <spieler> ausgelesen und im Array $arrChildren gespeichert. Besonders an dieser for...each-Schleife ist, dass wir neben den Werten des assoziativen Arrays auch die Schlüssel auslesen.

foreach($arrChildren as $strKnoten => $varValue)

Zum Schluss müssen wir nur noch die Daten des XML-Objekts auslesen.

echo("Knoten ".$strKnoten." hat den Wert ".$varValue."<br />");

2.12.3 XML-Dokumente erstellen Um eine XML-Datei zu erstellen, nutzen wir die SimpleXML-Funktion asXML(). Wir erstellen einfach einen String mit der bereits bekannten XML-Struktur. Auf das XML-Tag können wir verzichten, da dieses die Funktion asXML() für uns automatisch hinzugefügt.

$data = "

<basketball>

Page 76: Flash cs3, ajax und php

G R U N D L A G E N D E R P R O G R A M M I E R U N G 63

<spieler>

<name>Michael Jordan</name>

<team>Chicago Bulls</team>

</spieler>

<spieler>

<name>Allen Iverson</name>

<team>Philadelphia 76ers</team>

</spieler>

</basketball>

";

Dann erstellen wir wieder ein SimpleXML-Objekt und definieren dieses als XML:

$xmlData = simplexml_load_string($data);

$xmlData = $xmlData->asXML();

Das war’s auch schon wieder. Zum Testen können wir die XML-Struktur noch im Browser anzeigen:

echo($xmlData);

So, nun sind Sie für die weiteren Themen und die Workshops gerüstet. Viel Spaß beim Weiterlesen.

Page 77: Flash cs3, ajax und php
Page 78: Flash cs3, ajax und php

3BASISWISSEN

Ein Programm zum Erstellen von Animationen – passt das zur Programmierung? Wir werden sehen ... Eines aber trotzdem schon vorweg – die Antwort ist ja, ohne wenn und aber!

Im einführenden Kapitel vermittelte ich Ihnen die Grundlagen der Programmierung. Dort haben Sie auch erfahren, dass diese Grundlagen für (beinahe) alle Programmiersprachen gleich sind. Es ist im Grunde meist vollkommen irrelevant, in welcher Programmiersprache man gelernt hat zu programmieren – die Logik ist immer dieselbe. In diesem Buch werden aber nur PHP, JavaScript und ActionScript genutzt und erklärt. Welche Punkte außerdem noch beachtet werden sollten und was Sie als Flash-Entwickler an Basiswissen mitbringen sollten, klärt dieses kurze Kapitel.

Wann immer eine neue Version von Flash auf dem Markt erscheint, glänzen bei den Entwicklern die Augen. Auch bei mir – ich muss es ehrlich zugeben. Jedoch sprechen wir in diesem Buch über ein Thema, bei dem Weiterentwicklungen sehr träge und zäh wirken, und das aus einem sehr einfachen Grund: Es geht hier nicht um eine Schnittstelle zwischen Flash und PHP, sondern um eine zwischen dem Browser auf der einen Seite (dem Client) und dem Server auf der anderen. Flash läuft clientseitig, PHP wird serverseitig ausgeführt. Wenn nicht am Standard der Datenübertragung zwischen Server und Client gearbeitet wird, sieht die Situation wie folgt aus: Die Daten-übertragung erfolgt per GET oder per POST.

Page 79: Flash cs3, ajax und php

K A P I T E L 366

Was sollte hier noch hinzukommen? Nichts mehr, da muss ich Sie wohl enttäuschen. Nein, „enttäuschen“ ist hier nicht die korrekte Aussage – vielmehr möchten wir Sie noch einmal an die Technik „Server vs. Client“ erinnern, die klar und deutlich defi-niert, dass eine Datenübertragung zwischen Client und Server auf genau diese beiden Arten erfolgen kann und nicht anders!

Die wesentlich wichtigere Frage ist, was Sie unter diesen Bedingungen alles erzeugen können. Genau hierauf eine Antwort zu geben, ist Ziel dieses Buchs. Einzig die Kom-munikation zwischen Browser und Flash ist von grundlegendem Interesse für uns.

AJAX tut an dieser Stelle nichts anderes: Es greift auf den Datenaustausch zwischen Server und Client per POST oder GET zurück. Der wesentliche Unterschied zum bis-herigen Denken ist, dass AJAX auf Clientseite in der Lage ist, ohne ein Neuladen der Seite nachträglich Daten vom Server abzufragen – dies ist ein Novum!

3.1 PHPPHP läuft mittlerweile in Version 5 (bei Drucklegung war die letztgültige Version die Version 5.2.3) objektorientiert – das konnte die Version 4 noch nicht. Obwohl – in unseren Anwendungen trifft uns das nicht, denn die meisten gängigen Anwendungen in Zusammenhang mit Flash oder AJAX werden nach wie vor ohne Objektorientierung entwickelt. Natürlich kann man an dieser Stelle keine generelle Aussage treffen, denn so ziemlich jede Anwendung ließe sich auch objektorientiert erstellen. Im Allgemeinen sind die Scripts für die Zusammenarbeit mit Flash jedoch so kurz, das Objektorien-tierte Programmierung (OOP) erst gar nicht zum Einsatz gelangt.

3.2 JavaScript (AJAX) & DOMIm vorigen Kapitel wiederholten wir die Grundlagen der Programmierung, die natür-lich auch für JavaScript gelten. Jede Programmiersprache hat ihre eigene „Umgebung“, in der sie wirken – im Fall von JavaScript ist dies das XHTML-Dokument. Es besteht zwar auch die Möglichkeit, JavaScript auf Serverseite zu verwenden, jedoch kommt diese Variante in unserem Fall nicht zum Einsatz.

Die grundlegende Frage ist also, wie JavaScript mit seiner Umgebung interagieren kann. In den letzten Jahren hat sich der Begriff DHTML (Dynamic HTML) eingebür-gert – grundsätzlich meint man damit die Möglichkeit, JavaScript, CSS und XHTML miteinander arbeiten zu lassen. Bleibt also zu klären, wie das möglich ist.

Unweigerlich stößt man dabei auf den Begriff des Document Object Model (DOM). Ein DOM beschreibt grundsätzlich die Objekte, die in einem Dokument verwendet werden, deshalb ist ein DOM auch nicht auf ein XHTML-Dokument beschränkt. Für JavaScript in Zusammenhang mit (damals noch) HTML wurde vom W3-Consorti-um ein DOM erstmals am 1. Oktober 1998 eingeführt, um der ewigen Diskrepanz

Page 80: Flash cs3, ajax und php

B A S I S W I S S E N 67

zwischen Netscape und Microsoft in Bezug auf JavaScript und JScript ein für alle mal einen Riegel vorzuschieben. Ende September 2000 wurde dann eine weitere Version dieses DOM veröffentlicht, das im November 2000 dann eine offizielle Empfehlung des W3C erhielt. Ein wichtiger Punkt ist, dass sich das DOM (ich beziehe mich ab jetzt nur noch auf das DOM für JavaScript) nicht speziell auf HTML-Elemente bezieht, sondern in abstrakter Form Zugriff auf Objekte definiert. Grundsätzlich ist mit dem DOM der Zugriff auf jedes XML-basierte Dokument möglich. Da jedoch auch auf die Gegebenheiten von HTML im Speziellen eingegangen werden muss, existiert eine Art „Kern-DOM“ speziell für die Bedürfnisse von HTML und den sich aus den Zwistig-keiten zwischen Netscape und Microsoft ergebenen Differenzen.

Leider wurde in der Erstversion von DOM komplett auf ein Eventhandling verzichtet, was speziell bei größeren Projekten unabdingbar notwendig ist. Daher muss oft auf die Möglichkeiten des DOM 2.0 zurückgegriffen werden, das – und das haben Sie sicher-lich schon erraten – in den verschiedenen Browsern noch nicht vollständig unterstützt wird ...

3.2.1 „Kern-DOM“

ABBILDUNG 3.1

„Kern-DOM“ – die Grundlage für alle gängigen Browser

Page 81: Flash cs3, ajax und php

K A P I T E L 368

Die obige Abbildung zeigt die Kernversion des DOM, das den Zugriff auf alle Elemente innerhalb eines XHTML-Dokuments ermöglicht. Der Zugriff erfolgt grundsätzlich hierarchisch: Möchte man beispielsweise auf ein Element innerhalb eines Formulars zugreifen, so muss man den „Weg durch den Hierarchiebaum“ gehen:

1. Das übergeordnetste Element ist das window, also bezieht man sich zunächst auf dieses Element: window. Selbstverständlich kann ein window auch ein Frame sein.

2. Daraufhin greift man auf das Dokument im window zu: window.document.

3. Danach muss auf das Formular zugegriffen werden. Da es in einem XHTML-Dokument mehr als nur ein Formular geben kann, existiert ein Array an Formularen, das entweder assoziativ oder über den Formularindex angesprochen werden kann. Der Formularindex bezieht sich auf die Reihenfolge der Formulare im Dokument: Das nullte Formular ist somit das erste vorkommende Formular im XHTML-Code. Viel einfacher ist der Zugriff über den Formularnamen (assoziativ):

window.document.forms[Formularindex]

oder

window.document.forms["Formularname"]

4. Hat man sich für ein Formular entschieden, kann man auf die Elemente (Buttons, Eingabefelder etc.) innerhalb des Formulars zugreifen. Auch hier besteht natürlich die Möglichkeit, dass sich mehr als nur ein Element im Formular befi nden, deshalb erfolgt der Zugriff auf die Elemente wieder über ein (assoziatives) Array:

window.document.forms["Formularname" oder –index].elements["Elementname" oder –index]

5. Hat man diesen Weg erst einmal hinter sich gebracht, kann man auf alle Eigenschaften und Methoden des Elements zugreifen.

Der Zugriff auf sämtliche HTML-Elemente funktioniert hier also immer gleich:

1. Weg durch den Hierarchiebaum zum Objekt fi nden

2. Auf die Attribute bzw. Eigenschaften des Objekts zugreifen

Eine komplette Auflistung aller Elemente und deren Eigenschaften und Methoden ist die Aufgabe einer Referenz – ich empfehle Ihnen eine einschlägige Literatur bzw. die Website http://de.selfhtml.org. Bücher zu diesem Thema füllen zum Teil mehrere hundert Seiten und beschreiben im Detail jedes Element und alle zugehörigen Details. Als Webdesigner sind Sie sicherlich mit diesen Elementen bereits vertraut, wes-halb Sie sehr wahrscheinlich auch mit SelfHTML schon zu tun hatten.

Page 82: Flash cs3, ajax und php

B A S I S W I S S E N 69

3.2.2 Alternativer Zugriff auf ObjekteEine andere Variante des Zugriffs auf Objekte innerhalb eines (XML-basierten) Doku-ments ist der Zugriff über die Baumstruktur des Dokuments an sich. Betrachten wir folgendes Beispiel:

<h1 class="myH1">Hier ist eine erste &Uuml;berschrift.</h1>

<p>Nun folgt Text, der verschiedene Auszeichnungen wie <strong>fett</strong> oder <em>kursiv</em> aufweist.</p>

<p>So, ein zweiter Text, der <em><strong>fett und kursiv</strong></em> geschrieben ist.</p>

Listing 3.1: Ein einfaches Beispiel eines XHTML-Dokuments

Die entsprechende Struktur dieses Dokuments wäre wie folgt:

Jedes Element innerhalb der Baumstruktur wird als Knoten bezeichnet. Man unter-scheidet zwischen drei Arten von Knoten:

1. Elementknoten

2. Attributknoten

3. Textknoten

In der obigen Abbildung (Abbildung 3.2) sind nur Elementknoten dargestellt. Würden wir alle Knoten darstellen, würde sich die Abbildung wie folgt erweitern:

ABBILDUNG 3.2

Die Baumstruktur des obigen Beispiels (Listing 3.1)

Page 83: Flash cs3, ajax und php

K A P I T E L 370

Was in den Abbildungen auffällt (und selbstverständlich auch absichtlich so gezeichnet ist ...), ist die Einteilung in sogenannte „Parent- und Child-Knoten“ sowie „Siblings“. Die Baumstruktur ist wie eine Ahnengalerie zu verstehen:

Parent-Knoten sind übergeordnete Knoten: Zu <h1> existiert in unserem Fall kein Parent-Knoten, zum ersten <strong> (zweite Ebene) ist der Parent-Knoten <p>, zum zweiten <strong> (dritte Ebene) ist der Parent-Knoten <em>, dessen Parent wiederum ein <p> ist.

Child-Knoten sind untergeordnete Knoten: <strong> ist beispielsweise ein Child-Knoten von <p> usw.

Siblings sind „Geschwister“: <h1> hat beispielsweise die beiden Geschwister <p> und <p>.

Um direkt und schnell auf einen beliebigen Knoten innerhalb eines Dokuments zugreifen zu können, wurden drei Funktionen eingeführt:

getElementById(Element-ID): greift auf ein Element (einen Knoten) mit einer (eindeutigen) id zu.

getElementsByName(Elementname)[i]: greift auf Elemente eines gewissen Namens zu. Da der Name von Elementen im Dokument nicht eindeutig sein muss, wird auf ein Array zugegriffen.

u

u

u

u

u

ABBILDUNG 2.3

Dieselbe Baumstruktur inklu-sive Attribut- (durchgezogen

umrandet) und Textknoten (gestrichelt umrandet)

Page 84: Flash cs3, ajax und php

B A S I S W I S S E N 71

getElementsByTagName(Tagname)[i]: greift auf Elemente eines gewissen Tag-Namens (wie etwa „p“, „h1“ etc.) zu. Wie im Fall von getElementsByName gilt auch hier: Es können mehrere Tags dieser Art existieren, deshalb erfolgt der Zugriff über ein Array.

Hat man ein Element eindeutig identifiziert, kann man sich über die Eigenschaften und Methoden des node-Objekts zu den weiteren Elementen „durcharbeiten“. Neh-men wir ein Beispiel:

<h1 class="myH1">Hier ist eine erste &Uuml;berschrift.</h1>

<p id="myP01">Nun folgt Text, der verschiedene Auszeichnungen wie <strong>fett</strong> oder <em>kursiv</em> aufweist.</p>

<p>So, ein zweiter Text, der <em><strong>fett und kursiv</strong></em> geschrieben ist.</p>

Listing 3.2: Erweiterung des obigen Beispiels um id="myP01". Der Zugriff soll auf das Element <em> erfolgen.

Ziel ist es, den Textknoten des <em> auszulesen. Um zunächst auf den Paragrafen mit der id="myP01" zuzugreifen, verwendet man folgenden Befehl:

document.getElementById("myP01")

Da das Tag <em> das zweite Kind von <p> ist, verwenden wir das Array childNodes, welches den Zugriff auf alle Child-Elemente eines gegebenen Knotens zulässt:

document.getElementById("myP01").childNodes[1]

Nun erfolgt der Zugriff auf den Textknoten. Hierbei ist zu berücksichtigen, dass ein Textknoten immer ein Child-Knoten eines Elementknotens ist. Aus diesem Grund erfolgt der Zugriff wie folgt:

document.getElementById("myP01").childNodes[1].fi rstChild

Der letzte Schritt besteht im Auslesen des Werts des Knotens – dies erfolgt über die Eigenschaft nodeValue eines Knotens:

document.getElementById("myP01").childNodes[1].fi rstChild.nodeValue

Damit hätten wir den Wert des Knotens erreicht! Weitere Informationen zu Knoten und deren Eigenschaften und Methoden finden Sie in der einschlägigen Literatur wie beispielsweise der SelfHTML-Site.

Ein abschließender Tipp noch: Bedenken Sie, dass Sie per JavaScript erst dann auf Knoten zugreifen können, wenn diese zum User übertragen wurden. Aus diesem Grund sollte der Zugriff erst erfolgen, wenn die gesamte Seite zum User übertragen wurde – ideal ist hier das Verwenden des Ereignisses onload des window-Objekts.

u

Textknoten ist ein Kind des Elementknotens

Textknoten ist ein Kind des Elementknotens

Page 85: Flash cs3, ajax und php

K A P I T E L 372

3.3 Flash

3.3.1 Sinnvolle Kombination von Flash und PHPAb wann – sprich ab welcher Generation von Flash – ist der Einsatz von Flash auf Clientseite und PHP auf Serverseite sinnvoll? Seit der sechsten Version (Flash MX) können wir bereits relativ problemlos über die LoadVars - und die XML-Klasse Daten versenden und einlesen. Zwar wurde die XML-Klasse bereits mit Flash 5 eingeführt, man konnte jedoch nur sehr eingeschränkt damit arbeiten. Die LoadVars-Klasse exis-tiert hingegen erst ab Flash 6. Fassen wir kurz zusammen, ab welcher Generation uns welche Möglichkeiten zur Verfügung standen:

1. Flash 5: Die Methode loadVariables (mittlerweile nur noch sehr selten verwendet) stand schon ab Generation 4 von Flash bereit, die XML-Klasse wird mit Flash 5 eingeführt.

2. Flash 6 (Flash MX): Macromedia integriert die LoadVars -Klasse.

3. Flash 7 (Flash MX 2004): Nachdem die loadVariables-Methode nicht mehr adäquat ist, wird diese mit Release 7 von Flash überarbeitet und hat seitdem ein geändertes Verhalten.

4. Flash 8: keine Neuerungen

5. Flash CS3: umfassende Änderungen durch die Einführung von ActionScript 3.0

Die achte Version von Flash brachte uns in puncto Kommunikation mit PHP auf Ser-verseite also keine Neuerungen, weil sie technisch nicht sinnvoll bzw. möglich wären: Zum Datenaustausch mit PHP stehen im Prinzip alle notwendigen Klassen bereit und hinsichtlich der Client-Server-Kommunikation müsste ein Technologiewechsel statt-finden. Die Möglichkeit, XML-Daten in Flash einzulesen, hat uns einen wesentlichen Schritt weitergebracht und die Tür zu strukturierten Daten geöffnet. Eine Neuerung hinsichtlich der Datenstrukturierung à la XML ist in naher Zukunft nicht zu erwarten – auch Techniken wie RSS (Real Simple Syndication) bauen auf XML auf.

Flash CS3 bedeutete in dieser Hinsicht in Zusammenhang mit ActionScript 3.0 beina-he eine „Revolution“. Das Laden von Daten jeglicher Art wurde durch die Einführung der URLLoader- und URLRequest-Objekte komplett geändert. Viele der aus Action-Script 2.0 bekannten Klassen wurden in ActionScript 3.0 entweder verschoben oder umfassend umstrukturiert. Eine Übersicht aller Änderungen finden Sie am Ende des Kapitels.

ActionScript 3.0 bringt die

Revolution

ActionScript 3.0 bringt die

Revolution

Page 86: Flash cs3, ajax und php

B A S I S W I S S E N 73

3.3.2 Weitere Verbindungsmöglichkeiten zur ServerseiteNeben den genannten Klassen sind in Flash auch Komponenten installiert, mit deren Hilfe man zu einem Server Kontakt aufbauen kann. Sie erfordern jedoch eine Instal-lation auch auf Serverseite, die im Allgemeinen nicht gegeben ist (das Betreiben eines Communication-Servers von Macromedia wäre ein Beispiel).

Jeder gute Webentwickler sollte in der Lage sein, auf solche zusätzlichen serverseitigen Komponenten verzichten zu können, weil es einfach nicht der Realität entspricht, dass uns solche Installationen zur Verfügung stehen. Deshalb wird der Beschreibung dieser Komponenten in diesem Buch nur wenig Platz eingeräumt. Sollten Sie in der glück-lichen Lage sein, auf einen Communication-Server von Macromedia zurückgreifen zu können, dann schlagen Sie doch mal in der ActionScript-Referenz bei Camera und Microphone nach – und flugs haben Sie einen Video-Chat gebastelt.

Keine zusätzlichen Server-Dienste verfügbar? Egal oder vielmehr – Gott sei dank! Wir sind in der glücklichen Lage, eine definierte und (in naher Zukunft) auch nicht verän-derbare Schnittstelle vorliegen zu haben, mit der wir in aller Ausführlichkeit arbeiten können – nämlich das Senden von Daten vom Client zum Server per GET oder POST. Dazu mehr in den folgenden Kapiteln.

3.3.3 ActionScript 3.0 – die wichtigsten ÄnderungenNachfolgend finden Sie die wesentlichen Änderungen von ActionScript 2.0 auf Action-Script 3.0 in Bezug auf die Themen dieses Buchs – eine umfassende Darstellung aller Änderungen in den Klassen finden Sie im Anschluss.

1. Eigenschaften von MovieClips: Der bekannte Unterstrich „_“ am Beginn einer MovieClip-Eigenschaft wurde eliminiert (visible anstatt _visible, alpha anstatt _alpha, x anstatt _x usw.). Ebenso wurde die Handhabung von Prozentwerten geändert: Die Werte werden nun von 0–1 anstatt von 0–100 angegeben.

2. Levelbezug und -verwaltung: Die Arrays _global und _root existieren nicht mehr, wobei anstatt _root der Bezug über stage verwendet werden kann. Anstatt _parent muss nun parent verwendet werden.

Ebenso hat sich die gesamte Verwaltung der Levels geändert. Die Methoden swapDepths und getNextHighestDepth sind Vergangenheit – stattdessen wird die Level-Verwaltung nun über die DisplayObjectContainer-Klasse gespielt, wobei diese Klasse als ein Array aller verwendeten Objekte auf der Bühne verstanden werden kann, die über einen Index angesprochen werden. So kann die Reihenfolge (in z-Richtung) von Elementen nach wie vor beeinfl usst und gesetzt werden.

Page 87: Flash cs3, ajax und php

K A P I T E L 374

3. MovieClip vs. DisplayObjectContainer: Die meisten MovieClip-Funk-tionen, die man bisher zur Entwicklung verwendet hat, wurden geändert. Beispielsweise existiert die Methode createEmptyMovieClip nicht mehr. Stattdessen wird die Methode addChild der DisplayObjectContainer-Klasse verwendet. Dementsprechend lassen sich auch die Methoden createTextField, duplicateMovieClip usw. nicht mehr auffi nden.

4. Laden von Daten: In allen Bereichen des Datenladens haben sich Änderungen ergeben. Grundsätzlich erfolgt nun der Ladevorgang immer über das URLRequest-Objekt in Zusammenhang mit diversen anderen Objekten:

Bilder und SWF-Dateien: Es werden die Objekte URLRequest und URLLoader verwendet. Die ActionScript 2.0-Variante mit loadMovie bzw. MovieClipLoader wurde entfernt.

XML-Daten und Servervariablen: Auch hier wird auf die Objekte URLRequest und URLLoader zurückgegriffen. Als zusätzliches Objekt kommt hier natürlich das XML-Objekt zum Einsatz. Servervariablen können nach dem Laden direkt angesprochen werden.

Laden einer URL: Die Funktion getURL wurde ebenfalls eliminiert. An ihre Stelle treten die Funktionen sendToURL und navigateToURL.

5. Eventhandler: auch bei der Ereignisbehandlung hat sich einiges getan. Die Ereignisse sind nun strukturierter, auch können – wie in ActionScript 2.0 gang und gäbe – Button-Ereignisse auf MovieClips nicht mehr angewandt werden. Es wurde beispielsweise auch das Ereignis onReleaseOutside komplett eliminiert und es muss durch andere Techniken ersetzt werden. Eine Umbenennung vieler Ereignisse (speziell Mausereignisse) hat ebenfalls stattgefunden.

Page 88: Flash cs3, ajax und php

B A S I S W I S S E N 75

ActionScript 3.0 – sämtliche Änderungen

ActionScript 2.0 ActionScript 3.0 Kommentare

Accessibility-Klasse flash.accessibility.Accessibility

isActive() flash.accessibility.Accessibility.active

Von einer Funktion zu einer Accessor-Eigenschaft geändert. Der Name wurde von isActive in active geändert.

updateProperties() flash.accessibility.Accessibility.updateProperties()

arguments-Klasse arguments

caller Entfernt Sie erreichen die gleiche Funktionalität durch Übergeben von arguments.callee als ein Argument von der anrufenden Funktion an die angerufene Funktion. Ein Beispiel fi nden Sie im Abschnitt „Beispiele“ unter argu-ments.callee.

Array-Klasse Array Keine Änderung

CASEINSENSITIVE Array.CASEINSENSITIVE Der Datentyp wurde in uint geändert.

DESCENDING Array.DESCENDING Der Datentyp wurde in uint geändert.

length Array.length Der Datentyp wurde in uint geändert.

NUMERIC Array.NUMERIC Der Datentyp wurde in uint geändert.

RETURNINDEXEDARRAY Array.RETURNINDEXEDARRAY Der Datentyp wurde in uint geändert.

UNIQUESORT Array.UNIQUESORT Der Datentyp wurde in uint geändert.

Array Array.Array() Der Parameter wurde geändert und verwendet jetzt das Format ...(rest).

push() Array.push() Der Parameter wurde geän-dert und verwendet jetzt das Parameterformat ...(rest).

sort() Array.sort() Der Datentyp des options-Parameters wurde in uint geän-dert.

Page 89: Flash cs3, ajax und php

K A P I T E L 376

ActionScript 2.0 ActionScript 3.0 Kommentare

sortOn() Array.sortOn() Der Datentyp des options-Para-meters wurde in uint geändert. Der Funktionsumfang wurde unter ActionScript 3.0 erweitert. Jetzt können Sie nach mehreren Feldnamen sortieren, indem Sie ein Objekte-Array für den field-Name-Parameter übergeben. Wenn Sie außerdem ein entsprechendes Optionsfl ags-Array für den op-tions-Parameter übergeben, kann jedes Sortierfeld seinen eigenen übereinstimmenden options-Parameter aufweisen.

splice() Array.splice() Die Parameter können jeden Daten-typ annehmen, die bevorzugten Datentypen sind jedoch int und uint. Der Parameter value wurde in das Parameterformat ...(rest) geändert.

unshift() Array.unshift() Der Parameter value wurde in das Parameterformat ...(rest) geändert. Der Datentyp des Rückgabewerts wurde in uint geändert.

AsBroadcaster-Klasse flash.events.EventDispatcher

_listeners flash.events.EventDispatcher.willTrigger()

Kein direktes Äquivalent. Die willTrigger()-Methode meldet Ihnen zwar, ob Listener regis-triert sind, jedoch nicht wie viele.

addListener() flash.events.EventDispatcher.addEventListener()

Kein direktes Äquivalent, da Sie im ActionScript 3.0-Ereignismodell nicht nur dem Broadcaster-Objekt, sondern jedem Objekt im Ereignisablauf Ereignis-Listener hinzufügen können.

broadcastMessage() flash.events.EventDispatcher.dispatchEvent()

Kein direktes Äquivalent, da das ActionScript 3.0-Ereignismodell auf andere Weise arbeitet. Die dispatch Event()-Methode sendet ein Ereignisobjekt in den Ereignisablauf, während die broadcastMessage()-Methode Meldungen direkt an jedes regis-trierte Listener-Objekt sendet.

Page 90: Flash cs3, ajax und php

B A S I S W I S S E N 77

ActionScript 2.0 ActionScript 3.0 Kommentare

initialize() Entfernt Es gibt kein direktes Äquivalent in ActionScript 3.0, aber eine ähnliche Funktionalität wird durch die Unterklassen der EventDispatcher-Klasse er-reicht. Beispielsweise erweitert die DisplayObject-Klasse EventDispatcher, daher sind alle Instanzen von DisplayObject und der DisplayObject-Unterklassen in der Lage, Ereignisobjekte zu senden und zu empfangen.

removeListener() flash.events.EventDispatcher.removeEventListener()

Kein direktes Äquivalent, da Sie im ActionScript 3.0-Ereignismodell nicht nur dem Broadcaster-Objekt, sondern jedem Objekt im Ereignisablauf Ereignis-Listener hinzufügen und wieder entfernen können.

BitmapData-Klasse flash.display.BitmapData ActionScript 3.0 verwendet die BitmapDataChannel-Klasse zur Aufzählung der Konstanten, die den zu verwendenden Kanal angeben.

height flash.display.BitmapData.height

Der Datentyp wurde von Number in int geändert.

rectangle flash.display.BitmapData.rect Die Eigenschaft wurde um-benannt, um für Konsistenz mit anderen Mitgliedern der API zu sorgen.

width flash.display.BitmapData.width Der Datentyp wurde von Number in int geändert.

copyChannel() flash.display.BitmapData.co-pyChannel()

Die Datentypen der Parameter code, sourceChannel und dest-Channel wurden in uint geän-dert.

draw() flash.display.BitmapData.draw()

Der source-Parameter lau-tet jetzt IBitmapDrawable; DisplayObject und BitmapData implementieren jetzt die IBitmapDrawable-Schnittstelle, so dass Sie entweder ein DisplayObject- oder ein BitmapData-Objekt an den Parameter source übergeben können.

fillRect() flash.display.BitmapData.fill-Rect()

Der Datentyp des Parameters color wurde in uint geändert.

floodFill() flash.display.BitmapData.floodFill()

Akzeptiert jetzt int-Werte für die Parameter x und y sowie einen uint-Wert für color.

getColorBoundsRect() flash.display.BitmapData.get-ColorBoundsRect()

Akzeptiert jetzt uint-Werte für die Parameter mask und color.

Page 91: Flash cs3, ajax und php

K A P I T E L 378

ActionScript 2.0 ActionScript 3.0 Kommentare

getPixel() flash.display.BitmapData.get-Pixel()

Akzeptiert jetzt int-Parameter-werte und gibt einen uint-Wert zurück.

getPixel32() flash.display.BitmapData.get-Pixel32()

Akzeptiert jetzt int-Parameter-werte und gibt einen uint-Wert zurück.

hitTest() flash.display.BitmapData.hit-Test()

Akzeptiert jetzt uint-Werte für die Parameter firstAlphaThreshold und secondAlphaThreshold.

loadBitmap() Entfernt Diese Funktion wird wegen der neuen Bitmap-Unterstützung in ActionScript 3.0 nicht mehr be-nötigt.

merge() flash.display.BitmapData.merge()

Akzeptiert jetzt uint-Werte für die Multiplizierer-Parameter.

noise() flash.display.BitmapData.noi-se()

Akzeptiert jetzt einen int-Wert für den Parameter randomSeed und uint-Werte für die Parameter low, high und channelOptions.

perlinNoise() flash.display.BitmapData.per-linNoise()

Akzeptiert jetzt einen int-Wert für den Parameter randomSeed und uint-Werte für die Parameter numOctaves und channel-Options.

pixelDissolve() flash.display.BitmapData. pixelDissolve()

Akzeptiert jetzt einen int-Wert für die Parameter randomSeed und numPixels sowie einen uint-Wert für den Parameter fillColor. (Der numPixels-Parameter wurde in ActionScript 2.0 in numberOf-Pixels umbenannt.)

scroll() flash.display.BitmapData. scroll()

Akzeptiert jetzt int-Werte für die Parameter x und y.

setPixel() flash.display.BitmapData.set-Pixel()

Akzeptiert jetzt int-Werte für die Parameter x und y sowie einen uint-Wert für color.

setPixel32() flash.display.BitmapData.set-Pixel32()

Akzeptiert jetzt int-Werte für die Parameter x und y sowie einen uint-Wert für color.

threshold() flash.display.BitmapData.threshold()

Akzeptiert jetzt uint-Werte für die Parameter threshold, color und mask und gibt einen uint-Wert zurück.

BlurFilter-Klasse

quality flash.filters.BlurFilter.qua-lity

Der Datentyp der quality-Eigenschaft wurde von Number in uint geändert.

Button-Klasse flash.display.SimpleButton

_alpha flash.display.DisplayObject.alpha

blendMode flash.display.DisplayObject.blendMode

Page 92: Flash cs3, ajax und php

B A S I S W I S S E N 79

ActionScript 2.0 ActionScript 3.0 Kommentare

cacheAsBitmap flash.display.DisplayObject.cacheAsBitmap

enabled flash.display.SimpleButton.enabled

filters flash.display.DisplayObject.filters

In ActionScript 3.0 lautet der Datentyp Array.

_focusrect flash.display.InteractiveObject.focusRect

_height flash.display.DisplayObject.height

_highquality Entfernt Siehe Stage.quality

_name flash.display.DisplayObject.name

_parent flash.display.DisplayObject.parent

_quality Entfernt Sie können die Wiedergabequalität aller Anzeigeobjekte mit flash.display.Stage.quality ein-stellen.

_rotation flash.display.DisplayObject.rotation

scale9Grid flash.display.DisplayObject.scale9Grid

_soundbuftime flash.media.SoundMixer.buffer-Time

In die SoundMixer-Klasse verschoben, die zur globalen Soundsteuerung verwendet wird. Umbenannt, sodass keine Abkürzungen mehr vorhanden sind. Der Unterstrich am Anfang des Namens wurde entfernt.

tabEnabled flash.display.InteractiveObject.tabEnabled

tabIndex flash.display.InteractiveObject.tabIndex

_target Entfernt ActionScript 3.0 identifi ziert Anzeigeobjekte direkt, daher ist die Identifi zierung eines Anzeigeobjekts über dessen Pfad nicht mehr notwendig.

trackAsMenu flash.display.SimpleButton.trackAsMenu

_url Entfernt Siehe DisplayObject.loader-Info.url

useHandCursor flash.display.SimpleButton.useHandCursor

_visible flash.display.DisplayObject.visible

_width flash.display.DisplayObject.width

_x flash.display.DisplayObject.x

_xmouse flash.display.DisplayObject.mouseX

_xscale flash.display.DisplayObject.scaleX

_y flash.display.DisplayObject.y

Page 93: Flash cs3, ajax und php

K A P I T E L 380

ActionScript 2.0 ActionScript 3.0 Kommentare

_ymouse flash.display.DisplayObject.mouseY

_yscale flash.display.DisplayObject.scaleY

getDepth() flash.display.DisplayObjectContainer.get-ChildIndex()

ActionScript 3.0 bietet direkten Zugriff auf die Anzeigeliste, daher wird die Tiefe auf andere Weise bearbeitet.

onDragOut() flash.display.InteractiveObject dispatches event: mouseOut

Wurde im neuen Ereignismodell durch ein mouseOut-Ereignis ersetzt.

onDragOver() flash.display.InteractiveObject dispatches event: mouseOver

Wurde im neuen Ereignismodell durch ein mouseOver-Ereignis ersetzt.

onKeyDown() flash.display.InteractiveObject dispatches event: keyDown

Wurde im neuen Ereignismodell durch ein keyDown-Ereignis er-setzt.

onKeyUp() flash.display.InteractiveObject dispatches event: keyUp

Wurde im neuen Ereignismodell durch ein keyUp-Ereignis ersetzt.

onKillFocus() flash.display.InteractiveObject dispatches event: focusOut

Wurde im neuen Ereignismodell durch ein focusOut-Ereignis ersetzt.

onPress() flash.display.InteractiveObject dispatches event: mouseDown

Wurde im neuen Ereignismodell durch ein mouseDown-Ereignis ersetzt.

onRelease() flash.display.InteractiveObject dispatches event: mouseUp

Wurde im neuen Ereignismodell durch ein mouseUp-Ereignis er-setzt.

onReleaseOutside() flash.display.InteractiveObject dispatches event: mouseUp

Wurde im neuen Ereignismodell durch ein mouseUp-Ereignis er-setzt.

onRollOut() flash.display.InteractiveObject dispatches event: mouseOut

Wurde im neuen Ereignismodell durch ein mouseOut-Ereignis ersetzt.

onRollOver() flash.display.InteractiveObject dispatches event: mouseOver

Wurde im neuen Ereignismodell durch ein mouseOver-Ereignis ersetzt.

onSetFocus() flash.display.InteractiveObject dispatches event: focusIn

Wurde im neuen Ereignismodell durch ein focusIn-Ereignis er-setzt.

Camera-Klasse flash.media.Camera

activityLevel flash.media.Camera.activity-Level

bandwidth flash.media.Camera.bandwidth

currentFps flash.media.Camera.currentFPS Änderung bei der Groß-/Kleinschreibung von FPS

fps flash.media.Camera.fps

height flash.media.Camera.height Der Datentyp wurde von Number in int geändert.

index flash.media.Camera.index Der Datentyp wurde von String in int geändert.

Page 94: Flash cs3, ajax und php

B A S I S W I S S E N 81

ActionScript 2.0 ActionScript 3.0 Kommentare

motionLevel flash.media.Camera.motionLevel Der Datentyp wurde von Number in int geändert.

motionTimeOut flash.media.Camera.motionTime-out

Der Datentyp wurde von Number in int geändert.

muted flash.media.Camera.muted

name flash.media.Camera.name

names flash.media.Camera.names

quality flash.media.Camera.quality Der Datentyp wurde von Number in int geändert.

width flash.media.Camera.width Der Datentyp wurde von Number in int geändert.

get() flash.media.Camera.getCamera()

onActivity() flash.events.ActivityEvent.ACTIVITY

onStatus() flash.media.Camera dispatches event: status

Wurde im neuen Ereignismodell durch ein StatusEvent-Objekt status ersetzt.

setMode() flash.media.Camera.setMode() Die Parameter width und height wurden zum Datentyp int geän-dert.

setMotionLevel() flash.media.Camera.setMotion-Level()

Beide Parameter wurden zum Datentyp int geändert.

setQuality() flash.media.Camera.setQuality() Beide Parameter wurden zum Datentyp int geändert.

capabilities-Klasse flash.system.Capabilities Bei diesem Klassennamen wurde die Groß-/Kleinschreibung geän-dert.

Color-Klasse flash.geom.ColorTransform Die Color-Klasse wurde entfernt, da die gesamte Funktionalität dieser Klasse auch mit der flash.geom.ColorTransform-Klasse erreicht werden kann. Farbwerte lassen sich mit-hilfe des ColorTransform-Klassenkonstruktors oder dessen Eigenschaften direkt zuweisen. ColorTransform-Objekte können dann der Eigenschaft color-Transform eines Transform-Objekts zugewiesen werden, die wiederum der Eigenschaft transform einer DisplayObject-Instanz zugewiesen werden kann.

Color flash.geom.ColorTransform.ColorTransform()

Entfernt. Sie können Farbwerte mithilfe des ColorTransform()-Konstruktors zuweisen.

getRGB() flash.geom.ColorTransform.color

Auf den RGB-Farbwert kann mithil-fe der Accessor-Eigenschaft co-lor der ColorTransform-Klasse zugegriffen werden.

Page 95: Flash cs3, ajax und php

K A P I T E L 382

ActionScript 2.0 ActionScript 3.0 Kommentare

getTransform() Entfernt Farbwerte können mithilfe des ColorTransform()-Klassenkonstruktors oder dessen Eigenschaften direkt zugewiesen werden.

setRGB() flash.geom.ColorTransform.color

Der RGB-Farbwert kann mithilfe der Accessor-Eigenschaft color der ColorTransform-Klasse ein-gerichtet werden.

setTransform() Entfernt Farbwerte können mithilfe des ColorTransform()-Klassenkonstruktors oder dessen Eigenschaften direkt zugewiesen werden.

ContextMenu-Klasse flash.ui.ContextMenu Die ContextMenu-Klasse ist jetzt Teil des flash.ui-Pakets.

builtInItems flash.ui.ContextMenu.built-InItems

customItems flash.ui.ContextMenu.custom-Items

ContextMenu flash.ui.ContextMenu.ContextMenu()

copy() flash.ui.ContextMenu.clone()

hideBuiltInItems() flash.ui.ContextMenu.hideBuilt-InItems()

onSelect() flash.ui.ContextMenu dispat-ches event: menuSelect

Anstatt die Ereignisprozedur on-Select() aufzurufen, löst diese ActionScript 3.0-Klasse ein menu-Select-Ereignis aus.

ContextMenuItem-Klasse flash.ui.ContextMenuItem Die ContextMenuItem-Klasse ist jetzt Teil des flash.ui-Pakets.

caption flash.ui.ContextMenuItem.cap-tion

enabled flash.ui.ContextMenuItem.en-abled

separatorBefore flash.ui.ContextMenuItem.sepa-ratorBefore

visible flash.ui.ContextMenuItem.vi-sible

ContextMenuItem flash.ui.ContextMenuItem.ContextMenuItem()

copy() flash.ui.ContextMenuItem.clo-ne()

onSelect() flash.ui.ContextMenuItem dis-patches event: menuItemSelect

Anstatt die Ereignisprozedur on-Select() aufzurufen, löst diese ActionScript 3.0-Klasse ein menu-Select-Ereignis aus.

ConvolutionFilter-Klasse

clone() flash.filters.ConvolutionFilter.clone()

Gibt jetzt ein BitmapFilter-Objekt zurück.

Page 96: Flash cs3, ajax und php

B A S I S W I S S E N 83

ActionScript 2.0 ActionScript 3.0 Kommentare

Date-Klasse Date ActionScript 3.0 umfasst ein neu-es Set von Read-Accessoren für alle Methoden, die mit getxxx() beginnen. Beispielsweise geben Date.getDate() und Date.date in ActionScript 3.0 den gleichen Wert zurück.

getUTCFullYear() Date.getUTCFullYear() Keine Änderung.

getYear() Date.getFullYear() Diese Methode wurde entfernt, da sie nicht zum ECMAScript gehört. Verwenden Sie stattdessen Date.getFullYear().

setFullYear() Date.setFullYear() Keine Änderung

DisplacementMapFilter-Klasse

flash.filters.DisplacementMapFilter

Der Datentyp verschiedener Parameter wurde von Number in uint geändert.

color flash.filters.DisplacementMapFilter.color

Der Datentyp dieses Parameters lautet jetzt uint.

componentX flash.filters.DisplacementMapFilter.compo-nentX

Der Datentyp dieses Parameters lautet jetzt uint.

componentY flash.filters.DisplacementMapFilter.compo-nentY

Der Datentyp dieses Parameters lautet jetzt uint.

DisplacementMapFilter flash.filters.DisplacementMapFilter.DisplacementMapFilter()

Der Datentyp der Parameter com-ponentX, componentY und color wurde in uint geändert.

clone() flash.filters.DisplacementMapFilter.clone()

Gibt jetzt ein BitmapFilter-Objekt zurück.

DropShadowFilter-Klasse flash.filters.DropShadowFilter

color flash.filters.DropShadowFilter.color

Der Datentyp dieses Parameters wurde von Number in uint geän-dert.

quality flash.filters.DropShadowFilter.quality

Der Datentyp dieses Parameters wurde von Number in uint geän-dert.

DropShadowFilter flash.filters.DropShadowFilter.DropShadowFilter()

Alle Parameter weisen jetzt ei-nen Standardwert auf. Einige Parametertypen wurden geändert.

clone() flash.filters.DropShadowFilter.clone()

Gibt jetzt ein BitmapFilter-Objekt anstelle eines Drop-ShadowFilter-Objekts zurück.

Error-Klasse Error Zur Unterstützung beim Debugging wurde eine neue getStackTrace()-Methode hinzugefügt.

ExternalInterface-Klasse

flash.external.ExternalInterface

Für zwei Methoden dieser Klasse wurden die Parameter geändert.

Page 97: Flash cs3, ajax und php

K A P I T E L 384

ActionScript 2.0 ActionScript 3.0 Kommentare

addCallback() flash.external.ExternalInterface.addCall-back()

Die ActionScript 3.0-Version dieser Methode akzeptiert keinen in-stance-Parameter. Der method-Parameter wurde durch einen closure-Parameter ersetzt, der einen Verweis auf eine Funktion, eine Klassenmethode oder eine Methode einer bestimmten Klasseninstanz enthalten kann. Darüber hinaus kann der aufrufen-de Code aus Sicherheitsgründen nicht auf den Verweis closure zugreifen. In diesem Fall wird der Ausnahmefehler SecurityError erzeugt.

call() flash.external.ExternalInterface.call()

Wenn ein Problem auftritt, erzeugt die ActionScript 3.0-Version dieser Methode eine Fehlermeldung oder den Ausnahmefehler SecurityError und gibt darüber hinaus null zurück.

FileReference-Klasse flash.net.FileReference Die ActionScript 3.0-Version dieser Klasse übernimmt die Methoden addEventListener() und removeEventListener() von der EventDispatcher-Klasse. Die Ereignisverarbeitungsfunk-tionen werden durch ausgelöste Ereignisse ersetzt.

postData flash.net.URLRequest.data ActionScript 2.0 in Flash Player 9 wurde die postData-Eigenschaft hinzugefügt, um POST-Daten mit dem Datei-Upload oder -Download zu senden. In ActionScript 3.0 verwenden Sie die Eigenschaft data der URLRequest-Klasse, um entweder POST- oder GET-Daten zu senden. Weitere Informationen fi nden Sie unter flash.net.URLRequest.data in diesem Referenzhandbuch.

size flash.net.FileReference.size Gibt den Datentyp uint anstelle von Number zurück.

addListener() flash.events.EventDispatcher.addEventListener()

Im neuen Ereignismodell ist eine klassenspezifi sche addLis-tener()-Methode nicht mehr erforderlich, da die Klasse die addEventListener()-Methode von der EventDispatcher-Klasse übernimmt.

Page 98: Flash cs3, ajax und php

B A S I S W I S S E N 85

ActionScript 2.0 ActionScript 3.0 Kommentare

browse() flash.net.FileReference.brow-se()

Gibt in ActionScript 2.0 beim Auftreten eines Fehlers fal-se zurück. In ActionScript 3.0 wird der Ausnahmefehler IllegalOperationError oder ArgumentError erzeugt. Dennoch gibt die Methode noch immer false zurück, wenn die Parameter ungültig sind, das Dialogfeld zum Suchen nach Dateien nicht öffnet oder eine weitere Browser-Sitzung ausgeführt wird. Darüber hinaus wurde der typelist-Parameter geändert. In ActionScript 2.0 kön-nen Sie die browse()-Methode an ein Array mit Zeichenfolgen über-geben, um einen Dateifi lter anzu-geben. In ActionScript 3.0 überge-ben Sie ein Array von Filtern.

download() flash.net.FileReference.down-load()

Gibt beim Auftreten eines Fehlers Ausnahmefehler anstelle von false aus. Der Datentyp des ers-ten Parameters wurde geändert. In ActionScript 2.0 ist der erste von Ihnen an download() übergebene Parameter eine Zeichenfolge. In ActionScript 3.0 übergeben Sie ein URLRequest-Objekt.

removeListener() flash.events.EventDispatcher.removeEventListener()

Im neuen Ereignismodell ist eine klassenspezifi sche removeLis-tener()-Methode nicht mehr erforderlich, da die Klasse die re-moveEventListener()-Methode von der EventDispatcher-Klasse übernimmt.

Page 99: Flash cs3, ajax und php

K A P I T E L 386

ActionScript 2.0 ActionScript 3.0 Kommentare

upload() flash.net.FileReference.up-load()

Es wurden verschiedene Änderungen vorgenommen:

Der Datentyp des ersten Parameters wurde geändert. In ActionScript 2.0 ist der erste von Ihnen an upload() übergebene Parameter eine Zeichenfolge. In ActionScript 3.0 übergeben Sie ein URLRequest-Objekt.

In ActionScript 3.0 gibt es einen neuen zweiten Parameter, up-loadDataFieldName, bei dem es sich um einen Feldnamen handelt, der den Dateidaten in der POST-Operation des Upload-Vorgangs voransteht.

In ActionScript 3.0 gibt es einen neuen dritten Parameter, test-Upload, mit dem Sie steuern können, ob Flash Player einen Test-Upload durchführt, bevor die Datei hochgeladen wird.

Wenn ein Fehler auftritt, erzeugt browse() Ausnahmefehler-meldungen anstelle von false.

onCancel flash.net.FileReference dis-patches event: cancel

Diese Klasse ruft in ActionScript 3.0 nicht mehr die Ereignisprozedur onCancel() auf, sondern löst ein Ereignis mit der Bezeichnung cancel aus.

onComplete flash.net.FileReference dis-patches event: complete

Diese Klasse ruft in ActionScript 3.0 nicht mehr die Ereignisprozedur onComplete() auf, sondern löst ein Ereignis mit der Bezeichnung complete aus.

onHTTPError flash.net.FileReference dis-patches event: httpStatus

Diese Klasse ruft in ActionScript 3.0 nicht mehr die Ereignisprozedur onHTTPError() auf, sondern löst ein Ereignis mit der Bezeichnung httpStatus aus.

onIOError flash.net.FileReference dis-patches event: ioError

Diese Klasse ruft in ActionScript 3.0 nicht mehr die Ereignisprozedur onIOError() auf, sondern löst ein Ereignis mit der Bezeichnung ioError aus.

onOpen flash.net.FileReference dis-patches event: open

Diese Klasse ruft in ActionScript 3.0 nicht mehr die Ereignisprozedur onOpen() auf, sondern löst ein Ereignis mit der Bezeichnung open aus.

Page 100: Flash cs3, ajax und php

B A S I S W I S S E N 87

ActionScript 2.0 ActionScript 3.0 Kommentare

onProgress flash.net.FileReference dis-patches event: progress

Diese Klasse ruft in ActionScript 3.0 nicht mehr die Ereignisprozedur onProgress() auf, sondern löst ein Ereignis mit der Bezeichnung progress aus.

onSecurityError flash.net.FileReference dis-patches event: securityError

Diese Klasse ruft in ActionScript 3.0 nicht mehr die Ereignisprozedur onSecurityError() auf, son-dern löst ein Ereignis mit der Bezeichnung securityError aus.

onSelect flash.net.FileReference dis-patches event: select

Diese Klasse ruft in ActionScript 3.0 nicht mehr die Ereignisprozedur onSelect() auf, sondern löst ein Ereignis mit der Bezeichnung select aus.

onUploadCompleteData flash.net.FileReference dis-patches event: complete

Diese Klasse ruft in ActionScript 3.0 nicht mehr die Ereignisprozedur onUploadCompleteData() auf, sondern löst ein Ereignis mit der Bezeichnung uploadComplete-Data aus.

FileReferenceList-Klasse

flash.net.FileReferenceList Diese ActionScript 3.0-Klasse übernimmt die Methoden ad-dEventListener() und remo-veEventListener() von der EventDispatcher-Klasse. Anstelle der Ereignisprozeduren onCan-cel() und onSelect() verwen-det diese ActionScript 3.0-Klasse die Ereignisse cancel und select.

addListener() flash.events.EventDispatcher.addEventListener()

Im neuen Ereignismodell ist eine klassenspezifi sche addLis-tener()-Methode nicht mehr erforderlich, da die Klasse die addEventListener()-Methode von der EventDispatcher-Klasse übernimmt.

browse() flash.net.FileReferenceList.browse()

Diese Methode gibt in ActionScript 3.0 beim Auftreten eines Fehlers nicht false zurück, sondern erzeugt den Ausnahmefehler IllegalOperationError. Darüber hinaus wurde der type-list-Parameter geändert. In ActionScript 2.0 können Sie die browse()-Methode an ein Array mit Zeichenfolgen übergeben, um einen Dateifi lter anzugeben. In ActionScript 3.0 übergeben Sie ein Array von Filtern.

Page 101: Flash cs3, ajax und php

K A P I T E L 388

ActionScript 2.0 ActionScript 3.0 Kommentare

removeListener() flash.events.EventDispatcher.removeEventListener()

Im neuen Ereignismodell ist eine klassenspezifi sche removeLis-tener()-Methode nicht mehr erforderlich, da die Klasse die re-moveEventListener()-Methode von der EventDispatcher-Klasse übernimmt.

onCancel flash.net.FileReferenceList dispatches event: cancel

Diese Klasse ruft in ActionScript 3.0 nicht mehr die Ereignisprozedur onCancel() auf, sondern löst ein Ereignis mit der Bezeichnung cancel aus.

onSelect flash.net.FileReferenceList dispatches event: select

Diese Klasse ruft in ActionScript 3.0 nicht mehr die Ereignisprozedur onSelect() auf, sondern löst ein Ereignis mit der Bezeichnung select aus.

GlowFilter-Klasse flash.filters.GlowFilter Der Datentyp mehrerer Parameter wurde von Number zu uint ge-ändert.

color flash.filters.GlowFilter.color Der Datentyp dieser Eigenschaft wurde von Number zu uint ge-ändert.

quality flash.filters.GlowFilter.qua-lity

Der Datentyp dieser Eigenschaft wurde von Number zu uint ge-ändert.

GlowFilter flash.filters.GlowFilter.GlowFilter()

Die Parameter color und qua-lity weisen jetzt die Datentypen uint und int anstelle von Number auf. Allen Parametern ist jetzt ein Standardwert zugewiesen.

clone() flash.filters.GlowFilter. clone()

Gibt ein BitmapFilter-Objekt an-stelle eines GlowFilter-Objekts zurück.

GradientBevelFilter-Klasse

flash.filters.GradientBevelFilter

quality flash.filters.GradientBevelFilter.quality

Der Datentyp dieser Eigenschaft wurde von Number in int geän-dert.

clone() flash.filters.GradientBevelFilter.clone()

Gibt ein BitmapFilter-Objekt anstelle eines GradientBevelFilter-Objekts zurück.

GradientGlowFilter-Klasse

flash.filters.GradientGlowFilter

quality flash.filters.GradientGlowFilter.quality

Der Datentyp dieser Eigenschaft wurde von Number zu int geän-dert.

GradientGlowFilter flash.filters.GradientGlowFilter.GradientGlowFilter()

Allen Parametern sind jetzt Standardwerte zugewiesen und der Datentyp des quality-Parameters wurde von Number zu int geändert.

Page 102: Flash cs3, ajax und php

B A S I S W I S S E N 89

ActionScript 2.0 ActionScript 3.0 Kommentare

clone() flash.filters.GradientGlowFilter.clone()

Gibt ein BitmapFilter-Objekt an-stelle eines GradientGlowFilter-Objekts zurück.

IME-Klasse flash.system.IME Diese Klasse wurde in das flash.system-Paket verschoben.

ALPHANUMERIC_FULL flash.system.IMEConversionMode.ALPHANUMERIC_FULL

ALPHANUMERIC_HALF flash.system.IMEConversionMode.ALPHANUMERIC_HALF

CHINESE flash.system.IMEConversionMode.CHINESE

JAPANESE_HIRAGANA flash.system.IMEConversionMode.JAPANESE_HIRAGANA

JAPANESE_KATAKANA_FULL flash.system.IMEConversionMode.JAPANESE_KATAKANA_FULL

JAPANESE_KATAKANA_HALF flash.system.IMEConversionMode.JAPANESE_KATAKANA_HALF

KOREAN flash.system.IMEConversionMode.KOREAN

UNKNOWN flash.system.IMEConversionMode.UNKNOWN

addListener() flash.events.EventDispatcher.addEventListener()

Im neuen Ereignismodell ist eine klassenspezifi sche addLis-tener()-Methode nicht mehr erforderlich, da die Klasse die addEventListener()-Methode von der EventDispatcher-Klasse übernimmt.

getConversionMode() flash.system.IME.conversion-Mode

Wurde in eine Accessor-Eigenschaft geändert.

getEnabled() flash.system.IME.enabled Wurde in eine Accessor-Eigenschaft geändert.

removeListener() flash.events.EventDispatcher.removeEventListener()

Im neuen Ereignismodell ist eine klassenspezifi sche removeLis-tener()-Methode nicht mehr erforderlich, da die Klasse die re-moveEventListener()-Methode von der EventDispatcher-Klasse übernimmt.

setConversionMode() flash.system.IME.conversion-Mode

Wurde in eine Accessor-Eigenschaft geändert.

setEnabled() flash.system.IME.enabled Wurde in eine Accessor-Eigenschaft geändert.

onIMEComposition flash.system.IME dispatches event: imeComposition

Diese Klasse ruft in ActionScript 3.0 nicht mehr die Ereignisprozedur onIMEComposition() auf, son-dern löst ein Ereignis mit der Bezeichnung imeComposition aus.

Page 103: Flash cs3, ajax und php

K A P I T E L 390

ActionScript 2.0 ActionScript 3.0 Kommentare

Key-Klasse flash.ui.Keyboard Diese Klasse hat in ActionScript 3.0 einen neuen Namen, damit sie anderen zur Keyboard-Klasse gehörenden Klassen entspricht, wie z.B. KeyboardEvent.

BACKSPACE flash.ui.Keyboard.BACKSPACE Wird in ActionScript 3.0 als eine Konstante deklariert. Der Datentyp wurde in uint geändert.

CAPSLOCK flash.ui.Keyboard.CAPS_LOCK Wird in ActionScript 3.0 als eine Konstante deklariert. Ein Unterstrich wurde hinzugefügt und der Datentyp wurde in uint geändert.

CONTROL flash.ui.Keyboard.CONTROL Wird in ActionScript 3.0 als eine Konstante deklariert. Der Datentyp wurde in uint geändert.

DELETEKEY flash.ui.Keyboard.DELETE Der Name wurde in ActionScript 3.0 zu DELETE geändert. Das Objekt wird als eine Konstante deklariert und der Datentyp wurde in uint geändert.

DOWN flash.ui.Keyboard.DOWN Wird in ActionScript 3.0 als eine Konstante deklariert. Der Datentyp wurde in uint geändert.

END flash.ui.Keyboard.END Wird in ActionScript 3.0 als eine Konstante deklariert. Der Datentyp wurde in uint geändert.

ENTER flash.ui.Keyboard.ENTER Wird in ActionScript 3.0 als eine Konstante deklariert. Der Datentyp wurde in uint geändert.

ESCAPE flash.ui.Keyboard.ESCAPE Wird in ActionScript 3.0 als eine Konstante deklariert. Der Datentyp wurde in uint geändert.

HOME flash.ui.Keyboard.HOME Wird in ActionScript 3.0 als eine Konstante deklariert. Der Datentyp wurde in uint geändert.

INSERT flash.ui.Keyboard.INSERT Wird in ActionScript 3.0 als eine Konstante deklariert. Der Datentyp wurde in uint geändert.

LEFT flash.ui.Keyboard.LEFT Wird in ActionScript 3.0 als eine Konstante deklariert. Der Datentyp wurde in uint geändert.

_listeners flash.events.EventDispatcher.willTrigger()

Kein direktes Äquivalent. Die willTrigger()-Methode meldet Ihnen zwar, ob Listener registriert sind, jedoch nicht wie viele.

PGDN flash.ui.Keyboard.PAGE_DOWN Der Name wurde in ActionScript 3.0 in PAGE_DOWN geändert. Das Objekt wird als eine Konstante deklariert und der Datentyp wurde in uint geändert.

Page 104: Flash cs3, ajax und php

B A S I S W I S S E N 91

ActionScript 2.0 ActionScript 3.0 Kommentare

PGUP flash.ui.Keyboard.PAGE_UP Der Name wurde in ActionScript 3.0 in PAGE_UP geändert. Das Objekt wird als eine Konstante deklariert und der Datentyp wurde in uint geändert.

RIGHT flash.ui.Keyboard.RIGHT Wird in ActionScript 3.0 als eine Konstante deklariert. Der Datentyp wurde in uint geändert.

SHIFT flash.ui.Keyboard.SHIFT Wird in ActionScript 3.0 als eine Konstante deklariert. Der Datentyp wurde in uint geändert.

SPACE flash.ui.Keyboard.SPACE Wird in ActionScript 3.0 als eine Konstante deklariert. Der Datentyp wurde in uint geändert.

TAB flash.ui.Keyboard.TAB Wird in ActionScript 3.0 als eine Konstante deklariert. Der Datentyp wurde in uint geändert.

UP flash.ui.Keyboard.UP Wird in ActionScript 3.0 als eine Konstante deklariert. Der Datentyp wurde in uint geändert.

addListener() flash.events.EventDispatcher.addEventListener()

In ActionScript 3.0 ist eine klas-senspezifi sche addListener()-Methode nicht mehr erforderlich, da alle Anzeigeobjekte die add-EventListener()-Methode von der EventDispatcher-Klasse übernehmen.

getAscii() flash.events.KeyboardEvent.charCode

getCode() flash.events.KeyboardEvent.keyCode

isAccessible() flash.ui.Keyboard.isAccessib-le()

isDown() Entfernt Aus Sicherheitsgründen entfernt

isToggled() Entfernt Aus Sicherheitsgründen entfernt

removeListener() flash.events.EventDispatcher.removeEventListener()

In ActionScript 3.0 ist eine klassen-spezifi sche removeListener()-Methode nicht mehr erforderlich, da alle Anzeigeobjekte die remove-EventListener()-Methode von der EventDispatcher-Klasse übernehmen.

onKeyDown flash.display.InteractiveObject dispatches event: keyDown

In ActionScript 3.0 löst die InteractiveObject-Klasse das KeyboardEvent-Objekt keyDown aus, anstatt die onKeyDown-Ereignisprozedur aufzurufen.

onKeyUp flash.display.InteractiveObject dispatches event: keyUp

In ActionScript 3.0 löst die InteractiveObject-Klasse das KeyboardEvent-Objekt keyUp aus, anstatt die onKeyUp-Ereignisprozedur aufzurufen.

Page 105: Flash cs3, ajax und php

K A P I T E L 392

ActionScript 2.0 ActionScript 3.0 Kommentare

LoadVars-Klasse flash.net.URLLoader Die LoadVars-Klassenfunktionen wurden durch die Klassen URLLoader, URLRequest, URLStream, und URLVariables ersetzt.

contentType flash.net.URLRequest.conten-tType

loaded Entfernt Es gibt keine entsprechende.

LoadVars flash.net.URLLoader.URLLoader()

addRequestHeader() flash.net.URLRequestHeader

decode() flash.net.URLVariables.de-code()

getBytesLoaded() flash.net.URLLoader.bytesLoa-ded

Die Klasse wurde in URLLoader geändert, von einem Funktionen- zu einem Eigenschaften-Accessor geändert und der Name wurde von getBytesLoaded zu by-tesLoaded geändert.

getBytesTotal() flash.net.URLLoader.bytesTotal Die Klasse wurde in URLLoader geändert, von einem Funktionen- zu einem Eigenschaften-Accessor geändert und der Name wurde von getBytesTotal zu bytes-Total geändert.

load() flash.net.URLLoader.load()

onData() flash.net.URLLoader dispatches event: complete

Siehe URLLoader-Klasse. Nach Abschluss des Download-Vorgangs, aber noch vor dem Parsen der Daten wird ein comple-te-Ereignis ausgelöst.

onHTTPStatus() flash.net.URLLoader dispatches event: httpStatus

In ActionScript 3.0 löst die URL Loader-Klasse das HTTP-StatusEvent-Objekt httpStatus aus, anstatt die onHTTPStatus-Ereignisprozedur aufzurufen.

onLoad() flash.net.URLLoader dispatches event: complete

Siehe URLLoader-Klasse. Nach Abschluss des Download-Vorgangs wird ein complete-Ereignis ausgelöst.

send() flash.net.sendToURL()

sendAndLoad() flash.net.sendToURL() Die sendToURL()-Methode sen-det eine URL-Anforderung an den Server, ignoriert aber die Antwort. Zum Empfangen der Antwort verwenden Sie flash.net.send-ToURL().

toString() Entfernt Diese Methode ist in ActionScript 3.0 nicht mehr erforderlich.

LocalConnection-Klasse flash.net.LocalConnection Diese Klasse wurde in das flash.net-Paket verschoben.

LocalConnection flash.net.LocalConnection.LocalConnection()

Page 106: Flash cs3, ajax und php

B A S I S W I S S E N 93

ActionScript 2.0 ActionScript 3.0 Kommentare

allowDomain() flash.net.LocalConnection.allowDomain()

Wurde in ActionScript 3.0 zu einer regulären Methode geändert und ist jetzt keine Ereignisprozedur mehr. Der Parameter wurde ge-ändert und verwendet jetzt das Format ...(rest). Der Rückgabewert wurde in void geändert.

allowInsecureDomain() flash.net.LocalConnection.allowInsecureDomain()

Wurde in ActionScript 3.0 zu einer regulären Methode geändert und ist jetzt keine Ereignisprozedur mehr. Der Parameter wurde ge-ändert und verwendet jetzt das Format ...(rest). Der Rückgabewert wurde in void geändert.

close() flash.net.LocalConnection.close()

connect() flash.net.LocalConnection.connect()

domain() flash.net.LocalConnection.domain

Zu einem Eigenschaften-Accessor geändert

onStatus() flash.net.LocalConnection dis-patches event: status

Im neuen Ereignismodell wurden die Rückruffunktionen durch Ereignisobjekte ersetzt.

send() flash.net.LocalConnection.send()

Der dritte Parameter wurde ge-ändert und verwendet jetzt das Parameterformat ...(rest). Der Rückgabetyp wurde in void ge-ändert.

Microphone-Klasse flash.media.Microphone Diese Klasse wurde in das flash.media-Paket verschoben.

index flash.media.Microphone.index Der Datentyp wurde in uint ge-ändert.

rate flash.media.Microphone.rate Der Datentyp wurde in uint ge-ändert.

silenceTimeOut flash.media.Microphone.silenceTimeout

Die Groß-/Kleinschreibung wur-de in „Timeout“ geändert. Der Datentyp wurde in int geändert.

get() flash.media.Microphone.getMi-crophone()

Der Name wurde von get() zu getMicrophone() geändert. Der Datentyp des Parameters wurde in uint geändert.

onActivity() flash.media.Microphone dispat-ches event: activity

Diese Klasse ruft in ActionScript 3.0 nicht mehr die Ereignisprozedur onActivity auf, sondern löst ein Ereignis mit der Bezeichnung activity aus.

onStatus() flash.media.Microphone dispat-ches event: status

Diese Klasse ruft in ActionScript 3.0 nicht mehr die Ereignisprozedur onStatus auf, sondern löst ein Ereignis mit der Bezeichnung status aus.

Page 107: Flash cs3, ajax und php

K A P I T E L 394

ActionScript 2.0 ActionScript 3.0 Kommentare

setGain() flash.media.Microphone.gain Die gain-Eigenschaft und die setGain()-Methode wurden zu einem get/set-Eigenschaften-Accessor mit der Bezeichnung gain zusammengefasst. Der Datentyp wurde in uint geändert.

setRate() flash.media.Microphone.rate Die rate-Eigenschaft und die setRate()-Methode wurden zu einem get/set-Eigenschaften-Accessor mit der Bezeichnung rate zusammengefasst. Der Datentyp wurde in uint geändert.

setSilenceLevel() flash.media.Microphone.set-SilenceLevel()

Der Datentyp des timeOut-Parameters wurde in int geändert. Die Groß-/Kleinschreibung des timeOut-Parameter wurde in timeout geändert.

setUseEchoSuppressi-on()

flash.media.Microphone.setU-seEchoSuppression()

Mouse-Klasse flash.ui.Mouse

addListener() flash.events.EventDispatcher.addEventListener()

Im neuen ActionScript 3.0-Ereignismodell ist eine klassenspe-zifi sche addListener()-Methode nicht mehr erforderlich, da alle Anzeigeobjekte die addEvent-Listener()-Methode von der EventDispatcher-Klasse über-nehmen.

hide() flash.ui.Mouse.hide() Gibt jetzt void zurück.

removeListener() flash.events.EventDispatcher.removeEventListener()

Im neuen ActionScript 3.0-Ereignismodell ist eine klassen-spezifi sche removeListener()-Methode nicht mehr erforderlich, da alle Anzeigeobjekte die remo-veEventListener()-Methode von der EventDispatcher-Klasse übernehmen.

show() flash.ui.Mouse.show() Gibt jetzt void zurück.

onMouseDown flash.display.InteractiveObject dispatches event: mouseDown

Wurde im neuen Ereignismodell durch ein mouseDown-Ereignis ersetzt.

onMouseMove flash.display.InteractiveObject dispatches event: mouseMove

Wurde im neuen Ereignismodell durch ein mouseMove-Ereignis ersetzt.

onMouseUp flash.display.InteractiveObject dispatches event: mouseUp

Wurde im neuen Ereignismodell durch ein mouseUp-Ereignis er-setzt.

onMouseWheel flash.display.InteractiveObject dispatches event: mouseWheel

Wurde im neuen Ereignismodell durch ein mouseWheel-Ereignis ersetzt.

Page 108: Flash cs3, ajax und php

B A S I S W I S S E N 95

ActionScript 2.0 ActionScript 3.0 Kommentare

MovieClip-Klasse flash.display.MovieClip Viele MovieClip-Methoden wurden in ActionScript 3.0 in andere Klassen verschoben. Alle Ereignisprozeduren wurden im neuen Ereignismodell durch Ereignisobjekte ersetzt.

_alpha flash.display.DisplayObject.alpha

In die DisplayObject-Klasse verschoben. Der Unterstrich am Anfang des Namens wurde ent-fernt.

blendMode flash.display.DisplayObject.blendMode

cacheAsBitmap flash.display.DisplayObject.cacheAsBitmap

_currentframe flash.display.MovieClip.cur-rentFrame

Der Unterstrich am Anfang des Namens wurde entfernt.

_droptarget flash.display.Sprite.dropTar-get

In die Sprite-Klasse verschoben. Der Unterstrich am Anfang des Namens wurde entfernt und die Groß-/Kleinschreibung wurde geändert.

filters flash.display.DisplayObject.filters

focusEnabled Entfernt In ActionScript 3.0 sind alle inter-aktiven Objekte Fokus-aktiviert. Diese Eigenschaft ist daher nicht mehr erforderlich.

_focusrect flash.display.InteractiveObject.focusRect

In die InteractiveObject-Klasse verschoben. Der Unterstrich am Anfang des Namens wur-de entfernt und die Groß-/Kleinschreibung wurde geändert.

_framesloaded flash.display.MovieClip.fra-mesLoaded

Der Unterstrich am Anfang des Namens wurde entfernt und die Groß-/Kleinschreibung wurde geändert.

_height flash.display.DisplayObject.height

In die DisplayObject-Klasse verschoben. Der Unterstrich am Anfang des Namens wurde ent-fernt.

_highquality Entfernt Siehe Stage.quality

hitArea flash.display.Sprite.hitArea In die Sprite-Klasse verschoben

_lockroot Entfernt In ActionScript 3.0 wird der Stamm eines Anzeigeobjekts automatisch festgelegt. Die Eigenschaft _lock-root ist damit praktisch immer aktiviert. Siehe flash.display.DisplayObject.root.

menu Entfernt Siehe InteractiveObject.contextMenu

_name flash.display.DisplayObject.name

In die DisplayObject-Klasse verschoben. Der Unterstrich am Anfang des Namens wurde ent-fernt.

Page 109: Flash cs3, ajax und php

K A P I T E L 396

ActionScript 2.0 ActionScript 3.0 Kommentare

opaqueBackground flash.display.DisplayObject.opaqueBackground

_parent flash.display.DisplayObject.parent

In die DisplayObject-Klasse verschoben. Der Unterstrich am Anfang des Namens wurde ent-fernt.

_quality flash.display.Stage.quality

_rotation flash.display.DisplayObject.rotation

In die DisplayObject-Klasse verschoben. Der Unterstrich am Anfang des Namens wurde ent-fernt.

scale9Grid flash.display.DisplayObject.scale9Grid

scrollRect flash.display.DisplayObject.scrollRect

In den Datentyp Rectangle ge-ändert

_soundbuftime flash.media.SoundMixer.buffer-Time

In die SoundMixer-Klasse verschoben, die zur globalen Soundsteuerung verwendet wird. Infolge der Umbenennung ist keine Abkürzung mehr vorhanden und der Unterstrich am Anfang des Namens wurde entfernt.

tabChildren flash.display.DisplayObjectContainer.tabChildren

tabEnabled flash.display.InteractiveObject.tabEnabled

tabIndex flash.display.InteractiveObject.tabIndex

_target Entfernt ActionScript 3.0 identifi ziert Anzeigeobjekte direkt, daher ist die Identifi zierung eines Anzeigeobjekts über dessen Pfad nicht mehr notwendig.

_totalframes flash.display.MovieClip.total-Frames

Die Groß-/Kleinschreibung wurde geändert. Der Unterstrich am Anfang des Namens wurde ent-fernt.

trackAsMenu flash.display.MovieClip.trackAsMenu

transform flash.display.DisplayObject.transform

_url flash.display.Loader.content-LoaderInfo

useHandCursor flash.display.Sprite.useHand-Cursor

_visible flash.display.DisplayObject.visible

In die DisplayObject-Klasse verschoben. Der Unterstrich am Anfang des Namens wurde ent-fernt.

_width flash.display.DisplayObject.width

In die DisplayObject-Klasse verschoben. Der Unterstrich am Anfang des Namens wurde ent-fernt.

Page 110: Flash cs3, ajax und php

B A S I S W I S S E N 97

ActionScript 2.0 ActionScript 3.0 Kommentare

_x flash.display.DisplayObject.x In die DisplayObject-Klasse verschoben. Der Unterstrich am Anfang des Namens wurde ent-fernt.

_xmouse flash.display.DisplayObject.mouseX

In die DisplayObject-Klasse verschoben. Der Name wurde in mouseX geändert und der Unterstrich am Anfang des Namens wurde entfernt.

_xscale flash.display.DisplayObject.scaleX

In die DisplayObject-Klasse verschoben. Der Name wurde in scaleX geändert und der Unterstrich am Anfang des Namens wurde entfernt.

_y flash.display.DisplayObject.y In die DisplayObject-Klasse verschoben. Der Unterstrich am Anfang des Namens wurde ent-fernt.

_ymouse flash.display.DisplayObject.mouseY

In die DisplayObject-Klasse verschoben. Der Name wurde in mouseY geändert und der Unterstrich am Anfang des Namens wurde entfernt.

_yscale flash.display.DisplayObject.scaleY

In die DisplayObject-Klasse verschoben. Der Name wurde in scaleY geändert und der Unterstrich am Anfang des Namens wurde entfernt.

attachAudio() Entfernt Wenn es sich bei der Audioquelle um ein Microphone-Objekt handelt, verwenden Sie NetStream.attachAudio() oder Microphone.setLoopBack().

Handelt es sich bei der Audio-quelle um eine FLV-Datei, ver wen den Sie Video.attach-NetStream() und ein NetStream-Objekt.

attachBitmap() Entfernt In ActionScript 3.0 verwenden Sie addChild(), um untergeordnete Anzeigeobjekte hinzuzufügen.

attachMovie() Entfernt In ActionScript 3.0 verwenden Sie addChild(), um untergeordnete Anzeigeobjekte hinzuzufügen.

beginBitmapFill() flash.display.Graphics.begin-BitmapFill()

beginFill() flash.display.Graphics.begin-Fill()

In die Graphics-Klasse verscho-ben. Der Datentyp des ersten Parameters wurde in uint geän-dert.

beginGradientFill() flash.display.Graphics.begin-GradientFill()

clear() flash.display.Graphics.clear()

Page 111: Flash cs3, ajax und php

K A P I T E L 398

ActionScript 2.0 ActionScript 3.0 Kommentare

createEmptyMovieClip() Entfernt In ActionScript 3.0 verwenden Sie zum Erstellen von MovieClips den new-Operator.

createTextField() Entfernt In ActionScript 3.0 verwenden Sie zum Erstellen von Textfeldern den new-Operator.

curveTo() flash.display.Graphics.curve-To()

duplicateMovieClip() Entfernt In ActionScript 3.0 verwenden Sie zum Erstellen einer neuen Instanz den new-Operator.

endFill() flash.display.Graphics.end-Fill()

getBounds() flash.display.DisplayObject.getBounds()

getBytesLoaded() flash.net.URLLoader.bytesLoa-ded

In die URLLoader-Klasse verscho-ben. Der Datentyp wurde von Number in int geändert.

getBytesTotal() flash.net.URLLoader.bytesTotal In die URLLoader-Klasse verscho-ben. Der Datentyp wurde von Number in int geändert.

getDepth() flash.display.DisplayObjectContainer.get-ChildIndex()

ActionScript 3.0 bietet direkten Zugriff auf die Anzeigeliste, daher wird die Tiefe auf andere Weise bearbeitet.

getInstanceAtDepth() flash.display.DisplayObjectContainer.get-ChildAt()

ActionScript 3.0 bietet direkten Zugriff auf die Anzeigeliste, daher wird die Tiefe auf andere Weise bearbeitet.

getNextHighestDepth() flash.display.DisplayObjectContainer.add-Child()

Kein direktes Äquivalent, aber die addChild()-Methode fügt nach allen untergeordneten Objekten der DisplayObjectContainer-Instanz ein weiteres untergeord-netes Objekt hinzu. Daher ist eine Methode, mit der die nächste verfügbare Tiefe ermittelt wird, nicht mehr erforderlich.

getRect() flash.display.DisplayObject.getRect()

getSWFVersion() flash.display.LoaderInfo.swf-Version

In die LoaderInfo-Klasse verscho-ben. Der Datentyp wurde in uint geändert.

getTextSnapshot() flash.display.DisplayObjectContainer.textS-napshot

getURL() flash.net.navigateToURL() Wurde durch die Methoden flash.net.navigateToURL() und flash.net.sentToURL() ersetzt. Siehe auch URLLoader-Klasse.

globalToLocal() flash.display.DisplayObject.globalToLocal()

Page 112: Flash cs3, ajax und php

B A S I S W I S S E N 99

ActionScript 2.0 ActionScript 3.0 Kommentare

gotoAndStop() flash.display.MovieClip.goto-AndStop()

hitTest() flash.display.DisplayObject.hitTestObject()

lineGradientStyle() flash.display.Graphics.line-GradientStyle()

lineStyle() flash.display.Graphics.li-neStyle()

lineTo() flash.display.Graphics.line-To()

loadMovie() flash.display.Loader.load() Siehe Loader-Klasse

loadVariables() flash.net.URLLoader Entfernt; siehe URLLoader-Klasse

localToGlobal() flash.display.DisplayObject.localToGlobal()

moveTo() flash.display.Graphics.move-To()

nextFrame() flash.display.MovieClip.next-Frame()

onData() flash.display.LoaderInfo dis-patches event: complete

Wurde im neuen Ereignismodell durch ein complete-Ereignis ersetzt, das nach Abschluss des Download-Vorgangs, aber noch vor dem Parsen der Daten ausge-löst wird.

onDragOut() flash.display.InteractiveObject dispatches event: mouseOut

Wurde im neuen Ereignismodell durch ein mouseOut-Ereignis ersetzt.

onDragOver() flash.display.InteractiveObject dispatches event: mouseOver

Wurde im neuen Ereignismodell durch ein mouseOver-Ereignis ersetzt.

onEnterFrame() flash.display.DisplayObject dispatches event: enterFrame

Wurde im neuen Ereignismodell durch ein enterFrame-Ereignis ersetzt.

onKeyDown() flash.display.InteractiveObject dispatches event: keyDown

Wurde im neuen Ereignismodell durch ein keyDown-Ereignis er-setzt.

onKeyUp() flash.display.InteractiveObject dispatches event: keyUp

Wurde im neuen Ereignismodell durch ein keyUp-Ereignis ersetzt.

onKillFocus() flash.display.InteractiveObject dispatches event: focusOut

Wurde im neuen Ereignismodell durch ein focusOut-Ereignis ersetzt.

onLoad() flash.display.LoaderInfo dis-patches event: complete

Siehe auch URLLoader-Klasse. Nach Abschluss des Download-Vorgangs wird ein complete-Ereignis ausgelöst.

onMouseDown() flash.display.InteractiveObject dispatches event: mouseDown

Wurde im neuen Ereignismodell durch ein mouseDown-Ereignis ersetzt.

onMouseMove() flash.display.InteractiveObject dispatches event: mouseMove

Wurde im neuen Ereignismodell durch ein mouseMove-Ereignis ersetzt.

Page 113: Flash cs3, ajax und php

K A P I T E L 3100

ActionScript 2.0 ActionScript 3.0 Kommentare

onMouseUp() flash.display.InteractiveObject dispatches event: mouseUp

Wurde im neuen Ereignismodell durch ein mouseUp-Ereignis er-setzt.

onPress() flash.display.InteractiveObject dispatches event: mouseDown

Wurde im neuen Ereignismodell durch ein mouseDown-Ereignis ersetzt.

onRelease() flash.display.InteractiveObject dispatches event: mouseUp

Wurde im neuen Ereignismodell durch ein mouseUp-Ereignis er-setzt.

onReleaseOutside() flash.display.InteractiveObject dispatches event: mouseUp

Wurde im neuen Ereignismodell durch ein mouseUp-Ereignis er-setzt.

onRollOut() flash.display.InteractiveObject dispatches event: mouseOut

Wurde im neuen Ereignismodell durch ein mouseOut-Ereignis ersetzt.

onRollOver() flash.display.InteractiveObject dispatches event: mouseOver

Wurde im neuen Ereignismodell durch ein mouseOver-Ereignis ersetzt.

onSetFocus() flash.display.InteractiveObject dispatches event: focusIn

Wurde im neuen Ereignismodell durch ein focusIn-Ereignis er-setzt.

onUnload() flash.display.LoaderInfo dis-patches event: unload

Wurde im neuen Ereignismodell durch ein unload-Ereignis ersetzt.

play() flash.display.MovieClip.play()

prevFrame() flash.display.MovieClip.prev-Frame()

removeMovieClip() flash.display.DisplayObjectContainer.remove-Child()

Entfernt. Rufen Sie die remove-Child()-Methode des übergeord-neten Anzeigeobjekt-Containers auf, der den MovieClip enthält.

setMask() flash.display.DisplayObject.mask

startDrag() flash.display.Sprite.start-Drag()

stop() flash.display.MovieClip.stop()

stopDrag() flash.display.Sprite.stopDrag()

swapDepths() Entfernt In ActionScript 3.0 erreichen Sie eine ähnliche Funktionalität mithilfe der Methoden der DisplayObjectContainer-Klasse, z.B. addChildAt(), setChild-Index(), swapChildren() und swapChildrenAt().

unloadMovie() flash.display.Loader.unload()

MovieClipLoader-Klasse flash.display.Loader Wurde durch die flash.dis-play.Loader-Klasse ersetzt.

MovieClipLoader flash.display.Loader.Loader()

Page 114: Flash cs3, ajax und php

B A S I S W I S S E N 101

ActionScript 2.0 ActionScript 3.0 Kommentare

addListener() flash.events.EventDispatcher.addEventListener()

Im neuen Ereignismodell ist eine klassenspezifi sche addLis-tener()-Methode nicht mehr erforderlich, da die Klasse die addEventListener()-Methode von der EventDispatcher-Klasse übernimmt.

getProgress() flash.display.LoaderInfo dis-patches event: progress

Wurde im neuen Ereignismodell durch ein progress-Ereignis ersetzt. Ereignisobjekte des Typs progress enthalten Eigenschaften mit den Bezeichnungen by-tesLoaded und bytesTotal.

loadClip() flash.display.Loader.load() Wurde durch die load()-Methode der flash.display.Loader-Klasse ersetzt.

removeListener() flash.events.EventDispatcher.removeEventListener()

Im neuen Ereignismodell ist eine klassenspezifi sche removeLis-tener()-Methode nicht mehr erforderlich, da die Klasse die re-moveEventListener()-Methode von der EventDispatcher-Klasse übernimmt.

unloadClip() flash.display.Loader.unload() Wurde durch die unload()-Methode der flash.display.Loader-Klasse ersetzt.

onLoadComplete flash.display.LoaderInfo dis-patches event: complete

Wurde im neuen Ereignismodell durch ein complete-Ereignis ersetzt.

onLoadError flash.display.LoaderInfo dis-patches event: ioError

Wurde im neuen Ereignismodell durch ein ioError-Ereignis er-setzt.

onLoadInit flash.display.LoaderInfo dis-patches event: init

Wurde im neuen Ereignismodell durch ein init-Ereignis ersetzt.

onLoadProgress flash.display.LoaderInfo dis-patches event: progress

Wurde im neuen Ereignismodell durch ein progress-Ereignis ersetzt.

onLoadStart flash.display.LoaderInfo dis-patches event: open

Wurde im neuen Ereignismodell durch ein open-Ereignis ersetzt.

NetConnection-Klasse flash.net.NetConnection Diese Klasse wurde in das flash.net-Paket verschoben.

NetConnection flash.net.NetConnection.NetConnection()

connect() flash.net.NetConnection.con-nect()

In der ActionScript 3.0-Version wurde ein ...(rest)-Parameter hin-zugefügt.

NetStream-Klasse flash.net.NetStream Diese Klasse wurde in das flash.net-Paket verschoben.

bytesLoaded flash.net.NetStream.bytesLoa-ded

Der Datentyp wurde in uint geändert.

bytesTotal flash.net.NetStream.bytesTotal Der Datentyp wurde in uint geändert.

Page 115: Flash cs3, ajax und php

K A P I T E L 3102

ActionScript 2.0 ActionScript 3.0 Kommentare

currentFps flash.net.NetStream.currentFPS In ActionScript 3.0 steht FPS in Großbuchstaben.

onStatus() flash.net.NetStream dispatches event: netStatus

Wurde im neuen Ereignismodell durch ein netStatus-Ereignis ersetzt.

pause() flash.net.NetStream.pause() In ActionScript 3.0 nimmt die pau-se-Methode keinen Parameter auf. Es stehen zwei neue Methoden zur Verfügung, mit denen die gleiche Funktionalität erreicht wird: resu-me() und togglePause().

play() flash.net.NetStream.play() Die Parameter name, start, len und reset sind nicht mehr gültig, stattdessen wird ...arguments verwendet.

setBufferTime() flash.net.NetStream.bufferTime Wurde in ActionScript 3.0 zu einer Accessor-Eigenschaft mit Lese- und Schreibzugriff geändert.

Number-Klasse Number

Number Number.Number() In ActionScript 3.0 haben der Number()-Konstruktor und die globale Funktion Number() die gleichen Auswirkungen. Darüber hinaus gibt es keinen Unterschied zwischen einem Number-Objekt und einem literalen Zahlenwert.

Object-Klasse Object

__proto__ Entfernt In ActionScript 3.0 ist eine direkte Bearbeitung der Prototypkette nicht zulässig. Zum Erstellen einer Unterklasse verwenden Sie die extends-Anweisung in der Unterklassendeklaration. Um weitere Informationen über die Vererbungsstruktur und den Datentyp eines Objekts zu er-halten, verwenden Sie die neue Reflection-API flash.utils.describeType().

__resolve flash.utils.Proxy Verwenden Sie die neue Proxy-Klasse, um eine ähnliche Funktion umzusetzen.

addProperty() Entfernt In ActionScript 3.0 können Accessor-Eigenschaften mithilfe der Schlüsselwörter get und set direkt erstellt werden.

Page 116: Flash cs3, ajax und php

B A S I S W I S S E N 103

ActionScript 2.0 ActionScript 3.0 Kommentare

registerClass() Entfernt In ActionScript 3.0 sind alle Klassen standardmäßig registriert. Wenn Sie ein Objekt mithilfe von AMF verschlüsseln, wird die Objektklasse während des Verschlüsselungsvorgangs nicht beibehalten, es sei denn, Sie verwenden die Funktion flash.utils.registerClassAlias().

unwatch() Entfernt ActionScript 3.0 hat keine Watchpoints, daher ist die Methode unwatch() überholt.

watch() Entfernt Verwenden Sie die Accessor-Eigenschaften (get/set-Funktionen) oder die flash.utils.Proxy-Klasse, um eine ähn-liche Funktionalität zu erreichen.

PrintJob-Klasse flash.printing.PrintJob

orientation flash.printing.PrintJob.orien-tation

Diese Eigenschaft hat jetzt den Wert der PrintJobOrientation-Klasse.

pageHeight flash.printing.PrintJob.page-Height

Der Datentyp wurde in int geändert.

pageWidth flash.printing.PrintJob.page-Width

Der Datentyp wurde in int geändert.

paperHeight flash.printing.PrintJob.paper-Height

Der Datentyp wurde in int geändert.

paperWidth flash.printing.PrintJob.paper-Width

Der Datentyp wurde in int geändert.

PrintJob flash.printing.PrintJob.PrintJob()

addPage() flash.printing.PrintJob.add-Page()

In ActionScript 3.0 wurden die Datentypen der Parameter geändert: Der erste Parameter target weist jetzt den Datentyp Sprite auf; der zweite Parameter printArea den Datentyp Rectangle; der dritte Parameter options hat den neuen Datentyp PrintJobOptions und der vierte Parameter frameNum hat den Datentyp int.

send() flash.printing.PrintJob.send()

start() flash.printing.PrintJob.start()

Rectangle-Klasse

containsRectangle() flash.geom.Rectangle.contains-Rect()

Aus Konsistenzgründen um-benannt

security-Klasse flash.system.Security Diese Klasse wurde in das flash.system-Paket verschoben.

Selection-Klasse Entfernt Die Methoden dieser Klasse wur-den in andere Klassen verschoben.

Page 117: Flash cs3, ajax und php

K A P I T E L 3104

ActionScript 2.0 ActionScript 3.0 Kommentare

addListener() flash.events.EventDispatcher.addEventListener()

Im neuen Ereignismodell ist eine klassenspezifi sche addListe-ner()-Methode nicht mehr erfor-derlich, da alle Anzeigeobjekte die addEventListener()-Methode von der EventDispatcher-Klasse übernehmen.

getBeginIndex() flash.text.TextField.selec-tionBeginIndex

Wurde von einer Methode in eine Accessor-Eigenschaft geändert. Der Name wurde in selection-BeginIndex geändert.

getCaretIndex() flash.text.TextField.caret-Index

Wurde von einer Methode in eine Accessor-Eigenschaft geändert. Der Name wurde in caretIndex geändert.

getEndIndex() flash.text.TextField.selectio-nEndIndex

Wurde von einer Methode in eine Accessor-Eigenschaft geändert. Der Name wurde in selection-EndIndex geändert.

getFocus() flash.display.Stage.focus Wurde von einer Methode in einen Eigenschaften-Accessor geändert. Der Name wurde in focus ge-ändert. In ActionScript 2.0 hatte der Rückgabewert den Datentyp String, in ActionScript 3.0 hin-gegen weist die Eigenschaft den Datentyp InteractiveObject auf.

removeListener() flash.events.EventDispatcher.removeEventListener()

Im neuen Ereignismodell ist eine klassenspezifi sche removeListe-ner()-Methode nicht mehr erfor-derlich, da Anzeigeobjekte die re-moveEventListener()-Methode von der EventDispatcher-Klasse übernehmen.

setFocus() flash.display.Stage.focus Wurde von einer Methode zu einer Accessor-Eigenschaft geändert. Der Name wurde in focus ge-ändert. In ActionScript 2.0 hatte der Rückgabewert den Datentyp String, in ActionScript 3.0 hin-gegen weist die Eigenschaft den Datentyp InteractiveObject auf.

setSelection() flash.text.TextField.setSelec-tion()

Der Datentyp beider Parameter wurde von Number in uint geän-dert.

onSetFocus flash.display.InteractiveObject dispatches event: focusIn

Wurde im neuen Ereignismodell durch ein focusIn-Ereignis er-setzt.

SharedObject-Klasse flash.net.SharedObject Diese Klasse wurde in das flash.net-Paket verschoben.

Page 118: Flash cs3, ajax und php

B A S I S W I S S E N 105

ActionScript 2.0 ActionScript 3.0 Kommentare

flush() flash.net.SharedObject.flush() Diese Methode gibt jetzt kei-nen booleschen Wert mehr zurück. Wenn die Ausgabe fehl-schlägt, gibt Flash Player einen Ausnahmefehler aus. Wenn die Ausgabe erfolgreich ist oder eine Benutzerreaktion aussteht, gibt der Flash Player die Zeichenfolge „fl ushed“ oder „pending“ zu-rück. Darüber hinaus wurde der Datentyp des minDiskSpace-Parameters in int geändert.

getSize() flash.net.SharedObject.size Wurde in eine Accessor-Eigenschaft geändert. Der Datentyp wurde in uint geändert.

onStatus() flash.net.SharedObject dispat-ches event: netStatus

Wurde im neuen Ereignismodell durch ein netStatus-Ereignis ersetzt.

Sound-Klasse flash.media.Sound Diese Klasse wurde in das flash.media-Paket verschoben.

checkPolicyFile flash.media.SoundChannel.stop()

Wurde durch die flash.media.SoundChannel.stop()-Methode ersetzt.

duration flash.media.Sound.length

id3 flash.media.Sound.id3 Der Datentyp wurde von Object in ID3Info geändert. ID3Info ist eine neue Klasse, die die ID3-Eigenschaften enthält. Darüber hinaus wurde die Schreibweise der songname-Eigenschaft in song-Name geändert.

position flash.media.SoundChannel.po-sition

In die SoundChannel-Klasse ver-schoben

attachSound() Entfernt Erstellen Sie eine Instanz eines Sound-Objektes.

getBytesLoaded() flash.media.Sound.bytesLoaded Wurde in eine Accessor-Eigenschaft geändert. Der Datentyp wurde in uint geändert.

getBytesTotal() flash.media.Sound.bytesTotal Wurde in einen Eigenschaften-Accessor geändert. Der Datentyp wurde in uint geändert.

getPan() flash.media.SoundTransform.pan Wurde in eine Accessor-Eigenschaft geändert und in die SoundTransform-Klasse verscho-ben.

getTransform() flash.media.SoundMixer.sound-Transform

Wurde in eine Accessor-Eigenschaft geändert. Der Datentyp wurde in SoundTransform geändert.

getVolume() flash.media.SoundTransform.volume

Richten Sie die flashmedia. SoundTransform.volu-me- Eigenschaft ein, um die Soundlautstärke zu steuern.

Page 119: Flash cs3, ajax und php

K A P I T E L 3106

ActionScript 2.0 ActionScript 3.0 Kommentare

loadSound() flash.media.Sound.load() Der erste Parameter wurde von einem einfachen URL-String in ein URLRequest-Objekt geändert. Der zweite Parameter wurde von einem booleschen Wert, mit dem angegeben wird, ob der Sound so bald wie möglich wiedergegeben wird, in ein SoundLoaderContext-Objekt geändert.

onID3() flash.media.Sound dispatches event: id3

Wurde im neuen Ereignismodell durch ein id3-Ereignis ersetzt.

onLoad() flash.media.Sound dispatches event: complete

Wurde im neuen Ereignismodell durch ein complete-Ereignis ersetzt.

onSoundComplete() flash.media.SoundChannel dis-patches event: soundComplete

Wurde im neuen Ereignismodell durch ein soundComplete-Ereignis ersetzt.

setPan() flash.media.SoundTransform.pan Wurde in eine Accessor-Eigenschaft geändert und in die SoundTransform-Klasse verscho-ben.

setTransform() flash.media.SoundMixer.sound-Transform

Wurde in eine Accessor-Eigenschaft geändert. Der Datentyp wurde in SoundTransform geändert.

setVolume() flash.media.SoundChannel Entfernt. Verwenden Sie flash.media.SoundChannel.left-Peak und flash.media.SoundChannel.rightPeak zur Überwachung der Amplitude eines Soundkanals.

start() flash.media.Sound.play() Der Datentyp des loops-Parameters wurde von Number in int geändert. Ein dritter Parameter, sndTransform, wurde hinzugefügt, um die anfängliche Soundtransformation festzulegen, die vom Soundkanal verwendet werden soll.

stop() flash.media.SoundChannel.stop()

Stage-Klasse flash.display.Stage Diese Klasse wurde in das flash.display-Paket verschoben.

align flash.display.Stage.align

height flash.display.Stage.stage-Height

Der Name wurde von height in stageHeight geändert, so-dass jetzt kein Konfl ikt mehr mit der flash.display.DisplayObject.height-Eigenschaft auftreten kann.

scaleMode flash.display.Stage.scaleMode

showMenu flash.display.Stage.showDe-faultContextMenu

Der Name wurde geändert, um das angezeigte Menü besser widerzu-spiegeln.

Page 120: Flash cs3, ajax und php

B A S I S W I S S E N 107

ActionScript 2.0 ActionScript 3.0 Kommentare

width flash.display.Stage.stageWidth Der Name wurde von width in stageWidth geändert, sodass jetzt kein Konfl ikt mehr mit der flash.display.DisplayObject.width-Eigenschaft auftreten kann.

addListener() flash.events.EventDispatcher.addEventListener()

Im neuen Ereignismodell ist eine klassenspezifi sche addLis-tener()-Methode nicht mehr erforderlich, da die Klasse die addEventListener()-Methode von der EventDispatcher-Klasse übernimmt.

removeListener() flash.events.EventDispatcher.removeEventListener()

Im neuen Ereignismodell ist eine klassenspezifi sche removeLis-tener()-Methode nicht mehr erforderlich, da die Klasse die re-moveEventListener()-Methode von der EventDispatcher-Klasse übernimmt.

onResize flash.display.Stage dispatches event: resize

Wurde im neuen Ereignismodell durch ein resize-Ereignis ersetzt.

String-Klasse String Unterstützung für reguläre Ausdrücke mit drei neuen Methoden hinzugefügt: match(), replace() und search().

concat() String.concat() Der Parameter wurde geändert und verwendet jetzt das Format ...(rest).

StyleSheet-Klasse flash.text.StyleSheet Diese Klasse wurde in das flash.text-Paket verschoben. Die Mitglieder load() und onLoad() wurden entfernt und einige pri-vate Funktionen und Variablen wurden hinzugefügt.

StyleSheet flash.text.StyleSheet.StyleSheet()

clear() flash.text.StyleSheet.clear()

getStyle() flash.text.StyleSheet.get-Style()

Der Name des Parameters wurde in n geändert.

getStyleNames() flash.text.StyleSheet.style-Names

Wurde in eine Accessor-Eigenschaft geändert.

load() flash.net.URLLoader.load() Verwenden Sie die neuen Klassen URLLoader und URLRequest zum Laden von URLs.

onLoad() flash.net.URLLoader dispatches event: complete

Wurde im neuen Ereignismodell durch ein complete-Ereignis ersetzt.

parseCSS() flash.text.StyleSheet.par-seCSS()

Gibt in ActionScript 3.0 void anstelle eines booleschen Werts zurück.

setStyle() flash.text.StyleSheet.set-Style()

Der Name des Parameters wurde in n und der Stil in s geändert.

transform() flash.text.StyleSheet.trans-form()

Page 121: Flash cs3, ajax und php

K A P I T E L 3108

ActionScript 2.0 ActionScript 3.0 Kommentare

System-Klasse flash.system.System

exactSettings flash.system.Security.exact-Settings

In die flash.System.Security-Klasse verschoben

useCodepage flash.system.System.useCode-Page

In ActionScript 3.0 ist der Buchstabe „P“ in useCodePage ein Großbuchstabe.

onStatus() Entfernt Diese Ereignisprozedur ist im ActionScript 3.0-Ereignismodell überholt.

setClipboard() flash.system.System.setClip-board()

showSettings() flash.system.Security.showSet-tings()

TextField-Klasse flash.text.TextField Diese Klasse wurde in das flash.text-Paket verschoben.

_alpha flash.display.DisplayObject.alpha

Diese Eigenschaft wird jetzt von der DisplayObject-Klasse übernommen. Der Unterstrich am Anfang wurde entfernt.

antiAliasType flash.text.TextField.antiAli-asType

autoSize flash.text.TextField.autoSize

background flash.text.TextField.back-ground

backgroundColor flash.text.TextField.back-groundColor

border flash.text.TextField.border

borderColor flash.text.TextField.border-Color

In ActionScript 3.0 wird ein uint-Wert anstelle eines Number-Werts zurückgegeben.

bottomScroll flash.text.TextField.bottom-ScrollV

In ActionScript 3.0 wird ein uint-Wert anstelle eines Number-Werts zurückgegeben.

condenseWhite flash.text.TextField.conden-seWhite

embedFonts flash.text.TextField.embed-Fonts

filters flash.display.DisplayObject.filters

gridFitType flash.text.TextField.gridFit-Type

_height flash.display.DisplayObject.height

Diese Eigenschaft wird jetzt von der DisplayObject-Klasse übernommen. Der Unterstrich am Anfang wurde entfernt.

_highquality flash.display.Stage.quality Entfernt.

hscroll flash.text.TextField.scrollH Der Datentyp wurde von Number zu uint geändert. Der Name wurde von hscroll zu scrollH geändert.

Page 122: Flash cs3, ajax und php

B A S I S W I S S E N 109

ActionScript 2.0 ActionScript 3.0 Kommentare

html flash.text.TextField.htmlText Entfernt. In ActionScript 3.0 werden alle Textfelder als HTML-Textfelder behandelt. Verwenden Sie die TextField.htmlText-Eigenschaft, um HTML-Text einzu-richten.

htmlText flash.text.TextField.htmlText

length flash.text.TextField.length Der Datentyp wurde von Number in uint geändert.

maxChars flash.text.TextField.maxChars Der Datentyp wurde von Number in uint geändert.

maxhscroll flash.text.TextField.maxSc-rollH

Der Datentyp wurde von Number in uint geändert.

maxscroll flash.text.TextField.maxSc-rollV

Der Datentyp wurde von Number in uint geändert. Im neuen Namen ist das S ein Großbuchstabe und der Buchstabe V wurde hinzugefügt, um das verti-kale Scrollen zu verdeutlichen.

menu flash.display.InteractiveObject.contextMenu

Diese Eigenschaft wird jetzt von der InteractiveObject-Klasse übernommen.

mouseWheelEnabled flash.text.TextField.mouse-WheelEnabled

multiline flash.text.TextField.multiline

_name flash.display.DisplayObject.name

Diese Eigenschaft wird jetzt von der DisplayObject-Klasse übernommen. Der Unterstrich am Anfang wurde entfernt.

_parent flash.display.DisplayObject.parent

Diese Eigenschaft wird jetzt von der DisplayObject-Klasse übernommen. Der Unterstrich am Anfang wurde entfernt. Der Datentyp wurde von MovieClip in DisplayObjectContainer geändert.

password flash.text.TextField.displayA-sPassword

Diese Eigenschaft wurde aus Konsistenzgründen umbenannt.

_quality flash.display.Stage.quality In die Stage-Klasse verschoben

restrict flash.text.TextField.restrict

_rotation flash.display.DisplayObject.rotation

Diese Eigenschaft wird jetzt von der DisplayObject-Klasse übernommen. Der Unterstrich am Anfang wurde entfernt.

scroll flash.text.TextField.scrollV Der Datentyp wurde von Number in uint geändert und der Name von scroll in scrollV.

selectable flash.text.TextField.selec-table

sharpness flash.text.TextField.sharpness

Page 123: Flash cs3, ajax und php

K A P I T E L 3110

ActionScript 2.0 ActionScript 3.0 Kommentare

_soundbuftime flash.media.SoundMixer.buffer-Time

Eigenschaften und Methoden für die globale Soundsteuerung in einer SWF-Datei befi nden sich jetzt in der flash.media.SoundMixer-Klasse.

styleSheet flash.text.TextField.styleS-heet

tabEnabled flash.display.InteractiveObject.tabEnabled

Diese Eigenschaft wird jetzt von der InteractiveObject-Klasse übernommen.

tabIndex flash.display.InteractiveObject.tabIndex

Diese Eigenschaft wird jetzt von der InteractiveObject-Klasse übernommen.

_target Entfernt ActionScript 3.0 identifi ziert Anzeigeobjekte direkt, daher ist die Identifi zierung des Pfads nicht mehr notwendig.

text flash.text.TextField.text

textColor flash.text.TextField.textColor Der Datentyp wurde von Number in uint geändert.

textHeight flash.text.TextField.text-Height

textWidth flash.text.TextField.textWidth

thickness flash.text.TextField.thickness

type flash.text.TextField.type

_url flash.display.LoaderInfo.url

variable Entfernt Diese Variable ist in ActionScript 3.0 nicht mehr erforderlich.

_visible flash.display.DisplayObject.visible

Diese Eigenschaft wird jetzt von der DisplayObject-Klasse übernommen. Der Unterstrich am Anfang wurde entfernt.

_width flash.display.DisplayObject.width

Diese Eigenschaft wird jetzt von der DisplayObject-Klasse übernommen. Der Unterstrich am Anfang wurde entfernt.

wordWrap flash.text.TextField.wordWrap

_x flash.display.DisplayObject.x Diese Eigenschaft wird jetzt von der DisplayObject-Klasse übernommen. Der Unterstrich am Anfang wurde entfernt.

_xmouse flash.display.DisplayObject.mouseX

Diese Eigenschaft wird jetzt von der DisplayObject-Klasse übernommen. Der Unterstrich am Anfang wurde entfernt.

_xscale flash.display.DisplayObject.scaleX

Diese Eigenschaft wird jetzt von der DisplayObject-Klasse übernommen. Der Unterstrich am Anfang wurde entfernt.

_y flash.display.DisplayObject.y Diese Eigenschaft wird jetzt von der DisplayObject-Klasse übernommen. Der Unterstrich am Anfang wurde entfernt.

Page 124: Flash cs3, ajax und php

B A S I S W I S S E N 111

ActionScript 2.0 ActionScript 3.0 Kommentare

_ymouse flash.display.DisplayObject.mouseY

Diese Eigenschaft wird jetzt von der DisplayObject-Klasse übernommen. Der Unterstrich am Anfang wurde entfernt.

_yscale flash.display.DisplayObject.scaleY

Diese Eigenschaft wird jetzt von der DisplayObject-Klasse übernommen. Der Unterstrich am Anfang wurde entfernt.

addListener() flash.events.EventDispatcher.addEventListener()

Im neuen Ereignismodell ist eine klassenspezifi sche addLis-tener()-Methode nicht mehr erforderlich, da die Klasse die addEventListener()-Methode von der EventDispatcher-Klasse übernimmt.

getDepth() flash.display.DisplayObjectContainer

Entfernt. Verwenden Sie jetzt die Methoden der DisplayObjectContainer-Klasse, um die Textfeldtiefe festzustellen.

getFontList() flash.text.Font.enumerate-Fonts()

Entfernt. Verwenden Sie Font.enumerateFonts() und setzen Sie den Parameter enumerate-DeviceFonts auf true.

getNewTextFormat() flash.text.TextField.default-TextFormat

Der Name wurde von getNew-TextFormat in defaultTextFor-mat geändert. Von einer Methode in eine Accessor-Eigenschaft geändert.

getTextFormat() flash.text.TextField.getText-Format()

Der Datentyp beider Parameter wurde von Number in uint geän-dert.

onChanged() flash.text.TextField dispat-ches event: change

Wurde im neuen Ereignismodell durch ein change-Ereignis ersetzt.

onKillFocus() flash.display.InteractiveObject dispatches event: focusOut

Wurde im neuen Ereignismodell durch ein focusOut-Ereignis ersetzt.

onScroller() flash.text.TextField dispat-ches event: scroll

Wurde im neuen Ereignismodell durch ein scroll-Ereignis ersetzt.

onSetFocus() flash.display.InteractiveObject dispatches event: focusIn

Wurde im neuen Ereignismodell durch ein focusIn-Ereignis er-setzt.

removeListener() flash.events.EventDispatcher.removeEventListener()

Im neuen Ereignismodell ist eine klassenspezifi sche removeLis-tener()-Methode nicht mehr erforderlich, da die Klasse die re-moveEventListener()-Methode von der EventDispatcher-Klasse übernimmt.

removeTextField() flash.display.DisplayObjectContainer.remove-Child()

Entfernt. Rufen Sie die remove-Child()-Methode des übergeord-neten Anzeigeobjekt-Containers auf, der das Textfeld enthält.

Page 125: Flash cs3, ajax und php

K A P I T E L 3112

ActionScript 2.0 ActionScript 3.0 Kommentare

replaceSel() flash.text.TextField.replaceS-electedText()

Der Name wurde von replaces-el() in replaceSelectedText() geändert. Der newText-Parameter wurde durch eine Zeichenfolge ersetzt.

replaceText() flash.text.TextField.replace-Text()

Der Datentyp der ersten beiden Parameter wurde von Number zu uint geändert.

setNewTextFormat() flash.text.TextField.default-TextFormat

Der Name wurde von setNew-TextFormat in defaultTextFor-mat geändert. Von einer Methode in eine Accessor-Eigenschaft geändert.

setTextFormat() flash.text.TextField.setText-Format()

Die Reihenfolge der Parameter wurde geändert. Der Datentyp der Indexparameter wurde von Number in int geändert.

TextFormat-Klasse flash.text.TextFormat Diese Klasse wurde in das flash.text-Paket verschoben.

align flash.text.TextFormat.align

blockIndent flash.text.TextFormat.blockIn-dent

Der Datentyp wurde in ActionScript 3.0 in Object ge-ändert, da einer der möglichen Werte null ist. Dieser Wert ist in ActionScript 3.0 kein Mitglied des Datentyps Number.

bold flash.text.TextFormat.bold Der Datentyp wurde in ActionScript 3.0 in Object ge-ändert, da einer der möglichen Werte null ist. Dieser Wert ist in ActionScript 3.0 kein Mitglied des Datentyps Boolean.

bullet flash.text.TextFormat.bullet Der Datentyp wurde in ActionScript 3.0 in Object ge-ändert, da einer der möglichen Werte null ist. Dieser Wert ist in ActionScript 3.0 kein Mitglied des Datentyps Boolean.

color flash.text.TextFormat.color Der Datentyp wurde in ActionScript 3.0 in Object ge-ändert, da einer der möglichen Werte null ist. Dieser Wert ist in ActionScript 3.0 kein Mitglied des Datentyps Number.

font flash.text.TextFormat.font

indent flash.text.TextFormat.indent Der Datentyp wurde in ActionScript 3.0 in Object ge-ändert, da einer der möglichen Werte null ist. Dieser Wert ist in ActionScript 3.0 kein Mitglied des Datentyps Number.

Page 126: Flash cs3, ajax und php

B A S I S W I S S E N 113

ActionScript 2.0 ActionScript 3.0 Kommentare

italic flash.text.TextFormat.bullet Der Datentyp wurde in ActionScript 3.0 in Object ge-ändert, da einer der möglichen Werte null ist. Dieser Wert ist in ActionScript 3.0 kein Mitglied des Datentyps Boolean.

kerning flash.text.TextFormat.kerning Der Datentyp wurde in ActionScript 3.0 in Object ge-ändert, da einer der möglichen Werte null ist. Dieser Wert ist in ActionScript 3.0 kein Mitglied des Datentyps Boolean.

leading flash.text.TextFormat.leading Der Datentyp wurde in ActionScript 3.0 in Object ge-ändert, da einer der möglichen Werte null ist. Dieser Wert ist in ActionScript 3.0 kein Mitglied des Datentyps Number.

leftMargin flash.text.TextFormat.leftM-argin

Der Datentyp wurde in ActionScript 3.0 in Object ge-ändert, da einer der möglichen Werte null ist. Dieser Wert ist in ActionScript 3.0 kein Mitglied des Datentyps Number.

letterSpacing flash.text.TextFormat.letter-Spacing

Der Datentyp wurde in ActionScript 3.0 in Object ge-ändert, da einer der möglichen Werte null ist. Dieser Wert ist in ActionScript 3.0 kein Mitglied des Datentyps Number.

rightMargin flash.text.TextFormat.rightM-argin

Der Datentyp wurde in ActionScript 3.0 in Object ge-ändert, da einer der möglichen Werte null ist. Dieser Wert ist in ActionScript 3.0 kein Mitglied des Datentyps Number.

size flash.text.TextFormat.size Der Datentyp wurde in ActionScript 3.0 in Object ge-ändert, da einer der möglichen Werte null ist. Dieser Wert ist in ActionScript 3.0 kein Mitglied des Datentyps Number.

underline flash.text.TextFormat.under-line

Der Datentyp wurde in ActionScript 3.0 in Object ge-ändert, da einer der möglichen Werte null ist. Dieser Wert ist in ActionScript 3.0 kein Mitglied des Datentyps Boolean.

url flash.text.TextFormat.url

TextFormat flash.text.TextFormat.TextFormat()

Die Parameter size, color, bold, italic, underline, url, left-Margin, rightMargin, indent und leading wurden in Objekte umgewandelt.

Page 127: Flash cs3, ajax und php

K A P I T E L 3114

ActionScript 2.0 ActionScript 3.0 Kommentare

getTextExtent() Entfernt Verwenden Sie die Eigenschaften von flash.text.TextField zum Messen eines Felds mit ei-ner Textzeile und flash.text.TextLineMetrics zum Messen des Inhalts innerhalb eines Textfelds.

TextRenderer-Klasse flash.text.TextRenderer Der Speicherort wurde geändert. In das flash.text-Paket verscho-ben.

maxLevel flash.text.TextRenderer.max-Level

In ActionScript 3.0 als uint defi -niert

setAdvancedAntialia-singTable()

flash.text.TextRenderer.setA-dvancedAntiAliasingTable()

Die Parameterwerte fontStyle und colorType können jetzt mit den Konstanten FontStyle und TextColorType eingestellt werden. Der advancedAntiAlia-singTable-Parameter nimmt jetzt ein Array mit mindestens einem CSMSettings-Objekt an.

TextSnapshot-Klasse flash.text.TextSnapshot Diese Klasse wurde in das flash.text-Paket verschoben. Verschiedene Parameter wur-den geändert, ebenso einige Methodennamen und einige Rückgabetypen.

findText() flash.text.TextSnapshot.find-Text()

Der Name des startIndex-Parameters wurde in beginIndex geändert. Der Datentyp des star-tIndex-Parameters wurde von Number zu int geändert.

getCount() flash.text.TextSnapshot.char-Count

Von einer Methode zu einer Accessor-Eigenschaft geändert. Der Datenrückgabetyp wurde von Number in uint geändert.

getSelected() flash.text.TextSnapshot.getSe-lected()

Der Datentyp der Parameter wur-de von Number in uint geändert und die Namen wurden von start und end in beginIndex und EndIndex geändert.

getSelectedText() flash.text.TextSnapshot.getSe-lectedText()

In ActionScript 3.0 hat der Parameter den Standardwert false.

getText() flash.text.TextSnapshot.get-Text()

Der Datentyp der Parameter start und end wurde von Number in uint geändert und die Namen wurden von start und end in beginIndex und endIndex ge-ändert.

getTextRunInfo() flash.text.TextSnapshot.getT-extRunInfo()

Der Datentyp der Parameter wur-de von Number in uint geändert.

Page 128: Flash cs3, ajax und php

B A S I S W I S S E N 115

ActionScript 2.0 ActionScript 3.0 Kommentare

hitTestTextNearPos() flash.text.TextSnapshot.hit-TestTextNearPos()

Der Name des closeDist-Parameters wurde in maxDistance geändert. Dieser Parameter hat jetzt den Standardwert = 0.

setSelectColor() flash.text.TextSnapshot.setSe-lectColor()

Der Datentyp des Parameters wurde von Number in uint geän-dert. Der Parameter hat jetzt den Standardwert = 0xFFFF00.

setSelected() flash.text.TextSnapshot.setSe-lected()

Der Datentyp der Parameter start und end wurde von Number in uint geändert und die Namen wurden von start und end in beginIndex und endIndex ge-ändert.

Video-Klasse flash.media.Video Diese Klasse wurde in das flash.media-Paket verscho-ben. Videoobjekte können in ActionScript jetzt dynamisch mit dem Video()-Konstruktor erstellt werden. Hängen Sie einen Videostream mit attachCamera() oder attachNetStream() an das Videoobjekt an.

_alpha flash.display.DisplayObject.alpha

Diese Eigenschaft wird von der DisplayObject-Klasse übernom-men. Der Unterstrich am Anfang wurde entfernt.

deblocking flash.media.Video.deblocking Der Datentyp wurde von Number in int geändert.

_height flash.display.DisplayObject.height

Diese Eigenschaft wird von der DisplayObject-Klasse übernom-men. Der Unterstrich am Anfang wurde entfernt.

height flash.media.Video.videoHeight Der Datentyp wurde von Number in int geändert.

_name flash.display.DisplayObject.name

Diese Eigenschaft wird von der DisplayObject-Klasse übernom-men. Der Unterstrich am Anfang wurde entfernt.

_parent flash.display.DisplayObject.parent

Diese Eigenschaft wird von der DisplayObject-Klasse übernom-men. Der Unterstrich am Anfang wurde entfernt.

_rotation flash.display.DisplayObject.rotation

Diese Eigenschaft wird von der DisplayObject-Klasse übernom-men. Der Unterstrich am Anfang wurde entfernt.

smoothing flash.media.Video.smoothing

_visible flash.display.DisplayObject.visible

Diese Eigenschaft wird von der DisplayObject-Klasse übernom-men. Der Unterstrich am Anfang wurde entfernt.

Page 129: Flash cs3, ajax und php

K A P I T E L 3116

ActionScript 2.0 ActionScript 3.0 Kommentare

_width flash.display.DisplayObject.width

Diese Eigenschaft wird von der DisplayObject-Klasse übernom-men. Der Unterstrich am Anfang wurde entfernt.

width flash.media.Video.videoWidth Der Datentyp wurde von Number zu int geändert.

_x flash.display.DisplayObject.x Diese Eigenschaft wird von der DisplayObject-Klasse übernom-men. Der Unterstrich am Anfang wurde entfernt.

_xmouse flash.display.DisplayObject.mouseX

Diese Eigenschaft wird von der DisplayObject-Klasse übernom-men. Der Unterstrich am Anfang wurde entfernt.

_xscale flash.display.DisplayObject.scaleX

Diese Eigenschaft wird von der DisplayObject-Klasse übernom-men. Der Unterstrich am Anfang wurde entfernt.

_y flash.display.DisplayObject.y Diese Eigenschaft wird von der DisplayObject-Klasse übernom-men. Der Unterstrich am Anfang wurde entfernt.

_ymouse flash.display.DisplayObject.mouseY

Diese Eigenschaft wird von der DisplayObject-Klasse übernom-men. Der Unterstrich am Anfang wurde entfernt.

_yscale flash.display.DisplayObject.scaleY

Diese Eigenschaft wird von der DisplayObject-Klasse übernom-men. Der Unterstrich am Anfang wurde entfernt.

attachVideo() flash.media.Video.attachNet-Stream()

Verwenden Sie fl ash.media.Video.attachCamera(), um einen Videostream von einem Kameraobjekt anzugeben.

clear() flash.media.Video.clear()

XML-Klasse flash.xml.XMLDocument Diese Klasse wurde in das flash.xml-Paket verschoben und der Name in XMLDocument geändert, um einen Konfl ikt mit der neuen Top-Level XML-Klasse zu vermei-den, die ECMAScript für XML (E4X) implementiert.

contentType flash.net.URLRequest.conten-tType

docTypeDecl flash.xml.XMLDocument.docType-Decl

idMap flash.xml.XMLDocument.idMap

ignoreWhite flash.xml.XMLDocument.ignore-White

loaded Entfernt Die Funktionen zum Laden einer Datei wurden aus der XMLDocument-Klasse entfernt. Verwenden Sie stattdessen URLLoader.

Page 130: Flash cs3, ajax und php

B A S I S W I S S E N 117

ActionScript 2.0 ActionScript 3.0 Kommentare

status Entfernt Fehler beim Parsen werden jetzt über Ausnahmefehler gemeldet.

xmlDecl flash.xml.XMLDocument.xmlDecl

XML flash.xml.XMLDocument.XMLDocument()

addRequestHeader() flash.net.URLRequest.request-Headers

createElement() flash.xml.XMLDocument.create-Element()

createTextNode() flash.xml.XMLDocument.create-TextNode()

getBytesLoaded() flash.net.URLLoader.bytes-Loaded

Die Funktionen zum Laden einer Datei wurden aus der XMLDocument-Klasse entfernt. Verwenden Sie stattdessen URLLoader.

getBytesTotal() flash.net.URLLoader.bytesTotal Die Funktionen zum Laden einer Datei wurden aus der XMLDocument-Klasse entfernt. Verwenden Sie stattdessen URLLoader.

load() Entfernt Die Funktionen zum Laden einer Datei wurden aus der XMLDocument-Klasse entfernt (in ActionScript 2.0 war dies die XML-Klasse). Verwenden Sie stattdessen URLLoader.

onData() flash.net.URLLoader dispatches event: complete

Die Funktionen zum Laden einer Datei wurden aus der XMLDocument-Klasse entfernt. Verwenden Sie stattdessen URLLoader. Wurde im neuen Ereig-nismodell durch ein complete-Ereignis ersetzt.

onHTTPStatus() flash.net.URLLoader dispatches event: httpStatus

Die Funktionen zum Laden einer Datei wurden aus der XMLDocument-Klasse entfernt. Verwenden Sie stattdessen URLLoader. Wurde im neuen Ereignismodell durch ein http-Status-Ereignis ersetzt.

onLoad() flash.net.URLLoader dispatches event: complete

Die Funktionen zum Laden einer Datei wurden aus der XMLDocument-Klasse entfernt. Verwenden Sie stattdessen URLLoader. Wurde im neuen Ereig-nismodell durch ein complete-Ereignis ersetzt.

parseXML() flash.xml.XMLDocument. parseXML()

Page 131: Flash cs3, ajax und php

K A P I T E L 3118

ActionScript 2.0 ActionScript 3.0 Kommentare

send() Entfernt Die Funktionen zum Senden einer Datei wurden aus der XMLDocument-Klasse entfernt (in ActionScript 2.0 war dies die XML-Klasse). Verwenden Sie stattdessen die Funktionen und Klassen im flash.net-Paket.

sendAndLoad() Entfernt Die Funktionen zum Senden und Laden einer Datei wurden aus der XMLDocument-Klasse entfernt (in ActionScript 2.0 war dies die XML-Klasse). Verwenden Sie stattdessen URLRequest und URLLoader.

XMLNode-Klasse flash.xml.XMLNode Der Speicherort wurde geändert. Diese Klasse wurde in das flash.xml-Paket verschoben.

nodeType flash.xml.XMLNode.nodeType Der Datentyp wurde von Number in uint geändert.

XMLNode flash.xml.XMLNode.XMLNode() Der Datentyp des type-Parameters wurde von Number in uint geän-dert.

XMLSocket-Klasse flash.net.XMLSocket Diese Klasse wurde in das flash.net-Paket verschoben.

XMLSocket flash.net.XMLSocket.XMLSocket()

Es wurden zwei optionale Parameter zum Festlegen von Host und Port hinzugefügt.

connect() flash.net.XMLSocket.connect() Der Datentyp des port-Parameters wurde in int geändert.

onClose() flash.net.XMLSocket dispatches event: close

Wurde im neuen Ereignismodell durch ein close-Ereignis ersetzt.

onConnect() flash.net.XMLSocket dispatches event: connect

Wurde im neuen Ereignismodell durch ein connect-Ereignis er-setzt.

onData() flash.net.XMLSocket dispatches event: data

Wurde im neuen Ereignismodell durch ein data-Ereignis ersetzt.

onXML() Entfernt In ActionScript 3.0 wird nur das data-Ereignis ausgelöst, sodass Sie entweder E4X- oder den äl-teren XML-Parser (XMLDocument-Klasse) verwenden können. Die alte Ereignisprozedur onXML wurde nach dem Parsen des XML-Codes aufgerufen. Dies ergibt in ActionScript 3.0 keinen Sinn, weil Sie zum Parsen des XML-Codes jetzt zwischen der XML-Klasse (E4X) und der XMLDocument-Klasse (ältere Version) wählen können.

Tabelle 3.1: Migration von ActionScript 2.0 auf ActionScript 3.0 (Quelle: ActionScript-Hilfe von Flash CS3)

Page 132: Flash cs3, ajax und php

4AJAX – ASYNCHRONUS JAVASCRIPT AND XML

In diesem Kapitel setzen wir uns mit den Grundlagen von AJAX auseinander und zeigen die Möglichkeiten der „Zusam-menarbeit“ mit Flash auf. Unweigerlich werden wir in diesem Kapitel zu dem Schluss gelangen, dass alle Möglichkeiten von AJAX (Web 2.0) in Flash schon seit langem implementiert sind. Aus diesem Grund müssen wir uns auch mit der Thematik befassen, inwiefern AJAX eine Konkurrenz bzw. Alternative zu Flash darstellt und wo der Einsatz der einen oder der anderen Technologie mehr oder weniger Sinn macht.

Klarerweise ist dieses Buch kein AJAX-Buch – aus diesem Grund werden wir uns auch nur mit den Kernthemen von AJAX befas-sen (die im Übrigen gar nicht so umfassend sind) und diese für uns sinnvoll nutzen. Auch möchte ich nicht auf die Entwicklung aller Scripten eingehen, sondern vielmehr diese als „Entwickelt und zum Benutzen bereitgestellt“ vorstellen.

Page 133: Flash cs3, ajax und php

K A P I T E L 4120

4.1 Was ist AJAX?Der grundlegende Vorteil von AJAX ist, dass auf ein bereits vollständig vom Server zum Client übertragenes Webdokument im Nachhinein und ohne Neuladen des Dokuments weitere Daten vom Server abgefragt werden können. Eine Interaktion mit dem Server ist also ohne Neuladen (Refresh) des Dokuments möglich.

AJAX ist im Grunde genommen eine Kombination mehrerer Technologien:

XHTML und CSS: Diese beiden Technologien verwenden wir zur Darstellung der Daten auf einer Website – sie bilden bekannterweise unser Gerüst. Dies gilt selbst-verständlich nach wie vor und – wie wir wissen – hierin werden alle unsere Assets wie Texte, Grafiken, SWF-Dateien usw. eingebettet.

XML: wird zur Übertragung von Daten zwischen Server und Client verwendet.

XMLHttpRequest: stellt die essenziell wichtige Möglichkeit des asynchronen Nach-ladens von Informationen vom Server dar. Erst mithilfe dieser „Technologie“ wird es möglich, auf einer bereits vollständig zum User übertragenen Website weitere Daten vom Server nachzuladen.

JavaScript: bildet die Schnittstelle zwischen allen Technologien. Das DOM (Docu-ment Object Model) steht hier als die Möglichkeit, bereits im Webdokument vor-handene Daten nachträglich zu verändern.

Das einzig wirklich Neue an AJAX ist der XMLHttpRequest, alles andere ist bekannt. Dies soll jedoch keineswegs bedeuten, dass wir sofort AJAX-Experten sind, wenn wir XHTML-Dokumente mit CSS aufbauen und JavaScript programmieren können. Kei-neswegs! Gerade das Zusammenspiel aller Technologien stellt die eigentliche Schwie-rigkeit dar. Auch müssen wir im Umgang mit dem Document Object Model relativ fit sein.

4.2 Was ist AJAX nicht?AJAX ist in aller Munde und Web 2.0 sowieso. Je mehr „Web 2.0“ eine Website ist, umso trendiger und moderner ist sie. Oder etwa nicht?

AJAX ist kein Allheilmittel für alle Probleme und Workarounds, die während der Ent-wicklung einer Website auftreten. Klar – jeder Webdesigner, der etwas auf sich hält, wird versuchen, um die Burg eine AJAX-Anwendung zu programmieren. Ja, AJAX stellt eine Abhilfe für dynamische Anwendungen dar, die während der Darstellung eines einzelnen Webdokuments im Nachhinein noch Daten zusätzlich anzeigen möch-ten (ohne das Dokument neu zu laden). Jedoch darf nicht außer Acht gelassen werden, dass AJAX sinnvoll eingesetzt gehört: Je häufiger die Anfragen an einen Server gestellt werden, umso mehr gerät der Server unter Last.

u

u

u

u

Nachladen von Daten ohne

Refresh

Nachladen von Daten ohne

Refresh

Page 134: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 121

Stellen Sie sich folgendes Szenario vor: Auf einer Website werden die Schlagzeilen des Tages (in Österreich haben wir das Beispiel des Österreichischen Rundfunks (ORF) – www.orf.at) dargestellt. Mehrmals am Tag besuche ich die Seite und sehe nach, was sich getan hat (gehen wir mal davon aus, dass ich keinen Newsreader verwende). Nachdem ich einen Proxy-Server in Betrieb habe und somit die Inhalte gecached werden, muss ich die Seite aktualisieren, um zu den neuesten Informationen zu kom-men. Eigentlich würde man meinen, dass dies ein tolles Einsatzgebiet für eine AJAX-Anwendung ist: Statt dass ein User den Refresh-Button klicken muss, lädt sich die Seite in regelmäßigen Abständen (beispielsweise jede Minute) die neuesten Informationen automatisch down und gibt diese aus. Bei einer geschätzten Anzahl von zigtausend Usern der ORF-Seite wäre das eine ungeheure Belastung für den Server: Für diese zigtausend User muss er jede Minute einen Datenbank-Server abfragen, die News zusammenstellen und den (zigtausend) Usern zurückschicken. Der Datentransfer wäre enorm! Ein guter Webdesigner ist deshalb ein solcher, der die zur Verfügung stehenden Technologien sinnvoll und bewusst einsetzt.

Es gibt jedoch noch weitere Probleme, die im Zusammenhang mit AJAX auftreten:

1. Der Back- oder Zurück-Button hat bei AJAX-Anwendungen keine Bedeutung mehr: Nachdem der Back-Button dafür bestimmt ist, das zuvor angezeigte Webdokument anzuzeigen, wird dies vom Server neu angefordert. Genau das ist aber das Verfahren, das wir bei AJAX vermeiden (umgehen) wollen: das Neuladen eines Dokuments. In einem AJAX-basierten Dokument werden die neuen/zusätzlichen Inhalte nicht in Form eines neuen (anderen) Webdokuments, sondern im aktuellen Webdokument selbst dargestellt.

2. Keine Unterstützung in älteren Browsern: AJAX in vollem Umfang setzt relativ neue Browser voraus! Konkret heißt das, dass diese Browser zwar mit der asynchronen Datenübertragung keine Probleme haben, jedoch das Document Object Model (DOM) und die zugehörigen JavaScript-Befehle nicht in dem Umfang unterstützen, wie AJAX das für vernünftige Anwendungen benötigt.

3. Thema Barrierefreiheit: AJAX ist beileibe nicht barrierefrei. Nehmen wir den Fall eines sehbehinderten Users: Dieser verwendet zumeist eine Software, die den Quellcode einer Seite liest, diesen interpretiert und akustisch ausgibt. Nun, AJAX verändert im Nachhinein den Inhalt eines Webdokuments, jedoch nicht den Quelltext (dieser ist unveränderlich und liegt so auf, wie er vom Server geliefert wurde). Somit kann ein Quellcode-Interpreter die durch AJAX geänderten Inhalte auch nicht wiedergeben.

Setzen Sie AJAX bewusst ein – bedenken Sie insbesondere auch die Serverseite wie oben angesprochen. Was haben Ihre User davon, dass das Webdokument zwar nicht mehr aktualisiert werden muss, jedoch der Server regelmäßig unter Volllast in die Knie geht.

Page 135: Flash cs3, ajax und php

K A P I T E L 4122

4.3 Der XMLHttpRequestWie wir bereits aus dem Grundlagenkapitel wissen, erfolgt eine Datenanforderung eines Clients (im Allgemeinen meinen wir hier den User und seinen Browser) an einen Server (Webserver) aus folgenden Gründen:

1. Anfordern eines Webdokuments: Der User sitzt vor seinem Browser und gibt in der Adresszeile eine URL an oder klickt in einer bereits angezeigten Website auf einen Link.

2. Aktualisieren eines (bereits angezeigten) Webdokuments: Der User entscheidet sich für ein Aktualisieren der Site und klickt auf den Refresh-Button.

3. Abschicken eines Formulars: Der User füllt (bewusst oder unbewusst) ein Formular innerhalb eines Webdokuments aus und schickt das Formular (bewusst oder unbewusst) ab.

In jedem der drei Fälle entsteht für den User durch die Datenanforderung eine Warte-zeit, die sich wie folgt zusammensetzt – in dieser Zeit kann der User die Website nicht bedienen, sie ist inaktiv:

1. Datenübertragung vom Client zum Server: Die Anforderung des Clients an den Server wird abgeschickt. Dieser Teil der Wartezeit ist relativ gering und hängt wesentlich von der Anbindung des Users ans Internet ab. Im Allgemeinen ist diese Zeitspanne jedoch vernachlässigbar gering.

2. Datenverarbeitung am Server: Die Anforderung des Clients wird am Server verarbeitet. Je nach angeforderten Informationen stellt dies eine mehr oder weniger lange Wartezeit dar – für den Fall, dass beispielsweise Daten aus einer Datenbank gelesen werden und in ein PHP- (oder ähnliches) Dokument geschrieben werden müssen, kann dies durchaus eine Wartezeit von mehreren Sekunden bedeuten.

3. Datenübertragung vom Server zum Client: Die vom Server aufbereiteten Daten (XHTML-basiertes Webdokument) werden zurück an den Client geschickt. An dieser Stelle spielt selbstverständlich die Menge an zu übertragenden Daten sowie die Anbindung des Users an das Internet eine wesentliche Rolle.

4. Aufbau der Site auf Userseite: Je nach Komplexität des Webdokuments kann der Aufbau der Website mehr oder weniger lange dauern. Im Allgemeinen dauert jedoch auch diese Zeitspanne mehrere Sekunden.

Die nachfolgende Grafik verdeutlicht die Wartezeiten:

Page 136: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 123

Mit dem Einsatz von AJAX (im Speziellen: dem XMLHttpRequest) wird sich das Thema „Inaktivität der Website“ grundlegend ändern. Selbstverständlich bleiben die Schritte 1 (Clientanforderung an den Server) und 2 (Serververarbeitung) bestehen, jedoch wird die Site durch die Clientanforderung nicht inaktiv, da die Site nicht wie bisher neu geladen wird, sondern ihr vielmehr nur mehr Daten hinzugefügt wer-den – das angezeigte Webdokument bleibt im Browser bestehen und der User kann somit normal weiterarbeiten. Durch dieses Prinzip verringern sich zusätzlich auch die Wartezeiten auf die nachgeladenen Daten, da einerseits nicht mehr das gesamte Webdokument vom Server zurückgeschickt wird und andererseits nur noch ein Teil des (bestehen gebliebenen) Webdokuments neu aufgebaut werden muss. Dies gilt selbstverständlich nur für den Fall, dass der Webdesigner umdenkt:

Anzeigen eines anderen Webdokuments wird ersetzt durch Verändern der Inhalte eines bereits angezeigten Webdokuments.

Anzeigen von zusätzlichen Formularfeldern je nach voriger Auswahl durch den User (bei Formularen): Es wird nicht mehr dasselbe Dokument zum Server zurück-geschickt und vom Server mit zusätzlichen Formularfeldern versehen, sondern dem bestehenden Dokument werden neue Formularfelder hinzugefügt.

usw.

u

u

u

ABBILDUNG 4.1

Durch eine Anfrage des Clients an den Server ent-steht ein nicht unerheblicher Zeitraum, in dem die Website inaktiv ist.

Page 137: Flash cs3, ajax und php

K A P I T E L 4124

Diese Liste lässt sich noch weiter fortsetzen, doch letzten Endes wäre sie nur eine Auflistung von Möglichkeiten, die nie vollständig sein wird. Ich überlasse es Ihnen, lieber Leser, die Möglichkeiten im Rahmen von XHTML zu erkennen und daraus Ihre Schlüsse zu ziehen. Uns geht es darum, wie AJAX mit Flash arbeiten kann bzw. inwie-weit Flash in Hinblick auf AJAX Gefahr läuft, den Rang abgelaufen zu bekommen.

Das Prinzip des „Nachladens“ stellt sich also wie folgt dar – während der gesamten Zeitspanne kann der User ungehindert auf der Website weiterarbeiten:

1. Datenübertragung vom Client zum Server: Die Anforderung des Clients an den Server wird abgeschickt. Dies geschieht im Hintergrund und der User kann weiter auf der Website arbeiten.

2. Datenverarbeitung am Server: Die Anforderung des Clients wird am Server verarbeitet. Da im Allgemeinen nun die Menge an Daten geringer ist als ohne AJAX (jetzt werden nur mehr zusätzliche Daten aufbereitet und nicht mehr das gesamte Webdokument), verringert sich auch die Abarbeitungszeit am Server.

3. Datenübertragung vom Server zum Client: Die vom Server aufbereiteten Daten (XML-basiert) werden zurück an den Client geschickt. An dieser Stelle spielt wie auch zuvor die Menge an zu übertragenden Daten sowie die Anbindung des Users an das Internet eine wesentliche Rolle, jedoch gilt auch hier: Man kann davon ausgehen, dass diese Zeitspanne geringer ist als ohne AJAX, da wiederum nur weniger Daten zum Client zurückgeschickt werden.

4. Anzeigen der Daten auf Userseite: Die nachgeladenen Daten werden durch JavaScript mithilfe des DOM auf der Website dargestellt.

Als Webdesigner muss man an dieser Stelle davon ausgehen, dass dem User ein etwa-iges Nachladen gar nicht bewusst ist – Usability kommt ins Spiel! Sollten Sie davon ausgehen müssen, dass der Nachladevorgang einige Sekunden in Anspruch nimmt, so teilen Sie dies dem User mit. Dem User ist nicht klar, ob die betrachtete Webanwen-dung AJAX-basiert ist (und er somit zu jeder Zeit damit rechnen muss, dass Daten nachgeladen werden) oder nicht.

AJAX & UsabilityAJAX & Usability

Page 138: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 125

4.3.1 Details zum XMLHttpRequest -ObjektNun ist es an der Zeit, das XMLHttpRequest-Objekt aus Programmiersicht einmal genauer zu betrachten. Wie jedes Objekt in der Objektorientierten Programmierung (OOP) besteht es aus Methoden und Eigenschaften:

Methode Beschreibung

abort() Eine aktuelle mit (send()) abgeschickte Serveranfrage wird gestoppt.

getAllResponseHeaders() Auslesen der vom Server zurückgesandten Header-Felder in Form eines String

getResponseHeader("Feldname") Funktioniert wie die Methode getAllResponseHeaders(), nur dass hier über einen Parameter Feldname ein spezielles Feld abgefragt wird. Der Rückgabewert ist vom Typ String.

open("Methode", "URL" [,asyncMo-de[, "Username"[, "Passwort"]]])

Diese Methode wird verwendet, um eine Verbindung zu einem Webserver zu öffnen. (Beachte: Eine konkrete Anfrage an den Server wird zu diesem Zeitpunkt noch nicht gestellt – dies geschieht erst mit der Methode send()). Auf die einzelnen Parameter gehen wir weiter unten genau ein.

send(Content) Hiermit wird die Anfrage an den Server übermittelt und nach der Methode open() ausgeführt. Der Parameter Content ist entweder null (bei einer gewählten Übertragungsmethode GET) oder ein QueryString (bei POST).

ABBILDUNG 4.2

Im Falle des Nachladens von Daten durch AJAX kann der User ungehindert weiter mit der Site arbeiten – es ent-steht keinerlei Inaktivität auf Clientseite!

Page 139: Flash cs3, ajax und php

K A P I T E L 4126

setRequestHeader("Label", "Wert") Diese Methode wird dafür verwendet, etwaige Header-Felder mit bestimmten Werten zu füllen. Beispielsweise wird diese Methode benötigt, um dem Server bekanntzugeben, dass die gesandten Daten Formulardaten sind.

setMimeType("Typ") Hiermit wird der Typ der angeforderten (und per Response zurückzuschickenden) Daten angegeben und zwar wie üb-lich in Form eines Strings wie etwa "text/xml". Da manche Browser (hierunter auch der Internet Explorer) Probleme mit diesem Parameter haben, wird er zumeist einfach wegge-lassen, da beim Anfordern von XML-Daten keine konkrete Kennzeichnung als XML erforderlich ist.

Tabelle 4.1: Methoden des XMLHttpRequest-Objekts

Betrachten wir die Parameter der open()-Methode etwas genauer:

Methode (String): Dieser Parameter kann GET, POST, HEAD oder PUT sein. Typischerweise werden die (bekannteren) Methoden GET oder POST verwendet. HEAD wird verwendet, wenn man nur die Header-Informationen und keine Daten erhalten möchte. PUT verwendet man, wenn beispielsweise Dateien zum Server transferiert werden sollen (doch selbst in diesem Fall wird oft mit der POST-Methode übertragen).

URL (String): Gibt an, welches serverseitige Script (mit anderen Worten, welche PHP-Datei) aufgerufen werden soll. Der Bezug auf das Script kann absolut oder relativ gewählt werden.

asyncMode (Boolean): Kennzeichnet die Art der Abarbeitung der Anfrage an den Server:

asyncMode==true: Die Anfrage wird asynchron verarbeitet, was so viel bedeu-tet, wie dass das Webdokument auf Userseite nicht blockiert wird und somit der User weiter im Dokument arbeite

e Antwort vom Server eingelangt ist – der User kann in der Zwischenzeit nicht im Dokument weiterarbeiten.

Username (String) und Passwort (String): In manchen Fällen sind ein Username ein und Passwort für den Zugriff auf Ressourcen (beispielsweise Scripts in geschützten Ordnern, die nicht für den Zugriff des Internet-Users freigegeben sind) des Webservers von Nöten, die über diese beiden Parameter angegeben wer-den können.

Nachdem wir nun die Methoden des XMLHttpRequest-Objekts kennen, müssen wir uns noch um die Eventhandler und Eigenschaften kümmern:

u

u

u

u

u

u

Page 140: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 127

Eventhandler Beschreibung

onreadystatechange Dieser Handler wird immer dann aufgerufen, wenn sich der Verbindungsstatus (readyState) des XMLHttpRequest-Objekts ver-ändert hat. Mithilfe der Eigenschaft readyState kann der aktuelle Verbindungsstatus verarbeitet werden. In der Regel wird über diesen Eventhandler eine Funktion aufgerufen – man nennt solche Funktionen wie oben beschrieben Callback-Funktionen.

Tabelle 4.2: Eventhandler des XMLHttpRequest-Objekts

Eigenschaft Beschreibung

readyState Hiermit wird der aktuelle Status der Verbindung zum Server abgefragt. Die möglichen Werte werden weiter unten genau behandelt.

responseText Hierin befi nden sich die vom Server nach einer Anfrage übermittelten Daten in Textform.

responseXML Gleich wie responseText, nur dass die Daten eine XML-Struktur auf-weisen. Sollten die Daten nicht in XML-Form vom Server verschickt worden sein, ist diese Eigenschaft null.

status Beinhaltet den HTTP-Status der aktuellen Verbindung als Zahl.

statusText Gleich wie status, nur wird der Status in Form einer Textmeldung ausgegeben (dies muss nicht notwendigerweise der Fall sein – arbeiten Sie deshalb besser mit der Eigenschaft status).

Tabelle 4.3: Eigenschaften des XMLHttpRequest-Objekts

responseText oder responseXML ?Wie Sie anhand der oben stehenden Tabelle sehen, existieren zwei (Formatierungs-)Arten der Rückgabedaten durch den Server: responseText und responseXML. Je nach Anwendungsgebiet verwendet man eine der beiden Varianten. Man sollte jedoch nicht außer Acht lassen, dass AJAX – wie der Name „Asynchronous JavaScript and XML“ schon sagt – darauf spezialisiert ist, mit XML-Daten zu arbeiten. Wann immer es darum geht, komplexere Datenstrukturen darzustellen, sollte man deshalb zu responseXML greifen. Sie sollten sich jedoch bewusst sein, dass eine Abarbeitung von XML für eine Browser-Darstellung mitunter sehr aufwändig sein kann.

Von besonderem Interesse für uns ist auch die Eigenschaft readyState , die alle Infor-mationen über die aktuelle Verbindung zum Server für uns hat:

Wert Bedeutung Beschreibung

0 UNITIALIZED Es besteht derzeit keine geöffnete Verbindung, da die Methode open() noch nicht aufgerufen wurde. Man könnte sagen, dies entspricht dem „Ruhezustand“ des XMLHttpRequest-Objekts.

1 LOADING Zu diesem Zeitpunkt wur-de mit open() bereits ein XMLHttpRequest-Objekt erstellt, jedoch wurde die Methode send() noch nicht aufgerufen.

Page 141: Flash cs3, ajax und php

K A P I T E L 4128

2 LOADED Die Anfrage wurde per send() bereits abgeschickt. Auf den Header der Antwort vom Server kann bereits zugegriffen werden, jedoch nicht auf die zurückge-schickten Daten (diese sind zu diesem Zeitpunkt noch nicht eingetroffen).

3 INTERACTIVE Zu diesem Zeitpunkt sind die ers-ten Daten bereits übermittelt und es treffen noch weitere Daten ein. Man kann zwar schon Daten von responseText und responseXML abfragen, jedoch sind diese noch nicht vollständig.

4 COMPLETED Jetzt sind alle Daten vom Server zum Client übermittelt worden (sofern während der Übermittlung kein Fehler auf-getreten ist). Nun sind auch die Eigenschaften responseText und responseXML mit sämtlichen Daten gefüllt und können voll-ständig verarbeitet werden.

Tabelle 4.4: Werte der Eigenschaft readyState des XMLHttpRequest-Objekts

4.3.2 AJAX im EinsatzWenn wir nun alles Gelesene des XMLHttpRequest-Objekts zusammenfassen, können wir die Abarbeitung dessen wie folgt zusammenfassen:

1. Instanz des XMLHttpRequest-Objekts anlegen: Zunächst muss eine Instanz des XMLHttpRequest-Objekts angelegt werden. Weiter unten sehen wir, dass wir – wie üblich – auf verschiedene Browser eingehen müssen.

2. Callback-Funktion defi nieren: Noch bevor wir uns um eine etwaige Anfrage an einen Server kümmern, müssen wir festlegen, was passieren soll, wenn die Übertragung einmal läuft. Hierzu bedienen wir uns des Eventhandlers onreadystatechange, der uns gemeinsam mit der Eigenschaft readyState genau Auskunft gibt, wie es um die Kommunikation mit dem Server bestellt ist.

3. Verbindung öffnen: Mithilfe der Methode open() wird eine Verbindung zum Server geöffnet, jedoch noch nicht abgeschickt. Solange send() nicht aufgerufen wird, passiert gar nichts.

4. Anfrage abschicken: Dies geschieht wie angesprochen mit send(). Ab diesem Zeitpunkt wird der Server aktiv. Nun gilt es abzuwarten, bis der Server alle angeforderten Daten zurückgeschickt hat – wann dies der Fall ist, sagt uns die Eigenschaft readyState des XMLHttpRequest-Objekts.

Page 142: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 129

5. Auf abgeschlossene Übertragung warten: Wie eingangs erwähnt, ist nun der Eventhandler onreadystatechange am Werkeln. Hat die Eigenschaft readyState den Wert 4, so ist die Kommunikation zwischen Server und Client wieder abgeschlossen und es kann auf die übermittelten Daten zugegriffen werden.

ABBILDUNG 4.3

Die fünf Schritte einer XMLHttpRequest-Anfrage

Kommen wir also zur essenziellen Frage, wie diese fünf Schritte aus Sicht des Pro-grammierers aussehen. Bitte beachten Sie an dieser Stelle, dass wir weiter unten im Buch eine alternative Variante (Listing 4.8) für die Abarbeitung von AJAX-Anfragen besprechen werden, da diese erste Variante im Internet Explorer nur ein einziges Mal ausgeführt werden kann. Jedoch verdeutlicht diese erste Variante sehr schön die (korrekte) Vorgehensweise, sodass ich Sie zunächst über diesen Weg in die Thematik einführen möchte.

In Schritt 1 kümmern wir uns um die Instanzierung des XMLHttpRequest-Objekts. Wie oben schon angedeutet, müssen wir auf verschiedene Browser Rücksicht neh-men. Beispielsweise verhalten sich verschiedene Browser-Generationen des Internet Explorer ebenfalls unterschiedlich. Der „offizielle Weg“ führt über die Instanzierung mittels:

var myXMLHttpRequest = new XMLHttpRequest();

Listing 4.1: Der „offi zielle Weg“ zum Instanzieren eines XMLHttpRequest-Objekts. Im Gegensatz zu allen Mozilla-basierten Browsern (wie etwa dem Firefox) versteht der Internet Explorer diese Instanzierung nicht.

Instanzierung für Firefox & Co.Instanzierung für Firefox & Co.

Page 143: Flash cs3, ajax und php

K A P I T E L 4130

Diese Instanzierung verwenden alle Mozilla-basierten Browser wie etwa der Firefox.

Ein Internet Explorer der Generation 6 und höher erwartet eine Instanzierung wie folgt:

var myXMLHttpRequest = new ActiveXObject("MSXML2.XMLHTTP");

Listing 4.2: Instanzierung für den Internet Explorer 6 und höher

Ältere Internet Explorer hingegen möchten folgende Instanzierung:

var myXMLHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");

Listing 4.3: Instanzierung für Internet Explorer-Versionen kleiner als 6

Fasst man diese drei Wege in einem gemeinsamen Script zusammen, so bedient man sich gerne der Methode „try & catch“, wo mithilfe des try-Befehls eine Variante ausprobiert wird. Sollte diese fehlschlagen, so wird der Programmblock im catch-Abschnitt ausgeführt:

try { var myXMLHttpRequest = new XMLHttpRequest(); }

catch(error) {

try { var myXMLHttpRequest = new ActiveXObject("MSXML2.XMLHTTP"); }

catch(error) { var myXMLHttpRequest = new ActiveXObject("Microsoft.XMLHTTP"); }

}

}

Listing 4.4: Nachdem alle Möglichkeiten von Browsern berücksichtigt („durchprobiert“) wurden, beinhaltet die Variable myXMLHttpRequest eine gültige Instanz eines XMLHttpRequest-Objekts.

Idealerweise verpackt man dieses Script in eine Funktion, die als Rückgabewert die Instanz liefert.

In Schritt 2 kümmern wir uns darum, dass wir clientseitig in der Lage sind, auf die abgeschlossene Übertragung der vom Server angeforderten Daten reagieren zu kön-nen.

myXMLHttpRequest.onreadystatechange = function() {

switch(myXMLHttpRequest.readyState) {

case 0:

case 1:

case 2:

case 3: return;

case 4: showResponse(); return;

Instanzierung für IE-Versionen 6

und höher

Instanzierung für IE-Versionen 6

und höher

Instanzierung für IE-Versionen

kleiner als 6

Instanzierung für IE-Versionen

kleiner als 6

Page 144: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 131

}

}

Listing 4.5: Der Eventhandler onreadystatechange hilft uns, auf Änderungen in unserem XMLHtt-pRequest-Objekt zu reagieren. Lediglich der Fall 4 (Übertragung aller vom Server angeforderten Daten abgeschlossen) ist für uns interessant.

Mithilfe einer switch-Anweisung werden alle Möglichkeiten der Eigenschaft ready-State durchgegangen. Für die Fälle 0–3 macht die Funktion nichts, erst im Fall 4 rea-giert sie und ruft ihrerseits die Funktion showResponse auf. Diese Funktion erledigt dann die Ausgabe der vom Server angeforderten und vollständig zurückgelieferten Daten.

In Schritt 3 wollen wir die soeben erzeugte Instanz öffnen und bedienen uns daher der open-Methode:

myXMLHttpRequest.open("GET", "testrequest.htm", true);

Listing 4.6: Anfrage für das Dokument testrequest.htm per POST im Asynchron-Modus (Parameter true)

Schritt 4 schickt die Anfrage ab:

myXMLHttpRequest.send(null);

Listing 4.7: Absenden der Anfrage an den Server: „Schick mir das Dokument testrequest.htm“

Zusammengefasst in einem Beispiel könnte das wie folgt aussehen: Per Klick auf einen Button fordern wir den Server auf, uns die Datei testrequest.htm zu schicken. Nachdem wir das Dokument erhalten haben, geben wir es in ein Textfeld (<textarea>) aus. Gleichzeitig erzeugen wir ein zweites Textfeld, wo wir uns jeweils den aktuellen Wert der Eigenschaft readyState ausgeben lassen. Dies ist zwar nicht erforderlich, jedoch ist es gut zu wissen, welchen Status readyState gerade einnimmt (speziell hinsicht-lich der Fehlersuche ist eine solche Ausgabe immer ganz geschickt).

Page 145: Flash cs3, ajax und php

K A P I T E L 4132

Bitte beachten Sie, dass das obige Beispiel im Internet Explorer bei einem wiederhol-ten Klick auf den „Klick mich!“-Button keine neuerliche Anfrage an den Server stellt. Dieses Problem lösen wir weiter unten.

Dieses Beispiel war ja noch nicht sonderlich aufregend, da uns nicht so recht bewusst ist, dass wir während der Anfrage ohne weiteres auf der Seite weiterarbeiten können (was hätten wir neben dem Klicken auf den „Klick mich!“-Button auch tun sollen?). Interessanter wird die Sache aber dann, wenn es uns bewusst wird, dass ohne Neuladen der Seite immer Daten vom Server abgefragt werden können.

Problem bei der Mehrfach-nutzung eines Eventhandlers

im IE

Problem bei der Mehrfach-nutzung eines Eventhandlers

im IE

ABBILDUNG 4.4

Unser Beispiel vor und nach dem Klicken des „Klick

mich!“-Buttons. Wie Sie sehen, wird das hinzu-

geladene Dokument als reiner String im Textfeld

ausgegeben. Das Dokument finden Sie unter dem Namen

ajax01.htm im Kapitel zum Buch auf der Buch-CD.

Page 146: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 133

Denken wir beispielsweise an ein Chat-System in XHTML: Angenommen, alle einge-henden Messages von Usern werden in einer Datenbank gespeichert. Sobald ein User eine Message eingibt, muss diese an den Server geschickt und dort in der Datenbank gespeichert werden. Würden wir nicht AJAX verwenden, müssten wir nun aus XHTML ein Formular abschicken, um wieder Kontakt mit dem Server aufzunehmen – unser Chat wäre für diesen Zeitraum inaktiv. Erst wenn uns der Server das aktualisierte Dokument wieder zurückgeschickt hat (darin sollte sich dann auch unsere so eben eingegebene Message wiederfinden lassen), können wir weiter chatten. Zusätzlich müssten wir in regelmäßigen Abständen den Server abfragen, ob neue Messages ein-getroffen sind – auch hier ist unser Chat wieder inaktiv. Verwenden wir jedoch AJAX, sind wir in der Lage, jederzeit weitere Daten (= Messages) vom Server abzufragen, ohne dabei jedes Mal die Seite neu zu laden.

Problem im Internet Explorer: Mehrfachnutzung eines XMLHttpRequest-EventhandlersLeider tritt im Internet Explorer ein Problem mit der Mehrfachnutzung eines Eventhandlers einer XMLHttpRequest-Instanz auf: Wird eine global definierte XMLHttpRequest-Instanz mehr als einmal mit der send-Methode dazu aufgefordert, Daten vom Server anzufordern, geschieht dies leider nicht, da (global definierte) Eventhandler nicht mehr abgearbeitet werden. Aus diesem Grund muss nach jedem Aufruf der open-Methode der Eventhandler neu zugewie-sen werden.Im Firefox und Opera tritt dieses Phänomen nicht auf.

Das oben geschilderte Problem lässt sich relativ einfach lösen, indem der Eventhandler der XMLHttpRequest-Instanz nach jeder open-Anforderung neu zugewiesen wird:

var myXMLHttpRequest = createRequestObject();

function sendRequest() {

myXMLHttpRequest.open("GET", "testrequest.htm", true);

myXMLHttpRequest.onreadystatechange = handleRequest;

myXMLHttpRequest.send(null);

}

function createRequestObject() {

try { var myRequest = new XMLHttpRequest(); }

catch(error) {

try { var myRequest = new ActiveXObject("MSXML2.XMLHTTP"); }

catch(error) { var myRequest = new ActiveXObject("Microsoft.XMLHTTP"); }

}

Page 147: Flash cs3, ajax und php

K A P I T E L 4134

return myRequest;

}

function handleRequest() {

document.forms["frmAjax"].elements["msgStatus"].value += "readyState changed: "+myXMLHttpRequest.readyState+"\n";

switch(myXMLHttpRequest.readyState) {

case 0:

case 1:

case 2:

case 3: return;

case 4: showResponse(); return;

}

}

function showResponse() {

document.forms["frmAjax"].elements["msgOut"].value = myXMLHttpRequest.responseText;

}

Listing 4.8: Alternatives Listing für eine Mehrfachanwendung einer XMLHttpRequest-Instanz, die auch den Internet Explorer zufriedenstellt. Die entsprechende Datei fi nden Sie auf der Buch-CD im Buchkapitel unter dem Namen ajax01_alternativ.htm.

Im Script sehen Sie den Ablauf und folgende Änderungen gegenüber unserer ersten Variante:

1. Es wird zwar eine globale Variable myXMLHttpRequest angelegt und diese mittels createRequestObject defi niert. Somit liegt die Variable myXMLHttpRequest global vor.

2. Sobald der User den Button „Klick mich!“ anklickt, wird die Funktion sendRequest aufgerufen (das ist ebenfalls noch nicht neu – das hatten wir vorher auch schon). Innerhalb der Funktion wird nun mittels open der globalen Variable myXMLHttpRequest mitgeteilt, dass eine Anforderung an den Server ansteht.

3. Ebenfalls innerhalb von sendRequest wird in der darauffolgenden Zeile der Eventhandler für dieses Objekt defi niert:

myXMLHttpRequest.onreadystatechange = handleRequest;

Page 148: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 135

Geändert hat sich die Defi nition des Eventhandlers: Entgegen der ursprünglichen Variante wird nicht mehr mit einer sogenannten nativen Funktion gearbeitet, sondern eine Funktion angegeben, die im Falle dieses Events aufgerufen wird (in unserem Fall ist dies die Funktion handleRequest).

Alles andere ist unverändert geblieben. Wo liegen also die Nachteile dieser Variante bzw. warum haben wir nicht sofort diese Variante entwickelt? Nun, der Nachteil liegt einzig und allein in der Performance: In der neuen Variante wird mit jedem send-Request-Aufruf der Eventhandler der XMLHttpRequest-Instanz neu zugewiesen und dies benötigt Zeit. Diese Problematik wird uns zwar in dieser Anwendung nicht auf den Kopf fallen, in zeitkritischen Anwendungen jedoch schon. Leider kommen wir nicht herum, so zu arbeiten und deshalb mein Tipp: Verwenden Sie die soeben neu entwickelte Variante, wo der Eventhandler nach jedem Aufruf der open-Methode neu zugewiesen wird.

Informationen an die Serverseite übermitteln

In vielen Fällen ist es notwendig, diverse Informationen von Clientseite auf Serverseite zu übermitteln. In XHTML war das sehr einfach: Man musste lediglich ein Formular bemühen und schon konnte man per GET oder POST Daten (Formularfeldinhalte) zum Server schicken. Diese Varianten stehen uns in AJAX ebenfalls zur Verfügung, wobei wir jedoch in beiden Fällen einen Querystring zusammenbasteln müssen, der danach entweder per GET (als Anhängsel zur aufzurufenden Datei) oder per POST (im Body der send-Methode) an den Server übergeben wird. Im Übrigen gelten für den Versand dieselben Regeln wie bei Formularen in XHTML-Dokumenten: Werden die Daten per GET übertragen, so werden diese an die URL angehängt; werden sie hingegen per POST versandt, befinden sich die Formulardaten im HTTP-Header.

Gesetzt den Fall, wir programmieren ein kleines Kontaktformular und möchten zwei Werte an den Server übermitteln: eine E-Mail-Adresse und eine Nachricht. Ein ent-sprechender Querystring würde dann folgendes Aussehen haben:

var querystring = "[email protected]&Nachricht=TEST";

bzw. (wenn wir die Werte aus einem Formular mit dem Namen frmKontakt über-nehmen):

var querystring = "Email="+document.forms["frmKontakt"].elements["Email"].value+"&Nachricht="+document.forms["frmKontakt"].elements["Nachricht"].value;

Listing 4.9: Zusammenbasteln eines Querystrings aus gegebenen Formularfeldern „E-Mail“ und „Nach-richt“

Übergeben wir nun diese Daten an den Server, so müssen wir die zwei Varianten der Übertragungsmethode wie folgt anweisen:

GET oder POST?GET oder POST?

Page 149: Flash cs3, ajax und php

K A P I T E L 4136

GET-Variante:

contactXMLHttpRequest.open("GET", "includes/kontakt.inc.php?"+querystring, true);

contactXMLHttpRequest.send(null);

Hierbei ist auf drei Punkte zu achten:

In der open-Methode muss die Übertragungsmethode GET gewählt werden.

An den Namen der am Server aufzurufenden Funktion wird ein Querystring im Format Feld=Wert angehängt.

Der Body in der send-Methode hat den Wert null.

POST-Variante:

contactXMLHttpRequest.open("POST", "includes/kontakt.inc.php", true);

contactXMLHttpRequest.setRequestHeader ("Content-Type","application/x-www-form-urlencoded");

contactXMLHttpRequest.send(querystring);

Entgegen der GET-Variante wird hier etwas anders gearbeitet:

In der open-Methode muss die Übertragungsmethode POST gewählt werden.

An den Namen der am Server aufzurufenden Funktion wird nichts ange hängt.

Es muss dem Server mittels der setRequestHeader-Methode mitgeteilt werden, dass die gesendeten Daten Formulardaten sind – dies geschieht durch die Definition des Content-Type als application/x-www-form-urlencoded.

Der Body in der send-Methode beinhaltet den Querystring im Format Feld=Wert.

Auf zu einem konkreten Beispiel, wenn wir schon von einem Kontaktformular spre-chen:

u

1.

2.

3.

u

1.

2.

3.

4.

Page 150: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 137

Ziel ist es, per AJAX ein serverseitiges Script aufzurufen, das eine E-Mail an [email protected] schickt, worin der Name des Absenders und deren Nachricht zu finden sind.

Der HTML-Part ist relativ unspektakulär – ein paar DIVs, ein Formular mit zwei Feldern und zwei Buttons:

...

<script language="javascript" type="text/javascript" src="js/common.inc.js"></script>

<script language="javascript" type="text/javascript" src="js/kontakt.inc.js"></script>

...

<form name="frmKontakt" id="frmKontakt" action="">

<div id="msgOut"></div>

<div class="label">Ihre Email-Adresse:</div>

<div class="fi eld"><input type="text" name="Email" id="Email" /></div>

<div class="cleaner"></div>

<div class="label">Ihre Nachricht an mich:</div>

<div class="fi eld"><textarea name="Nachricht" cols="50" rows="10" id="Nachricht"></textarea></div>

<div class="cleaner"></div>

<div class="button">

<input type="button" name="submitIt" id="submitIt" value="Abschicken

E-Mails versen-den mit AJAX und PHP

E-Mails versen-den mit AJAX und PHP

ABBILDUNG 4.5

Ein einfaches Kontakt-formular für die Eingabe von E-Mail-Adresse und Nachricht. Wir können wählen, ob die Daten per GET oder POST übertragen werden.

Page 151: Flash cs3, ajax und php

K A P I T E L 4138

(GET)" onclick="sendContact('GET');" />

<input type="button" name="submitIt2" id="submitIt2" value="Abschicken (POST)" onclick="sendContact('POST');" />

</div>

</form>

...

Listing 4.10: Wir fi nden ein (noch) leeres <div id="msgOut"> zur Ausgabe der Statusmeldung nach dem Versenden der E-Mail sowie zwei Buttons, die jeweils dieselbe Funktion sendContact mit zwei unterschiedlichen Parametern aufrufen.

Der JavaScript-Code ist komplett in zwei externe Dateien namens common.inc.js und kontakt.inc.js ausgelagert worden, um den XHTML-Code übersichtlicher zu halten bzw. den JavaScript-Code für weitere Beispiele einfach verknüpfen zu können.

Das derzeit noch leere <div id="msgOut"> wird im Weiteren dafür verwendet, dass wir eine Meldung nach dem Versenden der E-Mail ausgeben, ob der Versand erfolg-reich oder eben nicht erfolgreich war.

Des Weiteren sehen Sie, dass wir eine Funktion sendContact in Verwendung haben, an die über einen Parameter übergeben wird, mit welcher Methode wir die Daten an den Server übergeben werden: GET oder POST.

Die Datei common.inc.js beinhaltet lediglich die Auswahl des korrekten XMLHttp-Request-Objekts aus Listing 4.4. In kontakt.inc.js sind die für das Beispiel spezifischen Codes abgelegt, worin zunächst einmal eine Variable für die Instanz des XMLHttp-Request-Objekts angelegt wird:

var contactXMLHttpRequest;

function sendContact(method) {

contactXMLHttpRequest = createRequestObject();

contactXMLHttpRequest.onreadystatechange = handleRequestContact;

var querystring = "Email="+document.forms["frmKontakt"].elements["Email"].value+"&Nachricht="+document.forms["frmKontakt"].elements["Nachricht"].value+"&Methode="+method;

if(method.toLowerCase()=="get") {

contactXMLHttpRequest.open("GET", "includes/kontakt.inc.php?"+querystring, true);

contactXMLHttpRequest.send(null);

}

else {

contactXMLHttpRequest.open("POST", "includes/kontakt.inc.php", true);

Page 152: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 139

contactXMLHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

contactXMLHttpRequest.send(querystring);

}

}

function showResponse2() {

document.getElementById("msgOut").innerHTML = contactXMLHttpRequest.responseText;

}

function handleRequestContact() {

switch(contactXMLHttpRequest.readyState) {

case 0:

case 1:

case 2:

case 3: return;

case 4: showResponse2(); return;

}

}

Listing 4.11: Code der Datei kontakt.inc.js

Die Funktion sendContact mit dem Parameter method dient dazu, je nach geklicktem Button die Nachricht entweder per GET oder per POST zu versenden (dies geschieht in der if-Anweisung). Bevor eine Auswahl für GET oder POST geschieht, wird erst einmal dem XMLHttpRequest-Objekt ein Eventhandler zugewiesen. (dieser ist ebenfalls schon bekannt – siehe Listing 4.8 in leicht abgeänderter Form: Aufruf von showResponse2 anstatt showResponse, da wir eine andere Funktion für den Fall der abgeschlossenen Übertragung verwenden.) Danach werden wie oben besprochen im Fall von GET die Formularfeldwerte an die URL der am Server aufzurufenden Datei angehängt und der Body in der send-Methode leergelassen. Bei POST wird an die URL nichts angehängt, dafür werden die Formularfeldwerte in den Body der send-Anweisung gegeben. Bei POST muss ebenfalls noch angegeben werden, dass es sich bei den Daten um Formu-larfelder handelt (Content-Type=application/x-www-form-urlencoded).

Um dem User nach dem Versenden der E-Mail auch eine Erfolgs- (oder Misserfolgs-)Meldung auszugeben, wird in der Funktion showResponse2 auf das weiter oben angesprochene <div id="msgOut"> zugegriffen und dort hinein (innerHTML) geschrieben, was uns die (serverseitige) Datei kontakt.inc.php zurückliefert. Also wer-fen wir mal einen Blick auf diese Datei:

Page 153: Flash cs3, ajax und php

K A P I T E L 4140

<?php

function create_email_header($name, $value) {

return ($name && $value) ? "$name: $value\r\n" : "";

}

function sendContact() {

$success = "";

if(count($_REQUEST)>0) {

$REQUESTdata = $_REQUEST;

$msg = "Kontaktaufnahme auf fl ashphpajax.beelzebuben.at.\nDie eingegebenen Daten waren:\n\n";

foreach($REQUESTdata as $itm=>$val) { $msg.= "\t$itm: $val\n"; }

$mailto = "[email protected]";

$mailfrom = "[email protected]";

$headers = «»;

$cc_email = $REQUESTdata[«Email»];

$bcc_email = «[email protected]»;

$headers .= create_email_header(«Cc», $cc_email);

$headers .= create_email_header(«Bcc», $bcc_email);

$headers .= create_email_header(«From», $mailfrom);

if(!mail($mailto, «- Kontaktaufnahme auf fl ashphpajax.beelzebuben.at -», $msg, $headers)) { $success = $msg; }

else { $success = «OK»; }

}

return $success;

}

$msgOut = sendContact();

if($msgOut=="OK") { echo('<p class="success">Ihre Anfrage wurde ERFOLGREICH an uns versandt.</p>'); }

else { echo('<p class="error">Ihre Anfrage wurde NICHT ERFOLGREICH an uns versandt.</p>'); }

?>

Listing 4.12: Code der Datei kontakt.inc.php, die rein serverseitig liegt und der User nie zu Gesicht bekommt

Page 154: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 141

Wird diese Datei serverseitig aufgerufen, wird nach dem Aufruf von sendContact() (dies geschieht im unteren Teil des Scripts mittels $msgOut = sendContact();) zunächst einmal überprüft, ob an die Datei Formulardaten gleich welcher Art überge-ben wurden:

...

if(count($_REQUEST)>0) {

...

Der Nachrichtentext wird in der Variablen $msg gespeichert, worin zunächst ein kur-zer Infotext geschrieben wird:

$msg = "Kontaktaufnahme auf fl ashphpajax.beelzebuben.at.\nDie eingegebenen Daten waren:\n\n";

Die weiteren Inhalte werden über eine foreach-Schleife aus den übergebenen Formu-larfelddaten gelesen und zeilenweise in den Text geschrieben.

Die Funktion create_email_header dient dazu, die Header-Informationen für eine E-Mail korrekt zu formatieren (dieses Script ist schon quasi Standard – vielen Dank an www.php.net). Sollte zu guter Letzt das Abschicken der E-Mail mittels der mail-Funktion geklappt haben, wird in $success der Wert „OK“ geschrieben, ansonsten der Inhalt der E-Mail (um etwaige Tests durchführen zu können). Selbstverständlich könnte anstatt eines Textes auch einfach der Rückgabewert (true oder false) von mail() geschrieben werden – in diesem Fall hätte man jedoch keine Möglichkeit, zu überprüfen, ob der Nachrichtentext überhaupt korrekt geschrieben wurde. Der User selbst erhält die E-Mail in CC ($cc_email = $REQUESTdata["Email"];).

Ganz unten im Script wird zuletzt noch überprüft, ob in $msg der Wert „OK“ steht (und somit die E-Mail erfolgreich versandt wurde) – wenn ja, wird in das PHP-Dokument per echo der XHTML-Code <p class="success">Ihre Anfrage wurde ERFOLG-REICH an uns versandt.</p> geschrieben, ansonsten <p class="error">Ihre Anfrage wurde NICHT ERFOLGREICH an uns versandt.</p>. Genau dieser XHTML-Code stellt also den Wert dar, der von AJAX vom Server angefordert und in dem Tag <div id="msgOut"> ausgegeben wird.

Wenn ich also eine E-Mail an mich selbst schicke, sieht unser Beispiel wie folgt aus:

Page 155: Flash cs3, ajax und php

K A P I T E L 4142

Die Ergebnis-Mails (einmal per GET, einmal per POST verschickt) sehen Sie in den nachfolgenden Abbildungen (mit Umlauten gibt’s so kleine Probleme, da wir nicht den korrekten Zeichensatz definiert haben):

ABBILDUNG 4.6

AJAX in Verbindung mit einem geeigneten PHP-Script

verschickt E-Mails.

ABBILDUNG 4.7

Die empfangenen E-Mails – hat also super funktioniert!

Um den Code so einfach wie möglich zu halten, habe ich bewusst auf Formatierungen der E-Mail verzichtet – selbstverständlich könnte die E-Mail auch als HTML-E-Mail verschickt werden. PHP macht auf Serverseite keine Unterscheidung, ob die Seite nur serverseitig aufgerufen wird oder doch als XHTML-Dokument zum User übertragen

Page 156: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 143

wird. Ob nun AJAX die Seite anfordert oder der User selbst (beispielsweise durch einen Klick auf einen Link), spielt keine Rolle.

Darstellen des Ladezustands

In letzter Zeit findet man auf AJAX-basierten Websites immer öfter eine Anzeige des Ladezustands, da der User im Fall von AJAX nichts davon mitbekommt, dass Daten an den Server übertragen werden – im Gegensatz zu Standard-XHTML-Anwendungen, wo der weitere Ablauf der Site blockiert wird. Deshalb ist es als Entwickler nicht unge-schickt, dem User eine entsprechende Meldung am Bildschirm auszugeben. Ideal dafür geeignet sind die verschiedenen Stati der readyState-Eigenschaft, denn solange rea-dyState nicht den Wert 4 erreicht hat, ist die Übertragung der Daten noch im Gange.

Erweitern wir also unser zuvor entwickeltes Kontaktformular um eine Grafik, die immer dann eingeblendet wird, wenn eine aktive Übertragung stattfindet. Dies sollte wie folgt am Bildschirm des Users aussehen:

ABBILDUNG 4.8

Verwenden eines „Abdunklers“, um dem User eine gerade stattfindende Übertragung zu verdeut-lichen

Abdunkler oder Sanduhr?An dieser Stelle kommt wieder Usability ins Spiel: Wann soll man bei AJAX-Anwendungen einen Abdunkler, wann eine Sanduhr (oder etwas Ähnliches) verwenden? Nun, Abdunkler sollten immer dann zum Einsatz kommen, wenn dem User verdeutlicht werden soll, dass er „jetzt bitte einen Moment warten“ soll. Eine Sanduhr als Grafik neben beispielsweise dem Abschicken-Button hinge-gen soll nur einen laufenden Prozess verdeutlichen – der User kann aber ungestört weiterarbeiten.Bitte sehen Sie davon ab, den Cursor in eine Sanduhr zu „verwandeln“, denn das hätte zur Folge, dass der User meint, er dürfe nun gar nichts mehr tun – da könnten Sie den Abdunkler auch gleich verwenden ;=).

Page 157: Flash cs3, ajax und php

K A P I T E L 4144

Um den Abdunkler in die Realität umzusetzen, bediene ich mich eines teiltranspa-renten Bilds in Form einer PNG-Datei (Schwarz mit 70% Deckkraft) sowie eines vor-erst unsichtbaren Layers namens abdunkler:

div#abdunkler {

visibility:hidden;

text-transform:uppercase;

position:absolute;

width:100%;

height:100%;

padding:10px;

background-image:url(../../images_standard/abdunkler70.png);

background-repeat:repeat;

font-size:16px;

color:white;

}

Listing 4.13: CSS-Defi nition des Layers

<div id="abdunkler">Bitte einen Moment Geduld - Ihre Anfrage wird gerade an uns weitergeleitet...</div>

Listing 4.14: XHTML-Code des Layers mit einem entsprechenden Mitteilungstext an den User. Dieser Layer wird vorerst durch die obige CSS-Defi nition ausgeblendet.

Um diesen Layer während der Übertragung anzeigen zu lassen, verwenden wir den Eventhandler des XMLHttpRequest-Objekts und modifizieren ihn ein wenig:

function handleRequestContact() {

switch(contactXMLHttpRequest.readyState) {

case 0:

case 1: return;

case 2: showHideDiv("abdunkler",true); return;

case 3: return;

case 4:

showHideDiv("abdunkler",false);

showResponse2();

return;

}

}

Listing 4.15: Die adaptierte Eventhandler-Funktion

Page 158: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 145

Anstatt im Fall 2 (die send-Methode wurde aufgerufen) einfach nur die Funktion mit einem return abzubrechen (die Fälle 0 und 1 tun dies indes immer noch), rufen wir eine Funktion auf, die über die Funktion showHideDiv den Abdunkler-Layer einblen-det:

function showHideDiv(divname,isVisible) {

if(isVisible) { document.getElementById(divname).style.visibility = "visible"; }

else { document.getElementById(divname).style.visibility = "hidden"; }

}

Listing 4.16: Die Funktion showHideDiv blendet – je nach Wert der Variable isVisible – einen über die Variable divname defi nierten Layer ein oder aus.

Dieser Layer wird im Fall von readyState==4 über dieselbe Funktion wieder ausge-blendet.

In unserem Fall wäre es genauso möglich, bereits bei readyState==1 (die open-Methode wurde aufgerufen) den Layer einzublenden, da open und danach send in unserem Fall durch dieselbe Funktion sendContact aufgerufen werden und es somit keine Unterbrechung zwischen open und send gibt.

Bevor wir in den Workshops zu komplexeren Themen übergehen, werden wir einige Anwendungen für AJAX entwickeln, damit Sie einen tieferen Einblick gewinnen kön-nen.

Anwendung 1 – Mini-Website

In diesem Beispiel werden wir eine Mini-Website entwickeln, wo sich die Hauptseite nicht ändert, sondern nur per AJAX Dokumente hinzugeladen werden.

Wie funktioniert eine Website bisher:

Variante 1: Es wird eine Frame-Site verwendet.

Diese Variante ist mittlerweile zwar verpönt (und in XHTML Strict auch nicht mehr standardisiert), fi ndet in manchen Fällen aber immer noch Verwendung. Durch Klick auf einen Link wird in einen Frame ein neues Dokument geladen. Nachteilig ist, dass die Site so lange nicht verwendbar ist, solange dieses Dokument nicht geladen ist.

Variante 2: Es wird ein IFrame verwendet.

Die Möglichkeit der IFrames gibt es zwar auch schon länger, jedoch ist die Verwendung der IFrames erst in den letzten Jahren so wirklich in Mode gekommen, da alle gängigen Browser mittlerweile IFrames unterstützen. IFrames funktionieren wie Frames, jedoch mit dem Unterschied, dass kein Frameset benötigt wird – ein IFrame wird wie eine Grafi k direkt im XHTML-Code platziert.

u

u

Page 159: Flash cs3, ajax und php

K A P I T E L 4146

Variante 3: Für jedes Inhaltselement (Navigationspunkt) wird die Site komplett neu geladen.

Dies ist die Standardvariante, die auch vom XHTML-Standard gutgeheißen wird. Nachteilig ist, dass immer wiederkehrende Elemente permanent neu geladen werden und sich so die Ladezeit der Site erhöht. Zwar werden Grafi ken im Cache gespeichert und müssen so nicht neu vom Server angefordert werden, jedoch gilt dies nicht für Texte etc. Somit fällt ein nicht zu geringer Brocken an Daten an, die mit jedem Klick redundant übertragen werden.

Variante 4: Ein und dieselbe Seite wird serverseitig mit geänderten Inhalten gefüllt.

Typischerweise arbeiten Content Management Systeme (CMS) auf diese Weise: Es existiert lediglich eine Indexseite mit integrierten Platzhaltern. Diese Platzhalter werden serverseitig durch geeignete (PHP oder ähnliche) Programmierung mit Inhalten gefüllt, die vorzugsweise aus einer Datenbank generiert werden. Nachteilig ist wie in Variante 3 die Tatsache, dass die Seite immer wieder neu geladen wird, da ja die Inhalte auf Serverseite generiert werden.

Der Vorteil unseres Systems wird sein, dass wir unsere Seite nie neu laden müssen, sondern nur geänderte Inhalte vom Server auf Anfrage geliefert bekommen, die wir dann mithilfe des DOM an vorgegebene Stellen im Dokument (Platzhalter) schreiben werden.

Sehen wir es uns einfach mal an.

u

u

ABBILDUNG 4.9

Eine einfache Website mit vier Links und einem

Content-Bereich. Die Gestaltung haben wir erst mal außer Acht gelassen,

um nicht den Fokus auf das Wesentliche zu verlieren.

Page 160: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 147

Wenn wir kurz zusammenfassen, benötigen wir folgende Dokumente:

1. index.htm: Die „Startseite“ oder „Homepage“ unserer Mini-Website. Hierin befi nden sich die Links sowie ein Container (ein <div>) für die Darstellung der Inhalte.

2. home.htm: Der Begrüßungstext, der unseren User auf der Website willkommen heißt. Dieses Dokument wird als Erstes automatisch in den leeren Container geladen. An diesem Dokument werden wir lernen, wie man nach erfolgtem Laden der index.htm ein Dokument per AJAX in den leeren Container lädt.

3. ueberuns.htm: Eine statische Seite ohne spezielle Features. Sie wird uns gute Dienste leisten, indem wir lernen, wie man ein statisches Dokument auf Klick lädt.

4. kontakt.php: Entgegen ueberuns.htm ist dies eine dynamische Seite mit der Möglichkeit des Versendens einer Nachricht an einen gegebenen Empfänger. An ihr zeigen wir auf, wie ein dynamisches Dokument per AJAX geladen und von sich aus wiederum AJAX zum Versenden von Nachrichten funktioniert. Das Dokument kontakt.php ist im Wesentlichen mit dem Dokument vom letzten Beispiel identisch.

5. links.php: Ebenfalls ein dynamisches Dokument – in diesem Fall wird eine Datenbank abgefragt und die Ergebnisse (Links) werden in Form einer Liste wiedergegeben.

Zunächst kümmern wir uns um unser Gerüst index.htm:

...

<div id="navigation">

<div class="navitem"><a href="#" id="home">Home</a></div>

<div class="navitem"><a href="#" id="ueberuns">&Uuml;ber uns</a></div>

<div class="navitem"><a href="#" id="kontakt">Kontakt</a></div>

<div class="navitem"><a href="#" id="links">Links</a></div>

<div class="cleaner"></div>

</div>

<div id="content"></div>

...

Listing 4.17: Auszug aus dem Listing der Datei index.htm unserer Mini-Website (wie üblich zu fi nden auf der beiliegenden Buch-CD)

In diesem Script existiert nichts Aufregendes – einzig das (noch) leere <div id="content"> für das nachträgliche Einfügen von Inhalt. Die vier Navigationsele-mente sind bewusst ohne onclick-Ereignis definiert, da wir in diesem Beispiel auch

Page 161: Flash cs3, ajax und php

K A P I T E L 4148

sehen werden, wie man im Nachhinein (nämlich nach dem vollständigen Laden des Dokuments) einem gegebenen Element ein Ereignis zuweisen kann. Des Weiteren hat diese Vorgehensweise den Vorteil, dass der User erst dann auf einen Link klicken kann, wenn die Site vollständig geladen ist (was man ihm aus Usability-Gründen eventuell mitteilen sollte …). Das Element der Klasse cleaner dient dazu, dass die float-Eigenschaft der Elemente der Klasse navitem wieder beendet wird. Ein Blick auf die CSS-Definition verdeutlicht dies:

div.navitem {

fl oat:left;

margin-right:20px;

}

div.cleaner {

clear:both;

}

Listing 4.18: CSS-Defi nition für <div> der Klassen navitem und cleaner

Die Eigenschaft float:left bewirkt, dass DIV-Tags nebeneinander angeordnet wer-den (und zwar mit dem Platz, den sie benötigen – es sei denn, Sie geben eine Breite an), clear:both bewirkt, dass eine float-Eigenschaft (egal ob left oder right) wieder eliminiert wird. Wir benötigen einen solchen „Cleaner“, damit das darauffol-gende Element (bei uns ist das das DIV mit der id=content) nicht auch rechts neben den Navigationselementen platziert wird. Falls Sie mehr über CSS erfahren möchten, so kann ich Ihnen die einschlägige Literatur aus dem Verlag Addison-Wesley nur ans Herz legen.

Nun müssen wir uns überlegen, wie den Links die onclick-Ereignisse zugewiesen werden können. Wie oben erwähnt, wollen wir eine Zuweisung erst nach dem voll-ständigen Laden des Dokuments. Hierzu bedienen wir uns des onload-Ereignisses des window-Objekts:

window.onload = init;

function init() {

navigateTo("home.htm"); //Homepage laden

document.getElementById("home").onclick = function() { navigateTo("home.htm"); }

document.getElementById("kontakt").onclick = function() { navigateTo("kontakt.htm"); }

document.getElementById("ueberuns").onclick = function() { navigateTo("ueberuns.htm"); }

Page 162: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 149

document.getElementById("links").onclick = function() { navigateTo("links.php"); }

}

Listing 4.19: Wir nutzen das onload-Ereignis des window-Objekts, um nach dem vollständigen Laden des Dokuments im Browser des Users den Links ein onclick-Ereignis zuzuweisen. Des Weiteren wird als „Homepage“ das Dokument home.htm geladen.

Wir gehen den ausführlichen Weg und weisen dem Ereignis onload vom window-Objekt zunächst eine Funktion init zu und definieren diese Funktion im nächsten Schritt. Innerhalb von init wird zunächst eine Funktion navigateTo mit dem Para-meter home.htm aufgerufen – diese Funktion wird im Weiteren dafür sorgen, dass ein Dokument per AJAX in den Container content geladen wird. Genau diese Funktion verwenden wir auch in den onclick-Ereignissen der einzelnen Links. Wenn wir einen solchen Eventhandler genauer betrachten, finden wir Folgendes:

document.getElementById("home").onclick = function() { navigateTo("home.htm"); }

Zunächst wird über die Methode getElementById auf ein benanntes Element (hier: "home") zugegriffen und diejenige Methode definiert (hier: onclick), die wir benö-tigen. Danach wird dieser Methode eine Funktion zugewiesen, die beim Aufruf des Ereignisses abgearbeitet werden muss. In unserem Fall sorgt diese Funktion lediglich dafür, dass eine weitere Funktion namens navigateTo aufgerufen wird. Kommen wir also zu navigateTo:

function navigateTo(URL) {

myXMLHttpRequest = createRequestObject();

myXMLHttpRequest.onreadystatechange = handleRequest;

myXMLHttpRequest.open("GET", URL, true);

myXMLHttpRequest.send(null);

}

Listing 4.20: Listing der Funktion navigateTo, die die Schnittstelle zu AJAX bildet

Der Inhalt der Funktion ist aus den vorigen Beispielen bekannt: Es wird eine Ins-tanz des XMLHttpRequest-Objekts gebildet. (Die Funktion createRequestObject wurde im Listing 4.4 ausführlich besprochen; in diesem Beispiel ist sie in der extern verknüpften Datei common.inc.js im Verzeichnis js des aktuellen Kapitels abgelegt, sollten Sie die Funktion auf der CD suchen.) Danach wird ein Request-Handler hand-leRequest definiert (dessen Funktionalität kennen wir aus Listing 4.5). Mit open wird eine Anfrage für die per URL definierte Datei an den Server geöffnet und mit send abgeschickt.

function handleRequest() {

switch(myXMLHttpRequest.readyState) {

Page 163: Flash cs3, ajax und php

K A P I T E L 4150

case 0:

case 1:

case 2:

case 3: return;

case 4: showResponse(); return;

}

}

function showResponse() {

var myContent = document.getElementById("content");

myContent.innerHTML = myXMLHttpRequest.responseText;

}

Listing 4.21: Der Eventhandler handleRequest ruft nach der vollständigen Übertragung der Anfrage eine Funktion showResponse auf.

Nachdem die Anfrage per send abgeschickt und die Übertragung (readyState==4) vollständig abgeschlossen wurde, wird mithilfe von showResponse auf das Element content zugegriffen und dessen Inhalt über die Anweisung innerHTML auf den zurückgegebenen Text (responseText) der XMLHttpRequest-Instanz gesetzt – fertig.

DOM und innerHTML Wie Sie sehen, habe ich im letzten Beispiel die Methode innerHTML verwendet, um das „Innere“ eines XHTML-Elements zu setzen – diese Methode ist jedoch nicht im Standard des W3C enthalten. Jedoch hat sich diese ursprünglich von Microsoft eingeführte Methode mit-tlerweile in allen Browsern durchgesetzt, sodass man sie als Quasi-Standard ansehen kann. Aus dem Kapitel zum DOM kennen Sie jedoch auch Varianten, ohne diese – zugegebenermaßen sehr einfache – Methode zu arbeiten.

So weit, so gut. Dass wir natürlich ganz zu Beginn eine Variable für die XMLHttpRe-quest-Instanz anlegen mussten, versteht sich von selbst. Das gesamte Script dieser Datei finden Sie auf der Buch-CD im Verzeichnis Miniwebsite im Verzeichnis zum Kapitel.

Nachdem unsere Navigation nun funktioniert, wenden wir uns den einzelnen Web-dokumenten zu – zunächst hier einmal die statischen Dokumente:

<h2>Home...</h2>

<p>Willkommen auf der Miniwebsite zum Testen von AJAX!</p>

Listing 4.22: Quellcode von home.htm

<h2>&Uuml;ber uns...</h2>

<p>Ein bisschen BlaBla, oder auch nicht...?!</p>

Listing 4.23: Quellcode von ueberuns.htm

Page 164: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 151

Sollten Sie sich nun die Frage stellen, ob dieser Quellcode nur ein Auszug ist oder schon alles war, dann seien Sie versichert: Das ist der gesamte Quellcode der beiden Dokumente! Warum? Ganz einfach: Wir laden diese Daten in ein bereits bestehendes Webdokument (index.htm) hinzu – darin befinden sich sämtliche Tags zum Seiten-aufbau (<html>, <head>, <body> etc.) und bilden somit ein gültiges Webdokument. Die gute Nachricht ist, dass Sie in Dreamweaver Dokumente mit nur einem Teilcode eines gültigen Webdokuments ebenso bearbeiten können, als wäre es ein vollständiges Webdokument:

Da der Dreamweaver eines der gängigsten Tools für das Arbeiten mit Webdokumenten ist, habe auch ich mich in diesem Buch für dieses Tool entschieden.

Das Nachladen eines statischen Dokuments ist also denkbar einfach – per AJAX das Dokument anfordern und den responseText einem Container zuweisen.

Im Fall von dynamischen Dokumenten würden wir erwarten, dass sich die Sache viel-leicht doch etwas komplizierter darstellt. Deshalb werfen wir doch mal einen Blick auf ein solches: links.php:

<link href="css/common.inc.css" rel="stylesheet" type="text/css">

<h2>Links...</h2>

<?php require("includes/links.inc.php"); ?>

Listing 4.24: Auch die Einbindung eines dynamischen Dokuments ist nichts anderes als das Einbinden eines statischen Dokuments, da der PHP-Code ja bereits auf Serverseite verarbeitet wird.

Grundsätzlich ist alles gleich wie beim statischen Dokument, da der PHP-Code ser-verseitig in XHTML-Code umgewandelt wird. Um das Dokument übersichtlicher

ABBILDUNG 4.10

Bearbeiten eines nicht voll-ständigen Webdokuments in Dreamweaver – alles wie gehabt

Page 165: Flash cs3, ajax und php

K A P I T E L 4152

zu gestalten, habe ich die eigentliche PHP-Funktionalität in eine Datei links.inc.php verlegt, die ich per require anfordere (sollte Ihnen das unbekannt vorkommen, so schlagen Sie bitte im Grundlagenkapitel zur Programmierung nach):

<?php

function showLinks() {

if(!$conn = mysql_connect("mysql.syneweb.com","usr_fl ashphpajax","123passwort")) { die(‚<p>Der Datenbankserver konnte nicht kontaktiert werden. ERROR='.mysql_error()); }

if(!$db = mysql_select_db("db_fl ashphpajax")) { die(‚<p>Die Datenbank konnte nicht ausgewaehlt werden. ERROR='.mysql_error()); }

$sql = "SELECT * FROM tbl_04links WHERE(bitP_chk_aktiv=1)";

$query = mysql_query($sql);

$returner = ‚';

if(mysql_num_rows($query)>0) {

$returner.= '<ul>';

while($data = mysql_fetch_array($query)) { $returner.= '<li><a href="'.$data["vcP_URL"].'" target="_blank">'.$data["vcP_Bezeichnung"].'</a></li>';

}

$returner.= '</ul>';

}

else { $returner.= '<p class="info">Keine Links vorhanden.</p>'; }

return $returner;

}

echo(showLinks());

?>

Listing 4.25: Der vollständige Code der Datei links.inc.php, in der sich die gesamte PHP-Funktionalität zum Generieren des XHTML-Codes befi ndet

Ich verwende in solchen Fällen gerne eine Funktion, die mir eine Variable (hier: $returner) mit dem generierten XHTML-Code zurückgibt. Alternativ wäre man auch ohne Funktion und anschließendem Funktionsaufruf ausgekommen.

In der untersten Zeile wird also die Funktion showLinks aufgerufen – der von ihr zurückgelieferte Wert wird danach per echo ausgegeben. Die Funktion selbst nimmt zunächst Kontakt mit einem Datenbankserver auf, danach wird die Datenbank ausge-wählt. Sollte einer der beiden Aufrufe nicht funktionieren, wird mittels die abgebro-chen und eine entsprechende Fehlermeldung ausgegeben. Sollte alles geklappt haben, wird für den Zugriff auf die Tabelle tbl_04links ein entsprechendes SQL-Statement erzeugt. Die Tabelle selbst besteht aus vier Feldern:

Page 166: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 153

Feldname Typ Extras Beschreibung

idP_Links int(11) auto-increment, Primary Key, not null

Dieses Feld stellt die ID der Tabelle dar – dementsprechend verwende ich ein auto-increment und defi niere es als Primärschlüssel.

vcP_Bezeichnung varchar(128) not null Linktext wie etwa „Addison-Wesley“ für die URL „http://www.addison-wesley.de“

vcP_URL varchar(128) not null URL zur Website (beispielsweise „http://www.addison-wesley.de“)

bitP_chk_aktiv tinyint(1) not null, Standardwert=1 Kennzeichnet, ob der Link auf der Website ausgegeben werden soll

Tabelle 4.5: Tabellenstruktur der verwendeten Tabelle tbl_04links

Wir fragen nur Links ab, die die Kennzeichnung bitP_chk_aktiv=1 aufweisen. Danach wird das SQL-Statement abgesetzt und das Ergebnis der Abfrage in der Vari-ablen $query gespeichert. Sollten mehr als null Zeilen zurückgeliefert worden sein, wird ein <ul> in $returner hinzugefügt. In einer while-Schleife geht man zeilen-weise das Ergebnis durch und generiert in $returner einen XHTML-Code in Form von <li><a href="URL" target="_blank">LINKTEXT</a></li>. Nachdem die while-Schleife vollständig durchgelaufen ist, wird ein abschließendes </ul> an $returner angehängt und die Variable $returner an den Aufrufer zurückgeliefert (= Rückgabewert der Funktion). Sollte unsere Abfrage keine Daten zurückgeliefert haben, so wird der Text <p class="info">Keine Links vorhanden.</p> an den Aufrufer zurückgeschickt.

In unserem Fall liefert das SQL-Statement fünf Links zurück, die per echo in das Dokument geschrieben werden:

ABBILDUNG 4.11

AJAX fordert ein PHP-Dokument an, das auf Serverseite eine Datenbank ausliest und das Ergebnis per echo in das Dokument schreibt.

Page 167: Flash cs3, ajax und php

K A P I T E L 4154

Wie zu erwarten war, ist auch das Anfordern von PHP-basierten Dokumenten kein Problem, da diese zunächst am Server abgearbeitet werden und somit das Rückgabe-dokument in jedem Fall reinen XHTML-Code beinhaltet.

Wenden wir uns also der schwierigsten Aufgabe zu: einem Dokument (kontakt.htm), das per AJAX eingebunden wird und von sich aus wieder per AJAX eine Anfrage an den Server stellt. Zunächst einmal nachfolgend der Code dieses Dokuments:

<link href="css/common.inc.css" rel="stylesheet" type="text/css">

<h2>Kontakt...</h2>

<p>Hier ein Kontaktformular, damit Sie mir auch eine Email schreiben k&ouml;nnen:</p>

<form name="frmKontakt" id="frmKontakt" method="post" action="">

<div id="msgOut"></div>

<div class="label">Ihre Email-Adresse:</div>

<div class="fi eld"><input type="text" name="Email" id="Email" /></div>

<div class="cleaner"></div>

<div class="label">Ihre Nachricht an mich:</div>

<div class="fi eld"><textarea name="Nachricht" cols="50" rows="10" id="Nachricht"></textarea></div>

<div class="cleaner"></div>

<div class="button"><input type="button" name="submitIt" id="submitIt" value="Abschicken" onclick="sendContact();" /></div>

<div><textarea name="msgStatus" rows="10" id="msgStatus">Status:\n</textarea>

</div>

</form>

Listing 4.26: Der XHTML-Code bietet keine Überraschungen: Es wird ein Formular mit zwei Feldern und einem Button verwendet, welche allesamt in DIV-Tags eingebettet sind.

In Listing 4.10 wurde ein sehr ähnliches Beispiel gezeigt. Das derzeit noch leere <div id="msgOut"> verwenden wir wie üblich dafür, dass wir eine Statusmeldung an den User ausgeben. Sobald der Button „Abschicken“ geklickt wird, wird die Funktion sendContact aufgerufen. Fraglich ist jedoch, wo sich diese Funktion befindet, da in der Datei kontakt.htm keinerlei Hinweis auf eine JavaScript-Funktion gefunden wer-den kann. Wenn wir jedoch die Datei index.htm genauer betrachten, finden wir in ihr einen Verweis auf eine JavaScript-Datei kontakt.inc.js:

<script language="javascript" type="text/javascript" src="js/kontakt.inc.js"></script>

Listing 4.27: Die verknüpfte Datei kontakt.inc.js befi ndet sich in der Datei index.htm und nicht in kontakt.htm.

Page 168: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 155

An dieser Stelle möchte ich Sie bewusst auf einen Punkt hinweisen, der bei der Ent-wicklung erster AJAX-Anwendungen sehr häufig auftritt: das Abfragen von Doku-menten mit inkludierten JavaScript-Anweisungen, die per responseText einem Dokument hinzugefügt werden.

Einschub: AJAX und JavaScript

Beim Einfügen von XHTML-basiertem Code, der per responseText von einer XMLHttpRequest-Instanz bereitgestellt wurde, wird der Code als reiner Text einem bereits bestehenden Element hinzugefügt. Sollte dieser XHTML-Code JavaScript bein-halten (was für manche Anwendungen erwünscht sein kann), so wird dieser nicht als JavaScript, sondern als normaler Text interpretiert.

Ein Ausweg aus dieser Misere ist die Verwendung der eval-Funktion: Sie weist den Interpreter an, einen String so zu verarbeiten, als wäre er ein echter JavaScript-Code.

Nehmen wir den einfachen Fall, dass per AJAX ein Dokument simplejs.js angefor-dert wird, das reinen JavaScript-Code (und nicht mehr!) beinhaltet:

alert("Ein erster Test");

Das Dokument besteht also aus nur einer einzigen Zeile. Fordern wir nun dieses Dokument wie gewohnt an, so würden wir wie folgt verfahren:

function showResponse() {

document.getElementById("msgOut").innerHTML = myXMLHttpRequest.responseText;

}

function sendRequest() {

myXMLHttpRequest.open("GET", "simplejs.js", true);

myXMLHttpRequest.send(null);

}

Listing 4.28: Die für unser Beispiel wichtigen Funktionen sendRequest und showResponse in der Datei ajax03.htm

Die Funktion sendRequest fordert die Datei simplejs.js an und showResponse gibt wie gewohnt den Inhalt dieser Datei in ein leeres DIV aus. Statt dass der Code ausge-führt wird, wird er als reiner Text ausgegeben:

AJAX und JavaScriptAJAX und JavaScript

Page 169: Flash cs3, ajax und php

K A P I T E L 4156

Gut, da könnten Sie noch antworten: „War ja klar – binden wir doch ein XHTML-Dokument ein, das den Code schön zwischen <script> und </script> verpackt!“ Gesagt, getan, versuchen wir die Datei simplejs.htm und ändern den Aufruf in der Funktion sendRequest entsprechend:

<script language="javascript" type="text/javascript">

alert("Ein erster Test");

</script>

Listing 4.29: Code von simplejs.htm

...

myXMLHttpRequest.open("GET", "simplejs.htm", true);

...

Listing 4.30: Anfrage der Datei simplejs.htm

Der geänderte Aufruf führt zu folgendem Ergebnis (ajax03a.htm):

ABBILDUNG 4.12

Statt dass der JavaScript-Code ausgeführt wird, wird

er als Text ins Dokument eingebettet.

Page 170: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 157

Leider ist unser Versuch gescheitert – das Ergebnis des Beispiels ist nicht besser gewor-den, denn jetzt sehen wir gar nichts mehr. Versuchen wir es also noch mal anders. Verwenden wir wieder die Datei simplejs.js (mit nichts als JavaScript-Code im Inhalt) und versuchen die eval-Methode bei der Ausgabe der Rückgabe (ajax03b.htm):

function showResponse() {

document.getElementById("msgOut").innerHTML = eval(myXMLHttpRequest.responseText);

}

function sendRequest() {

myXMLHttpRequest.open("GET", "simplejs.js", true);

myXMLHttpRequest.send(null);

}

Listing 4.31: Wir verwenden die Methode eval sowie die zuvor erstellte Datei simplejs.js.

Wir erhalten nun (fast) das gewünschte Ergebnis:

ABBILDUNG 4.13

Diesmal liefert unsere Anfrage gar nichts …

Page 171: Flash cs3, ajax und php

K A P I T E L 4158

Die Ausgabe des Textes „undefined“ ist verständlich, da wirListing . eine m Container einen XHTML-Text zuweisen, der nicht vorhanden ist (es wurde lediglich JavaScript-Code ausgeführt). Wir korrigieren also die Ausgabe der JavaScript-Datei wie folgt:

Aus

function showResponse() {

document.getElementById("msgOut").innerHTML = eval(myXMLHttpRequest.responseText);

}

ABBILDUNG 4.14

Fast wie gewünscht: einzig der Text „undefined“ wird

ausgegeben.

Page 172: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 159

wird

function showResponse() {

eval(myXMLHttpRequest.responseText);

}

Listing 4.32: Die Ausgabe an das DIV-Tag „msgOut“ wurde entfernt, da wir nur JavaScript-Code ausführen und nichts weiteres an das Dokument ausgeben wollen (ajax03c.htm).

Halten wir also fest: Wenn Sie eine reine JavaScript-Datei anfordern und abarbeiten wollen, so müssen Sie den Rückgabewert von AJAX (responseText) mit der Methode eval abarbeiten lassen, sodass der Code als Code und nicht als Text interpretiert wird. Diese Variante funktioniert übrigens auch, wenn Sie mit Funktionen in der JavaScript-Datei arbeiten (simplejs2.js):

function myAlert(msg) {

alert(msg);

}

myAlert("Ein erster Test");

Listing 4.33: Eine Funktion anstatt eines direkten Aufrufs von alert

Wie stellt sich die Sachlage jedoch dar, wenn wir eine XHTML-Datei anfordern, die sowohl aus XHTML als auch aus JavaScript-Code besteht? Nehmen wir folgendes Beispiel (notsosimplejs.htm):

<script language="javascript" type="text/javascript">

alert("Ein zweiter Test");

</script>

<p>So - wir erwarten eine alert-Box sowie die Ausgabe dieses Textes auf dem Bildschirm!</p>

<script language="javascript" type="text/javascript">

<!--

function myAlert(msg) {

alert(msg);

}

myAlert("Ein dritter Test");

//-->

</script>

<p>Und noch ein Text!</p>

Listing 4.34: Eine gemischte XHTML-Datei (XHTML und JavaScript)

JavaScript-Dateien anfor-dern und Code ausführen

JavaScript-Dateien anfor-dern und Code ausführen

Page 173: Flash cs3, ajax und php

K A P I T E L 4160

An dieser Stelle bleibt uns dann nicht mehr viel anderes übrig, als den XHTML-Code zu parsen und den JavaScript-Code vom XHTML-Code zu trennen. Hierbei bedient man sich gerne sogenannter „Regular Expressions“. S ie werden verwendet, um in Strings gewisse Suchausdrücke zu definieren und diese durch andere Strings zu erset-zen. Mithilfe der JavaScript-Methode RegExp können wir direkt zur Laufzeit Scripts erzeugen (Details zur Funktion RegExp entnehmen Sie bitte beispielsweise der Website http://de.selfhtml.org).

Wir werden also versuchen, den XHTML-Code vom JavaScript-Code zu trennen, danach den JavaScript-Code auszuführen und den XHTML-Code in unserem Ausga-be-DIV (<div id="msgOut">) auszugeben.

Zunächst laden wir hierzu die Antwort vom Server in eine Variable respRaw:

var respRaw = myXMLHttpRequest.responseText;

Nun definieren wir einen ersten String, den wir aus dieser Variable entfernen wollen, da er uns bei der Ausführung von JavaScript-Code stören wird. Des Weiteren legen wir eine Instanz des Objekts RegExp an:

var fi ndStr = "(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)";

var myRegExp = new RegExp(fi ndStr,"img");

Der Instanz myRegExp werden zwei Parameter übergeben:

Parameter 1 bezeichnet den Ausdruck, der innerhalb eines Textes gefunden werden soll. In unserem Fall sind das alle Tags, die mit „<script .. >“ anfangen (mit beliebig vielen Attributen zwischen „<script“ und „>“), alle Zeilenumbrüche (\n), alle Wagenrückläufe (\r) sowie alle Tags „</script>“.

Parameter 2 kann folgende Einstellungen bezeichnen:

g: Kennzeichnet ein „global matching“: Es werden im Fall der Verwendung von replace alle gefundenen Ausdrücke von Parameter 1 aus dem String entfernt.

i: Kennzeichnet, dass wir Groß- und Kleinschreibung nicht beachten (case-insensitive).

m: Kennzeichnet den Multiline Mode – somit werden vor und nach neuen Zeilen Ausdrücke mit einem beginnenden $ oder ^ gesucht (diese Einstellung gibt es nur in JavaScript 1.5 und höher).

Um nun den XHTML-Teil vom JavaScript-Teil zu trennen, müssen wir also aus dem Antworttext vom Server (respRaw) für den XHTML-Teil genau diesen String entfer-nen und für den JavaScript-Teil genau diesen Teil aufheben – dazu verwendet man die Methoden match und response:

u

u

u

u

u

Page 174: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 161

var xhtml = resp.replace(myRegExp,"");

var js = resp.match(myRegExp);

Listing 4.35: Entfernen des Suchstrings mit replace (genau gesprochen: Ersetzen des Suchstrings mit „“) und speichern des Suchstrings mit match.

Den XHTML-Teil müssen wir nicht mehr verändern, dieser ist bereits komplett und wartet auf seine Ausgabe. Den JavaScript-Teil hingegen müssen wir nun wieder von den Tags <script> und </script> säubern, da wir – wie wir weiter oben schon besprochen haben – für die Abarbeitung des Codes die Methode eval verwenden und diese nur puren JavaScript-Code ausführen kann. (Zur Erinnerung: Das Tag <script> gehört nicht zum Sprachumfang von JavaScript, sondern von XHTML.) Des Weiteren stört uns auch die Kommentarkennzeichnung aus HTML „<!--“, die ebenfalls ent-fernt gehört:

var myRegExp3 = new RegExp(fi ndStr,"im");

for(var i=0; i<js.length; i++) {

var toEval = js[i].match(myRegExp3)[1].replace(/<!--/g,"");

eval(toEval);

}

Listing 4.36: Entfernen des ursprünglichen Suchstrings aus js sowie Entfernen des Strings „<!--“ mittels replace

Nachdem also unser JavaScript-Code ausgeführt wurde, geben wir auch noch den XHTML-Code im dafür vorgesehenen Container aus:

document.getElementById("msgOut").innerHTML = xhtml;

Listing 4.37: Ausgabe der Variable xhtml in den Container msgOut

Damit können wir den Einschub: AJAX und JavaScript abschließen und uns wieder unserer Miniwebsite widmen. Wir sind bei der in index.htm eingebundenen Datei kontakt.inc.js stehen geblieben – werfen wir einen Blick darauf:

var contactXMLHttpRequest;

function sendContact() {

contactXMLHttpRequest = createRequestObject();

contactXMLHttpRequest.onreadystatechange = handleRequestContact;

var querystring = "Email="+document.forms["frmKontakt"].elements["Email"].value+"&Nachricht="+document.forms["frmKontakt"].elements["Nachricht"].value

contactXMLHttpRequest.open("GET", "includes/kontakt.inc.php?"+querystring, true);

Page 175: Flash cs3, ajax und php

K A P I T E L 4162

contactXMLHttpRequest.send(null);

}

function showResponse2() {

document.getElementById("msgOut").innerHTML = contactXMLHttpRequest.responseText;

}

function handleRequestContact() {

document.forms["frmKontakt"].elements["msgStatus"].value += contactXMLHttpRequest.readyState+"\n";

switch(contactXMLHttpRequest.readyState) {

case 0:

case 1:

case 2:

case 3: return;

case 4: showResponse2(); return;

}

}

Listing 4.38: Der Inhalt der Datei kontakt.inc.js

Da der Code aus einem vorigen Beispiel (siehe Listing 4.11) bereits bekannt ist, fasse ich noch einmal zusammen:

1. Die Variable contactXMLHttpRequest dient als Instanz für den XMLHttpRequest.

2. Bei Aufruf von sendContact wird contactXMLHttpRequest zur Instanz von XMLHttpRequest und es wird ihr ein Eventhandler handleRequestContact zugewiesen. In diesem Atemzug werden auch ein Querystring (Variable querystring) mit allen eingegebenen Daten aus dem Formular sowie der open-Aufruf an die Datei kontakt.inc.php durchgeführt.

3. Hat contactXMLHttpRequest die Eigenschaft readyState==4 erreicht (der Datentransfer von Server zu Client ist abgeschlossen), wird die Funktion showResponse2 aufgerufen. Solange dies nicht der Fall ist (also readyState<4), passiert nichts.

4. Die Funktion showResponse2 sorgt dafür, dass der Rückgabewert von kontakt.inc.php (dies wird eine Erfolgs- oder Misserfolgsmeldung sein) in dem leeren DIV msgOut dargestellt wird.

Page 176: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 163

Da wir auch die Funktionsweise der Datei kontakt.inc.php bereits in Listing 4.12 ausführlich besprochen haben, bleibt uns nichts weiter zu tun, als kurz zusammenzu-fassen:

1. Durch den send-Aufruf der XMLHttpRequest-Instanz wird auf Serverseite die Datei kontakt.inc.php aufgerufen, wobei dieser der oben genannte Querystring mit den Formularfeldwerten übermittelt wird (als GET-Variable).

2. Innerhalb von kontakt.inc.php wird eine Funktion defi niert (und selbstverständlich auch aufgerufen), die aus den gegebenen Daten eine E-Mail „bastelt“ und diese mithilfe der mail-Funktion verschickt.

3. Liefert mail den Wert true zurück, war der Mail-Versand erfolgreich und es wird eine Erfolgsmeldung per echo als XHTML ausgegeben; im Fall eines Misserfolgs wird eine Misserfolgsmeldung ausgegeben. In jedem Fall bildet der so erzeugte XHTML-Code den Rückgabewert an die XMLHttpRequest-Instanz.

Das Ergebnis können Sie wie gewohnt (nachdem Sie die Daten online gestellt haben) in einem Browser testen:

ABBILDUNG 4.15

Wie zu erwarten, hat alles funktioniert – die E-Mail wurde versandt (siehe fol-gende Abbildung).

Und hier noch – quasi als Beweis – die empfangene E-Mail:

Page 177: Flash cs3, ajax und php

K A P I T E L 4164

Bilden wir ein Resümee zu unserer Website-Entwicklung. Wie wir gesehen haben, sind zwar alle gängigen Anforderungen an eine Website erfüllt worden: Wir konnten statische, dynamische sowie AJAX-basierte Dokumente einbinden. Jedoch muss man auch offen gestehen, dass es immer wieder einiger Tricks bedurfte, um letzten Endes das Ziel zu erreichen – und genau so ein „Tricksen“ ist nicht sinnvoll! Man sollte immer die optimale Technologie für den optimalen Fall verwenden und nicht zwanghaft auf eine Technologie setzen, die für die gegebene Anwendung gar nicht so sehr geeignet ist. AJAX leistet große Dienste, wenn im Nachhinein Daten in ein Dokument hinzugela-den werden sollen – wir meinen jedoch zumeist statische Information wie zusätzliche Texte, Grafiken etc. In nur wenigen (Ausnahme-)Fällen ist von dynamischen oder gar AJAX-basierten Daten die Rede.

In den nächsten beiden Kapiteln wollen wir uns deshalb ein bisschen die Augen öffnen lassen für Anwendungsgebiete, in denen AJAX Platz findet – vor allem liegt uns jedoch das Zusammenspiel mit Flash am Herzen!

4.4 Flash vs. AJAXWie wir aus den Darstellungen des letzten Kapitels gesehen haben, ist AJAX in der Lage, nachträglich und ohne Neuladen des Webdokuments Daten vom Server nach-zuladen – sogar dynamische wie AJAX-basierte Dokumente können (ausgewertet und) nachgeladen werden. Flash kann das schon sehr lange und deshalb wurden viele Anwendungen, in denen immer wieder mal Daten nachgeladen werden müssen (aber deshalb die Seite nicht neu geladen wird) in Flash realisiert. Man denke beispielsweise an Chat-Systeme – eine typische Flash-Domäne (sehen wir einmal von ActiveX-Kom-ponenten oder Applets ab).

Warum war Flash eigentlich immer schon in der Lage, das zu tun, was mit AJAX mühsam eingeführt wurde? Nun, das liegt daran, dass AJAX auf Standardtechnologien

ABBILDUNG 4.16

Die versandte E-Mail ist angekommen – was wollen

wir noch mehr?

Page 178: Flash cs3, ajax und php

A J A X – A S Y N C H R O N U S J A V A S C R I P T A N D X M L 165

basiert, die jeder halbwegs gängige Browser unterstützt: XHTML und JavaScript. Flash hingegen ist ein Plug-in, das ein User selbstständig installieren muss (sollte es nicht bereits installiert sein). Solche Plug-ins haben wesentlich mehr „Rechte“ im Browser des Users als die Standardtechnologien. Dies liegt mitunter auch daran, dass wir User selbst das Einverständnis dafür gegeben haben: Mit dem Zeitpunkt der Installation haben wir Flash implizit „erlaubt“, das zu tun, was Flash imstande ist – dazu gehört unter anderem auch das Nachladen von Daten beispielsweise mithilfe des LoadVars -Objekts, das wir im Laufe dieses Buchs noch genau kennenlernen werden.

Nachdem die Applikation „Flash“ immer noch (und das wird es auch immer bleiben) ein rotes Tuch in den Augen mancher User im Internet ist (O-Ton: „Dieses Flash: Alles dreht sich und überall wird böse Musik abgespielt!“), hat man mit AJAX nun eine Möglichkeit, einige der Anwendungen zu realisieren, die man ursprünglich nur mit Flash (oder einem anderen Plug-in) realisieren konnte. Man könnte also sagen, dass Flash in gewissen Bereichen des Internets ein bisschen an Boden verlieren wird. Speziell in Hinblick auf News-Systeme (Anzeigen der aktuellsten Newsticker in einem regelmäßigen Abstand), dynamische Grafiken (Börsenkurse usw.), Chat-Systeme, dynamische Auswahlsysteme (Google Suggest, Suche in wikipedia.de usw.) stellt AJAX eine ernst zu nehmende Kon-kurrenz zu Flash dar. Wobei – und das sollte man nicht außer Acht lassen! – Flash für solchen Anwendungen oft auch nur eine „Notlösung“ war: Warum sollte man für einen simplen Newsticker Flash installiert haben, wenn die Darstellung der News ja lediglich Textinformationen sind? XHTML ist dafür wesentlich besser geeignet.

Ein Killerargument für Flash ist selbstverständlich die Plattformunabhängigkeit: Egal, ob eine Flash-Anwendung auf einem PC, Mac oder einem Handy angezeigt wird – sie wird immer gleich ablaufen. Im Fall von AJAX-Anwendungen können wir das nicht behaupten, da wir immer noch mit unterschiedlichen Browsern rechnen müssen.

Viel wichtiger, als herauszufinden, wo AJAX Flash eine Konkurrenz sein kann (eigent-lich ist es ja müßig, darüber überhaupt nachzudenken), ist es, herauszufinden, wo diese beiden großartigen Technologien zusammenarbeiten können – die Devise lautet also „Flash & AJAX“ statt „Flash vs. AJAX“.

4.5 Flash & AJAXViel interessanter ist also die Frage, in welcher Hinsicht Flash und AJAX zusammenspie-len können oder AJAX eine (zusätzliche) Alternative zu Flash bietet. Um diese Frage zu beantworten, müssen wir uns zunächst einmal bewusst werden, welche der möglichen Technologien in welchen Bereichen Vor- und in welchen Bereichen Nachteile aufweist.

Bereich AJAX Flash

Kein Plug-in erforderlich + -

Darstellen von ausschließlich Textinformationen (inklusive Bildern)

+ -

Darstellen von pixelbasierten Grafi ken + +

Page 179: Flash cs3, ajax und php

K A P I T E L 4166

Bereich AJAX Flash

Darstellen von Vektorgrafi ken - +

Darstellen von Animationen - +

Darstellen von weiteren multimedialen Inhalten - +

Arbeiten mit Formularen und Formularinhalten + +/-

Browser-Unterstützung + +/-

Akzeptanz des Users + +/-

Barrierefreiheit - +/-

Schnelligkeit in der Darstellung + +

Kompatibilität zwischen verschiedenen Versionen - browserabhängig +

Programmiermodell +/- JavaScript 1.5 wird bei größeren OOP-Anwen dungen nicht empfohlen

+

Unterstützung von XML-Darstellung - +

Tabelle 4.6: Übersicht von Vor- und Nachteilen der Technologien AJAX und Flash (ohne Anspruch auf Vollständigkeit)

Aus der obigen Tabelle ergeben sich folgende Synergien:

Einsatz von AJAX und Flash parallel: Sollten Sie die Möglichkeit haben, eine Flash-Anwendung in AJAX nachzubauen (Newsticker, Auswahlsysteme etc.), so ist dies für den User positiv, da Sie den User nicht zum Einsatz von Flash nötigen müssen. Somit nutzen Sie den Vorteil, dass der User kein Flash-Plug-in installiert haben muss und trotzdem interaktiv arbeiten kann. Im Rahmen der Workshops werden wir beispielsweise ein Chat-System entwickeln, das sowohl in Flash als auch in XHTML gleichermaßen gut funktioniert.

Interaktive Darstellung von Bildern/Statistiken: Über Standard-XHTML-Doku-mente wird der User zur Eingabe diverser Daten aufgefordert (beispielsweise Tabel-len wie etwa ein „Online-Excel“). Die Grafiken werden dynamisch mit jeder Ein-gabe in einer Flash-Anwendung angezeigt. Generell ist Flash zum Visualisieren von Informationen (basierend auf beispielsweise XML-Daten hervorragend geeignet).

Letzten Endes ist die Kombination von Flash und AJAX immer dann sinnvoll, wenn man die Vorteile beider Welten miteinander kombinieren möchte. Flash ist in der Lage, alles abzudecken, was AJAX kann – dementsprechend könnte man sagen, dass für einen Flash-Entwickler AJAX keinen Vorteil bringen würde. Nachteilig ist ja nur, dass Flash ein Plug-in ist …

Doch nachdem ein Web-Designer kein reiner Flash-Entwickler ist und selbst Flash-Entwickler hin und wieder über den eigenen Tellerrand blicken sollten, kann man AJAX als „Flashlose“ Alternative betrachten. Denn anders gefragt: Warum sollte man auf die Idee kommen, beispielsweise ein Webmail-System mit Flash zu programmie-ren, wo man doch die wirklichen Vorteile von Flash gar nicht nützen kann? Hier ist man mit AJAX viel besser aufgehoben.

In den folgenden Kapiteln werden wir uns ausführlich mit den Möglichkeiten von Flash & AJAX befassen – also nehmen Sie sich nicht zu viel vor, wenn Sie gerade am Buchlesen sind, denn Sie werden das Buch nicht mehr weglegen können.

u

u

Page 180: Flash cs3, ajax und php

5CLIENTSEITIGER DATENAUSTAUSCH – FLASH & JAVASCRIPT

In den folgenden Kapiteln befassen wir uns mit der Frage, wie Flash mit seiner Umgebung Daten austauschen kann – einer-seits serverseitig mit dem Webserver und andererseits clientsei-tig mit dem Browser über das Flash-Plug-in.

Die Schnittstelle zur Außenwelt … Bei dieser Betrachtung wer-den wir die zwei Bereiche server- und clientseitig voneinander trennen, da hier zwei ganz verschiedene Vorgehensweisen von-nöten sind.

Wenn man von clientseitigem Datenaustausch spricht, so meint man immer zwei Richtungen:

Der Browser sendet Daten an Flash.

Flash versendet Daten an den Browser.

Wie Sie wissen, stehen uns auf Clientseite zwei Technologien zur Verfügung, die uns beim Datenaustausch behilflich sein können – (X)HTML und JavaScript . (X)HTML ist die Bezeich-nungssprache, die für den Aufbau des Webdokuments verwen-det wird. JavaScript hingegen ermöglicht uns eine Interaktion mit dem User und den eingebundenen Objekten. Dadurch wird JavaScript diejenige der beiden genannten Technologien sein, die uns beim Datenaustausch hilfreich zur Seite steht.

u

u

Page 181: Flash cs3, ajax und php

K A P I T E L 5168

XHTML versus HTMLJedes Webdokument basiert auf einer Bezeichnungssprache. Ursprünglich wurde die Bezeichnungssprache HTML verwendet, die sich jedoch als nicht sehr konsistent erwiesen hat, werden doch zu viele Ungereimtheiten geduldet wie beispielsweise das Schließen der meisten, aber nicht aller Tags. HTML stammt direkt vom übergeordneten Standard SGML (Standard Generalized Markup Language) ab, XHTML hingegen von XML (Extended Markup Language), das wiederum von SGML abstammt. Nachdem XML in seiner Anwendung sehr strikt und konsequent ist (sprich: keine Fehler duldet) und XHTML diese Eigenschaften vererbt wurden, ist XHTML in der Anwendung ebenfalls nicht fehlertolerant. Letzten Endes ist dies eine große Erleichterung für jeden Webdesigner, da ihm weniger Fehler erlaubt werden und sein Code dadurch immer besser wird. HTML wird seit der Version 4.01 nicht mehr weiterentwickelt – an seine Stelle ist XHTML 1.0 getreten.In diesem Buch werden wir konsequent mit XHTML arbeiten.

5.1 Daten senden: Browser an FlashMan kann auf zwei Arten Daten an Flash übergeben:

1. Es wird von JavaScript auf die SWF-Datei zugegriffen und dort innerhalb der SWF-Datei eine Variable gesetzt: Diese Variante hat den Vorteil, dass das Senden von Daten an Flash beispielsweise auch über einen Klick auf einen Button erfolgen kann – sprich durch eine Benutzereingabe. Nachteilig ist, dass verschiedene Browser diese Variante unterschiedlich unterstützen.

2. Über geeignete Attribute im HTML-Code werden direkt beim Laden der SWF-Datei Daten an die SWF-Datei übergeben: Entgegen der oben genannten Variante besteht hier keine Möglichkeit, per Benutzereingabe Daten an die SWF-Datei zu senden. Der grundlegende Vorteil dieser Variante ist, dass alle gängigen Browser eine Datenübergabe in dieser Form unterstützen.

Im Folgenden werde ich auf diese beiden Varianten genauer eingehen.

5.1.1 Variante 1: JavaScript greift auf die SWF-Datei zuFür den Fall, dass der Browser mittels JavaScript Daten an Flash übermitteln soll, sind folgende Schritte notwendig:

1. JavaScript muss die eingebundene SWF-Datei bzw. Flash-Datei eindeutig identifi zieren können.

2. Mithilfe eines geeigneten Befehls wird eine Variable in der Flash-Datei angesprochen und es wird dieser ein Wert zugewiesen.

Page 182: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 169

Die einzige Variante, um vom Browser aus Daten an Flash zu übermitteln, ist die, dass man Flash-Variablen einen Wert zuweist. Hierbei ist es nicht zwingend notwendig, dass die Variable zu diesem Zeitpunkt bereits existiert – Flash ist in der Lage, dyna-misch Variablen anzulegen, wie Sie in den vorigen Kapiteln bereits erfahren haben.

Einbinden von Flash

Je nach verwendetem Browser wird die Flash-Datei entweder mit dem <object>- (Standard-HTML, Internet Explorer) oder dem <embed>-Tag (Mozilla-basierte Brow-ser wie etwa der Netscape Navigator) in die HTML-Datei eingebunden. Damit die Flash-Datei in diesem HTML-Dokument eindeutig identifiziert werden kann, wird das <object>- bzw. das <embed>-Tag mit dem id-Attribut eindeutig gekennzeichnet. Im Allgemeinen wird eine Flash-Datei mithilfe beider Tags eingebunden – dadurch hat man beiden größeren Browser-Typen Genüge getan und sichergestellt, dass die Datei auch wirklich verarbeitet werden kann.

<object id="myFlash" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/fl ash/swfl ash.cab#version=6,0,29,0" width="200" height="150"style="border:1px solid #999999;">

<param name="movie" value="browserAnFlash01.swf" />

<param name="quality" value="high" />

<embed id="myswf" name="myFlash" src="browserAnFlash01.swf" width="200" height="150" quality="high" pluginspage="http://www.macromedia.com/go/getfl ashplayer" type="application/x-shockwave-fl ash"></embed>

</object>

Listing 5.1: Einbinden einer Flash-Datei in HTML-Code

classid und codebase

Mit dem Attribut classid gibt man an, welche Applikation in die Seite eingebun-den werden soll. Jede (einbindbare) Applikation hat eine eigene eindeutige classid (classid = class identifier = Klassenbezeichner). Die Angabe besteht aus der fest vorgegebenen Zeichenfolge CLSID:, gefolgt von der Bezeichner-ID. Im Fall von Flash ist das: classid="CLSID:D27CDB6E-AE6D-11cf-96B8-444553540000".

Mithilfe der codebase kann eine Quelle für das Downloaden der Applikation angege-ben werden. Im Fall von Flash ist dies das Flash-Plug-in. Auf die codebase wird dann zugegriffen, wenn das benötigte Plug-in nicht im Browser des Users installiert ist.

Die Attribute id und name

Wie man aus dem obigen Codefragment leicht erkennen kann, wurde das id-Attri-but in beiden genannten Tags gleichermaßen angewendet. Grundsätzlich ist es nicht erlaubt, ein und dieselbe ID mehrmals zu verwenden. Nachdem jedoch in allen Fäl-

Page 183: Flash cs3, ajax und php

K A P I T E L 5170

len nur eines der beiden Tags zum Einsatz kommt, stellt dies kein Problem dar: Der Internet Explorer von Microsoft ignoriert das in das <object>-Tag verschachtelte <embed>-Tag, genau wie der Netscape Navigator das <object>-Tag ignoriert. Viel-mehr wäre dieser Einsatz von IDs für uns sogar ein großer Vorteil, da wir somit auf eine immer gleiche ID zugreifen können.

Anders verhält es sich beim name-Attribut. Im Weiteren werden wir sehen, dass es keine einheitliche Möglichkeit gibt, um eine eingebundene Flash-Datei über JavaScript anzusprechen. Aus diesem Grund möchte ich an dieser Stelle folgenden Tipp geben:

Verwenden Sie das id-Attribut für das <object> und <embed>.

Verwenden Sie das name-Attribut nur für das <embed>.

Nachdem dieser (wichtigste) Schritt erledigt ist, ist unsere Flash-Datei eindeutig iden-tifizierbar und kann nun per JavaScript angesprochen werden. An dieser Stelle muss man – wie es der Webdesigner leider schon allzu oft gewohnt ist – zwischen verschie-denen Browsern unterscheiden.

Allgemein dient der Befehl SetVariable dazu, auf Variablen innerhalb von Flash zuzugreifen. Hierzu müssen diesem Befehl zwei Attribute zugewiesen werden:

SetVariable("Variablenname", Wert);

Dieser Befehl muss noch auf das Flash-Objekt angewandt werden – man muss sich also Zugriff auf die eingebundene Flash-Datei verschaffen. Sofern der verwendete Brow-ser das DOM (Document Object Model ) für JavaScript unterstützt, ist der geeignete Befehl in JavaScript getElementById .

Den eher ungewöhnlichen Fall (dass dieser Fall gar nicht so ungewöhnlich ist, werden wir leider weiter unten noch sehen …) einmal ausgeschlossen, dass das DOM nicht unterstützt wird, lautet der vollständige Zugriff auf die eingebundene Flash-Datei demnach wie folgt:

document.getElementById("ID des Elements").SetVariable("Variablenname", Wert);

Listing 5.2: DOM-korrekte Syntax für den Zugriff auf eine Flash-Variable per JavaScript

Alternativ dazu lässt sich im Internet Explorer jedes vorhandene Element auch über document.all ansprechen, also:

document.all["ID des Elements"].SetVariable("Variablenname",Wert);

Listing 5.3: Alternative Syntax für den Internet Explorer

Um den Code für alle gängigen Browser zu optimieren, müssen wir jedoch ein biss-chen tiefer in die Trickkiste greifen. Je nach Browser möchte das Flash-Plug-in unter-schiedlich angesprochen werden. Einerseits haben wir gesehen, wie es der Internet Explorer „gerne hätte“, andererseits müssen wir uns an dieser Stelle auch noch um den

u

u

id für <object>, name für <embed>id für <object>,

name für <embed>

DOM-korrekte Syntax

DOM-korrekte Syntax

Internet Explorer Syntax alternativeInternet Explorer

Syntax alternative

Firefox Syntaxalternative

Firefox Syntaxalternative

Page 184: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 171

(beliebten) Browser namens Firefox kümmern – dieser möchte wiederum, dass er über das embeds -Objekt angesprochen wird, also:

document.embeds["Name des Elements"].SetVariable("Variablenname",Wert);

Listing 5.4: Syntax für den Zugriff auf eine Flash-Variable per JavaScript im Firefox

Wie nicht anders zu erwarten war, funktioniert die Sache leider nicht im Safari-Brow-ser unter Mac OS. Somit bleibt uns nichts anderes übrig, als noch tiefer in der Trick-kiste zu stöbern …

Grundsätzlich kann man auch direkt über das document-Objekt auf HTML-Elemente zugreifen, sofern der Browser das zulässt:

document["Name des Elements"].SetVariable("Variablenname", Wert);

Listing 5.5: Alternative Schreibweise, um auch noch den Safari-Browser „mit ins Boot“ zu holen.

Fassen wir all die Varianten zusammen, um schlussendlich ein Script zu erhalten, mit dem der Zugriff auf die Flash-Datei in allen gängigen Browsern möglich ist, so erhalten wir:

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]; }

}

function sendDataToFlash() {

var myswf = getFlashElement("myswf");

myswf.SetVariable("myVar", "EXPLODE");

}

Listing 5.6: Universalzugriff auf eine eingebundene Flash-Datei

Zur Erklärung:

Die Funktion getFlashElement() findet den korrekten „Zugang“ zur Flash-Datei und liefert die entsprechende Referenzierung an das aufrufende Script zurück:

Sollte es sich um den Internet Explorer handeln (und nicht um einen Opera-Browser, der sich als Internet Explorer ausgibt), so liefert es document.all[elem] zurück.

Sollte es sich nicht um den Internet Explorer handeln, so erhält man document[elem].

u

u

u

Page 185: Flash cs3, ajax und php

K A P I T E L 5172

Die Funktion sendDataToFlash() ruft die oben genannte Funktion auf, um kor-rekt auf die Flash-Datei zuzugreifen, und setzt danach mit der Methode SetVari-able eine Variable namens myVar auf den Wert „EXPLODE“.

Aktion in Flash auslösen

Sehen wir uns dies an einem Beispiel an: Einmal angenommen, man möchte durch Klicken auf einen HTML-Button in Flash eine Aktion auslösen. Nachdem man per JavaScript einzig und allein Variablenwerte in Flash setzen kann, ist der Aufruf einer Funktion in Flash also nicht möglich. Man umgeht dieses Problem, indem man in Flash so lange auf einen gewissen Wert einer Variablen „wartet“, bis dieser – in unserem Fall mittels JavaScript – gesetzt wird.

Im Kapitel über die ExternalInterface-Klasse werden wir sehen, dass das Procedere „Warten auf das Setzen einer Variable“ wegfällt, da es uns diese Klasse ermöglicht, direkt aus JavaScript auf ActionScript-Funktionen zuzugreifen – eine große Erleichte-rung, die jedoch erst seit Flash 8 funktioniert.

Schritt für Schritt: Flash-Aktion per JavaScript

In Flash benötigen wir für dieses Beispiel vier (vorerst) leere Bilder in der Zeitleiste.

Wie üblich legen wir für unseren ActionScript-Code eine eigene Ebene in der Zeitleiste an und benennen sie mit „Aktionen“. Die darüberliegende Ebene beinhaltet nichts anderes als Bildnamen. Solche Bildnamen erleichtern die Übersichtlichkeit in Pro-grammen enorm, außerdem ist das nachträgliche Einfügen von Bildern so auch kein Problem für das korrekte Ausführen des Codes.

Arbeitet man nicht mit Bildnamen, sondern mit den Bildnummern, müsste man nach dem Einfügen oder Löschen von Bildern immer überprüfen, ob nicht ein Codefrag-ment auf eine spezielle Bildnummer zugreift, die sich nun eventuell geändert hat.

u

External-Interface-Klasse

als Erleichterung

External-Interface-Klasse

als Erleichterung

1. Bilder anlegen1. Bilder anlegen

Page 186: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 173

In der untersten Ebene befinden sich je nach Bild in der Zeitleiste verschiedene Texte. Dies hilft uns dabei, uns bei der Darstellung der Flash-Datei im Browser leicht zurecht-zufinden. Anhand der ausgegebenen Texte können wir leicht überprüfen, ob unser Code funktioniert.

Im ersten Bild – dem Initialisierungsbild der Zeitleiste – deklarieren wir eine Variable namens myVar vom Typ String und weisen dieser den Wert "" (leerer String) zu.

Zur Erinnerung: Möchten Sie in ein Bild der Zeitleiste ActionScript-Code schreiben, so müssen Sie das Bild in der Zeitleiste markieren und danach im ActionScript-Editor den Code eingeben. Sollte der Editor nicht eingeblendet sein, so finden Sie diesen in der Menüzeile im Menü FENSTER bzw. durch Drücken der Taste (F9).

var myVar:String = "";

Im Folgenden werden wir diese Variable auf ihren Wert abfragen.

Im zweiten Bild wird kein Code ausgeführt. Dieses Bild bekommt jedoch einen Namen („warten“), den wir zum Zurückspringen verwenden werden.

Um einem Bild der Zeitleiste einen Namen zu geben, muss es in der Zeitleiste zuerst markiert werden und danach im Eigenschaften-Inspektor im Feld „Bild“ ein Name eingetragen werden.

2. Variablen-deklaration2. Variablen-deklaration

3. Namens-gebung für das „Wartebild“

3. Namens-gebung für das „Wartebild“

ABBILDUNG 5.1

Das fertig programmierte Beispiel – hier unser erstes Bild in der Zeitleiste

Page 187: Flash cs3, ajax und php

K A P I T E L 5174

Im dritten Bild wird der Wert von myVar abgefragt – sollte dieser (immer noch) auf "" gesetzt sein, springen wir auf das Bild mit dem Namen „warten“ zurück. Dies geschieht so lange, bis die Variable einen String beinhaltet, der ungleich "" ist.

if(myVar=="") { gotoAndPlay("warten"); }

4. Wert von myVar abfragen

4. Wert von myVar abfragen

ABBILDUNG 5.2

Dem zweiten Bild wird kein ActionScript-Code zugewie-

sen, es dient vielmehr nur als „Sprungbild“ zum Warten auf das Setzen von myVar durch

den externen JavaScript-Code.

ABBILDUNG 5.3

Wurde durch den externen JavaScript-Code myVar

auf einen Wert ungleich "" gesetzt, so erfüllt sich die

Bedingung in Bild 3 und Flash springt ins vierte Bild

der Zeitleiste weiter, wo durch einen stop()-Befehl das Weiterlaufen des Zeigers

in der Zeitleiste verhindert wird.

Page 188: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 175

In Bild 4 ist das Beispiel auch schon zu Ende – mithilfe des Befehls stop(); beenden wir das Abspielen der Zeitleiste.

stop();

Des Weiteren beinhaltet das vierte Bild ein dynamisches Textfeld zur Ausgabe einer Kontrollmeldung.

Hierzu erzeugen Sie mithilfe des Textwerkzeugs ein Textfeld, dem Sie im Eigenschaften-Inspektor den Typ „Dynamischer Text“ zuweisen.

5. Das Ende-Bild5. Das Ende-Bild

Tipp zum Ausgeben von KontrollinformationenDer Entwickler von Flash-Anwendungen kommt oftmals in die Situation, dass er die Flash-Anwendung online in einem Browser testen muss. Nachdem ihm dort das Ausgabefenster von Flash nicht zur Verfügung steht, verwendet er gern dynamische Textfelder oder TextArea-Kom ponenten zum Ausgeben von Variablenwerten. Welche der beiden Varianten Sie verwenden, ist Ihnen überlassen. Für einzeilige Ausgaben verwenden wir bevorzugt dynamische Textfelder, für mehrzeilige Ausgaben TextArea-Komponenten, wegen des dort automatisch erzeugten Scrollbalkens.

Werfen wir noch einmal einen Blick auf unseren Code und dessen Ablauf: Offen-sichtlich wird in Bild 1 eine Variable myVar vom Typ String deklariert und es wird ihr der Wert "" zugewiesen. Gelangt der Bildzeiger in der Zeitleiste zu Bild 3, so wird hier überprüft, ob diese Variable den Wert "" besitzt – sollte dies der Fall sein, springt Flash in das Bild mit dem Namen „warten“ (in unserem Fall das zweite Bild) zurück und spielt von dort aus weiter ab. Solange myVar also den Wert "" besitzt, springt Flash fortwährend zwischen Bild 2 und 3 hin und her. Sollte myVar irgendwann einen

6. Codeanalyse6. Codeanalyse

ABBILDUNG 5.4

In Bild 4 erstellen Sie ein dynamisches Textfeld.

Page 189: Flash cs3, ajax und php

K A P I T E L 5176

Wert ungleich "" besitzen, spielt Flash zu Bild 4 weiter ab und wird dort per stop(); angehalten. Im Prinzip haben wir also eine sehr einfache Schleife programmiert!

Im nächsten Schritt überlegen wir uns den JavaScript-Code, der unserer Flash-Variable myVar den Wert „EXPLODE“ zuweist, um zum vierten Bild in der Flash-Zeitleiste zu gelangen. Dieser Wert soll genau dann gesetzt werden, wenn wir auf einen Button im HTML-Dokument klicken.

7. JavaScript-Code

7. JavaScript-Code

ABBILDUNG 5.5

So soll unser kleines Beispiel in einem Browser darge-stellt werden. Die Flash-

Anwendung wartet auf einen Klick auf den nachfolgenden

Button.

Wenden wir uns zunächst einmal dem Inhalt des <body> zu. Um einen Button HTML-konform in das Dokument einzubauen, benötigen wir ein Formular. Auß er für diesen Button wäre das Formular nicht erforderlich, lassen Sie sich deshalb also nicht davon ablenken. Ebenso dient die eingebaute Tabelle nur der übersichtlicheren Darstellung. Letzten Endes soll das HTML-Dokument in einem Browser wie in Abbildung 5.5 gezeigt dargestellt werden.

<div id="Flash">

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/fl ash/swfl ash.cab#version=7,0,19,0" width="200" height="150" id="myswf">

<param name="movie" value="browserAnFlash01.swf" />

<param name="quality" value="high" />

<embed id="myswf" name="myswf" src="browserAnFlash01.swf" width="200" height="150" quality="high" pluginspage="http://www.macromedia.com/go/getfl ashplayer" type="application/x-shockwave-fl ash"></embed>

</object>

8. HTML-Dokument

erstellen

8. HTML-Dokument

erstellen

Page 190: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 177

</div>

<div id="SendButton">

<form name="frmSetVariable" id="frmSetVariable" method="post" action="">

<input type="button" value="Daten senden" onClick="sendDataToFlash();" />

</form>

</div>

Listing 5.7: Einbinden der Flash-Datei und Erzeugen des Formulars inklusive Button

Der wesentliche Teil des Codes – neben dem eingebundenen Flash-Dokument, das im <object> durch id="myswf" und im <embed> durch name=" myswf" eindeutig gekennzeichnet ist – ist der Aufruf der Funktion sendDataToFlash() durch Klicken auf den Button:

<input type="button" value="Daten senden" onclick="sendDataToFlash();" />

Es wird also eine JavaScript-Funktion namens sendDataToFlash() aufgerufen, wobei der Name der Funktion frei wählbar ist, da es sich hier nicht um eine vordefi-nierte Funktion handelt.

Im Allgemeinen werden JavaScript-Blöcke (und da im Speziellen Funktionsdefini-tionen) im <head>-Bereich eines HTML-Dokuments eingebunden, weshalb auch ich Ihnen diese Vorgehensweise empfehle.

Hier zunächst einmal der benötigte JavaScript-Code:

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]; }

}

function sendDataToFlash() {

var myswf = getFlashElement("myswf");

myswf.SetVariable("myVar", "EXPLODE");

}

Listing 5.8: Die benötigten Funktionen zum Erkennen der korrekten „Ansprache“ der SWF-Datei einerseits (Funktion getFlashElement) sowie dem Schreiben der Variable innerhalb Flash andererseits (Funktion sendDataToFlash).

Die Funktion sendDataToFlash() (das ist diejenige, die beim Klick auf den Button aufgerufen wird) selbst ruft – wie im einleitenden Teil dieses Kapitels dargelegt – wie-

9. JavaScript-Funktion schreiben

9. JavaScript-Funktion schreiben

Page 191: Flash cs3, ajax und php

K A P I T E L 5178

derum eine Funktion getFlashElement(elem) auf, welche laut Document Object Model von JavaScript die eingebundene Flash-Datei (Attribut elem) anspricht. Die entsprechende Referenzierung wird von der Funktion per return zurückgeliefert.

Nachdem die Rückgabe der Referenzierung erfolgt ist, wird mithilfe der Methode SetVariable("Variablenname", "Variablenwert") innerhalb der Flash-Datei die Variable myVar auf den Wert „EXPLODE“ gesetzt.

Als Ergebnis unserer Bemühungen erhalten wir also:10. Testen der Funktio nalität10. Testen der

Funktio nalität

ABBILDUNG 5.6

Per Klick auf den Button wurde die Variable myVar

in der eingebundenen Flash-Datei auf den

Wert „EXPLODE“ gesetzt. Möglich wird das durch die

Verwendung der JavaScript-Funktion SetVariable().

Mögliche Fehlerquelle: die Adobe-eigene Funktion AC_FL_RunContent()An dieser Stelle sei angemerkt, dass hier eine potenzielle Fehlerquelle zutage treten kann: Im Internet Explorer muss eine eingebundene Flash-Datei „aktiviert“ werden. Dies bedeutet, dass der User die Flash-Datei im Browser anklicken muss, erst dann gilt sie als aktiviert und es kön-nen etwaige Benutzereingaben (Klicken eines Buttons in der Flash-Datei o.Ä.) getätigt werden. Um dies zu umgehen, hat sich Adobe entschlossen, einen Workaround anzubieten und damit die Flash-Datei per JavaScript einzubinden.Die von Adobe angebotene JavaScript-Funktion (AC_FL_RunContent()) lässt leider nicht zu, dass das <object> ein id-Attribut und das <embed> ein name-Attribut erhalten. Somit würde unser Code zum Ansprechen der Flash-Datei beispielsweise im Firefox und im Safari nicht mehr funktionieren.Um dies zu korrigieren, muss man in der Datei AC_RunActiveContent.js in der Funktion AC_FL_RunContent() die Zeilen

case "id":

durch

case "id":

Page 192: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 179

ret.objAttrs[args[i]] = args[i+1];

break;

und

case "name":

durch

case "name":

ret.embedAttrs[args[i]] = args[i+1];

break;

ersetzen.

5.1.2 Variante 2: Verwenden von HTML- Attributen zum Setzen von VariablenEine zweite Möglichkeit, Variablen von „außerhalb“ in einer Flash-Datei zu setzen, erfolgt mithilfe geeigneter Attribute in den Tags <object> und <embed>. Je nach ver-wendetem Browser müssen die entsprechenden Tags verwendet werden.

Nachdem die Attribute direkt in den HTML-Code geschrieben werden, ist diese Vari-ante unabhängig von JavaScript.

Grundsätzlich wird mit dem Attribut FlashVars gearbeitet, dem als Wert der Variab-lenname inklusive Wertzuweisung zugewiesen wird:

FlashVars = "meineVariable=meinWert"

Die Variablen inklusive Wert sind bereits im ersten Frame der Flash-Datei verfügbar und müssen nicht explizit deklariert werden. Es sollte darauf geachtet werden, dass – entgegen der vorigen Variante – die Variable nicht deklariert und ihr ein Wert zuge-wiesen wird, denn ansonsten würde der von außerhalb gesetzte Wert der Variablen überschrieben werden.

Beachten Sie bitte außerdem, dass – unabhängig vom Wertetyp – der Wert von meine-Variable immer ohne Anführungszeichen geschrieben wird. Somit:

korrekt: FlashVars = “myVar=once again”

falsch: FlashVars = „myVar=‘once again‘“

Es können beliebig viele Variablen über diese Methode gesetzt werden.

Attribute in <object>

Im Fall des <object> wird mit dem im <object> verschachtelten <param> gearbeitet:

<param name="FlashVars" value="myVar=once again" />

u

u

Kein JavaScript benötigtKein JavaScript benötigt

Page 193: Flash cs3, ajax und php

K A P I T E L 5180

Attribute in <embed>

Im Fall des <embed> verhält sich die Sache ähnlich, jedoch wird üblicherweise kein zusätzliches verschachteltes Tag (wie oben das <param>) verwendet, sondern alle Attri-bute werden direkt im <embed> aufgelistet:

<embed FlashVars="myVar=once again" .. ></embed>

In der nachfolgenden Abbildung sehen Sie eine Anwendung, die ähnlich wie die Anwendung im vorigen Kapitel arbeitet. Der Auszug des entsprechenden HTML-Codes ist wie folgt:

..

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/fl ash/swfl ash.cab#version=7,0,19,0" width="200" height="150" id="myswf">

<param name="movie" value="browserAnFlash01_var2.swf" />

<param name="quality" value="high" />

<param name="FlashVars" value="myVar=once again" />

<embed id="myswf" name="myswf" FlashVars="myVar=once again" src="browserAnFlash01_var2.swf" width="200" height="150" quality="high" pluginspage="http://www.macromedia.com/go/getfl ashplayer" type="application/x-shockwave-fl ash"></embed>

</object>

..

Listing 5.9: Auszug aus dem Listing der Datei browserAnFlash_var2.php, das Sie auf der Website zum Buch downloaden können.

ABBILDUNG 5.7

Ausgabe der Variante 2, in Flash-Dateien

Variablenwerte zu setzen. Wie Sie sehen, wird kein

Button mehr zum Setzen des Variablenwerts benötigt – die

Variablen und zugehörigen Werte werden als Attribute

in den entsprechenden Tags <object> und <embed>

gesetzt.

Page 194: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 181

Der große Vorteil dieser Variante 2 ist, dass sie ohne weiteres in jedem halbwegs gän-gigen Browser funktioniert und kein JavaScript benötigt wird. Nachteilig ist, dass sie nicht interaktiv (also beispielsweise per Klick auf einen Button) verwendet werden kann.

5.2 Daten senden: Flash an BrowserIn diesem Abschnitt beschäftigen wir uns damit, wie Flash auf Clientseite mit seiner Außenwelt Kontakt aufnehmen kann. Im nächsten Abschnitt widmen wir uns dann der Frage, wie Flash auf Serverseite Daten übermitteln kann.

5.2.1 Kontaktaufnahme mit getURLGehen wir doch kurz auf die Frage ein, welche Möglichkeiten der Webentwickler in Flash nutzen kann, damit Flash mit seinem „Äußeren“ – nämlich dem Browser – in Kontakt tritt. Als Erstes würde uns hier wohl der Flash-Befehl getURL() einfallen, mit dem man eine URL in einem Browser-Fenster oder einem Frame öffnen kann. Dieser Befehl ist demnach mit einem Anker <a> in HTML vergleichbar.

Nach kürzerem (oder längerem) Nachdenken über die Möglichkeiten von Ankern in HTML fällt uns ein, dass mithilfe des reservierten Worts javascript: im href-Attri-but ein JavaScript-Befehl ausgeführt werden kann, also:

<a href="javascript:JavaScript-Befehl;">Klick mich</a>

oder in einem Beispiel:

<a href="javascript:alert(‚Hallo Welt!');">Klick mich</a>

JavaScript ausführen

Beim Klick auf diesen Link wird der JavaScript-Befehl alert() ausgeführt, der in einem Meldefenster den Text „Hallo Welt!“ ausgibt. Das bedeutet also, dass HTML mithilfe von Ankern doch in der Lage ist, JavaScript-Befehle auszuführen. Wenn also dieses Tag vergleichbar mit dem Flash-Befehl getURL() ist, so liegt der Versuch nahe, dies auch mit dem Flash-Befehl auszuprobieren. Gesagt, getan:

getURL("javascript:JavaScript-Befehl;");

ist exakt vergleichbar mit dem HTML-Befehl

<a href="javascript:JavaScript-Befehl;">…</a>

Sobald in getURL() im URL-Bereich javascript: eingegeben wird, wird an den Browser eine JavaScript-Anfrage gesendet – so einfach ist die Kontaktaufnahme von Flash mit dem Browser per JavaScript also! Testen wir unser neu erlangtes Wissen an einem konkreten Beispiel.

Page 195: Flash cs3, ajax und php

K A P I T E L 5182

Schritt für Schritt: JavaScript-Funktion in Browser-Fenster über Flash aufrufen

Ziel dieses Beispiels ist, dass durch Klicken auf einen Flash-Button eine JavaScript-Funktion aufgerufen wird, die wiederum ein Meldungsfenster mit dem Text „Hallo Außenwelt!“ öffnet.

Wenden wir uns zunächst Flash zu. Hier ist die Sachlage sehr einfach – benötigt wird ein Button auf der Flash-Bühne, der beim Loslassen den getURL()-Befehl aufruft. Dieser veranlasst wiederum das Ausführen von JavaScript-Code im Browser.

Der zugehörige Code für den Button ist also:

on(release) {

getURL("javascript:executeMyCode();");

}

Listing 5.10: Mehr an Code ist in Flash nicht nötig, um eine (externe) JavaScript-Funktion aufzurufen – die Kommunikation zwischen Flash und JavaScript von Flash aus ist somit denkbar einfach.

1. ActionScript-Code erstellen

1. ActionScript-Code erstellen

ABBILDUNG 5.8

Die Abbildung zeigt den Code aus dem obigen Listing

(angewandt auf den Button). Alternativ hätte man auch

ein Script schreiben können, das nicht dem Button zuge-wiesen wird, sondern in der

Zeitleiste programmiert wird.

Für den Fall, dass Ihnen das Anbringen von Script-Code auf einen Button nicht so „sympathisch“ ist (vgl. hierzu auch das Kapitel über die Grundlagen der Programmie-rung), könnte man alternativ auch folgenden Code in die Zeitleiste der Bühne platzie-ren (vorausgesetzt, Sie haben dem Button den Namen „callJS_btn“ gegeben):

Page 196: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 183

callJS_btn.onRelease = function():Void {

getURL("javascript:executeMyCode();");

}

Listing 5.11: Alternativer Code für die Abarbeitung eines Klicks auf den Flash-Button (genau genommen handelt es sich um das Loslassen der Maustaste (onRelease), aber das wissen Sie ja bereits vom Grund-lagenkapitel).

Mehr Arbeit fällt für die Flash-Abteilung auch schon nicht mehr an. Beachten Sie jedoch bitte an dieser Stelle, dass sofern das Flash-Dokument nicht in einer Browser-Umgebung getestet wird, das Aufrufen dieses Codes nicht funktioniert – die Testum-gebung in Flash ist hier nicht ausreichend.

Bedeutet das Weniger an Arbeit in Flash nun ein Mehr an Arbeit in JavaScript im HTML-Dokument, wo auch die Flash-Datei eingebunden ist? Mitnichten, auch in JavaScript fällt der Arbeitsaufwand sehr gering aus:

<script language="javascript" type="text/javascript">

<!--

function executeMyCode() {

alert("Hallo Aussenwelt!");

}

//-->

</script>

Listing 5.12: JavaScript-Code, um die Anweisungen aus Flash heraus abarbeiten zu können.

2. JavaScript-Code erstellen2. JavaScript-Code erstellen

ABBILDUNG 5.9

Wie Sie sehen, ist die obige Schreibweise ebenso mög-lich. Im Allgemeinen wird diese Schreibweise auch bevorzugt, da so der Code übersichtlicher – da in der Zeitleiste platziert – bleibt.

Page 197: Flash cs3, ajax und php

K A P I T E L 5184

Die aus Flash aufzurufende JavaScript-Funktion wird – wie üblich – zwischen den HTML-Tags <script> und </script> definiert. Flash ist in der Lage, mithilfe des Befehls getURL und dem verwendeten URL-Attribut mit beginnendem javascript: direkt die JavaScript-Funktion aufzurufen.

ABBILDUNG 5.10

Das Ergebnis unserer Arbeit: Flash hat eine JavaScript-

Funktion angesprochen.

5.3 Die ExternalInterface-Klasse – Flash 8 und höherSeit der Einführung von Flash 8 ist Flash in der Lage, besser und umfassender mit JavaScript zu interagieren (versierte Leser wissen, dass dieses System auf dem „JavaScript Integration Kit“ basiert, der erstmals für den Flash-Player r6.5 vorgestellt wurde und somit eigentlich schon in früheren Versionen von Flash als „Add-On“ verfügbar war). Die Möglichkeit, von der hier gesprochen wird, ist die External-Interface -Klasse – diese ermöglicht die Kommunikation einer Flash-Anwendung mit irgendeiner anderen Anwendung, in der Flash eingebettet ist. In unserem Fall ist diese „andere Anwendung“ eine HTML-Seite – es könnte jedoch auch eine beliebige andere Anwendung (etwa eine Director-Umgebung) sein.

Vonseiten Adobe wird die Kommunikation zwischen ActionScript und JavaScript über die ExternalInterface-Klasse empfohlen. Folgende Möglichkeiten stehen uns zur Verfügung:

Flash an Browser: Von ActionScript aus können beliebige JavaScript-Funktionen aufgerufen werden, und zwar mit einer beliebigen Anzahl an Übergabeparametern. Des Weiteren ist ActionScript in der Lage, Rückgabewerte aus der aufgerufenen JavaScript-Funktion zu erhalten.

u

Page 198: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 185

Browser an Flash: Von JavaScript aus können beliebige ActionScript-Funktionen aufgerufen werden. Eventuelle Rückgabewerte der ActionScript-Funktion werden direkt von der JavaScript-Funktion entgegengenommen.

Ein großer Vorteil der Verwendung der ExternalInterface-Klasse ist, dass sie von allen gängigen Browsern unterstützt wird (Internet Explorer ab Version 5, Netscape ab 8, Mozilla ab 1.7.5, Firefox ab 1.0, Safari ab 1.3). Nichtsdestotrotz bleibt es uns natürlich nicht erspart, beim Ansprechen der SWF-Datei zwischen den Browsern zu unterscheiden – hierzu haben wir uns im vorigen Kapitel „Einbinden von Flash“ Gedanken gemacht und ein allgemein gültiges Script entwickelt. Des Weiteren müssen wir beachten, dass der Browser für die Verwendung dieser Klasse entweder ActiveX oder die NPRuntime-API unterstützen muss.

Der Hauptvorteil dieser Klasse ist jedoch, dass von beiden Seiten aus (von Seiten JavaScript und von Seiten ActionScript) Funktionen der jeweils anderen Technologie aufgerufen werden können. Dies bringt nämlich auch mit sich, dass – entgegen unserer bisherigen Kenntnis – man nicht mehr explizit auf das Setzen von Variablenwerten warten muss, sondern direkt Funktionen aufgerufen werden können.

Wo liegt also der Nachteil dieser Klasse, wenn doch alles so toll scheint? Nun, zwei Punkte könnte man als Nachteil anmerken: Zunächst einmal funktioniert diese Klasse standardmäßig erst ab Flash 8 (ist das wirklich ein Nachteil, schließlich arbeiten wir bereits mit Flash CS3, also dem Nachfolger von Flash 8?!). Außerdem bedeutet das Arbeiten mit externen Klassen auch immer einen Mehraufwand in der Dateigröße (wir werden jedoch sehen, dass sich der „Mehraufwand“ sehr in Grenzen hält, zumal Übertragungszeiten für Dateien im Kbyte-Bereich nicht mehr wirklich ein Problem darstellen).

Im Weiteren werden wir sehen, dass mit der Einführung von Flash CS3 und somit ActionScript 3.0 einige Erweiterungen erfolgt sind – mehr dazu im ActionScript 3.0-Teil dieses Kapitels.

5.3.1 ExternalInterface-Klasse mit ActionScript 1.0/2.0Wie bereits oben erwähnt, ermöglicht uns die ExternalInterface-Klasse das wech-selseitige Aufrufen von Funktionen in sowohl JavaScript als auch ActionScript.

Bevor wir jedoch in medias res gehen können, müssen wir uns zunächst noch Gedan-ken machen, wie wir die externe Klasse einbinden und ob die ExternalInterface-Klasse von der „Gegenseite“ (also in unserem Fall ein XHTML-basiertes Dokument) überhaupt unterstützt wird.

Die zu importierende Klasse trägt den Namen „ExternalInterface“ und ist eine Unter-klasse von external, die wiederum eine Unterklasse der allgemeinen Klasse flash ist.

u

Vorteile!Vorteile!

Nachteile?Nachteile?

Importieren der KlasseImportieren der Klasse

Page 199: Flash cs3, ajax und php

K A P I T E L 5186

Da ExternalInterface in ActionScript 2.0 die einzige Unterklasse von external ist, lautet der geeignete Befehl zum Importieren somit:

import fl ash.external.*;

Alternativ wäre auch folgende Variante zulässig:

import fl ash.external.ExternalInterface;

Sobald der Import geschehen ist, stehen uns folgende Möglichkeiten der Klasse zur Verfügung:

Eigenschaften

Eigenschaft Typ Beschreibungavailable Boolean Gibt an, ob das Dokument, in dem die SWF-Datei

eingebunden ist, die ExternalInterface-Klasse unterstützt. Diese Eigenschaft sollte immer zuerst abgeprüft werden, bevor man weitere Methoden und Eigenschaften der Klasse benützt.

Bei true wird die Klasse unterstützt, bei false nicht.

objectID String Gibt den Wert des name- bzw. id-Attributs zu-rück:

Internet Explorer: Wert des id-Attributs im <object>

Firefox (Mozilla-basierte Browser): Wert des name-Attributs im <embed>

Beachten Sie bitte, dass Sie – wie schon des Öfteren angemerkt – für das <object> aus-schließlich das id-Attribut und für das <embed> ausschließlich das name-Attribut verwenden.

Methode Attribute BeschreibungaddCallback :Boolean Registriert eine Funktion als „von JavaScript

aufrufbar“. Diese Methode muss verwendet wer-den, um eine ActionScript-Funktion überhaupt für JavaScript „verwendbar“ zu machen – wird diese Methode für eine spezielle ActionScript-Funktion nicht verwendet, kann JavaScript diese Funktion nicht aufrufen. Deshalb: jede „für JavaScript sichtbare“ Funktion mit dieser Methode explizit angeben (registrieren).

Die Methode liefert den Wert true zurück, sollte das Registrieren erfolgreich gewesen sein; an-sonsten liefert sie false.

methodName:String Ein Name (kann auch ein „Alias“ sein) für die Funktion, die JavaScript aufrufen kann. Dieser Name muss nicht notwendigerweise mit dem tatsächlichen Namen der ActionScript-Funktion übereinstimmen.

instance:Object Hier kann ein spezielles Objekt angegeben werden. Ist im Allgemeinen nicht notwendig, deshalb wird zumeist der Wert null verwendet.

Page 200: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 187

method:Function Als drittes Attribut wird der tatsächliche Name der ActionScript-Funktion angegeben. Bitte beachten Sie, dass der Name der Funktion ohne Anführungszeichen angegeben werden muss (Typ: Function, nicht String).

call:* Ruft eine JavaScript-Funktion auf. Wie Sie wissen, muss es sich nicht notwendigerweise um JavaScript (in XHTML) handeln – viel-mehr ruft die Methode call eine beliebige Funktion in einem beliebigen „Container“ (bei uns: das XHTML-Dokument) auf, der das ExternalInterface-API unterstützt. In unserem Fall als Webdesigner ist es zumeist eben ein XHTML-Dokument.

Der Rückgabewert der Funktion ist abhängig von der Funktion selbst:

null: Es ist ein Fehler aufgetreten.

Andere Typen: Es ist kein Fehler aufgetreten.

Die möglichen Fehler werden weiter unten im Abschnitt Browser an Flash an Browser ausführ-lich erklärt.

functionName:String An dieser Stelle wird der Name der JavaScript-Funktion angegeben, die von Flash aus aufgeru-fen werden soll.

arguments:Object An die JavaScript-Funktion kann eine beliebige Anzahl von Werten übergeben werden, wobei die Werte durch Komma voneinander zu tren-nen sind. Die Datentypen aus ActionScript wer-den automatisch in Datentypen von JavaScript überführt („marshalling“).

Tabelle 5.1: Mit diesen Eigenschaften und Methoden ausgestattet können wir ans Werk gehen.

Neben diesen Eigenschaften und Methoden der ExternalInterface-Klasse existie-ren noch weitere (an diese Klasse vererbte) Eigenschaften und Methoden, die für uns jedoch nicht wirklich wichtig sind – eine Übersicht derer finden Sie in der ActionS-cript-Hilfe, wenn Sie im Komponenten-Referenzhandbuch die ExternalInterface class nachschlagen.

Netterweise stellt uns Flash zum Überprüfen der Verfügbarkeit der Klasse also eine ein-fache Möglichkeit zur Verfügung: die Eigenschaft available der ExternalInter-face-Klasse. Sollte ein Abfragen dieser Eigenschaft true ergeben, sind wir sozusagen „im Spiel“ und können die Klasse verwenden. Sollte wider Erwarten doch der Wert false zurückgeliefert werden, so müssen wir den altbewährten Weg mit den anfangs im Kapitel erlernten Fähigkeiten gehen.

Der grundlegende Scriptcode für das Arbeiten mit der ExternalInterface-Klasse sieht dementsprechend wie folgt aus:

import fl ash.external.*;

if(ExternalInterface.available) {

ExternalInterface.availableExternalInterface.available

Page 201: Flash cs3, ajax und php

K A P I T E L 5188

trace("EXTERNAL INTERFACE verfüg150

bar");

}

else {

trace("EXTERNAL INTERFACE NICHT verfügbar");

}

Listing 5.13: Das wichtige Codefragment zum Einbinden der ExternalInterface-Klasse (die trace-Befehle können selbstverständlich auskommentiert werden)

Ein Wort zum Testen der KlasseBitte bedenken Sie, dass Sie die Möglichkeiten der ExternalInterface-Klasse nur dann nutzen können, wenn Sie eine entsprechende „Umgebung“ vorfinden. Eine solche Umgebung ist ein XHTML-Dokument in einem Browser mit den oben genannten Voraussetzungen (Versionen beachten) oder eben die Entwicklungsumgebung von Flash. Wenn Sie also den obigen Code testen und die Eigenschaft available immer false zurückgibt, dann ist kein entsprechender Container vorhanden.

Browser an Flash Variante 2

Möchte man nun den Weg gehen und den Browser eine Flash-Funktion aufrufen las-sen, so müssen drei Schritte vorgenommen werden:

1. Die entsprechende ActionScript-Funktion muss erzeugt werden.

2. Diese Funktion muss mithilfe der Methode addCallback freigegeben werden.

3. Die Funktion muss von JavaScript aus aufgerufen werden.

Sehen wir uns also die drei Schritte der Reihe nach an. Als Beispiel verwenden wir das-jenige aus Abbildung 5.6, nur dass wir nun die ExternalInterface-Klasse bemühen. Ziel des Beispiels ist es, dass per Klick auf einen Button eine JavaScript-Funktion auf-gerufen wird, die wiederum eine in Flash vorhandene ActionScript-Funktion aufruft. Die ActionScript-Funktion soll dann in einem dynamischen Textfeld denjenigen Wert ausgeben, der von JavaScript an ActionScript übergeben wurde (in unserem Fall wird es der Text „EXPLODE“ sein):

Page 202: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 189

Entgegen unserer Entwicklung aus dem Kapitel Browser an Flash werden nun in der ActionScript-Datei nur noch zwei Bilder in der Zeitleiste benötigt (wobei wir es theo-retisch auch auf ein Bild reduzieren könnten, wenn wir die Textfelder dynamisch erzeugen):

ABBILDUNG 5.11

Die Flash-Anwendung befin-det sich im „Wartezustand“ auf das Klicken des Buttons.

ABBILDUNG 5.12

Sobald geklickt wurde, wird der Text „EXPLODE“ in einem dynamischen Textfeld aus-gegeben.

Page 203: Flash cs3, ajax und php

K A P I T E L 5190

Wenden wir uns zunächst dem Einbinden der ExternalInterface-Klasse und dem Überprüfen der Verfügbarkeit zu (Aktionenebene):

var msg:mx.controls.TextArea; //TextArea initialisieren

msg.text = "Initialisiere...\n"; //Text der TextArea zuweisen

import fl ash.external.*;

if(ExternalInterface.available) {

ABBILDUNG 5.13

Bild 1 unserer Flash-Anwendung. Wie Sie sehen,

besteht das zweite Bild lediglich noch aus anderen

Elementen in der Ebene „Ausgabetext“ – die (wich-

tigen) Ebenen „Funktionen“ und „Aktionen“ beinhalten

keinerlei weiteren Code.

Page 204: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 191

msg.text += "EXTERNAL INTERFACE verfügbar\n";

..

}

else {

msg.text += "EXTERNAL INTERFACE NICHT verfügbar\n";

}

stop();

Listing 5.14: Importieren der ExternalInterface-Klasse und überprüfen, ob diese auch verfügbar ist. In den ersten beiden Zeilen wird lediglich noch die auf der Bühne verwendete TextArea initialisiert und ihr der Text „Initialisiere…“ mit einem folgenden Zeilenumbruch (\n) zugewiesen. Die beiden Punkte „..“ deuten an, dass an dieser Stelle noch weiterer Code eingefügt wird.

War das Einbinden erfolgreich und sind die benötigten Möglichkeiten verfügbar, so wird der TextArea mit dem Namen „msg“ der Text „EXTERNAL INTERFACE verfüg-bar“ zugewiesen. Gesetzt den unwahrscheinlichen Fall, dass es nicht geklappt hat, wird der entsprechend andere Text ausgegeben.

Im nächsten Schritt definieren wir in der Funktionenebene diejenige Funktion, die später aus JavaScript aus aufgerufen werden soll:

function jumpWithJS(myText:String):Void {

myVar = myText;

gotoAndStop("fertig");

}

Listing 5.15: Defi nieren der Funktion jumpWithJS, die per JavaScript aufgerufen wird. Der Funktion wird ein Wert übergeben, der dann in einem dynamischen Textfeld (Variable myVar) angezeigt werden soll. Des Weiteren wird in der Zeitleiste auf das Bild mit dem Namen „fertig“ gesprungen.

Schritt drei ist nun das Registrieren dieser ActionScript-Funktion für die Verwendung durch JavaScript:

var msg:mx.controls.TextArea;

msg.text = "Initialisiere...\n";

import fl ash.external.*;

if(ExternalInterface.available) {

msg.text += "EXTERNAL INTERFACE verfügbar\n";

if(ExternalInterface.addCallback("tryIt",null,jumpWithJS)) {

msg.text += "Callback-Funktion ERFOLGREICH registriert\n";

}

else {

msg.text += "Callback-Funktion NICHT erfolgreich registriert\n";

Page 205: Flash cs3, ajax und php

K A P I T E L 5192

}

}

else {

msg.text += "EXTERNAL INTERFACE NICHT verfügbar\n";

}

stop();

Listing 5.16: Mithilfe der Methode addCallback wird die (tatsächlich vorhandene) ActionScript-Funkti-on jumpWithJS unter dem Pseudonym tryIt (mittels dieses Namens wird JavaScript auf die Funktion zugreifen) im Objekt null registriert. War die Registrierung der Callback-Funktion erfolgreich, wird in der darauffolgenden Zeile in die TextArea „msg“ eine entsprechende Meldung ausgegeben (dies gilt auch für den Fall, dass die Registrierung nicht erfolgreich war).

Selbstverständlich können die tatsächliche Funktion (hier: jumpWithJS) und der Aufrufname für JavaScript (hier: tryIt) gleich benannt werden – dieses Beispiel soll lediglich demonstrieren, dass dies eben nicht notwendigerweise der Fall sein muss.

Damit ist die Flash-Entwicklung so weit abgeschlossen und wir können uns dem XHTML- und JavaScript-Teil zuwenden. Zunächst wird die SWF-Datei wie gewohnt in ein XHTML-Dokument eingebettet:

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/fl ash/swfl ash.cab#version=7,0,19,0" width="200" height="150" id="myswf">

<param name="movie" value="browserAnFlash02.swf">

<param name="quality" value="high">

<embed name="myswf" src="browserAnFlash02.swf" width="200" height="150" quality="high" pluginspage="http://www.macromedia.com/go/getfl ashplayer" type="application/x-shockwave-fl ash"></embed>

</object>

Listing 5.17: Einbetten der SWF-Datei, wobei wir wie immer darauf achten, dass das id-Attribut aus-schließlich dem <object> und das name-Attribut ausschließlich dem <embed> zugewiesen wurde.

Auch unser bereits entwickeltes Script zum korrekten Ansprechen der SWF-Datei kann ohne Einschränkungen übernommen werden:

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 {

Page 206: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 193

return document[elem];

}

}

Listing 5.18: Ansprechen der SWF-Datei mittels JavaScript – eins zu eins übernommen von dem Kapitel Browser an Flash.

Der noch ausstehende Arbeitsschritt ist nun also nur noch, die ActionScript-Funktion (beachte: diese Funktion hat das Pseudonym „tryIt“) per JavaScript aufzurufen. Hierzu übernehmen wir ebenfalls die bereits entwickelte JavaScript-Funktion aus dem Kapitel Browser an Flash und benennen sie von sendDataToFlash in sendDataToFlash2 um, da wir geringfügige Änderungen vornehmen: In Zeile drei des Scripts wird die (ActionScript-)Funktion tryIt mit dem Übergabewert „EXPLODE“ aufgerufen.

function sendDataToFlash2() {

var myswf = getFlashElement("myswf");

myswf.tryIt("EXPLODE");

}

Listing 5.19: Über die JavaScript-Funktion sendDataToFlash2 wird die ActionScript-Funktion tryIt (in Wirklichkeit heißt diese Funktion in Flash nicht tryIt, sondern jumpWithJS) mit dem Übergabewert „EXPLODE“ aufgerufen.

Zu guter Letzt müssen wir noch dafür sorgen, dass unsere Funktion sendData-ToFlash2 aufgerufen wird – hierzu bedienen wir uns eines XHTML-Buttons, der auf Klick die Funktion aufruft:

<input type="button" value="Daten senden" onClick="sendDataToFlash2();" />

Listing 5.20: Ein Standard-XHTML-Button sorgt für den Aufruf der JavaScript-Funktion.

Damit sind wir fertig – mehr ist dann auch nicht mehr notwendig! Sobald Sie den Button klicken, wird die JavaScript-Funktion sendDataToFlash2 aufgerufen, die wiederum die ActionScript-Funktion tryIt (Pseudonym für jumpWithJS) mit dem Übergabewert „EXPLODE“ aufruft. Dadurch wird innerhalb der Flash-Datei die ActionScript-Funktion jumpWithJS angesprochen, die den Text „EXPLODE“ in einem dynamischen Textfeld anzeigt, welches sich im Bild mit dem Namen „fertig“ befindet.

Als Erweiterung könnte man beispielsweise nicht einen fixen Wert (wie bei uns „EXPLODE“) an Flash übergeben, sondern ein Eingabefeld in XHTML basteln und den dort eingegebenen Wert an Flash übergeben. Um dies zu bewerkstelligen, muss erst mal ein Textfeld her:

<input type="text" name="myText" id="myText" />

Danach muss die JavaScript-Funktion so angepasst werden, dass sie den Inhalt des Textfelds ausliest und an die ActionScript-Funktion übergibt:

Page 207: Flash cs3, ajax und php

K A P I T E L 5194

var textToFlash = document.forms["frmExternalInterface"].elements["myText"].value;

myswf.tryIt(textToFlash);

Listing 5.21: Zunächst wird eine Variable textToFlash angelegt, die den Inhalt des Formularfelds my-Text im Formular frmExternalInterface ausliest. Der Inhalt von textToFlash wird dann mithilfe des Funktionsaufrufs tryIt an Flash übermittelt.

Gesagt – getan. Hier das Ergebnis:

ABBILDUNG 5.14

Der im Formularfeld einge-gebene Text „Hallo Welt“ wird

in Kürze an die Flash-Datei übermittelt (siehe folgende

Abbildung).

ABBILDUNG 5.15

Der Text „Hallo Welt“ wurde an Flash übermittelt und im dynamischen Textfeld

angezeigt.

Page 208: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 195

Tipp: Testen Sie immer wieder in verschiedenen Browsern (Internet Explorer, Firefox, Opera, Safari) die Funktionalität Ihrer Anwendungen – Ihre User werden es Ihnen mit Sicherheit danken.

Können wir das somit erlangte Wissen nun auf andere Technologien anwenden? Die Antwort ist eindeutig: ja! Die Türe steht nun sperrangelweit offen für AJAX-basierte interaktive Anwendungen zwischen Flash und XHTML, denn mit dem Zeitpunkt, wo man von JavaScript auf ActionScript-Funktionen zugreifen kann, muss Flash nicht mehr – wie bisher – auf das Setzen einer Variable „warten“, sondern kann funktions-basiert gesteuert werden. Wann diese Funktionen durch JavaScript aufgerufen werden (beispielsweise nach dem Nachladen von Daten vom Server durch AJAX), ist nun freigestellt.

Flash an Browser Variante 2

Betrachten wir den umgekehrten Fall, nämlich dass Flash eine JavaScript-Funkti-on aufruft. Hierzu bedienen wir uns der ActionScript-Methode call, die von uns (zumindest) den Namen der JavaScript-Funktion fordert, die aufgerufen werden soll. Zusätzlich können (je nach Definition der JavaScript-Funktion) noch weitere Parame-ter übergeben werden. Die allgemeine Syntax wäre:

ExternalInterface.call("Funktionsname", [Parameter1, Parameter2, ..]);

Bemühen wir das im Vorgängerkapitel Flash an Browser entwickelte Beispiel (Flas-hAnBrowser_alternativ.fla – zu finden wie üblich auf der Buch-CD mit dem Namen FlashAnBrowser02_alternativ.fla), wo wir mithilfe der Methode getURL auf eine JavaScript-Funktion zugegriffen haben, so würden wir den Code zunächst um den Import der ExternalInterface-Klasse erweitern (neben der Klasse wurde auch noch – wie im letzten Beispiel – eine TextArea angelegt, um uns ausgeben zu lassen, ob beim Import der Klasse alles geklappt hat):

var msg:mx.controls.TextArea;

msg.text = "Initialisiere...\n";

import fl ash.external.*;

if(ExternalInterface.available) {

msg.text += "EXTERNAL INTERFACE verfügbar\n";

}

else {

msg.text += "EXTERNAL INTERFACE NICHT verfügbar\n";

}

Listing 5.22: Code zum Importieren der benötigten Klasse. Neben dem Import wurde noch eine TextArea initialisiert – siehe auch nachfolgende Abbildung.

AJAX & Web 2.0?AJAX & Web 2.0?

Page 209: Flash cs3, ajax und php

K A P I T E L 5196

Dieser Teil war so weit ja schon aus dem vorigen Abschnitt bekannt. Interessanter wird es, wenn wir den Code betrachten, der bei Klick auf den Button ausgeführt werden soll:

callJS_btn.onRelease = function():Void {

msg.text+= ExternalInterface.call("executeMyCode2")+"\n";

}

Listing 5.23: Aufruf der JavaScript-Funktion executeMyCode2. Es werden bis dato noch keine Werte an die Funktion übergeben.

Der Befehl ExternalInterface.call("executeMyCode2") sorgt dafür, dass die JavaScript-Funktion executeMyCode2 (diese muss selbstverständlich in der XHTML-Datei vorhanden sein) aufgerufen wird. Da wir unsere JavaScript-Funktion so auslegen werden, dass sie uns einen Wert zurückliefert, wird dieser Wert als Text der TextArea hinzugefügt, \n sorgt wie üblich für einen Zeilenumbruch innerhalb der TextArea.

Auch die JavaScript-Funktion muss gegenüber dem Ursprungsbeispiel nicht wesent-lich verändert werden (um Verwechslungen zu vermeiden, habe ich die aufzurufende Funktion von executeMyCode auf executeMyCode2 umbenannt):

function executeMyCode2() {

alert("Hallo Außenwelt!");

return "JavaScript-Antwort: OK";

}

Listing 5.24: Sobald die JavaScript-Funktion durch ActionScript aufgerufen wird, wird in einer Alert-Box der Text „Hallo Außenwelt!“ ausgegeben und der Wert „JavaScript-Antwort: OK“ an ActionScript zurückge-geben.

ABBILDUNG 5.16

Ein Blick auf die Entwicklungsumgebung

zeigt, dass wir dem Beispiel aus dem letzten Kapitel eine

TextArea hinzugefügt haben, um diverse Statusmeldungen

ausgeben zu können. Grundsätzlich würde man die TextArea jedoch nicht

benötigen.

Page 210: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 197

Ein Test der Anwendung zeigt, dass wie zu erwarten war alles einwandfrei klappt:

Bitte beachten Sie, dass der Rückgabetext „JavaScript-Antwort: OK“ erst dann in der TextArea von Flash erscheint, wenn Sie den OK-Button der Alert-Box geklickt haben, da eine Alert-Box so lange das weitere Abarbeiten des Codes unterbricht, bis die Box wieder geschlossen ist.

Nun erweitern wir unser bestehendes Beispiel um eine Parameterübergabe von Flash an JavaScript. Konkret wollen wir zwei Parameter (eine Zahl und einen String) an JavaScript übermitteln. Um zu sehen, dass die übergebene Zahl auch wirklich eine Zahl ist, werden wir sie mit zwei multiplizieren – sollte das klappen, handelt es sich mit Sicherheit um eine Zahl!

Zunächst adaptieren wir den call-Aufruf:

callJS_btn.onRelease = function():Void {

msg.text+= ExternalInterface.call("executeMyCode2",23.5,"Uwe Mutz")+"\n";

}

Listing 5.25: Erweiterung des Codes um die Parameter 23.5 (Zahl) und „Uwe Mutz“ (Text) – die entsprechen-de Datei lautet FlashAnBrowser03_alternativ.fl a und fi ndet sich auf der Buch-CD wieder.

Danach erweitern wir die JavaScript-Funktion, sodass die übergebene Zahl mit zwei multipliziert und gemeinsam mit dem übergebenen Text in der Alert-Box ausgegeben wird:

function executeMyCode2(myNumber,myText) {

var msg = 2*myNumber+" / "+myText;

Parameter-übergabe an JavaScript

Parameter-übergabe an JavaScript

ABBILDUNG 5.17

Flash nimmt Kontakt mit JavaScript auf.

Page 211: Flash cs3, ajax und php

K A P I T E L 5198

alert(msg);

return "JavaScript-Antwort: OK";

}

Listing 5.26: An die JavaScript-Funktion werden zwei Parameter (myNumber und myText) übergeben. myNumber wird mit zwei multipliziert und dann gemeinsam mit myText in der Variable msg gespeichert, welche danach in der Alert-Box ausgegeben wird.

Browser an Flash an Browser

Nun machen wir die Probe aufs Exempel und übergeben von JavaScript an Flash einen Wert, der dann auf Knopfdruck (warum nur „auf Knopfdruck“ und nicht gleich direkt, werden wir noch klären müssen – Thema „Rekursion“) von Flash erweitert und an JavaScript zurückgegeben wird. Den zu übergebenen Wert werden wir aus einem Eingabefeld lesen, den zurückgegebenen Wert einem Textfeld anhängen. Der fertige Aufbau sieht dann folgendermaßen aus:

ABBILDUNG 5.18

Die übergebene Zahl (in unserem Fall: 23.5) wird

mit zwei multipliziert: Das Ergebnis lautet 47.

Gemeinsam mit dem über-gebenen Text („Uwe Mutz“)

wird sie in einer Alert-Box ausgegeben.

Page 212: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 199

Der Ablauf wird also wie folgt vor sich gehen:

1. In das Eingabefeld wird Text eingegeben und nach Klick auf den Button „Daten senden“ an Flash übergeben.

2. Flash empfängt den übermittelten Text und stellt diesen in der TextArea dar.

3. Bei Klick auf den Button „Zurück an JS…“ wird der übergebene Text wieder an JavaScript zurückgeschickt und im Ausgabebereich angezeigt.

So weit der Plan. Der XHTML-Teil wird uns wenig Kopfzerbrechen machen, denn bis auf zwei Felder und eine eingebettete SWF-Datei ist nicht viel zu tun:

...

<form name="frmExternalInterface" id="frmExternalInterface" method="post" action="">

<input type="text" name="myText" id="myText" />

<input type="button" value="Daten senden" onclick="sendDataToFlash2();" />

</form>

...

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/fl ash/swfl ash.cab#version=7,0,19,0" width="300" height="200" id="myswf">

<param name="movie" value="browserAnFlashAnBrowser.swf">

<param name="quality" value="high">

<embed name="myswf" src="browserAnFlashAnBrowser.swf" width="300"

ABBILDUNG 5.19

Ein Eingabefeld zum Versenden von Text an Flash, eine TextArea und ein „Zurücksende“-Button in Flash sowie ein Ausgabebereich (readonly) für die von Flash gesandten Daten.

Page 213: Flash cs3, ajax und php

K A P I T E L 5200

height="200" quality="high" pluginspage="http://www.macromedia.com/go/getfl ashplayer" type="application/x-shockwave-fl ash"></embed>

</object>

...

<form name="frmExternalInterface2" id="frmExternalInterface2" method="post" action="">

<textarea name="myText2" cols="30" rows="10" id="myText2" readonly="readonly"></textarea>

</form>

...

...

Listing 5.27: Auszug aus dem XHTML-Listing. Es werden die Felder myText (Eingabe) und myText2 (Aus-gabe) erzeugt sowie wie üblich die SWF-Datei eingebettet. Die Formularelemente sind von zwei Formularen frmExternalInterface und frmExternalInterface2 umgeben.

Auch die JavaScript-Funktionen werden uns keine Kopfzerbrechen bereiten, denn da ist alles wie gehabt – einzig die Ausgabe des von Flash zurückgelieferten Textes bedarf einer zusätzlichen JavaScript-Programmierung:

function sendDataToFlash2() {

var myswf = getFlashElement("myswf");

var textToFlash = document.forms["frmExternalInterface"].elements["myText"].value;

myswf.tryIt(textToFlash);

}

function executeMyCode2(textFromFlash) {

document.forms["frmExternalInterface2"].elements["myText2"].value += "AS says: "+textFromFlash+"\n";

return "OK";

}

Listing 5.28: Einzig die Ausgabe in eine <textarea> namens myText2 ist noch mehr oder weniger unbekannt.

Vielleicht ist Ihnen aufgefallen, dass wir uns zweier Formulare bedienen. Dies resul-tiert aus dem Grund, dass der Internet Explorer beim Verwenden des Adobe-Scripts zum Einbetten von SWF-Dateien (AC_RunActiveContent.js) so seine Probleme hat, wenn dieser Code innerhalb eines Formulars steht. Deshalb der Tipp: Teilen Sie Ihren XHTML-Code so auf, dass der Scriptaufruf AC_FL_RunContent(..) sich nicht innerhalb eines umgebenden <form> befindet.

Weiter zu Flash & ActionScript. Der Bühnenaufbau von Flash ist denkbar einfach, da wir nur noch ein Bild in der Zeitleiste benötigen. An dieser Stelle möchte ich jedoch

AC_FL_RunContent(..) nicht zwischen

<form> und </form>

AC_FL_RunContent(..) nicht zwischen

<form> und </form>

Page 214: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 201

wieder einmal in Erinnerung rufen, dass man die Ebenen der Bühne so übersichtlich wie möglich gestalten sollte. Den Hardcore-Programmierern unter uns wird dies wohl ein bisschen Kopfschütteln abverlangen („Eine einzige Ebene würde auch ausreichen, da ja alle Elemente auch per ActionScript erzeugt werden könnten!“), jedoch ist dieses Buch als Einsteigerbuch gedacht und deshalb auch so aufgebaut, dass Einsteiger die Beispiele so übersichtlich wie nur möglich vorfinden. Und „falsch“ ist es keineswegs – es wäre eben nur ein wenig „reduzierter“ auch möglich.

Wie dem auch sei, hier die zusammengeräumte Bühne:

ABBILDUNG 5.20

„As aufgeräumt as possible“

Die Aktionenebene beinhaltet wie gewohnt den Import der ExternalInterface-Klasse und deren Verwendung inklusive Callback-Registrierung sowie den Event-Handler für das Klicken des Buttons:

var msg:mx.controls.TextArea;

msg.text = "Initialisiere...\n";

var lastMsg:String = "(bisher nichts von JS erhalten..)";

import fl ash.external.*;

if(ExternalInterface.available) {

msg.text += "EXTERNAL INTERFACE verfügbar\n";

if(ExternalInterface.addCallback("tryIt",null,calledByJS)) {

Page 215: Flash cs3, ajax und php

K A P I T E L 5202

msg.text += "Callback-Funktion ERFOLGREICH registriert\n";

}

else {

msg.text += "Callback-Funktion NICHT erfolgreich registriert\n";

}

}

else {

msg.text += "EXTERNAL INTERFACE NICHT verfügbar\n";

}

callJS_btn.onRelease = function():Void {

var returnedFromJS = ExternalInterface.call("executeMyCode2",lastMsg);

if(returnedFromJS==null) { msg.text+= "after AS sent-> JS returned an ERROR\n"; }

else { msg.text+= "after AS sent-> JS returns: "+returnedFromJS+"\n"; }

}

Listing 5.29: Die Aktionenebene beinhaltet den Import der ExternalInterface-Klasse sowie den not-wendigen Aufruf addCallback (Registrieren der Funktion calledByJS unter dem Pseudonym „tryIt“ für den Aufruf durch JavaScript) sowie call (Aufruf einer JavaScript-Funktion durch ActionScript).

Zusätzlich hinzugekommen sind lediglich zwei Punkte: Erstens, dass wir den Rückga-bewert der Methode call nach dem Aufruf einer JavaScript-Funktion in einer Vari-able returnedFromJS speichern und diesen dann in einer if-Anweisung auswerten: Sollte der Rückgabewert null sein, so ist ein Fehler aufgetreten, der mehrere Gründe haben kann:

Die aufgerufene JavaScript-Funktion (hier: executeMyCode2) existiert nicht: Pro-grammiererfehler … Sehen Sie nach, ob die JavaScript-Funktion tatsächlich unter dem Namen aufrufbar ist, den Sie verwenden.

Die API (Anwendungsprogrammierungs-Schnittstelle) auf Browser-Seite zum Arbeiten mit der ExernalInterface-Klasse ist nicht vorhanden: Dies ist im Allgemeinen nur dann der Fall, wenn der Browser des Users die am Anfang des Kapitels aufgelisteten Mindestanforderungen nicht erfüllt. Da jedoch jeder halb-wegs gängige Browser diese Hürde mit Leichtigkeit überwindet, tritt dieser Fehler relativ selten auf.

Es ist eine Rekursion aufgetrete n: Rekursionen sind im Allgemeinen genau das Problem, das am häufigsten auftritt. Sie sind auch der Grund, warum eine automatische Rückmeldung von Flash an den Browser nicht funktioniert: Ruft

u

u

u

Page 216: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 203

JavaScript eine ActionScript-Funktion auf und ruft ActionScript wiederum eine JavaScript-Funktion auf, die von sich aus wiederum eine Antwort an ActionScript zurückliefert, erweckt es den Anschein einer Rekursion (in Wirklichkeit ist es keine Rekursion, aber Flash behauptet es zumindest).

Es ist ein Sicherheitsproblem aufgetreten: Dies ist normalerweise innerhalb eines Browsers nicht der Fall, es sei denn, Sie arbeiten Domain-übergreifend. Hier schafft die Methode allowDomain der security-Klasse Abhilfe. Schlagen Sie in der ACTIONSCRIPT-REFERENZ unter security.allowDomain nach.

Da man nicht genau eruieren kann, wodurch der Fehler aufgetreten ist (eine aus-führliche Fehlerbehandlungsmöglichkeit existiert erst ab ActionScript 3.0), wird von unserem Script nicht mehr als ein „after AS sent-> JS returned an ERROR“ ausgegeben – eine Fehlersuche (sollte wirklich ein Fehler auftreten) bliebe uns an dieser Stelle nicht erspart.

Der zweite hinzugekommene Punkt ist eine (globale, da auf der Hauptzeitleiste erzeugte) Variable lastText, die den zuletzt von JavaScript gesandten Text speichert und so für die Rückgabe nach Klick auf den Button „Zurück an JS...“ bereithält. Der jeweils aktuelle Wert dieser Variable wird in der Funktion calledByJS gespeichert, die sich wie folgt darstellt:

function calledByJS(myText:String):Void {

msg.text+= "JS says: "+myText+"\n";

var returnToJS:String = "OK: "+myText;

lastMsg = myText;

}

Listing 5.30: Auch diese Funktion ist bereits hinlänglich bekannt – hinzugefügt wurde, dass der zuletzt von JavaScript gesandte Text in der Variable lastMsg gespeichert wird.

Das fertige Beispiel finden Sie wie üblich auf der Buch-CD unter dem Namen brow-serAnFlashAnBrowser.fla sowie browserAnFlash_var3b.php.

u

Page 217: Flash cs3, ajax und php

K A P I T E L 5204

Flash an Browser an Flash

Nun sehen wir uns die umgekehrte Richtung an: ActionScript sendet eine Message an JavaScript, welches wiederum eine Rückmeldung an ActionScript schickt. In diesem Fall werden wir das Problem einer Rekursion nicht vorfinden, da die Rückmeldung von JavaScript an Flash systembedingt erlaubt ist.

Dieser Fall ist wesentlich einfach als der vorige, da ActionScript von JavaScript in jedem Fall eine Rückmeldung erhält, nachdem ActionScript eine JavaScript-Funktion aufgerufen hat – die ActionScript-Funktion call sorgt hierfür.

Damit reduziert sich der JavaScript-Code auf:

function executeMyCode2(textFromFlash) {

return "OK, got '"+textFromFlash+"'";

}

Listing 5.31: Die Funktion executeMyCode2 wird wie üblich diejenige Funktion sein, die von ActionScript aufgerufen wird. Sobald dies geschehen ist, liefert sie den an Sie übergebenen Wert inklusive des Textes „OK, got“ wieder zurück an Flash. Dies demonstriert sehr schön, wie ActionScript und JavaScript aus Rich-tung ActionScript zusammenarbeiten.

Auch der ActionScript-Code ist wesentlich einfacher, da wir im Gegensatz zum vorigen Beispiel erstens keine Callback-Funktion mehr definieren und diese zweitens somit auch nicht mehr registrieren müssen. Einzig die Ein- und Ausgabefelder in Form von TextAreas sind mehr geworden – siehe Abbildung:

ABBILDUNG 5.21

Der Text „teste mich!“ wird nach Klick auf „Daten sen-

den“ an Flash geschickt, dort in der TextArea angezeigt.

Nach Klick auf „Zurück an JS...“ wird der Text „AS

says: teste mich!“ in die <textarea> (XHTML)

geschrieben und von JavaScript die Meldung „OK“

an Flash zurückgeschickt, welche wiederum in der

(Flash-)TextArea angezeigt wird. Basta!

Page 218: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 205

var msgStatus:mx.controls.TextArea;

msgStatus.text = "Initialisiere...\n";

var msgIn:mx.controls.TextArea;

msgIn.text = "";

var msgOut:mx.controls.TextArea;

msgOut.text = "(type message)";

import fl ash.external.*;

if(ExternalInterface.available) {

msgStatus.text += "EXTERNAL INTERFACE verfügbar\n";

}

else {

msgStatus.text += "EXTERNAL INTERFACE NICHT verfügbar\n";

}

callJS_btn.onRelease = function():Void {

var sendMsg:String = msgOut.text;

var returnedFromJS = ExternalInterface.call("executeMyCode2",sendMsg);

msgStatus.text += "AS says: "+sendMsg+"\n";

if(returnedFromJS==null) { msgIn.text+= "after AS sent-> JS returned an ERROR\n"; }

ABBILDUNG 5.22

Wie man schön sehen kann, befindet sich in der Funktionenebene kein Inhalt mehr, da wir keine Funktionen mehr benötigen. Die Anzahl der TextAreas hat sich erhöht, da wir eine TextArea für die Statusmeldungen, eine für den Eingabetext und eine für die Rückmeldungen von JavaScript an ActionScript verwenden.

Page 219: Flash cs3, ajax und php

K A P I T E L 5206

else { msgIn.text+= "after AS sent-> JS returns: "+returnedFromJS+"\n"; }

}

Listing 5.32: Code der Aktionenebene: Es werden insgesamt drei TextAreas defi niert – msgStatus für Statusmeldungen, msgIn für von JavaScript an ActionScript gesandte Rückmeldungen und msgOut für den Eingabetext, der an JavaScript gesandt wird. Bei Klick auf den Button wird der vom User eingegebene Text in der Variable sendMsg zwischengespeichert, dann zunächst an JavaScript gesandt und danach in das Statusfeld als „an JS versendet“ ausgegeben.

Zunächst werden die drei TextAreas „msgStatus“, „msgIn“ und „msgOut“ definiert und die ExternalInterface-Klasse importiert. Wie üblich überprüfen wir, ob die API im Browser verfügbar ist. Die eigentliche „Intelligenz“ liegt diesmal im Event-Handler des Buttons:

Zunächst wird der vom User eingegebene Text in einer Variable sendMsg zwischen-gespeichert.

Über die Methode call der ExternalInterface-Klasse wird die JavaScript-Funktion executeMyCode2 aufgerufen und dieser der Wert der zuvor gespeicherten Variable sendMsg übergeben. Der Rückgabewert der JavaScript-Funtkion wird danach in der Variable returnedFromJS gespeichert.

Je nachdem, ob der JavaScript-Rückgabewert null oder nicht null war, wird unterschiedlich weiterverfahren:

Bei null ist ein Fehler aufgetreten – welche Gründe für Fehler existieren, haben wir im Kapitel Browser an Flash an Browser ausführlich behandelt.

Falls der Rückgabewert ungleich null ist, wird der von JavaScript zurückgelie-ferte Wert in der TextArea msgIn ausgegeben.

Das getestete Beispiel sehen Sie in der nachfolgenden Abbildung:

u

u

u

u

u

Page 220: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 207

5.3.2 ExternalInterface-Klasse mit ActionScript 3.0Bei Verwendung von ActionScript 3.0 hat sich bei den beiden Methoden addCallback und call etwas geändert:

Methode Beschreibung

addCallback(Pseudonym:String, AS-Funktion:Function):void

Gegenüber der addCallback-Methode in ActionScript 2.0 exis-tiert der Instanz-Parameter nicht mehr. Außerdem liefert die Funktion nach dem Aufruf keinen Wert mehr zurück.

call(JS-Funktion:String, Parameter:Object):*

Sollte beim Aufruf der JavaScript-Funktion ein Fehler auftreten, so wird entweder ein System- oder ein Security-Fehler erzeugt. Somit besteht die Möglichkeit einer besseren Fehleranalyse. Der Wert null würde bei einem Fehler in jedem Fall zurückgeliefert werden.

Tabelle 5.2: Änderungen der ExternalInterface-Klasse von ActionScript 2.0 auf 3.0

Wie wir also sehen, birgt ActionScript 3.0 keine herausragenden Neuerungen für uns. Und in Hinblick auf die Tatsache, dass es nicht Teil dieses Buchs ist, sich in die Tiefen von ActionScript 3.0 zu begeben, werde ich an dieser Stelle dem Gesagten auch nichts hinzufügen, sondern vielmehr auf die hervorragende Literatur zu AS 3.0 im Addison-Wesley Verlag hinweisen:

„ActionScript 3.0“ von Selma-Caroline Kannengießer und Matthias Kannengießer, ISBN 978-3827325365

Wenden wir uns also wieder dem eigentlichen und grundlegenderen Thema zu: Flash & AJAX. Wie im vorigen Kapitel angekündigt, packen wir den Stier bei den Hörnern, reißen ihn zu Boden und warten ab.

u

ABBILDUNG 5.23

Es klappt – der von Flash an JavaScript übermit-telte Text „teste auch mich!“ wird von JavaScript empfangen und wieder an Flash zurückgeliefert. Das Beispiel liegt auf der Buch-CD unter den Namen FlashAnBrowserAnFlash.fla sowie flashAnBrowser04.htm zum Testen für Sie bereit.

Page 221: Flash cs3, ajax und php

K A P I T E L 5208

5.4 Flash & AJAXGehen wir in Medias Res. Wir wollen uns nun die Frage stellen, wie man das erwor-bene Wissen rund um unsere „Flash-Browser- bzw. Browser-Flash-Kommunikation“ mit dem vorigen Kapitel über AJAX kombinieren kann.

Halten wir kurz fest:

1. Flash kann (mithilfe von getURL oder der ExternalInterface-Klasse) mit dem Browser kommunizieren: Es können JavaScript-Funktionen aufgerufen und an sie Variablenwerte übergeben werden.

2. Ein Browser kann mit Flash kommunizieren:

1. Mithilfe von setVariable können von einem Browser aus Variablenwerte gesetzt werden.

2. Binden wir die ExternalInterface-Klasse ein, sind wir sogar in der Lage, (freigegebene) Funktionen in Flash aufzurufen und an diese Variablen zu übergeben.

3. Nachdem AJAX auf Browser-Seite arbeitet und somit ebenso Flash-Funktionen aufrufen kann, sind wir somit auch in der Lage, beispielsweise nach einem erfolgten Laden von (zusätzlichen) serverseitigen Daten diese an Flash weiterzugeben.

Hierzu ein kleines Diagramm, um unsere Idee grafisch festzuhalten:

ABBILDUNG 5.24

AJAX kommuniziert mit dem Server und mit Flash.

Page 222: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 209

5.4.1 Parameterübergabe: TextIn diesem Teil des Flash & AJAX-Kapitels befassen wir uns mit der Übergabe von textbasierten Daten an Flash, im folgenden Kapitel werden wir statt Text- dann XML-Daten an Flash übergeben.

Wir starten mit einer kleinen Anwendung, wo Sie die Interaktion von Flash und AJAX grafisch dargestellt sehen: Mithilfe einer kleinen „Ampel“ werden wir in Flash die AJAX-Kommunikation mit dem Server einerseits und Flash andererseits darstellen. Die Funktionsweise soll folgende sein:

1. Wir basteln eine XHTML-Seite, die drei Buttons beinhaltet:

Initialisieren-Button: Wird auf diesen Button geklickt, wird das XMLHttp-Request-Objekt als Instanz angelegt und ihr ein Eventhandler zugewiesen.

Öffnen-Button: Mithilfe dieses Buttons wird die Verbindung geöffnet, jedoch noch nicht abgeschickt.

Senden-Button: Bei Klick wird die Anfrage an den Server abgeschickt.

2. Jeder (messbare) Zustand der XMLHttpRequest-Instanz soll in Flash in Form einer Art „Ampel“ angezeigt werden:

Ampel ist rot: AJAX-technisch ist noch nichts passiert.

Ampel ist orange: Die XMLHttpRequest-Instanz hat eine Verbindung zum Server geöffnet. In diesem Fall trägt die Eigenschaft readyState der Instanz den Wert 1.

Ampel ist gelb: readyState hat den Wert 2 erreicht.

Ampel ist dunkelgrün: readyState hat den Wert 3 erreicht.

Ampel ist leuchtend grün: readyState ist nun auf den Wert 4 gewechselt, der uns kennzeichnet, dass die Anfrage erfolgreich stattgefunden hat und wir nun mit den erhaltenen Daten arbeiten können.

3. Ist die Anfrage abgeschlossen, soll der zurückgegebene Text (= Inhalt der Datei testrequest.txt) an Flash übergeben und in der TextArea angezeigt werden.

Der Clou an dem Beispiel ist, dass wir unser erworbenes Wissen nur mehr zusammen-fügen müssen, da wir folgende Punkte bereits wissen:

1. Wir wissen, wie die AJAX-Kommunikation mit dem Server vor sich geht.

2. Wir wissen, wie die Kommunikation zwischen JavaScript und Flash vor sich geht.

Was bleibt also zu tun? Um jeden Zustand der readyState-Eigenschaft in Flash anzuzeigen, müssen wir im Eventhandler der XMLHttpRequest-Instanz für jeden

u

u

u

u

u

u

u

u

Page 223: Flash cs3, ajax und php

K A P I T E L 5210

der Zustände eine Flash-Funktion aufrufen – dazu werden wir auf die External-Interface-Klasse in Flash zurückgreifen. Ebenso verhält es sich mit der Anzeige des vom Server (durch die Datei testrequest.txt, die wir vom Server per AJAX anfordern) zurückgelieferten Textes: Wiederum rufen wir eine Flash-Funktion auf, die den Rest erledigt.

Wir können die Aufgabe in drei Teile unterteilen:

Das XHTML-Dokument mit den Buttons.

Den AJAX-(JavaScript-)Teil, der einerseits die Datei testrequest.txt vom Server anfordert und andererseits mit Flash kommuniziert.

Den Flash-Teil, der eine TextArea für die Ausgabe des Textes und unsere Ampel für die Anzeige der Zustände von readyState beinhaltet.

Zur besseren Veranschaulichung finden Sie nachfolgend einen Screenshot, der das Ausgangsszenario widerspiegelt:

u

u

u

Der XHTML-Teil ist denkbar einfach, da im Wesentlichen nur die drei Buttons von Interesse sind:

...

<input name="btnInit" type="submit" id="btnInit" value="Initialisieren" onclick="initXHR();" />

<input name="btnOpen" type="button" id="btnOpen" value="&Ouml;ffnen" onclick="openXHR();" />

ABBILDUNG 5.25

Unser Beispiel beinhaltet drei Buttons (Initialisieren, Öffnen und Senden) sowie

eine SWF-Datei für die Anzeige von einerseits einem

(Rückgabe-)Text und ande-rerseits einer kleinen „Ampel“.

Page 224: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 211

<input name="btnSend" type="submit" id="btnSend" value="Senden" onclick="sendXHR();" />

...

Listing 5.33: Im XHTML-Teil werden über drei Buttons drei verschiedene Funktionen initXHR, openXHR und sendXHR aufgerufen.

Befassen wir uns also gleich einmal mit dem JavaScript- und AJAX-Part. Die drei Funkti-onen initXHR, openXHR und sendXHR, die durch Klick auf die drei Buttons aufgerufen werden, initialisieren, öffnen und versenden die Anfrage an den Server. Zuvor wird in Zeile 1 des Scripts noch eine Variable für die XMLHttpRequest-Instanz angelegt:

var myXMLHttpRequest;

function initXHR() {

myXMLHttpRequest = createRequestObject();

myXMLHttpRequest.onreadystatechange = handleRequest;

}

function openXHR() {

myXMLHttpRequest.open("GET", "testrequest.txt", true);

}

function sendXHR() {

myXMLHttpRequest.send(null);

}

Listing 5.34: Drei Funktionen für drei Aufgaben: Initialisieren, Öffnen und Abschicken. Zu Beginn wird noch eine Variable myXMLHttpRequest für die spätere XMLHttpRequest-Instanz angelegt.

Die Funktion createRequestObject aus der Funktion init ist uns aus dem vorigen Kapitel über AJAX noch gut in Erinnerung, deshalb halte ich mich bei der Beschrei-bung relativ kurz:

function createRequestObject() {

try { var myRequest = new XMLHttpRequest(); }

catch(error) {

try { var myRequest = new ActiveXObject("MSXML2.XMLHTTP"); }

catch(error) { var myRequest = new ActiveXObject("Microsoft.XMLHTTP"); }

}

return myRequest;

}

Listing 5.35: createRequestObject sorgt je nach verwendetem Browser für die korrekte Initialisierung der XMLHttpRequest-Instanz.

Page 225: Flash cs3, ajax und php

K A P I T E L 5212

createRequestObject funktioniert nach dem „Trial and Error“-Prinzip: Klappt ein Codefragment (damit ist gemeint, dass beim Ausführen des Codefragments kein Feh-ler aufgetreten ist), das sich innerhalb einer try-Anweisung befindet, wird der catch-Abschnitt nicht mehr ausgeführt. Klappt es hingegen nicht, wird der catch-Teil ausgeführt. In unserer Funktion werden somit nach und nach alle Möglichkeiten des Instanzierens eines XMLHttpRequest-Objekts durchprobiert, bis ein Versuch geklappt hat. Details dazu finden Sie im Kapitel über AJAX. Das schlussendlich korrekt instan-zierte Objekt wird mit der return-Anweisung an den Aufrufer zurückgeliefert.

Neben der Instanzierung wird im nächsten Schritt der soeben geschaffenen Instanz ein Eventhandler handleRequest für das Ereignis onreadystatechange zugewiesen. Diesem Eventhandler widmen wir uns weiter unten noch.

In der Funktion openXHR wird die Instanz myXMLHttpRequest aufgefordert, eine Verbindung zur serverseitigen Datei testrequest.txt per GET herzustellen.

Die Funktion sendXHR sorgt dann dafür, dass die geöffnete (aber noch nicht abge-schickte) Verbindungsanforderung auch abgeschickt wird.

Der Eventhandler handleRequest ist der eigentlich interessante Teil für die Kom-munikation mit Flash: Bei jeder Zustandsänderung (spiegelt sich in der Eigenschaft readyState der XMLHttpRequest-Instanz wider) wird diese Funktion aufgerufen. Die switch-Anweisung hilft uns dabei, die fünf möglichen Zustände zu verarbeiten:

function handleRequest() {

var mySWF = getFlashElement("myswf");

switch(myXMLHttpRequest.readyState) {

case 0:

case 1:

case 2:

case 3: mySWF.showState(myXMLHttpRequest.readyState); break;

case 4: mySWF.showState(myXMLHttpRequest.readyState); mySWF.showReturnedText(myXMLHttpRequest.responseText); break;

}

}

Listing 5.36: Zunächst fi nden wir durch den Funktionsaufruf getFlashElement eine korrekte Referen-zierung auf die SWF-Datei, danach kümmern wir uns darum, die readyState-Eigenschaft auszuwerten.

Wie oben erwähnt soll der Eventhandler das bindende Glied zwischen AJAX und Flash darstellen – aus diesem Grund stellen wir eine Referenz zur SWF-Datei mit der ID (dem Namen) myswf her. Dies geschieht mittels der Funktion getFlashElement, die aus Listing 5.6 bekannt ist. Danach werten wir die Eigenschaft readyState aus: Für die Fälle 0–3 rufen wir eine Flash-Funktion namens showState auf, der wir den Wert von readyState übergeben (Flash wird diesen Wert in Form der angesprochenen

Page 226: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 213

Ampel ausgeben). Ist readyState==4, hat der Server sämtliche angeforderten Daten zurückgeliefert – auch dieser Zustand soll von unserer Ampel angezeigt werden, des-halb rufen wir wie auch zuvor showState aus. Des Weiteren wollen wir die Rückgabe vom Server aber auch noch in einer TextArea anzeigen lassen, weshalb die Funktion showReturnedText zum Einsatz kommt.

Kommen wir also zu Flash und seinen (freigegebenen) Funktionen:

function showReturnedText(myText:String):Void {

msg.text+= "AJAX says: "+myText+"\n";

}

function showState(readyState:Number):Void {

msg.text+= "readyState: "+readyState+"\n";

mcAmpel.gotoAndStop(readyState+1);

}

Listing 5.37: Die Flash-Funktionen showReturnedText und showState sorgen für die (grafi sche wie textuelle) Ausgabe.

Es war anzunehmen, dass diese beiden Funktionen denkbar einfach sind, da es einer-seits nur um die Ausgabe von Text oder andererseits das Ansprechen eines MovieClips geht. showState gibt zunächst den (übergebenen) Wert von readyState in der TextArea aus und spricht dann den MovieClip mcAmpel an. Je nach Wert von ready-State werden ein, zwei, drei, vier oder fünf Ampellichter angezeigt – die Zwiebelscha-lendarstellung des MovieClips zeigt dies:

ABBILDUNG 5.26

Die „Ampel“ in der Zwiebel-schalendarstellung. Pro Bild in der Zeitleiste kommt ein Satz an „Lampen“ hinzu.

Page 227: Flash cs3, ajax und php

K A P I T E L 5214

Um die Funktionen showState und showReturnedText für JavaScript (oder letztens AJAX) verfügbar zu machen, müssen sie noch freigegeben werden. Aus Kapitel 5.3 ken-nen wir den Vorgang zwar, jedoch ist eine kleine Wiederholung nicht schlecht:

...

import fl ash.external.*;

if(ExternalInterface.available) {

msg.text += "EXTERNAL INTERFACE verfügbar\n";

if(ExternalInterface.addCallback("showState",null,showState) && ExternalInterface.addCallback("showReturnedText",null,showReturnedText)) {

msg.text += "Callback-Funktionen ERFOLGREICH registriert\n";

}

else { msg.text += "Callback-Funktionen NICHT erfolgreich registriert\n"; }

}

else { msg.text += "EXTERNAL INTERFACE NICHT verfügbar\n"; }

Listing 5.38: Auszug aus dem Code zum Registrieren/Freigeben der Flash-Funktion für JavaScript – add-Callback macht’s möglich.

Hat das Registrieren beider Funktionen ordnungsgemäß funktioniert, wird in der TextArea msg der Text „Callback-Funktion ERFOLGREICH registriert“ ausgegeben – dies ist unsere Kontrolle, dass keine Fehler vorgefallen sind.

Testen wir das Beispiel, um uns von dessen Funktion zu vergewissern:

ABBILDUNG 5.27

Nachdem die Buttons „Initialisieren“ und „Öffnen“ angeklickt wurden, schaltet

die Ampel auf Orange (zweite Ampelreihe).

Page 228: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 215

Überlegen wir uns nun als konkretes Beispiel folgenden Fall: Wir erstellen eine kleine Umfrageseite, in der ein User aufgefordert wird, aus einer Liste von Antworten zu einer gegebenen Frage eine Antwort auszuwählen. Sobald er seine Auswahl bestätigt hat, wird seine „Stimme“ per AJAX an den Server geschickt und dort in einer Daten-bank abgelegt. Der Server soll die Anzahl der „Stimmen“ pro vorgegebener Antwort zurückliefern. Sobald der Server dies getan hat, übergibt AJAX an Flash diese Informa-tionen, wodurch Flash eine kleine Grafik (eine Art „Balkendiagramm“) aufbaut, die das Ergebnis der Umfrage in Form eines Balkendiagramms grafisch darstellt. Klickt der User dann auf einen der Balken in der Flash-Anwendung, so sollen Details zu diesem Balken in der XHTML-Datei angezeigt werden.

Im nachfolgenden Bild finden Sie zunächst einmal die Ausgangssituation, dass die Anwendung auf eine Stimme von Ihnen wartet – auch die Flash-Anwendung zeigt im Moment noch keine Grafik an:

ABBILDUNG 5.28

Klicken wir auch noch den „Senden“-Button, schal-tet die Ampel nach und nach auf Grün (unterste Lampenreihe) und gibt den per AJAX angeforderten Text der Datei testrequest.txt in der TextArea aus. Perfectly done! Klappt natürlich in jedem (gängigen) Browser ...

Page 229: Flash cs3, ajax und php

K A P I T E L 5216

Hat der User eine Auswahl getroffen und seine Stimme durch einen Klick auf den Button „Abstimmen“ abgegeben, wird diese Stimme in der Datenbank gespeichert (AJAX & PHP). Der Server gibt als Response eine URL-codierte Ausgabe an AJAX zurück, welche wiederum an Flash übergeben wird. Flash bastelt aus diesen Daten die Balkengrafik:

ABBILDUNG 5.29

Die Applikation wartet auf Ihre Stimme …

ABBILDUNG 5.30

Es wurde eine Stimme für „Ducati“ abgegeben. Flash

zeigt sogleich auch das bis-herige Voting an.

Klickt der User danach auf einen der Balken in der Flash-Datei, so wird unterhalb des „Abstimmen“-Buttons eine detailliertere Ausgabe des Votings für den geklickten Balken ausgegeben:

Page 230: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 217

Wie üblich beginnen wir mit der Analyse der XHTML-Datei. Ich empfehle Ihnen, par-allel zum Buch die jeweiligen Dateien auf Ihrem Computer zu öffnen – im jetzigen Fall handelt es sich um die Datei ajax02.php aus dem Verzeichnis zum aktuellen Kapitel.

...

<div id="Umfrage">

<form name="frmVote" id="frmVote" action="">

<div>

<?php

$conn = mysql_connect("mysql.syneweb.com","usr_fl ashphpajax","fl ashmyphpajax") or die('<div class="error">Die Verbindung zum Datenbankserver konnte NICHT hergestellt werden. Error: '.mysql_error().'</div>');

$db = mysql_select_db("db_fl ashphpajax") or die('<div class="error">Die Datenbank konnte NICHT ausgewaehlt werden. Error: ‚.mysql_error().'</div>');

$sql = "SELECT * FROM tbl_05fragen WHERE(bitP_chk_aktiv=1) ORDER BY RAND() LIMIT 1";

$query = mysql_query($sql);

$data = mysql_fetch_array($query);

$sql = "UPDATE tbl_05fragen SET dt_LetzterAufruf='".date("Y-m-d")."', int_AnzahlAufrufe=int_AnzahlAufrufe+1 WHERE idP_Frage=".$data["idP_Frage"];

$query = mysql_query($sql);

$msgOut = '<input type="hidden" name="idP_Frage" id="idP_Frage"

ABBILDUNG 5.31

Nachdem der User einen Balken (in unserem Fall den Balken „Ducati“) angeklickt hat, werden die Details der Umfrage für diese Auswahl dargestellt (unterhalb des „Abstimmen“-Buttons).

Page 231: Flash cs3, ajax und php

K A P I T E L 5218

value="'.$data["idP_Frage"].'" />';

$msgOut.= '<p>'.$data["vcP_Bezeichnung"].'</p>';

$sql = "SELECT * FROM tbl_05antworten WHERE(fi dP_select_Bezeichnung_Frage=".$data["idP_Frage"]." AND bitP_chk_aktiv=1) ORDER BY int_Reihenfolge";

$query = mysql_query($sql);

while($data2 = mysql_fetch_array($query)) {

$msgOut.= '<div><input type="radio" name="antwort" value="'.$data2["idP_Antwort"].'" />'.$data2["vcP_Antwort"].'</div>';

}

echo($msgOut);

?>

</div>

<div><input type="button" name="btnVote" id="btnVote" value="Abstimmen" onclick="vote();" /></div>

</form>

<div id="Details"></div>

</div>

<div id="Flash">...</div>

<div class="cleaner"></div>

...

Listing 5.39: Auszug aus dem Code der XHTML-Datei ajax02.php

Wir finden darin einige wesentliche Elemente:

Ein Formular „frmVote“, um auf die Formularfelder (Radiobuttons) zugreifen zu können.

Zwei SQL-Abfragen, wobei die erste der beiden per Zufall eine Frage aus der Daten-bank auswählt und die zweite danach die zugehörigen Antwortmöglichkeiten aus einer zweiten Tabelle lädt (das Tabellengerüst finden Sie in nachfolgender Abbil-dung).

Den Button „btnVote“ zum Abstimmen, der auf onclick die Funktion vote auf-ruft.

Einen (noch) leeren DIV-Container „Details“, den wir für die Ausgabe der Detail-infos verwenden.

u

u

u

u

Page 232: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 219

Die eingebundene Flash-Datei (im Container „Flash“) versteht sich von selbst und wurde deshalb aus dem Script entfernt, um es besser lesbar zu machen – in der Origi-naldatei ist ein entsprechendes <object> usw. selbstverständlich enthalten.

Der erste interessante Part ist also die Abfrage der Datenbank, um zu einer Umfra-ge zu kommen. In den ersten Zeilen des PHP-Teils wird zunächst Verbindung mit dem Datenbankserver aufgenommen (mysql_connect), danach eine Datenbank ausgewählt (mysql_select_db) und schließlich ein SQL-Statement $sql abgesetzt (mysql_query), das aus den gegebenen und aktiven (bitP_chk_aktiv=1) Einträgen der Tabelle tbl_05fragen per Zufall (RAND()) einen (LIMIT 1) Datensatz zurückliefert. Dieser eine Datensatz wird in $data gespeichert.

Im zweiten SQL-Statement wird der Eintrag mit der soeben gewählten Frage dahin-gehend verändert, als dass die Anzahl der Aufrufe der Frage um eins erhöht (int_AnzahlAufrufe=int_AnzahlAufrufe+1) und als letztes Abfragedatum das aktuelle Datum eingetragen wird (dt_LetzterAufruf='".date("Y-m-d")).

Danach wird ein drittes SQL-Statement (welches wieder den Namen $sql trägt) abgesetzt, das aus der Tabelle tbl_05antworten zu der gegebenen Frage (fidP_select_Bezeichnung_Frage=".$data["idP_Frage"]) alle aktiven (bitP_chk_aktiv=1) Antworten auswählt und entsprechend der in der Tabelle gespeicherten Reihenfolge (ORDER BY int_Reihenfolge) zurückliefert. Mithilfe einer while-Schleife wird aus dem Ergebnis eine Variable $msgOut zusammengebastelt, die als Inhalt eine Anzahl an Radio-Buttons mit den entsprechenden Antworten enthält. Am Ende der Schleife wird $msgOut per echo ausgegeben. Das entsprechende Ergebnis sehen Sie in Abbildung 5.29.

Gehen wir weiter zur Funktionalität des „Abstimmen“-Buttons. Dieser stellt wie üblich die Schnittstelle zu AJAX her, indem er die Funktion vote aufruft, die die Anfrage an den Server stellt:

function vote() {

var found = false;

for(var i=0; i<document.forms["frmVote"].elements["antwort"].length; i++) {

if(document.forms["frmVote"].elements["antwort"][i].checked==true) {

var theVote = document.forms["frmVote"].elements["antwort"][i].value;

found = true;

ABBILDUNG 5.32

Eine einfache Tabellenstruktur bil-det die Basis unserer Umfrageanwendung.

Page 233: Flash cs3, ajax und php

K A P I T E L 5220

break;

}

}

if(found) {

var idP_Frage = document.forms["frmVote"].elements["idP_Frage"].value;

var querystring = "idP_Frage="+idP_Frage+"&idP_Antwort="+theVote;

myXMLHttpRequest.open("GET", "storevote.php?"+querystring, true);

myXMLHttpRequest.onreadystatechange = handleRequest;

myXMLHttpRequest.send(null);

document.getElementById("Details").innerHTML = "";

}

else { alert("Bitte treffen Sie Ihre Wahl..."); }

}

Listing 5.40: Die Funktion vote, welche die Schnittstelle zwischen dem Formular zum Abstimmen und der AJAX-Anwendung bildet.

Ziel dieser Funktion ist zweierlei:

1. Überprüfen, ob der User auch wirklich eine Auswahl getroffen hat (er könnte ja auch auf den „Abstimmen“-Button geklickt haben, ohne zuvor eine Auswahl getroffen zu haben) und wenn ja, welche.

2. Die getroffene Auswahl per AJAX an den Server übermitteln, um diese in die Datenbank zu schreiben.

Ob der User tatsächlich abgestimmt hat, wird in der Variable found gespeichert. Hierzu wird in einer for-Schleife jeder Radio-Button namens „antwort“ auf den Wert checked==true überprüft. Wurde ein solcher Radio-Button gefunden, wird der Wert dieses Buttons in theVote gespeichert und found auf true gesetzt. Danach wird die Schleife abgebrochen (break), da es wenig Sinn macht, die restlichen Radio-Buttons auch noch zu überprüfen, da nur ein einziger Button ausgewählt sein kann. Wurde hingegen kein ausgewählter Radio-Button gefunden, ist found nach wie vor false. Genau dieser Wert wird darauffolgend mithilfe der if-Bedingung überprüft. Bei true wird eine Variable querystring erzeugt, welche die ID der Frage (idP_Frage) und die ID der Antwort (idP_Antwort) speichert. Diese Variable wird danach an die Datei storevote.php als URL-codierter Query-String angehängt. Per open wird die Verbin-dung zum Server geöffnet, onreadystatechange definiert einen Eventhandler für Änderungen in der Eigenschaft readyState und send schickt die Anfrage schlussend-lich ab. Danach wird noch dafür gesorgt, dass der Container „Details“ leer ist.

Page 234: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 221

Natürlich wurde weiter oben die Variable myXMLHttpRequest per

var myXMLHttpRequest = createRequestObject();

als Instanz eines XMLHttpRequest-Objekts angelegt – die Zuweisung des korrekten Objekts (je nach verwendetem Browser) erfolgt in einer Funktion createRequest-Object, welche in der externen JavaScript-Datei common.inc.js abgelegt ist. Dieses Prozedere ist aus dem vorigen Kapitel hinlänglich bekannt.

Gehen wir also weiter zum Eventhandler handleRequest:

function handleRequest() {

switch(myXMLHttpRequest.readyState) {

case 0:

case 1:

case 2:

case 3: break;

case 4:

if(myXMLHttpRequest.responseText.indexOf("ERROR")!=-1) {

alert("Es ist ein FEHLER beim Voting aufgetreten - bitte versuchen Sie es erneut!");

}

else {

var mySWF = getFlashElement("myswf");

mySWF.showVoteData(myXMLHttpRequest.responseText);

}

break;

}

}

Listing 5.41: Der Eventhandler für die AJAX-Kommunikation

Wie wir wissen, erledigt dieser Eventhandler die Abarbeitung der möglichen Zustände der readyState-Eigenschaft. Die Fälle 0–3 sind nicht interessant, deshalb brechen wir hier einfach mit break ab (sollte Ihnen das Kopfzerbrechen bereiten, so schlagen Sie bitte im vorigen Kapitel zu AJAX nach). Viel interessanter ist der Fall 4, wo der Server sämtliche angeforderten Daten zurückgeliefert hat. Die angeforderte Datei storevote.php ist so aufgebaut, dass sie im Fall eines Fehlers eine entsprechende Fehlermeldung mit dem Text „ERROR“ ausgibt. Das Script sucht also in der Rückgabe (response-Text) nach dem Text „ERROR“ – sollte dieser vorkommen, liefert die Methode index-Of diejenige Position im String zurück, wo „ERROR“ vorkommt. Sollte „ERROR“ nicht gefunden werden, liefert sie -1 zurück. Finden wir einen Fehler, wird über alert

Page 235: Flash cs3, ajax und php

K A P I T E L 5222

eine entsprechende Fehlermeldung ausgegeben, finden wir keinen Fehler, erzeugen wir eine Referenz auf das eingebundene Flash-Element „myswf“ und rufen die dort freigegebene Funktion showVoteData mit dem soeben erhaltenen Rückgabewert von storevote.php auf.

Bevor wir uns der Flash-Anwendung widmen, müssen wir noch einen Blick auf store-vote.php werfen:

if(count($_GET)>0 && isset($_GET["idP_Antwort"]) && isset($_GET["idP_Frage"])) {

$conn = mysql_connect("mysql.syneweb.com","usr_fl ashphpajax","fl ashmyphpajax") or die('<div class="error">Die Verbindung zum Datenbankserver konnte NICHT hergestellt werden. Error: '.mysql_error().'</div>');

$db = mysql_select_db("db_fl ashphpajax") or die('<div class="error">Die Datenbank konnte NICHT ausgewaehlt werden. Error: ‚.mysql_error().'</div>');

$sql = "UPDATE tbl_05antworten SET int_AnzahlStimmen=int_AnzahlStimmen+1 WHERE(idP_Antwort=".$_GET["idP_Antwort"].")";

if(!$query = mysql_query($sql)) { $returner = "ERROR (1)"; }

else {

$sql = "SELECT * FROM tbl_05antworten WHERE(fi dP_select_Bezeichnung_Frage=".$_GET["idP_Frage"].")";

if(!$query = mysql_query($sql)) { $returner = "ERROR (2)"; }

else {

$returner = '';

$i = 0;

while($data = mysql_fetch_array($query)) {

$returner.= 'ID'.$i.'='.$data["idP_Antwort"].'&Antwort'.$i.'='.$data["vcP_Antwort"].'&Anzahl'.$i.'='.$data["int_AnzahlStimmen"].'&';

$i++;

}

$returner = substr($returner,0,$returner.length-1);

}

}

}

else { $returner = "ERROR (3)"; }

echo($returner);

Listing 5.42: Der Code der Datei storevote.php (zu fi nden auf der Buch-CD)

Gleich im ersten Schritt der Datei wird überprüft, ob an die Datei überhaupt GET-Daten übergeben wurden (count($_GET)>0) und ob die benötigten Informationen über die Frage und die Antwort darin enthalten sind (isset($_GET["idP_Ant-

Page 236: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 223

wort"]) && isset($_GET["idP_Frage"])). Sollte dem nicht so sein, wird eine Rückgabevariable $returner auf den Wert „ERROR (3)“ gesetzt. War hingegen alles wie gewünscht, so gehen wir einen Schritt weiter und stellen die Verbindung zum Datenbankserver und zur Datenbank her.

Das erste SQL-Statement sorgt dafür, dass die Stimme des Users für die gegebene Antwort gespeichert wird. Falls dieses UPDATE-Statement fehlgeschlagen ist, wird in $returner der Wert „ERROR (1)“ gespeichert und abgebrochen. War es erfolgreich, wird das zweite SQL-Statement ausgeführt, das für die gestellte Frage alle Antworten mit ID, Antworttext und Anzahl abgegebener Stimme in eine entsprechende Form bringt (gesetzt den Fall, dass die Abfrage erfolgreich durchgeführt werden konnte):

IDn=...&Antwortn=...&Anzahln=...

n steht für eine Zählvariable, um jede „Variable“ eindeutig zu machen. Es ist Ihnen sicherlich aufgefallen, dass der Rückgabestring in URL-codierter Form generiert wird – im nächsten Kapitel werden wir noch lernen, warum diese Form ideal für eine Datenübergabe an Flash ist. Als Beispiel für den Rückgabestring hier eine Ausgabe zu den obig dargestellten Abbildungen:

ID0=14&Antwort0=BMW&Anzahl0=7&ID1=15&Antwort1=Ducati&Anzahl1=34&ID2=16&Antwort2=KTM&Anzahl2=10&ID3=17&Antwort3=keine der angegebenen&Anzahl3=2

Listing 5.43: Ein möglicher Rückgabestring in URL-codierter Form

Im Ideal- oder Normalfall (nämlich dann, wenn das Abarbeiten von storevote.php erfolgreich war) erhalten wir als responseText der XMLHttpRequest-Instanz genau diesen Text, der schnell an Flash übergeben wird (siehe Listing 5.41).

Also auf zu Flash! Wir benötigen einerseits die ExternalInterface-Klasse, um die reibungslose Kommunikation zwischen Flash und JavaScript zu gewährleisten, und andererseits die DropShadowFilter-Klasse, um die Ausgabe ein wenig aufzupeppen:

import fl ash.fi lters.DropShadowFilter;

var dropShadow:DropShadowFilter = new DropShadowFilter(4, 45, 0x333333, 0.8, 10, 10, 2, 3);

import fl ash.external.*;

//var msg:mx.controls.TextArea;

if(ExternalInterface.available) {

if(ExternalInterface.addCallback("showVoteData",null,showVoteData)) {

//msg.text += "Callback-Funktion ERFOLGREICH registriert\n";

}

Page 237: Flash cs3, ajax und php

K A P I T E L 5224

else {

//msg.text += "Callback-Funktion NICHT erfolgreich registriert\n";

}

}

else {

//msg.text += "EXTERNAL INTERFACE NICHT verfügbar\n";

}

Listing 5.44: Der Code der Aktionenebene: Es werden zwei Klassen eingebunden, ein Schlagschatten defi niert und überprüft, ob ExternalInterface verfügbar ist und die Callback-Funktion erfolgreich registriert wurde.

Die Variable dropShadow speichert eine Instanz des Objekts DropShadowFilter für die weitere Verwendung (Details zu den Parametern finden Sie in der ActionScript-Referenz). Des Weiteren finden Sie einige auskommentierte Codeteile für den Fall, dass Sie eine TextArea namens msg in Verwendung haben (beispielsweise für die Ausgabe etwaiger Informationsmeldungen).

Rufen wir uns in Erinnerung, dass JavaScript eine Funktion showVoteData aufruft (diese Funktion wurde als Callback-Funktion registriert):

function showVoteData(myData:String):Void {

var myDataArray:Array = parseDataIntoArray(myData);

createDiagram(myDataArray);

}

Listing 5.45: Die Funktion showVoteData, die für JavaScript freigegeben wurde

An showVoteData wird wie oben beschrieben von AJAX (JavaScript) der URL-codierte String der PHP-Datei storevote.php übergeben: Die Variable myData wird diesen String beinhalten. Um mit diesem String ordentlich arbeiten zu können, werden wir ihn in ein Array parsen – dazu verwenden wir die Funktion parseDataIntoArray:

function parseDataIntoArray(myData:String):Array {

var myLoadVars:LoadVars = new LoadVars();

myLoadVars.decode(myData);

var returner:Array = new Array();

var i:Number = 1, j:Number = 0, highestVal:Number = 0, itmname:String;

returner[0] = new Array();

for(itm in myLoadVars) {

itmname = itm.toLowerCase();

if(itmname.indexOf("anzahl")!=-1 && parseInt(myLoadVars[itm])>highestVal) { highestVal = parseInt(myLoadVars[itm]); }

Page 238: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 225

if(j==0) { returner[i] = new Array(); }

returner[i][j] = myLoadVars[itm];

j++;

if(j==3) { j = 0; i++; }

}

returner[0][0] = highestVal;

return returner;

}

Listing 5.46: Die Funktion parseDataIntoArray schreibt die von JavaScript übergebenen Werte in ein zweidimensionales Array returner.

Die einfachste Art, um mit URL-codierten Daten zu arbeiten ist, diese in ein sogenann-tes LoadVars-Objekt zu laden – dazu dient die Methode decode.

Das LoadVars-ObjektGrundsätzlich wird dieses Objekt zum Laden serverseitiger Daten in Flash verwendet – Details hierzu lernen Sie im folgenden Kapitel. Da wir in diesem Beispiel eigentlich auch mit serverseiti-gen Daten zu tun haben (unsere URL-codierten Daten), können wir das LoadVars-Objekt ein bisschen zweckentfremden und es zum leichteren Auslesen dieser URL-codierten Daten verwen-den.

Nach dem Ausführen von decode befinden sich alle Daten als Variablen in der Load-Vars-Instanz – eine for-in Schleife ist somit ideal zum Auslesen aller Daten. Zuvor legen wir noch einen ersten Eintrag im Array returner an, wo wir an Stelle [0][0] die höchste eingelesene Anzahl an Stimmen speichern werden.

Innerhalb der for-in-Schleife müssen wir beim Parsen berücksichtigen, dass wir pro Datensatz immer drei Informationen einlesen müssen: ID, Anzahl und Antwort. Aus diesem Grund lassen wir eine Variable j mitzählen, die die Werte 0–2 einnehmen soll. Sobald j==3 ist, wird j wieder auf 0 gesetzt und i um eins erhöht. Ist j==0, wird ein neuer Eintrag im returner-Array erzeugt. So weit zum grundsätzlichen Ablauf. Sollte die gerade bearbeitete Variable einen Text „anzahl“ im Namen tragen, wird der Wert in eine Ganzzahl umgewandelt (parseInt) und überprüft, ob die gerade eingelesene Anzahl größer als der höchste gespeicherte Wert für die Anzahl der abgegebenen Stim-men ist (parseInt(myLoadVars[itm])>highestVal). Falls ja, wird dieser Wert als der höchste Wert gespeichert.

Zuletzt schreiben wir den Wert von highestVal wie besprochen an die Stelle [0][0] des returner-Arrays und liefern das Array an den Aufrufer (die Funktion showVo-teData) zurück, wo das Array als myDataArray weiterverarbeitet wird. Um die Daten nun darzustellen, wird im zweiten Schritt die Funktion createDiagram aufgerufen, die das eigentliche Balkendiagramm erzeugt:

LoadVars & URL-codierte Informa-tionen

LoadVars & URL-codierte Informa-tionen

Page 239: Flash cs3, ajax und php

K A P I T E L 5226

function createDiagram(myDataArray:Array):Void {

mcWarten._visible = false;

var maxVal:Number = 160;

var xScaler:Number = maxVal/myDataArray[0][0];

var stringMaxLength:Number = 15;

var balkenOffsetX:Number = 120;

var balkenOffsetY:Number = 0;

var myFormat:TextFormat = new TextFormat();

myFormat.font = "Arial";

myFormat.size = 12;

for(var i:Number=1; i<myDataArray.length; i++) {

var myName:String = "Balken"+i;

this.createEmptyMovieClip(myName,i);

this[myName].id = myDataArray[i][2];

this[myName]._x = 120;

this[myName]._y = 5+(i-1)*15;

this[myName].createTextField("myTextfi eld",0,-110,0,100,20);

var theText:String = myDataArray[i][1];

if(theText.length>stringMaxLength) { theText = theText.substr(0,stringMaxLength-2)+".."; }

this[myName]["myTextfi eld"].text = theText;

this[myName]["myTextfi eld"].setTextFormat(0, this[myName]["myTextfi eld"].text.length, myFormat);

this[myName].createEmptyMovieClip("mcRechteck",1);

drawBalken(this[myName]["mcRechteck"], myDataArray[i][0]*xScaler, 10, 0x99FF00);

this[myName].onRelease = function():Void {

import fl ash.external.*;

ExternalInterface.call("showDetailData",this.id)

}

Page 240: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 227

}

}

Listing 5.47: Die Funktion createDiagram sorgt dafür, dass aus den übermittelten Daten ein Balkendia-gramm erzeugt wird.

Betrachten wir die Funktion genauer, stechen zunächst folgende Schritte bzw. Defini-tionen ins Auge:

mcWarten._visible = false: Der Text „WARTE AUF DATEN…“ (siehe Abbil-dung 5.29) ist im MovieClip mcWarten verpackt. Da dieser nach dem Aufbau der Balken nicht mehr benötigt wird, wird er ausgeblendet.

var maxVal:Number = 160: Die Variable maxVal bestimmt die Länge des längs-ten Balkens – an ihm werden alle anderen Balken gemessen und so entsprechend skaliert.

var xScaler:Number = maxVal/myDataArray[0][0]: xScaler berechnet aus der zuvor angegebenen maximalen Länge eines Balkens (maxVal) und der höchs-ten Anzahl an Stimmen (myDataArray[0][0] – siehe Beschreibung zu highest-Val weiter oben) den Skalierungsfaktor für jeden Balken.

var stringMaxLength:Number = 15: Diese Variable gibt an, wie lange der Beschriftungstext (die „Antwort“, die der User angezeigt bekommen hat) vor einem Balken maximal sein darf, bevor er abgeschnitten wird und ihm zwei Punkte „..“ angehängt werden.

var balkenOffsetX:Number = 120: Nullabstand des Balkens in horizontaler Richtung vom Anfang der Beschriftung des Balkens

var balkenOffsetY:Number = 3: Nullabstand des Balkens in vertikaler Rich-tung vom Anfang der Beschriftung des Balkens

Zwischenzeitlich erzeugen wir noch eine Formatvorlage myFormat (Schriftart Arial, Textgröße 12 Pixel) für den Beschriftungstext, die wir dann auf alle Beschriftungstexte anwenden werden:

var myFormat:TextFormat = new TextFormat();

myFormat.font = "Arial";

myFormat.size = 12;

Danach werden in einer for-Schleife sämtliche Balkendaten im Array myDataArray durchgegangen, wobei wir uns in Erinnerung halten müssen, dass pro Eintrag in myDataArray ein weiteres Array mit drei Einträgen steckt:

myDataArray[n][0]: Anzahl der Stimmen

myDataArray[n][1]: Beschriftung des Balkens

u

u

u

u

u

u

u

u

Page 241: Flash cs3, ajax und php

K A P I T E L 5228

myDataArray[n][2]: ID der Antwort (in unserer Tabelle tbl_05antworten ent-spricht dieser Wert dem Feld idP_Antwort)

(n steht für einen beliebigen Eintrag im Array.)

Innerhalb der Schleife erzeugen wir zunächst einen leeren MovieClip mit dem Namen „BalkenN“ (wobei N wiederum für einen fortlaufenden Zähler der Schleife – bei uns: die Variable i – steht). Innerhalb des neu erstellten Clips merken wir uns die zugehö-rige ID in der Variable id und setzen den Clip entsprechend des Schleifenzählers an eine x- (immer 0) und y-Position (mit einem Offset von 5 Pixel dann alle 15 Pixel nach unten: 5+(i-1)*15).

Vielleicht ist Ihnen aufgefallen, dass die for-Schleife nicht bei 0 zu zählen beginnt, wie das normalerweise üblich wäre, wenn man alle Einträge des myDataArray durchgehen möchte. In unserem Fall ist jedoch die Position 0 dieses Arrays durch die höchste vor-kommende Stimmenanzahl (highestVal aus der Funktion parseDataIntoArray) definiert und erst ab Position 1 sind die eigentlichen Balkenwerte gespeichert.

Im neuen Clip legen wir für die Beschriftung ein neues Textfeld an (dies trägt pro Clip immer denselben Namen „myTextfield“), Position [0][0] mit einer Länge von 120 Pixel und einer Höhe von 20 Pixel. Im selben Atemzug kümmern wir uns um den Inhalt dieses Textfelds: Sollte der Beschriftungstext länger als die maximal von uns gewünschte Anzahl an Zeichen sein (theText.length>stringMaxLength), so kür-zen wir den Text auf diese Länge minus 2 Pixel (= Anzahl der Punkte, die angehängt werden), hängen zwei Punkte „..“ an und weisen den Text korrekter Länge dann dem zuvor neu erzeugten Textfeld zu. Abschließend wenden wir die Formatvorlage myFor-mat noch auf den gesamten Text an – der Beschriftungsteil ist abgehakt.

Wenden wir uns dem Erzeugen eines Balkens (letzten Endes eines Rechtecks oder vierer Linien) zu. Schritt eins ist das Erzeugen eines eigenen MovieClips im MovieC-lip BalkenN mit dem Namen „mcRechteck“. Schritt zwei umfasst das Aufrufen einer selbst gebastelten Funktion drawBalken, an die wir den Namen des MovieClips, worin der Balken gezeichnet werden soll, den Offset zum Zeichnen in x- und y-Richtung, die Breite und Höhe des Balkens sowie die Farbe des Balkens (in hexadezimaler Notation) übergeben:

function drawBalken(mcBalken:MovieClip, boxOffsetX:Number, boxOffsetY:Number, boxWidth:Number, boxHeight:Number, fi llColor:Number):Void {

if(boxWidth==0) { boxWidth = 1; }

with (mcBalken) {

beginFill(fi llColor, 100);

moveTo(boxOffsetX,boxOffsetY+0);

lineTo(boxOffsetX+boxWidth, boxOffsetY);

lineTo(boxOffsetX+boxWidth, boxOffsetY+boxHeight);

lineTo(boxOffsetX, boxOffsetY+boxHeight);

u

Schleifen beginn bei 1, nicht bei 0Schleifen beginn bei 1, nicht bei 0

Page 242: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 229

lineTo(boxOffsetX, boxOffsetY);

endFill();

fi lters = [dropShadow];

}

}

Listing 5.48: Die Funktion drawBalken zeichnet einen Balken mit Mindestlänge 1 Pixel, bestehend aus vier Linien, die mit einer Füllfarbe gefüllt werden und dem so erzeugten Rechteck einen Schlagschatten zuweisen.

Da es wenig Sinn macht, einen Balken mit der Länge null zu zeichnen, setzen wir die Länge des Balkens auf minimal 1 Pixel (ansonsten würden wir auch Gefahr laufen, dass der User annimmt, hier würden Balken einfach fehlen):

Usability: bei keinen Stimmen trotzdem Balken mit Länge 1 Pixel

Usability: bei keinen Stimmen trotzdem Balken mit Länge 1 Pixel

Mit dem übergebenen MovieClip starten wir das Zeichnen eines Balkens, indem wir vier Linien zeichnen und den Bereich füllen (beginFill(fillColor, 100) – es wird die Füllfarbe fillColor zu 100% Deckkraft, wobei die Deckkraft nicht gesondert angegeben werden müsste). Die Methode moveTo sorgt dafür, dass wir an der richtigen Stelle zu zeichnen beginnen, da sie die Zeichnen-Startposition an die gegebene Stelle setzt. Sind alle vier Linien mit lineTo gezeichnet worden, kann das Füllen der so entstandenen Fläche wieder beendet und der Schlagschatten dropShadow angewandt werden (die Definition des Schlagschattens finden Sie in der Aktionenebene, die in Listing 5.44 beschrieben wurde).

Mittlerweile sind Beschriftung und Balken erzeugt. (Zur Erinnerung: Wir befinden uns im letzten Teil der for-Schleife aus Listing 5.47.) Unsere Aufgabenstellung sieht jedoch vor, dass der User einen Klick auf den Balken machen kann und so Details zum geklickten Balken bekommt – dies bedeutet für uns, dass wir unserem gesamten Clip noch ein onRelease-Ereignis zuweisen müssen:

...

this[myName].onRelease = function():Void {

import fl ash.external.*;

ABBILDUNG 5.33

Besser einen Balken mit 1 Pixel Länge erzeugen (bei null Stimmen) als keinen Balken – kein Balken wirkt auf den User als „Fehler“.

Page 243: Flash cs3, ajax und php

K A P I T E L 5230

ExternalInterface.call("showDetailData",this.id)

}

...

Listing 5.49: Auszug aus Listing 5.47

Beim Loslassen der Maustaste (onRelease) laden wir nochmals die External-Interface-Klasse (diese ist die einzige Klasse innerhalb flash.external) und rufen die JavaScript-Funktion showDetailData mit der MovieClip-eigenen id-Variable (idP_Antwort der Tabelle tbl_05antworten) auf. Der Flash-Part wäre aber an dieser Stelle beendet – also zurück zu JavaScript.

Wie oben beschrieben wird beim Klick auf einen Balken (oder auf dessen Beschrif-tung) über die ExternalInterface-Klasse die JavaScript-Funktion showDetail-Data aufgerufen. Sie sorgt dafür, dass per AJAX Detaildaten zum geklickten Balken angezeigt werden:

function showDetailData(idP_Antwort) {

var querystring = "idP_Antwort="+idP_Antwort;

myXMLHttpRequest.open("GET", "getdetails.php?"+querystring, true);

myXMLHttpRequest.onreadystatechange = handleRequestDetail;

myXMLHttpRequest.send(null);

}

Die Funktion showDetailData öffnet ihrerseits eine Verbindung zum Server auf die Datei getdetails.php, um Detailinformationen zu einer gegebenen Antwort abzuru-fen. Hierzu wird die angeforderte Antwort-ID als Querystring an den Dateinamen angehängt, der XMLHttpRequest-Instanz ein Eventhandler handleRequestDetail zugewiesen und die Anfrage abgeschickt. Der an dieser Stelle verwendete Eventhandler ist selbstverständlich nicht derselbe wie der Eventhandler, den wir für die Abarbeitung der Anfrage für Fragen aus Listing 5.41 verwendet haben – wir wollen ja den Rückga-bewert nicht an Flash übergeben, sondern in dem dafür vorgesehenen DIV-Container „Details“ (siehe Listing 5.39) darstellen.

Keine großen Geheimnisse birgt die Datei getdetails.php für uns:

if(count($_GET)>0 && isset($_GET["idP_Antwort"])) {

$conn = mysql_connect("mysql.syneweb.com","usr_fl ashphpajax","fl ashmyphpajax") or die('<div class="error">Die Verbindung zum Datenbankserver konnte NICHT hergestellt werden. Error: '.mysql_error().'</div>');

$db = mysql_select_db("db_fl ashphpajax") or die('<div class="error">Die Datenbank konnte NICHT ausgewaehlt werden. Error: ‚.mysql_error().'</div>');

$sql = "SELECT * FROM tbl_05antworten WHERE(idP_Antwort=".$_GET["idP_Antwort"].")";

Page 244: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 231

$query = mysql_query($sql);

$data = mysql_fetch_array($query);

$sql = "SELECT SUM(int_AnzahlStimmen) AS sum FROM tbl_05antworten WHERE(bitP_chk_aktiv=1 AND fi dP_select_Bezeichnung_Frage=".$data["fi dP_select_Bezeichnung_Frage"].")";

$query = mysql_query($sql) or die("ERROR: ".mysql_error());

$data2 = mysql_fetch_array($query);

$sum = $data2["sum"];

echo('

<ul>

<li>Anzahl abgebebener Stimmen gesamt: '.$sum.'</li>

<li>Anzahl Stimmen f&uuml; \''.$data["vcP_Antwort"].'\': '.$data["int_AnzahlStimmen"].'</li>

<li><span style="font-weight:bold;">Prozentsatz: '.round(100*$data["int_AnzahlStimmen"]/$sum,2).'%</span></li>

</ul>

‚);

}

Listing 5.50: Das gesamte Listing von getdetails.php ist mehr oder weniger Routine – zwei Abfragen, ein bisschen Ausgabe per echo.

Das Ziel dieser Datei ist Folgendes:

1. Überprüfen, ob an sie GET-Daten übergeben wurden und ob es sich um die GET-Variable idP_Antwort handelt (ansonsten würde das Abarbeiten dieser Datei keinen Sinn machen):

if(count($_GET)>0 && isset($_GET["idP_Antwort"]))

2. Ein erstes SQL-Statement abzusetzen, das alle Infos zur geforderten Antwort aus der Datenbank liest (zuvor muss natürlich der Datenbankserver kontaktiert und die Datenbank ausgewählt werden, aber das wissen Sie sicherlich):

SELECT * FROM tbl_05antworten WHERE(idP_Antwort=".$_GET["idP_Antwort"].")

3. Ein zweites SQL-Statement, das alle zur gegebenen Frage (die auch für unsere Antwort gegolten hat) abgegebenen Stimmen zählt (aufsummiert) und die Summe zurückliefert:

Page 245: Flash cs3, ajax und php

K A P I T E L 5232

SELECT SUM(int_AnzahlStimmen) AS sum FROM tbl_05antworten WHERE(bitP_chk_aktiv=1 AND fi dP_select_Bezeichnung_Frage=".$data["fi dP_select_Bezeichnung_Frage"].")

4. Aus den so gewonnenen Informationen eine Liste mit folgenden Informationen zusammenzustellen:

Anzahl der insgesamt abgegebenen Stimmen zu dieser Frage

Anzahl der Stimmen für die geklickte Antwort

Prozentsatz der auf die angeklickte Antwort abfallenden Stimmen

Diese zuletzt genannte Liste wird per echo ausgegeben und bildet somit den Rück-gabewert responseText für die XMLHttpRequest-Instanz myXMLHttpRequest. Der zuvor angesprochene Eventhandler handleRequestDetail sorgt schlussendlich dafür, dass dieser Rückgabewert in den DIV-Container „Details“ geschrieben wird:

function handleRequestDetail() {

switch(myXMLHttpRequest.readyState) {

case 0:

case 1:

case 2:

case 3: break;

case 4: document.getElementById("Details").innerHTML = myXMLHttpRequest.responseText; break;

}

}

Listing 5.51: Abschluss unserer Bemühungen: Der Rückgabewert responseText von getdetails.php wird in den dafür vorgesehenen DIV-Container „Details“ geschrieben.

Das war’s, meine Damen und Herren! Und damit wir nicht vergessen, warum wir den Aufwand mit AJAX getrieben haben: Dieses Umfragetool muss nicht die Seite neu laden, um die aktualisierten Daten anzuzeigen, wie es sonst üblich ist. Und wenn Sie Lust darauf haben, dass auch mehrere Umfragen ohne Neuladen des Dokuments durchgeführt werden sollen, dann sehen Sie sich die Datei ajax02a.htm an, die Sie auf der Buch-CD finden:

u

u

u

Page 246: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 233

Na, Lust auf mehr bekommen? ajax02a.htm, ajax02a.fla und getquestion.php sind die Antwort! Zu finden auf der Buch-CD. Folgende Änderungen wurden vorgenommen:

1. Die PHP-Abfrage der Frage und zugehörigen Antworten wurde in eine externe Datei verlegt (getquestion.php), die im Weiteren per AJAX abgefragt wird. Der erste Aufruf erfolgt beim Eintreten des onload-Ereignisses für das window-Objekt.

2. Bei Klick auf den Button „Neue Frage“ passiert genau dasselbe wie beim onload-Ereignis von oben, nur dass zusätzlich noch die Flash-Datei „zurückgesetzt“ wird (die von einer vorigen Frage dargestellten Balken werden eliminiert und es wird wieder der Text „WARTE AUF DATEN“ eingeblendet.

Werfen Sie einen Blick darauf ...

5.4.2 Parameterübergabe: XMLBisher haben wir ausschließlich mit der Eigenschaft responseText eines XMLHttp-Request-Objekts gearbeitet. Nun wollen wir die Gelegenheit beim Schopf packen und anstatt Text- nun XML -Daten vom Server abfragen und an Flash weiterleiten.

XML ist ideal dafür geeignet, strukturierte Daten darzustellen – genau wie unser obiges Beispiel es fordert. Würden wir die der Balkengrafik zugrunde liegenden Daten in XML-Form ausgeben, könnte das beispielsweise wie folgt aussehen:

ABBILDUNG 5.34

Nun werden auch die Fragen und zugehörigen Antworten per AJAX angefordert.

Page 247: Flash cs3, ajax und php

K A P I T E L 5234

Fraglich ist nun, ob die Daten vom Server als XML- (responseXML) oder Textdaten (responseText) abgefragt werden sollen. Überraschenderweise wählen wir auch hier die Variante responseText, obwohl die Daten in XML-Form bereitstehen. Flash verträgt sich jedoch nicht mit der Darstellung der XML-Daten, wie sie uns AJAX zur Verfügung stellen würde. Somit ergäben sich zwei Möglichkeiten:

1. Wir wandeln das per AJAX angeforderte XML-basierte Dokument so um, dass Flash damit etwas anfangen kann.

2. Wir laden die XML-Daten als Text und übergeben den Text an Flash, das für sich wiederum den Text in XML-Form umwandelt.

Variante 2 ist wesentlich einfacher, weshalb wir nach wie vor responseText an Flash schicken und dieses dann „echtes“ XML daraus macht.

AJAX-technisch ist an unserem Beispiel nichts zu ändern, trotzdem möchte ich Sie an dieser Stelle noch auf eine kleine Sache hinweisen, die Ihnen wahrscheinlich schon auf-gefallen ist und die wir idealerweise an dieser Stelle diskutieren können. Bisher hatten unsere Eventhandler immer eine relativ komplexe Struktur, da wir eine Auswertemög-lichkeit für jeden Wert der readyState-Eigenschaft des XMLHttpRequest-Objekts vorgesehen hatten:

function handleRequest() {

switch(myXMLHttpRequest.readyState) {

case 0:

case 1:

case 2:

response-Text oder

responseXML?

response-Text oder

responseXML?

ABBILDUNG 5.35

Die Antwortdaten für eine gegebene Frage in XML-

Form – vergleichen Sie doch mal mit Listing 5.43 und

Sie werden sicherlich auch der Meinung sein, dass

diese Form der Darstellung wesentlich übersichtlicher

ist.

Page 248: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 235

case 3: break;

case 4: FUNKTIONSAUFRUF BZW. CODE; break;

}

}

Listing 5.52: Ein typischer Aufbau der von uns verwendeten Eventhandler

Wie Sie aus dem obigen Listing entnehmen können, sind die Fälle 0–3 der switch-Anweisung sinnlos – wir werten diese Fälle gar nicht aus, sondern brechen vielmehr mit break ab. Warum sollten wir diese Fälle dann überhaupt verwenden? Wenn jedoch die Fälle 0–3 wegfallen, benötigen wir auch keine switch-Anweisung mehr, sondern kommen mit einer einfachen if-Anweisung aus:

function handleRequest() {

if(myXMLHttpRequest.readyState==4) {

FUNKTIONSAUFRUF BZW. CODE;

}

}

Listing 5.53: Sieht doch gleich einfacher aus – if anstatt switch für nur einen möglichen Wert von readyState.

Somit reduziert sich unser Script auf:

function handleRequest() {

if(myXMLHttpRequest.readyState==4) {

if(myXMLHttpRequest.responseText.indexOf("ERROR")!=-1) { alert("Es ist ein FEHLER beim Voting aufgetreten - bitte versuchen Sie es erneut!"); }

else { var mySWF = getFlashElement("myswf"); mySWF.showVoteData(myXMLHttpRequest.responseText); }

}

}

Listing 5.54: Unser Eventhandler hat sich gegenüber dem vorigen Beispiel von der Funktionsweise nicht ge-ändert – wir haben ihn nur etwas „abgespeckt“ und so auf unsere Bedürfnisse optimal angepasst. Obwohl wir XML-Daten vom Server laden, übergeben wir diese als responseText an Flash.

Nachdem wir so viel über XML-Daten gesprochen haben, wollen Sie sicherlich auch erfahren, wie die serverseitige Datei storevote.php sich nun ändern muss, sodass wir XML- anstatt Textdaten zurückerhalten. (Sie finden die neue Version von storevote.php übrigens unter dem Namen storevote2.php auf der Buch-CD.) Der wesentliche Unter-schied liegt in folgenden Zeilen:

Page 249: Flash cs3, ajax und php

K A P I T E L 5236

Bisher (für die Textrückgabe in URL-codierter Form) haben wir folgenden Code verwendet:

$returner = ‚';

$i = 0;

while($data = mysql_fetch_array($query)) {

$returner.= 'ID'.$i.'='.$data["idP_Antwort"].'&Antwort'.$i.'='.$data["vcP_Antwort"].'&Anzahl'.$i.'='.$data["int_AnzahlStimmen"].'&';

$i++;

}

$returner = substr($returner,0,$returner.length-1);

Nun verwenden wir:

header("Content-type: text/xml");

$returner = '

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>

<Umfrage>

';

while($data = mysql_fetch_array($query)) {

$returner.= '

<Antwort ID="'.$data["idP_Antwort"].'" Antworttext="'.$data["vcP_Antwort"].'" Anzahl="'.$data["int_AnzahlStimmen"].'" />

‚;

}

$returner.= ‚</Umfrage>';

Der wichtigste Unterschied liegt zunächst in der Definition des Content-type des Doku-ments: Mittels header("Content-type: text/xml") definieren wir, dass es sich bei den enthaltenen Daten um XML-basierte Daten in Textform handelt. Danach erzeugen wir das für ein XML-Dokument notwendige Tag <?xml ?>, wo wir als Attribute die verwendete XML-Version (version="1.0"), den Zeichensatz (encoding="ISO-8859-1") sowie die Info, ob das Dokument für die Darstellung noch ein Stylesheet benötigt oder nicht (kein Stylesheet benötigt: standalone="yes"), angeben.

Innerhalb der while-Schleife basteln wir nun keinen URL-codierten Text, sondern Tags zusammen, und zwar in der Form:

<Antwort ID="..." Antworttext="..." Anzahl="..." />

Das Ergebnis dessen haben Sie in Abbildung 5.35 bereits gesehen.

Viel interessanter ist nun die Frage, wie Flash mit den nun XML-basierten Daten umgeht. Betroffen davon sind vor allem die Funktionen storeVoteData (dies ist die

u

u

Page 250: Flash cs3, ajax und php

C L I E N T S E I T I G E R D A T E N A U S T A U S C H – F L A S H & J A V A S C R I P T 237

Funktion, die von JavaScript (AJAX) aufgerufen wird) und parseDataIntoArray. Die Datei storeVoteData erhält nach wie vor einen Text als Übergabeparameter, der mit geeigneten Flash-Befehlen in eine XML-Struktur gebracht gehört. Nachdem das gesamte Parsing der Daten jedoch in der Funktion parseDataIntoArray vor sich geht, muss an storeVoteData nichts geändert werden.

Wie steht es also um die Funktion parseDataIntoArray? Werfen wir einen Blick darauf:

function parseDataIntoArray(myData:String):Array {

var myXML:XML = new XML();

myXML.ignoreWhite = true;

myXML.parseXML(myData);

var returner:Array = new Array();

returner[0] = new Array();

returner[0][0] = 0;

var theData:Array = myXML.fi rstChild.childNodes;

for(var i:Number=0; i<theData.length; i++) {

returner[i+1] = new Array();

returner[i+1][0] = theData[i].attributes["Anzahl"];

returner[i+1][1] = theData[i].attributes["Antworttext"];

returner[i+1][2] = theData[i].attributes["ID"];

if(parseInt(returner[i+1][0])>returner[0][0]) { returner[0][0] = parseInt(returner[i+1][0]); }

}

return returner;

}

Listing 5.55: Die Funktion parseDataIntoArray in etwas geänderter Form: Anstatt des LoadVars- Objekts verwenden wir nun das XML-Objekt.

Statt der Verwendung des LoadVars-Objekts in Flash kommt nun das XML-Objekt zum Einsatz (var myXML:XML = new XML();). Um unnötige Zeilenumbrüche, Leer-zeichen und -zeilen (sog. „Whitespaces“) zu ignorieren, wird die Eigenschaft ignore-White auf den Wert true gesetzt. Um die von AJAX übergebenen Daten schlussen-dlich in das XML-Objekt zu bekommen, wenden wir den Befehl parseXML an. (Zur Erinnerung: Im Fall von LoadVars war es der Befehl decode.)

Page 251: Flash cs3, ajax und php

K A P I T E L 5238

An der Stelle [0][0] des returner-Arrays werden wir nach wie vor den höchsten gefundenen Wert von „Anzahl“ speichern, jedoch verwenden wir nun keine zusätzliche Variable highestVal mehr, sondern arbeiten gleich direkt mit diesem Wert.

Um in der XML-Struktur an das für uns interessante Tag „Umfrage“ zu gelangen, ver-wenden wir die Eigenschaft firstChild der XML-Instanz myXML; die einzelnen „Ant-wort“-Tags befinden sich als sog. „Kinder“ (Children) innerhalb des „Umfrage“-Tags. Aus diesem Grund gehen wir Schritt für Schritt alle dieser Kinder durch und speichern die Informationen „Anzahl“, „Antworttext“ und „ID“ (diese befinden sich als Attribute im jeweiligen „Antwort“-Tag – siehe Abbildung 5.35) im returner-Array. Da wie auch im letzten Beispiel die Stelle [0][0] des returner-Arrays für den Höchstwert an Stimmen reserviert ist, wir jedoch in diesem Fall bei i=0 in der Schleife zu zählen beginnen, schreiben wir diese Werte jeweils an die Stelle [i+1].

Alles weitere ist wie gehabt – es müssen keine weiteren Änderungen mehr vorgenom-men werden. Das Resultat sollte sich nicht geändert haben:

Stellt sich die abschließende Frage, warum wir nun XML-basierte Daten anstatt text-basierter Daten verwendet haben? Nun, die größte Stärke liegt bei Flash verborgen, denn Flash kann wesentlich besser mit XML- als mit Textdaten umgehen. Mit der Einführung von ActionScript 3.0 hat sich in Bezug auf Flash & XML noch einmal ordentlich was getan. Freuen Sie sich auf das nächste Kapitel, wo wir ausführlich mit XML-Daten arbeiten werden, denn dort geht es darum, wie Flash mit der Serverseite arbeiten kann.

ABBILDUNG 5.36

Auch bei Verwendung von XML-Daten hat sich an der

Funktionsweise unseres Beispiels nichts geän-

dert – wäre ja auch fatal gewesen …

Page 252: Flash cs3, ajax und php

6SERVERSEITIGER DATEN-AUSTAUSCH – FLASH, PHP & DATENBANK

Um die Frage zu beantworten, wie die Kommunikation zwi-schen Flash und einer serverseitigen Anwendung (wie etwa das Ansprechen eines serverseitigen Scripts oder das Anbinden einer Datenbank oder Ähnliches) erfolgt, müssen wir uns die Vorgehensweise bei der Darstellung eines Webdokuments (mit eingebundener Flash-Datei) auf Clientseite noch einmal kon-kret vor Augen führen.

Zunächst erhält der Server vom Browser des Users (also dem „Client“) eine Anfrage für ein Webdokument in Form einer URL. Der (Web-)Server bereitet die Daten für den Client auf und schickt diese (paketweise) zum Client zurück. Ist das Dokument vollständig beim Client eingetroffen, spricht man vom „fertig geladenen“ Dokument. Mit Beendigung dieses Schritts ist die Kommunikation zwischen Client und Server abgeschlossen und beide agieren wieder vollkommen unabhän-gig voneinander.

Nachdem Flash ein Plug-in auf Clientseite ist, kann Flash auch nur auf Clientseite agieren. Ein (serverseitiges) PHP-Script, eine Datenbank zum Abfragen oder Speichern von Daten im Rahmen einer Website liegt jedoch immer auf Serverseite vor, demnach muss Flash also mit der Serverseite Kontakt aufneh-men können. Ohne eine geeignete Technologie als „Vermittler“ zwischen Client- und Serverseite ist Flash dazu nicht (oder nur mit Einschränkungen – siehe etwas weiter unten) in der Lage.

Page 253: Flash cs3, ajax und php

K A P I T E L 6240

Soll eine Datenbank angesprochen werden, muss diese (oder eine zweite) Technologie zusätzlich noch die von Flash gesandten Daten in eine für die Datenbank verständliche Form bringen. PHP stellt also die ideale Kombination dieser beiden Anforderungen dar.

Fassen wir den theoretischen Teil noch einmal zusammen:

1. Flash möchte ein serverseitiges Script ansprechen.

Hierzu muss in jedem Fall eine Kommunikation mit dem Server hergestellt werden. Da in Flash (ohne Zusatztools auf Serverseite) keine Möglichkeiten zur direkten Anbindung mit einer Datenbank gegeben sind, muss eine geeignete Technologie bereitstehen, die diese Aufgabe erledigt.

2. Es wird durch Flash eine PHP-Seite aufgerufen.

PHP agiert auf Serverseite und bringt die übermittelten Daten in eine geeignete Form – die Daten werden „aufbereitet“.

3. Soll eine Datenbank angesprochen werden, nimmt PHP Kontakt zur Datenbank auf und schreibt bzw. liest mithilfe der Abfragesprache SQL die Daten.

PHP allein kann wiederum nicht mit einer Datenbank arbeiten. Aus diesem Grund bedient man sich einer weiteren Sprache – der Abfragesprache SQL (Structured Query Language).

Selbstverständlich könnten auch andere serverseitige Technologien wie etwa ASP zum Einsatz kommen. In diesem Buch haben wir uns für PHP entschieden, da PHP einerseits einfach zu erlernen und andererseits in Web-Entwicklerkreisen sehr weit verbreitet ist. Des Weiteren hat PHP mit der Datenbank MySQL wiederum eine im Web sehr verbreitete Datenbank zur Seite, wobei die Kommunikation zwischen diesen beiden auch noch hervorragend funktioniert. Schlussendlich sollten wir aber auch nicht vergessen, dass „serverseitiges Arbeiten“ ja nicht nur „Ansprechen einer Daten-bank“ bedeutet.

In den ersten Kapiteln befassen wir uns mit den Möglichkeiten, die sich im Rahmen von ActionScript 2.0 bieten. Danach sehen wir uns die – nicht unwesentlichen – Ände-rungen und Neuerungen im Rahmen von ActionScript 3.0 an (Kapitel 6.4).

6.1 Drei Technologien im EinsatzWie man sieht, ist das Arbeiten mit serverseitigen Technologien und im Weiteren mit einer Datenbank durchaus nicht trivial, da man zumindest zwei (drei bei Daten-banken) verschiedene Technologien vereinen muss. Dies soll uns jedoch nicht davon abhalten, diesen Schritt zu wagen – dafür ist dieses Thema in der Webwelt schon jetzt viel zu wichtig!

ActionScript 2.0 vs. ActionScript

3.0

ActionScript 2.0 vs. ActionScript

3.0

Page 254: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 241

In den nächsten Kapiteln werden wir uns mit genau dieser Thematik befassen – zuvor bleibt es uns aber nicht erspart, noch ein bisschen Theorie zu erläutern. Bitte bedenken Sie, dass sämtliche Ausführungen in den nächsten Kapiteln aus dem Blickwinkel von ActionScript 2.0 zu sehen sind – ActionScript 3.0 wird erst weiter unten behandelt. Erst dort werden wir erkennen, welche ungeheuren Fortschritte und auch Änderungen die neue Sprachversion uns Entwicklern bringt.

6.2 Das LoadVars -ObjektIm ersten Teil dieses Kapitels haben wir gesehen, wie JavaScript auf einfache Art und Weise beispielsweise Variablen in Flash setzen kann. Jetzt befassen wir uns mit der Frage, wie man in einem wesentlichen größeren Ausmaß Variablen in Flash einlesen (und auch ausgeben) kann – beispielsweise aus einer Textdatei.

Das LoadVars-Objekt in Flash wird aber nicht nur für das Einlesen von Daten zustän-dig sein – vielmehr werden wir auch Daten (sichtbar und unsichtbar) verschicken können. Der Empfänger der Daten könnte beispielsweise ein PHP-Dokument sein, das die Daten an eine Datenbank weiterleitet.

Daten aus einer Textdatei einlesen

Voraussetzung für das Einlesen von Daten ist zunächst einmal das Vorhandensein einer Textdatei. Hier ist für uns wichtig, dass diese Datei einem gewissen Muster entspricht: Sie muss „URL-codiert“ sein. Mit URL-Codierung oder URL-Encodierung meint man im ersten Schritt das Verfahren der Variable=Wert-Zuweisung. Es ist nicht ausrei-chend, in das Textdokument reinen Text zu schreiben (das wird erst mit ActionScript 3.0 klappen), wir müssen den Text (also den Wert) einer Variablen zuweisen.

ABBILDUNG 6.1

Die linke Datei „nichtKor-rekt“ ist ungeeignet für das Einlesen von Daten in Flash mit ActionScript 2.0 – in ActionScript 3.0 hätten wir damit keine Probleme. Die rechte Datei ist korrekt, da sie das Konzept Variable=Wert korrekt anwendet. Um die Leerzeichen müssen wir uns noch kümmern – mehr dazu weiter unten im Abschnitt zur URL-Codierung.

Abbildung 6.1 zeigt dieses Vorgehen. Die linke Abbildung zeigt eine für das Einlesen von Text nicht korrekte Textdatei, da sämtliche Informationen, die an Flash übergeben werden sollen, dem Konzept Variable=Wert genügen müssen (dies gilt für Version 2.0 von ActionScript, in Version 3.0 könnten wir mit dieser Datei arbeiten – siehe hierzu das Kapitel Laden von Textdaten). In der rechten Abbildung ist dieses Vorgehen zu sehen: Der (fiktiven) Variable myText wird der Wert „Hallo Welt!“ zugewiesen. Zu einem späteren Zeitpunkt werden wir sehen, dass wir eventuell aufgrund des Leerzei-chens auch an der rechten Darstellung noch ein wenig arbeiten müssen, um es perfekt zu machen.

Page 255: Flash cs3, ajax und php

K A P I T E L 6242

URL-Codierung

Ganz so einfach ist die Sache mit der Kodierung also nicht, denn es müssen einige Punkte beachtet werden:

1. Die Schreibweise von URL-Encodierung basiert auf der Variable=Wert-Zuweisung, d.h., es existiert immer eine Variable, der – getrennt durch ein Gleichheits zeichen – ein Wert zugewiesen wird.

2. Da die URL-Encodierung international gültig ist, dürfen im Text natürlich keine Umlaute vorhanden sein. Das bedeutet, dass alle Umlaute durch entsprechende Codes ersetzt werden müssen.

3. Auch Sonderzeichen (wie beispielsweise „ß“, Bindestriche und Fragezeichen) müssen durch entsprechende Codes ausgetauscht werden. Theoretisch müsste sogar das Leerzeichen ersetzt werden, Gott sei Dank ist das aber nur bei Formularfeldern nötig.

SonderzeichenEine vollständige Auflistung aller Sonderzeichen finden Sie unter http://www.unicode.org/charts/PDF/U0080.pdf – die im PDF-Dokument angeführten Codes werden als sog. „Escape Codes“ eingesetzt: Beispielsweise hat ein Leerzeichen den Code 0020, das in einem URL-codi-erten Dokument als %20 (die beiden Nullen werden durch ein Prozentzeichen ersetzt) eingefügt wird. Generell wird für die Codierung der Latin-1-Zeichensatz verwendet. Genaue Informationen über Unicode finden Sie auch unter http://www.unicode.org.

URL-Codierung: keine Leer- und Sonderzeichen

URL-Codierung: keine Leer- und Sonderzeichen

ABBILDUNG 6.2

Eine korrekt URL-codierte Datei

Mehrere Variablen übergeben

Jegliche Informationen, die URL-codiert an Flash übermittelt werden sollen, müssen also in Form von Variablen in der Textdatei vorliegen. Möchte man mehr als nur eine einzige Variable verwenden, so müssen die Variablen mithilfe des kaufmännischen Und „&“ verbunden werden:

Textdatei mit nur einer Variablen: myText=Hallo%20Welt

Textdatei mit mehreren Variablen: myText=Hallo%20Welt&myText2=Test

u

u

Page 256: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 243

Zu guter Letzt muss noch darauf geachtet werden, dass alle verwendeten Variablen eindeutige Namen erhalten. Sollte es vorkommen, dass ein Variablenname doppelt verwendet wird, so erhält diese Variable den Wert des letzten Eintrags.

„Quelle“ der einzulesenden DatenLetzten Endes ist es für Flash vollkommen irrelevant, ob die Datei, aus der Flash auslesen soll, eine Textdatei ist oder eine andere Datei eines anderen Formats, die nur genauso aufgebaut ist.

Dies eröffnet uns die Möglichkeit, beispielsweise eine PHP-Datei mit einem solchen Aufbau zu verwenden. Diese wiederum kann die Daten aus einer Datenbank auslesen, wobei wir schon beim Thema wären. Aber alles zu seiner Zeit – zunächst gehen wir den einfachen Weg des Auslesens aus einer (statischen, bereits existenten) Textdatei.

Ablauf eines Ladevorgangs

Das Hinzuladen der Daten aus der Textdatei erfolgt aus Flash heraus in folgenden Schritten:

1. Zunächst muss in Flash per ActionScript ein sogenanntes LoadVars-Ob jekt angelegt werden.

Mithilfe dieses Objekts wird es dann möglich sein, Daten einzulesen bzw. zu versenden, wie Sie in den nachfolgenden Kapiteln sehen werden. Das LoadVars-Objekt dient als eine Art Container, in dem alle eingelesenen Variablen abgelegt werden. Man kann sich ein solches Objekt wie eine Schachtel vorstellen, wo die Daten in Form von Variablen abgelegt sind.

2. Ein entsprechendes Ereignis – das onLoad-Er eignis – in Flash signalisiert, wann das Lesen der externen Datei abgeschlossen ist.

Wichtig ist hierbei, dass beim Auftreten dieses Ereignisses noch nicht gesagt ist, dass die Daten auch erfolgreich geladen wurden. Deshalb muss im nächsten Schritt noch überprüft werden, ob das Laden der Daten funktioniert hat.

3. Danach wird diesem LoadVars-Objekt eine Datei zugewiesen, von der die Daten gelesen werden sollen.

4. Nun muss geprüft werden, ob das Laden der Daten erfolgreich war.

Die Eigenschaft loaded de s LoadVars-Objekts sagt uns mit dem Wert true, ob dies geschehen ist. Sollte loaded den Wert false aufweisen, muss man sich überlegen, ob das Laden der Datei erneut versucht werden sollte.

Eindeutige VariablennamenEindeutige Variablennamen

ABBILDUNG 6.3

Die Textdatei links beinhal-tet lediglich eine einzige Variable, die Textdatei rechts umfasst fünf Variablen.

Page 257: Flash cs3, ajax und php

K A P I T E L 6244

Die Reihenfolge von Ereignissen bei LadevorgängenMan sollte darauf achten, dass Ereignisse, die unmittelbar mit dem Laden eines Dokuments in Verbindung stehen (wie beispielsweise das onLoad-Ereignis beim Laden externer Daten oder später auch einer XML-Datei), vor dem eigentliche Ladeaufruf definiert werden. Sollte beispiels-weise der Ladevorgang beendet sein, noch bevor die Ereignisprozedur zum Laden definiert wurde, wird diese eventuell nicht ausgeführt. Dieser Fall ist zwar zu beinahe 100% auszuschließen (keine Datei wird so schnell geladen werden, noch bevor die nächsten Zeilen des Flash-Dokuments abgearbeitet wurden), jedoch arbeitet man doch gerne konform der geltenden Regeln.

Mehrere Ladeversuche

Ein paar Worte zum Thema „Das Laden der Daten ist fehlgeschlagen“. Hier stellt sich unweigerlich die Frage, wodurch dies passieren kann. Mögliche Ursachen für den Fehl-schlag sind beispielsweise:

Die Verbindung zum Server is t abgebrochen.

Die Datei konnte nicht gefunden werden.

Die Datei ist nicht korrekt aufgebaut.

Natürlich wäre nur der erste Punkt der Liste ein Grund, das Laden der Datei erneut zu versuchen. Flash gibt uns leider nicht Auskunft darüber, warum, sondern nur, ob das Laden fehlgeschlagen ist. Aus diesem Grund sollte man auf jeden Fall einen erneuten Ladeversuch, maximal aber drei, in Erwägung ziehen.

Die nachfolgende Abbildung 6.4 zeigt den Ablauf eines Ladevorgangs mi t einer maxi-malen Anzahl an Wiederholungen.

u

u

u

ABBILDUNG 6.4

Diese Abbildung zeigt einen typischen Ablauf

eines Ladevorgangs mit einer maximalen Anzahl

an Wiederholungen. Sollte diese Anzahl erreicht werden,

bricht das Skript das Laden ab.

Page 258: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 245

Gehen wir die notwendigen Schritte in Flash also im Detail durch. Schritt eins besagt, dass wir ein neues LoadVars-Objekt anlegen müssen. Wir sind in der Namensgebung für das Objekt mit denselben Einschränkungen konfrontiert wie bei den Variablen, abgesehen davon muss nichts berücksichtigt werden.

1. Anlegen eines LoadVars-Objekts:

var myData:LoadVars = new LoadVars();

Im nächsten Schritt muss diesem LoadVars-Objekt eine Quelldatei zugewiesen werden, aus der die Daten geladen werden sollen. Diese Datei kann sowohl im selben wie auch in einem Unterverzeichnis abgelegt sein.

2. Warten auf das Auftreten des onLoad-Ereignisses mithilfe einer nativen Funk-tion:

myData.onLoad = function(loadedOK:Boolean):Void {

// Ereignisbehandlungsroutine

}

Innerhalb der Ereignisprozedur (be zeichnet dasselbe wie „Ereignisbehand-lungsroutine“) wi rd nun kontrolliert, ob das Laden der Datei erfolgreich war. Ein erfolgreiches Laden wird durch die Variable loadedOK==true des LoadVars-Objekts dargestellt. Der Wert der Variablen loadedOK wird direkt von Flash erzeugt – man könnte auch sagen, Flash „übergibt“ den Wert der Variablen loadedOK an die Funktion. Solche Variablen bezeichnet man gerne als Ereignisparameter.

Al ternativ zu dieser Vorgehensweise existiert auch noch eine zweite Variante: das Abfragen der Eigenschaft loaded eines LoadVars-Objekts – siehe hierzu den „Exkurs Ereignisparameter vs. Objekteigenschaft“.

3. Zuweisen einer Quelldatei:

myData.load("URL zur Quelldatei");

4. Überprüfen, ob das Laden erfolgreich war:

if(loadedOK) {

//beispielsweise Auslesen der Daten

}

else {

//Fehler beim Laden aufgetreten. Evtl. erneuter Ladeversuch?

}

Page 259: Flash cs3, ajax und php

K A P I T E L 6246

Exkurs: Ereignisparameter vs. ObjekteigenschaftUm zu überprüfen, ob ein Ladevorgang erfolgreich durchgeführt wurde, kann man sich zweierlei Möglichkeiten bedienen:

Man verwendet einen von Flash erzeugten Parameterwert der Ereignisprozedur onload eines LoadVars-Objekts. In unserem Fall wurde dieser Parameter in der Variable loadedOK gespei-chert.

Man überprüft die Eigenschaft loaded eines LoadVars-Objekts. In unserem Beispiel würde man in der if-Abfrage die Variable loadedOK durch den Ausdruck myData.loaded ersetzen. Ist myData.loaded==true, war der Ladevorgang erfolgreich, bei myData.loaded==false war er nicht erfolgreich.

Beide Möglichkeiten führen zum selben Ergebnis – welche Variante Sie einsetzen möchten, bleibt völlig Ihnen überlassen.

Geladene Daten auslesen

Sollte der Ladeversuch erfolgreich verlaufen sein, muss man sich darum kümmern, die geladenen Daten auszuwerten. Man muss sich bewusst sein, dass sämtliche einge-lesenen Daten im Container LoadVars gespeichert sind und von dort gelesen werden müssen. Wurde beispielsweise in der Quelldatei eine Variable mit dem Namen myText angelegt, so ist der Wert dieser Variable – in unserem Beispiel – über das LoadVars-Objekt myData abrufbar, und zwar wie folgt:

trace("myText="+myData.myText);

Listing 6.1: Auslesen der gelesenen Daten – beispielsweise per Ausgabe in das Ausgabefenster

In der obigen Zeile sieht man, dass die Variablen der Quelldatei in jedem Fall Variablen des LoadVars-Objekts werden und nicht Variablen der Hauptzeitleiste. Es steht dem Entwickler natürlich frei, die gelesenen Variablen in anderen (globalen) Variablen zu schreiben (siehe Abbildung 6.5).

u

u

ABBILDUNG 6.5

Die in der Textdatei unter dem Namen myText dekla-rierte Variable ist nach dem

Laden mithilfe des LoadVars-Objekts myData über eben

dieses Objekt auslesbar – myData.myText. Schritt für Schritt: Daten aus einer Textdatei mit Flash laden

In diesem Beispiel wollen wir das soeben erworbene theoretische Wissen in die Praxis umsetzen, indem wir Adressinformationen aus einer Textdatei auslesen.

Im ersten Schritt müssen wir also die Textdatei erstellen. Hierzu sei erwähnt, dass die Daten URL-codiert in die Textdatei eingefügt werden sollten.

1. Textdatei erstellen

1. Textdatei erstellen

Page 260: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 247

Der Inhalt der Textdatei sollte dann wie folgt aufgebaut werden (wie schon oben erwähnt, ist es nicht notwendig, dass die Leerzeichen mit „%20“ URL-codiert werden – deshalb verzichten wir hinsichtlich besserer Lesbarkeit im Folgenden darauf):

Vorname0=Uwe

&Nachname0=Mutz

&Firma=SYNE Marketing und Consulting GmbH

&Adresse0=Am Graben 29

&PLZ0=4020

&Ort0=Linz

&Staat0=AUT

&[email protected]

Vielleicht werden Sie sich wundern, warum wir bei den Variablen eine Nummerierung eingeführt haben. Diese ist in unserem Beispiel eigentlich nicht notwendig. Möchte man jedoch zu einem späteren Zeitpunkt dieses Beispiel erweitern und nicht nur eine Person, sondern mehrere Personen einlesen, ist es notwendig, eindeutige Variablen-namen zu verwenden. Durch eine derartige Nummerierung ist dies auf jeden Fall gewährleistet (die nächste Person hätte dann Vorname1, Nachname1 usw.).

Abbildung 6.6 zeigt die Datei Einlesedaten01.txt, wo wir unser Beispiel von oben umge-setzt haben.

Eindeutige VariablennamenEindeutige Variablennamen

ABBILDUNG 6.6

Die Datei Einlesedaten01.txt beinhaltet alle für unser Beispiel notwendigen Infor-mationen. Achten Sie stets darauf, dass alle Variablen-namen eindeutig sind.

Tipp zum Einlesen von TextdatenBitte beachten Sie, dass es bei manchen Versionen des Flash-Plug-in zu Problemen beim Einlesen kommen kann, wenn in der einzulesenden Datei Zeilenumbrüche nach den Variablenwerten eingefügt werden. Speziell beim Weiterverarbeiten von Dateinamen sollte darauf geachtet werden.

Ist die Textdatei fertig erstellt, können wir uns Flash widmen. Idealerweise teilt man in diesem Beispiel die Zeitleiste mithilfe von Bildern in drei „Bereiche“ auf.

Der erste Bereich dient dazu, Variablen zu deklarieren und dem LoadVars-Objekt die einzulesende Quelldatei anzugeben. Des Weiteren wird hier die Ereignisproze-dur definiert, die uns signalisiert, wann das Laden der Textdatei abgeschlossen ist.

u

2. Flash-Datei erstellen2. Flash-Datei erstellen

Page 261: Flash cs3, ajax und php

K A P I T E L 6248

Hierin werden auch die eingelesenen Werte weiterverarbeitet. Außerdem wird von hier aus zum zweiten („Ladevorgang war nicht erfolgreich“) oder dritten („Lade-vorgang war erfolgreich“) Bereich weitergeleitet.

Der zweite Bereich ist dafür bestimmt, dem User bei einem fehlgeschlagenen Lade-vorgang eine entsprechende Meldung zu geben.

Der dritte Bereich („Ladevorgang war erfolgreich“) dient der Anzeige der eingele-senen Daten.

Die Bereichsunterteilung ist in Abbildung 6.7 ersichtlich, ebenso die verwendeten Ebenen. Die Dokumentgröße wurde auf 500x200 Pixel festgelegt. Wie schon im ein-leitenden Kapitel zu Flash erwähnt, spielt es keine (wesentliche) Rolle, wie viele leere Bilder in der Zeitleiste existieren – in unserem Beispiel sehen Sie, dass wir unser erstes Schlüsselbild an Position 1, das nächste und übernächste Schlüsselbild aber erst an den Positionen 5 und 25 platziert haben. Der große Vorteil an der gezeigten Arbeitsweise ist die Übersichtlichkeit der Flash-Datei.

u

u

ABBILDUNG 6.7

Das Flash-Dokument wurde in drei Bereiche unterteilt –

Bild 1 für das Deklarieren der Variablen, „LadevorgangFehl-

geschlagen“, sofern das Laden nicht geklappt

hat, und „Ladevorgang-Erfolgreich“ für das Anzeigen

der geladenen Daten.

In Bild 1 werden zunächst alle Variablen und Objekte deklariert. Des Weiteren küm-mern wir uns um die Ereignisprozedur, die nach dem abgeschlossenen Ladevorgang aufgerufen wird.

var anzLadeversuche:Number = 0;

var maxLadeversuche:Number = 3;

var myLoader:LoadVars = new LoadVars();

myLoader.onLoad = function(loadedOK:Boolean):Void {

//Ladevorgang abgeschlossen.

3. Deklarieren der notwendigen

Variablen und Objekte

3. Deklarieren der notwendigen

Variablen und Objekte

Page 262: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 249

anzLadeversuche++;

if(loadedOK) {

//Daten wurden ERFOLGREICH geladen.

gotoAndStop("LadevorgangErfolgreich");

}

else {

if(anzLadeversuche<maxLadeversuche) { myLoader.load("Einlesedaten01.txt"); }

else { gotoAndStop("LadevorgangFehlgeschlagen"); }

}

}

myLoader.load("Einlesedaten01.txt");

Listing 6.2: Code für den Ladevorgang der Daten aus einer Textdatei

Mit Einführung von Flash CS3 wurden wie erwähnt neue Zahlentypen eingeführt, die den Umgang mit Ganzzahlen wesentlich vereinfachen: int und uint. Da diese jedoch erst in ActionScript 3 verfügbar sind, stellt sich die Frage, ob man sie bei relativ einfachen und wenig umfangreichen Beispielen einsetzen sollte. Oder stellen wir die Frage anders herum: Warum sollte man sie denn nicht einsetzen? Nun, sehen wir uns die Vor- und Nachteile noch einmal kurz an:

Vorteil: Der Prozessor kann mit Ganzzahlen wesentlich besser umgehen als mit Fließkommazahlen („Floating Point Numbers“) – somit erfolgt das Abarbeiten von Ganzzahlen wesentlich schneller.

Nachteil: Die Unterscheidung von Ganz- und Fließkommazahlen erfordert Action-Script 3, wodurch man gezwungen ist, den Flash 9 Player einzusetzen. Da dieser jedoch bei weitem nicht so verbreitet ist wie beispielsweise ein Flash 7 Player (dieser würde für unseren Fall vollkommen ausreichen), schließt man einen nicht unbe-trächtlichen Userkreis aus bzw. zwingt diese User, den 9er-Player zu installieren (und wie wir wissen, ist die Überwindung zum Installieren einer Software nach wie vor hoch).

Aus diesem Grund würde ich Ihnen raten, nach wie vor den Typ Number zu verwenden und nur im „Ernstfall“ auf int oder uint zurückzugreifen.

Wie bereits weiter oben erwähnt, empfiehlt es sich, die Anzahl der Ladeversuche auf einen maximalen Wert zu beschränken. Sollte der Ladevorgang danach noch immer nicht erfolgreich verlaufen sein, würde man den Ladevorgang abbrechen und dem Benutzer eine entsprechende Meldung am Bildschirm ausgeben.

In unserem Fall werden wir die Anzahl der Ladeversuche auf drei Versuche beschrän-ken. Damit wir flexibel arbeiten, legen wir diesen Wert in einer Variablen fest.

u

u

Number oder int / uint?Number oder int / uint?

4. Anzahl der Ladeversuche4. Anzahl der Ladeversuche

Page 263: Flash cs3, ajax und php

K A P I T E L 6250

In Zeile drei wird das LoadVars-Objekt erzeugt und diesem ganz unten im Script eine Datei zum Einlesen zugewiesen (Einlesedaten01.txt).

Ist dies geschehen, startet Flash automatisch den Ladevorgang. Sobald dieser abge-schlossen ist, tritt das Ereignis onLoad auf, das wir in den folgenden Zeilen auswerten. Zu diesem Zeitpunkt wissen wir noch nicht, ob der Ladevorgang erfolgreich oder nicht erfolgreich abgeschlossen wurde. Auskunft darüber gibt uns die Variable (der Ereignisparameter) loadedOK, die von Flash an die Funktion (korrekt gesprochen handelt es sich hierbei wie erwähnt um eine Ereignisprozedur des Lo adVars-Objekts) übergeben wird, also:

loadedOK==true; //erfolgreich

loadedOK==false; //nicht erfolgreich

Listing 6.3: Ladeerfolg überprüfen mittels Ereignisparameter

Wie erwähnt können Sie anstatt des Ereignisparameters auch die Eigenschaft loaded des LoadVars-Objekts überprüfen:

myloader.loaded==true; //erfolgreich

myloader.loaded==false; //nicht erfolgreich

Listing 6.4: Ladeerfolg überprüfen mittels der loaded-Eigenschaft

Dementsprechend wird in unserer Ereignisprozedur im Fall eines erfolgreichen Ladens mithilfe von gotoAndStop("LadevorgangErfolgreich"); in der Zeitleiste auf das Bild gesprungen, in der die Daten angezeigt werden.

War das Laden nicht erfolgreich, wird die Anzahl der Ladeversuche (gespeichert in der Variable anzLadeversuche) um eins erhöht und – sofern wir noch unter der Maxi-malzahl der Ladeversuche sind – der Vorgang erneut aufgerufen.

Im eher atypischen Fall, dass wir die Maximalzahl erreicht haben, verzweigt das Skript zum Bild „LadevorgangFehlgeschlagen“ – darauf kommen wir etwas später noch zu sprechen.

Vielleicht ist Ihnen aufgefallen, dass das obenstehende Skript keinen stop()-Befehl beinhaltet. Dies würde ja bedeuten, dass Flash automatisch ins zweite Bild der Zeit-leiste weiterspringt, und erst in Bild 2 wurde der stop()-Befehl von uns eingefügt. Warum also erst in Bild 2 und nicht bereits in Bild 1?

Der Grund dafür ist, dass wir dem User im Bild „LadevorgangFehlgeschlagen“ die Möglichkeit geben, den Ladevorgang „von Hand“ erneut zu starten, und wir somit wieder zurück in das erste Bild springen. Dies kann entweder mit gotoAndPlay() oder mit gotoAndStop() erfolgen. Der erste Befehl hat den Nachteil, dass ein etwai-ges stop() im ersten Bild ignoriert und der Bildzeiger ins zweite Bild weiterspringen

5. LoadVars-Objekt definieren

und Datei zum Einlesen angeben

5. LoadVars-Objekt definieren

und Datei zum Einlesen angeben

6. Ladevorgang starten und

Erfolg prüfen

Ereignisprozedur onload

6. Ladevorgang starten und

Erfolg prüfen

Ereignisprozedur onload

7. Fallunter-scheidung

7. Fallunter-scheidung

8. stop()-Befehl in Bild 2

8. stop()-Befehl in Bild 2

Page 264: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 251

würde. Der zweite Befehl würde in manchen Plug-in-Generationen des Flash-Plug-ins den Code im ersten Bild nicht ausführen.

Beide Probleme ersparen Sie sich, indem Sie erst im zweiten Bild den stop()-Befehl setzen.

Zum Darstellen der Daten verwendet man am einfachsten dynamische Textfelder, die direkt auf das LoadVars-Objekt myLoader zugreifen und die dort eingelesenen gespeicherten Werte darstellen.

9. Darstellen der eingele-senen Werte bei erfolgreich verlaufenem Ladevorgang

9. Darstellen der eingele-senen Werte bei erfolgreich verlaufenem Ladevorgang

Für den Fall eines fehlgeschlagenen Ladens muss – schon aus Usability-Gründen – dem User auf jeden Fall eine entsprechende Meldung ausgegeben werden.

Diese Meldung wird im else-Abschnitt der if-Bedingung mit folgendem Code fest-gelegt:

else {

gotoAndStop("LadevorgangFehlgeschlagen");

}

Zu diesem Zeitpunkt ist es dann relativ unwahrscheinlich, dass ein erneuter Ladever-such den gewünschten Erfolg bringen wird. Nichtsdestotrotz soll der User die Mög-lichkeit haben, einen erneuten Versuch zu starten.

Dies lässt sich natürlich relativ einfach realisieren, da in der Zeitleiste nur wieder auf das erste Bild gesprungen werden muss und somit der Ladeprozess von neuem

10. Ladevorgang nicht e rfolgreich10. Ladevorgang nicht e rfolgreich

11. Ladevorgang erneut starten11. Ladevorgang erneut starten

ABBILDUNG 6.8

Sofern der Ladevorgang erfolgreich verlaufen ist, wird in die dynamischen Textfelder der Wert der jeweiligen Variablen des myLoader-Objekts ein-gelesen, zum Beispiel der Nachname 1.

Page 265: Flash cs3, ajax und php

K A P I T E L 6252

beginnt. Hierzu erzeugt man einen Button und weist diesem den entsprechenden Code zu. Wir haben uns für eine Button-Komponente entschieden und dieser den Namen „restartBtn“ gegeben.

var btnListener:Object = new Object();

btnListener.click = function():Void {

gotoAndStop(1);

}

restartBtn.addEventListener("click", btnListener);

Listing 6.5: Dieser Code wird benötigt, damit der User den Ladevorgang erneut ausführen lassen kann.

Zunächst erzeugen wir ein neues Objekt, das als Listener dienen soll, und weisen diesem eine Funktion zu, die bei Klick aufgerufen werden soll (gotoAndStop(1);). Danach weisen wir dem Button „restartBtn“ diesen Ereignislistener mittels

restartBtn.addEventListener("click", btnListener);

zu. Hiermit springt Flash bei Klick auf den Button in das erste Bild der Zeitleiste zurück und alles beginnt von vorne.

ABBILDUNG 6.9

Sollte der Ladevorgang fehl-schlagen, muss dem User

aus Usability-Gründen eine entsprechende Meldung aus-

gegeben werden. Eventuell ermöglicht man ihm einen

erneuten Ladeversuch über einen Button.

Auf der Website zum Buch finden Sie dieses Beispiel – um mehrere Adressdaten ergänzt – zu einer Adresssammlung erweitert. Auf diese Art kann man auf sehr ein-fachem Wege Adressdaten von beispielsweise der Firmendatenbank per Handy oder PDA abfragen – natürlich nur, sofern diese Geräte auch einen Internetzugang und einen funktionsfähigen Webbrowser inklusive installiertem Flash-Plug-in haben.

Page 266: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 253

UsabilitySo einfach Ihre Flash-Anwendung für Sie anmuten sollte, so schwierig ist sie eventuell für den User zu nutzen. Gehen Sie immer vom „Dümmsten anzunehmenden User“ (DAU) aus. Keinesfalls wollen wir unsere User als dumm bezeichnen, jedoch hat sich dieser Ausdruck in Entwicklerkreisen eingebürgert. Je eindeutiger die Warn- oder Hinweismeldungen sind, desto leichter wird sich Ihr User beim Anwenden tun.

Daten au s eine r Datenbank einlesen

Das Einlesen von Daten aus einer Datenbank funktioniert im Wesentlichen exakt so wie das Einlesen von Daten aus einer simplen Textdatei. Der einzige Unterschied gegenüber dem Auslesen aus der Textdatei besteht darin, dass keine Textdatei existiert, sondern die entsprechenden Inhalte der Textdatei in einer PHP-Datei erzeugt werden. Würde man die Textdatei und die PHP-Datei (in einem Browser) zur selben Zeit öff-nen und die beiden betrachten, könnte man keinen Unterschied feststellen. Im Fall der Textdatei sind die Inhalte „statisch“ (wir haben diese „per Hand“ in die Datei geschrie-ben), im Fall der PHP-Datei „dynamisch“, denn die Inhalte werden über geeignete PHP-Funktionen aus einer Datenbank ausgelesen.

Nehmen wir der Einfachheit halber das vorige Beispiel zur Hand, wo wir mit der Text-datei Einlesedaten01.txt gearbeitet haben, die folgenden Inhalt aufweist:

Vorname0=Uwe

&Nachname0=Mutz

&Firma0=SYNE Marketing und Consulting GmbH

&Adresse0=Am Graben 29

&PLZ0=4020

&Ort0=Linz

&Staat0=AUT

&[email protected]

Listing 6.6: Inhalt der Datei Einlesedaten01.txt

Genau diesen Inhalt möchten wir nun mithilfe einer Datenbank und einer zugehö-rigen PHP-Datei erzeugen. Zunächst benötigt man also eine Datenbank mit einer entsprechenden Tabelle, welche die auszulesenden Daten beinhaltet.

Page 267: Flash cs3, ajax und php

K A P I T E L 6254

Ist diese Tabelle mit Daten gefüllt, können wir per PHP auch schon auf diese Daten zugreifen. Wie Sie im Grundlagenteil über PHP & MySQL erfahren haben, ist der erste Schritt der Zugriff auf die Datenbank mithilfe eines Users und eines Passworts. Sofern die Datenbank lokal am jeweiligen Webserver installiert ist, kann per „localhost“ der entsprechende Server ausgewählt werden.

localhost oder doch eine IP-Adresse?Typischerweise werden auf Seiten des Providers der Web- und der Datenbankserverdienst auf demselben Gerät betrieben. Ist dies der Fall, so kann eine serverseitige Technologie wie PHP über die Adresse „localhost“ („der lokale Rechner“) auf den Datenbank- und Webserver-Dienst zugrei-fen. Alternativ dazu könnte man auch die IP-Adresse 127.0.0.1 verwenden.

Zunächst einmal das benötigte Script:

$hostname = "IHR HOSTNAME";

$username = "IHR USERNAME";

$password = "IHR PASSWORT";

if(!$conn = mysql_connect($hostname, $username, $password)) {

die('<div class="error">Verbindung zur Datenbank konnte nicht hergestellt werden. Errorcode: ‚.mysql_error().'</div>');}

else {

//echo('<div class="success">Die Verbindung zur Datenbank wurde erfolgreich hergestellt.</div>');

}

Listing 6.7: Verbindungsaufbau zur Datenbank. Sollte die Verbindung zum Datenbankserver erfolgreich gewesen sein, so muss keine „Erfolgsmeldung“ ausgegeben werden – aus diesem Grund ist der echo-Befehl im else-Teil der if-Bedingung auskommentiert (für Testzwecke werden solche Ausgaben gerne verwendet, denn dann hat man beispielsweise Gewissheit, dass die Verbindung zum Datenbankserver geklappt hat). Klarerweise müssen Sie bei $hostname, $username und $passwort Ihre korrekten Zugangsdaten eingeben.

1. Connect zum Datenbankserver

1. Connect zum Datenbankserver

ABBILDUNG 6.10

Die obige Tabelle „tbl_Kunden“ speichert die

gewünschten Informationen über unsere Kunden.

Page 268: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 255

In den Va riablen $hostname, $username und $password werden die drei für den Verbindungsaufbau zum Datenbankserver und zur Datenbank notwendigen Infor-mationen gespeichert, die dann wiederum mithilfe der PHP-Funktion mysql_con-nect() zum Aufba u der Verbindung herangezogen werden.

Alternativ dazu könnten Sie selbstverständlich auch diese drei Variablen in einem Array zusammenfassen:

$dbConnect = array(

"hostname" => "IHR HOSTNAME",

"username" => "IHR USERNAME ",

"password" => "IHR PASSWORT",

"db" => "IHRE DATENBANK"

);

Listing 6.8: Alternative zu den verwendeten vier (bisher drei) Variablen für den Verbindungsaufbau sowie den Datenbankzugriff

Die Verbindung selbst wird in einer Variablen $conn hinterlegt. Sollte der Verbin-dungsaufbau aus irgendwelchen Gründen nicht funktioniert haben, weil z.B. Userna-me bzw. Passwort falsch ist, wird von der Funktion mysql_connect() der Wert false zurückgegeben und in der if-Bedingung entsprechend ausgewertet. Die Funktion die() beendet d en weiteren Ablauf der PHP-Datei und gibt mithilfe der Funktion mysql_error() eine entsprechende Meldung inklusive der MySQL-Fehlermeldung auf den Bildschirm aus.

War der Verbindungsaufbau erfolgreich, so wird in unserem Fall eine Meldung auf den Bildschirm ausgegeben. Normalerweise werden solche „Erfolgsmeldungen“ nicht angezeigt, sondern maximal für Testzwecke mit in den Code aufgenommen und danach auskommentiert – unsere Erfolgsmeldung würde im „wahren“ Betrieb eben-falls nicht zur Verwendung kommen, denn dass der Code erfolgreich war, merken sowohl Entwickler als auch User, indem die Site funktioniert.

Wenn der Verbindungsaufbau zum Datenbankserver gelungen ist, stehen uns meistens mehrere Datenbanken, die für uns freigegeben sind – sprich für die wir die notwen-digen Berechtigungen haben –, zur Verfügung. Demnach müssen wir uns für eine Datenbank entscheiden, was mithilfe der Methode mysql_select_db() erfolgt:

$db = "db_BuchFlashPHP";

if(!mysql_select_db($db)) {

die('<div class="error">Die Datenbank '.$db.' konnte nicht ausgewaehlt werden. Errorcode: ‚.mysql_error().'</div>');

}

else {

2. Auswählen der Datenbank2. Auswählen der Datenbank

Page 269: Flash cs3, ajax und php

K A P I T E L 6256

//echo('<div class="success">Die Datenbank '.$db.' wurde erfolgreich ausgewaehlt.</div>');

}

Listing 6.9: Auswählen der Datenbank

Der Ablauf ist wieder der gleiche wie schon zuvor:

1. Defi nieren, welche Datenbank verwendet wird

Dies kann einerseits über die Defi nition einer Variablen (wie in diesem Fall) oder direkt als Parameter der Methode mysql_select_db() geschehen. Ich habe mich für Ersteres entschieden, da diese Variante übersichtlicher ist (als Alternative zur Verwendung einer Variablen habe ich weiter oben schon die Verwendung eines Arrays dargestellt).

2. Prüfen, ob das Auswählen der Datenbank erfolgreich war

Sollte die Methode mysql_select_db() den Wert false zurückgeben, war die Auswahl der Datenbank nicht erfolgreich und man beendet im Allgemeinen die weitere Ausführung der Site durch Verwendung der Methode die(). Der Rückgabewert true signalisiert, dass die Auswahl der Datenbank in Ordnung war.

3. SQL-Statement ausführen

War die Auswahl der Datenbank erfolgreich, können aus den Tabellen der Datenbank Daten ausgelesen werden. Wie Ihnen bereits bekannt ist, verwendet man hierzu die standardisierte Abfragesprache SQL.

Der Einfachheit halber wird der SQL-String zunächst einer Variablen zugewiesen und danach ausgeführt. Diese Vorgehensweise hat den Vorteil, dass Testings einfacher durchgeführt werden können, sollte ein Fehler bei der Abfrage generiert werden. Selbstverständlich kann – wie bei den meisten PHP-Methoden – der entsprechende Parameter auch direkt an die Methode übergeben werden. Hier sprechen wir von dem SQL-Statement als String-Parameter für die Methode mysql_query(). Die meis ten Entwickler entscheiden sich jedoch für eine übersichtlichere Vorgehensweise mithilfe zusätzlicher Variablen, in denen diese Parameter als Strings oder Ähnliches gespeichert werden.

$sql = "SELECT * FROM tbl_Kunden";

if(!$query = mysql_query($sql)) {

die('<div class="error">Das SQL-Statement konnte nicht durchgefuehrt werden. Errorcode: ‚.mysql_error().'</div>');

}

else {

Page 270: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 257

//echo('<div class="success">Das SQL-Statement:<br/>$sql<br/>wurde erfolgreich abgesetzt.</div>');

}

Listing 6.10: Das SQL-Statement $sql wird der Methode mysql_query() als String-Parameter übergeben.

Sie kennen ja mittlerweile das Procedere: Zunächst wird geprüft, ob das Absetzen des SQL-Statement erfolgreich war. Dies erkennt man daran, dass in der Variable $query nicht der Wert false gespeichert wird. Danach kann mit dem weiteren Ablauf der Seite fortgesetzt werden. Für den Fall, dass das SQL-Statement nicht ausgeführt wer-den konnte, wird mithilfe von die() abgebrochen.

Haben wir auch diesen Schritt erfolgreich hinter uns gebracht, müssen wir nur noch für die korrekte Ausgabe der Daten sorgen. Idealerweise wird hierzu eine while()-Schleife verwendet, in der so lange Daten ausgelesen werden, wie sich Datensätze in der Tabelle befinden. Die Funktion mysql_fetch_array() läuft Zei le für Zeile die Tabelle durch und speichert die Daten in einem assoziativen Array (alternativ dazu können Sie auch die Funktion mysql_fetch_object() verwenden – diese Funktion liefert anstatt eines assoziativen Arrays ein Objekt zurück). Des Weit eren zählen wir die Anzahl der Zeilen mit – am einfachsten wird dies mit einer Variable (hier: $cnt) erreicht, die pro Schleifendurchlauf um eins erhöht wird.

Das Verwenden dieser Zählvariable $cnt hat auch noch einen zweiten Grund: Letzten Endes machen wir nichts anderes, als Text in ein „HTML“-Dokument zu schreiben, indem wir die echo()-Funktion verwenden. Die ausgegebenen Daten stellen dann nichts anderes als Variablen=Wert-Zuweisungen dar. Generiert man beispielsweise aus unserer bestehenden Tabelle Daten, so könnte das wie unten gezeigt aussehen:

Vorname=Uwe

&Nachname=Mutz

&Firma=SYNE Marketing und Consulting GmbH

&Adresse=Am Graben 29

&PLZ=4020

&Ort=Linz

&Staat=AUT

&[email protected]

Listing 6.11: Ausgabe des ersten Datensatzes. Diese Art der Datenausgabe ist nur für einen einzigen Daten-satz verwendbar. Warum dem so ist, wird weiter unten erläutert.

Gesetzt den Fall, unsere Tabelle speichert aber mehr als nur einen einzigen Datensatz. Dies hätte dann zur Folge, dass auch der zweite Datensatz in derselben Art und Weise ausgegeben wird:

3. Daten zeilen-weise auslesen3. Daten zeilen-weise auslesen

Page 271: Flash cs3, ajax und php

K A P I T E L 6258

Vorname=Thomas

&Nachname=Wegerer

&Firma=Softnomics Werbeagentur

&Adresse=Hart 14

&PLZ=4060

&Ort=Leonding

&Staat=AUT

&[email protected]

Listing 6.12: Ausgabe des zweiten Datensatzes

Eindeutige VariablenbenennungBetrachten wir kurz das obige Beispiel: Welchen Wert hätte beim Auslesen durch Flash beispielsweise die Variable Vorname? Die Antwort würde in unserem Fall „Thomas“ lauten, denn in beiden Fällen (bei Vorname=Uwe und Vorname=Thomas) wurde dieselbe Variable (näm-lich Vorname) als Speicherort verwendet. Um dieses Überschreiben zu verhindern, müssen die Variablen eindeutig benannt sein, was im einfachsten Fall durch eine Durchnummerierung der Variablen erreicht werden kann.

Vorname=Uwe und Vorname=Thomas liefern das falsche, Vorname0=Uwe und Vorname1=Thomas das gewünschte Resultat. Somit lautet der korrekte Code zur Aus-gabe der Daten:

$cnt = 0;

while($theData = mysql_fetch_array($query)) {

$msg = "";

if($cnt!=0) { $msg.="&"; }

$msg.="Vorname$cnt=".$theData["vc_Vorname"];

$msg.="&Nachname$cnt=".$theData["vcP_Nachname"];

$msg.="&Firma$cnt=".$theData["vc_Firma"];

$msg.="&Adresse$cnt=".$theData["vc_Adresse"];

$msg.="&PLZ$cnt=".$theData["vc_PLZ"];

$msg.="&Ort$cnt=".$theData["vc_Ort"];

$msg.="&Staat$cnt=".$theData["vc_Staat"];

$msg.="&email$cnt=".$theData["vc_email"];

echo($msg);

$cnt++;

}

Listing 6.13: Auslesen der Daten in einer while-Schleife in der Datei Einlesedaten02.php

4. Nummerierung der Variablen

4. Nummerierung der Variablen

Page 272: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 259

Sehen wir uns kurz den Code an: Über die Variable $cnt haben wir bereits gesprochen. Die Variable $msg wird dazu verwendet, um pro Datensatz einen String zu speichern, der dann später mit echo() ausgegeben wird (Codezeile 13). Mithilfe der Funkti-on mysql_fetch_array() wird in die Variable (besser: das Array) $theData pro Schleifendurchlauf ein kompletter Datensatz eingelesen, der dann in den Zeilen 5–12 zum Auslesen der einzelnen Spaltenwerte verwendet wird. Lediglich Zeile 4 des Codes bedarf noch der Erklärung: Hier wird geprüft, ob gerade der erste Datensatz zum Aus-geben in die HTML-Seite ansteht. Ist dies nämlich der Fall, darf kein führendes „&“ ausgegeben werden, in allen anderen Fällen jedoch schon.

Damit wären wir komplett – mehr darf auf die HTML-Seite an Information auch nicht ausgegeben werden (beachten Sie bitte, dass selbstverständlich nur das im Browser aus-gegeben wird, was durch einen echo()- oder die()-Befehl erzeugt wird). Vergleicht man das Resultat mit der (händisch erzeugten) Textdatei aus dem vorigen Kapitel, so werden Sie – bis eventuell auf Zeilenumbrüche – keinen Unterschied feststellen.

5. Ausgabe in eine HTML-Datei5. Ausgabe in eine HTML-Datei

ABBILDUNG 6.11

Unsere PHP-Datei erzeugt den gewünschten Inhalt im Browser-Fenster.

Nun machen wir die Probe aufs Exempel und bringen Flash dazu, statt aus einer sta-tischen Textdatei aus einer dynamischen PHP-Datei Daten einzulesen. Wir ersetzen die Textdatei Einlesedaten01.txt in unserem Flash-Beispiel durch die PHP-Datei Einle-sedaten02.php und testen, ob das Einlesen in Flash klappt.

PHP anstatt TXT in der Entwicklungsumgebung „Flash“Bitte beachten Sie an dieser Stelle, dass PHP-Dateien durch einen Webserver verarbeitet werden müssen. Aus diesem Grund können Sie PHP-Dateien nicht – wie gewohnt – direkt in Flash tes-ten, sondern müssen die fertige SWF-Datei auf einen Webserver hochladen (dies kann selbstver-ständlich auch ein lokal installiertes Webserver-Paket wie etwa XAMPP sein) und dort testen.

Schritt für Schritt: Daten aus einer PHP-Datei lesen

Ersetzt man in der vierten Codezeile des ersten Bilds der Flash-Datei aus der Schritt-für-Schritt-Anleitung „Daten aus einer Textdatei mit Flash laden“ von weiter oben:

myLoader.load("Einlesedaten01.txt");

durch:

myLoader.load("Einlesedaten02.php");

sollten wir schon „im Geschäft“ sein. Haben Sie das vorige Beispiel nicht mitgemacht, liegt die entsprechende Datei auch auf der Website zum Buch.

PHP anstatt TXTPHP anstatt TXT

1. Einlesen der PHP-Datei1. Einlesen der PHP-Datei

Page 273: Flash cs3, ajax und php

K A P I T E L 6260

Daten aus Flash heraus übergeben

Bis jetzt h aben wir Daten aus einer Textdatei oder einer Datenbank ausgelesen. Nun wollen wir den umgekehrten Weg gehen und uns mit der Frage beschäftigen, wie man Daten aus Flash heraus entweder einer (serverseitigen!) PHP-Datei zur Ausgabe auf den Bildschirm übergibt oder die Daten in eine Datenbank speichert.

In diesem Fall ist es also so, dass Flash Daten sendet und PHP Daten empfängt. Nach-dem PHP bekannterweise auf Serverseite und Flash auf Clientseite ausgeführt wird, kann die Übergabe der Daten aus Flash auf zwei Arten erfolgen:

1. Flash ruft über den Befehl getURL() ein Dokumen t auf und übergibt mithilfe von GET-Variablen auf diese Weise Daten an die PHP-Datei.

2. Flash verschickt Formulardaten und es wird das aus HTML bekannte Abschicken von Formularinhalten verwendet. Die Methode send() des LoadVar s-Objekts ist dazu in der Lage.

Daten versenden mit GET & g etURL

Beschäftige n wir uns also zunächst einmal mit Variante eins – dem Übergeben von Werten über GET-Variablen an eine PHP-Datei. Diese Variante ist denkbar einfach, denn es muss nichts anderes als ein URL-String „zusammengebaut“ werden, beispiels-weise in der Art:

ausgabe01.php?variable0=wert0&variable1=wert1

Listing 6.14: Über & werden einzelne Strings verkettet.

ABBILDUNG 6.12

Das Einlesen der PHP-Datei Einlesedaten02.php war

erfolgreich – so wie wir es wollten! Perfekt.

Page 274: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 261

Umgesetzt in Flash würde dies dann wie folgt aussehen:

getURL("ausgabe01.php?variable0=wert0&variable1=wert1");

Alternativ dazu könnte man alle verwendeten Variablen durch ein zusätzliches Attribut in der getURL()-Methode übe rgeben:

getURL("ausgabe01.php", "", "GET");

Listing 6.15: Versenden aller Variablen an die Datei ausgabe01.php

Das Attribut GET gibt also an, dass alle verwendeten Variablen per GET an die Datei ausgabe01.php geschickt werden sollen. Wie leicht zu erraten ist, können die Variablen auch per POST übergeben werden – darauf werden wir etwas weiter unten noch zu sprechen kommen. Die vollständige Syntax dieser Methode lautet:

getURL("URL", "Fenster", "GET/POST");

Listing 6.16: Syntax der Methode getURL()

Die URL gibt an, welche Adresse aufgerufen werden soll. „Fenster“ steht für die aus HTML bekannten Fenster (_self, _blank, _parent, _top, Standard ist _self) bzw. Frames. GET/POST wurde bereits oben dargestellt – sämtliche Variablen werden ent-weder per GET oder POST an die URL übergeben.

Für das Testen, ob die Daten aus Flash auch wirklich ankommen, verwenden wir fol-gendes sehr einfaches PHP-Skript:

if(count($_GET)>0) {

foreach($_GET as $variable=>$wert) {

echo("$variable=$wert<br/>");

}

}

else {

echo("Es wurden keine Daten &uuml;bergeben.");

}

Listing 6.17: Ein kurzes Skript zum Überprüfen und etwaigen Ausgeben von übergebenen Daten

Die Variable $_GET ist ein ass oziatives Array und beinhaltet alle per GET übergebenen Daten. Die Funktion count() gibt an, wi e viele Elemente im Array gespeichert sind. Sollte die Anzahl der gespeicherten Elemente größer null sein, so wurden Daten über-geben und man kann mit dem Auslesen der Daten beginnen. Die foreach-Schleife liest alle übergebenen Variablen in Form von Variablenname ($variable) und Vari-ablenwert ($wert) aus.

Wie Sie im Grundlagenkapitel zu PHP erfahren haben, dient die foreach-Schleife dazu, alle Elemente eines Arrays (oder Ähnlichem) auszulesen. Sie bricht ab, sollte kein

Page 275: Flash cs3, ajax und php

K A P I T E L 6262

weiteres Element mehr existieren. In jedem Schleifendurchlauf werden den Variablen $variable der Name der Variablen und $wert der Wert der Variablen zugewiesen. Ich möchte an dieser Stelle noch einmal darauf hinweisen, dass alle übergebenen Variablen immer vom Typ String sind.

$_GET , $_POST und $_REQUESTNeben der Variable $_GET für per GET übergebene Variablen existieren auch noch die Variablen $_POST (für alle per POST übergebenen Variablen) und $_REQUEST (generell für alle überge-benen Variablen). In früheren Versionen wurden die Variablen $HTTP_GET_VARS und $HTTP_P OST_VARS genutzt, di e im Gegensatz zu den jetzt verwendeten Variablen nicht global waren.

Nehmen wir mal an, wir würden in Flash folgendes Script verwenden:

var mySender:LoadVars = new LoadVars();

mySender.Vorname = "Uwe";

mySender.Nachname = "Mutz";

mySender.Variante = "LoadVars.send, per GET";

mySender.send("ausgabe01.php", "_blank", "GET");

Listing 6.18: Ein kleines Script, das drei Informationen (Vorname="Uwe", Nachmane="Mutz" sowie Variante="LoadVars.send, per GET") an eine Datei namens ausgabe01.php schickt. Dieses Dokument soll in einem neuen Fenster (_blank) aufgehen und die Daten werden mittels GET verschickt.

Das Resultat unseres kleinen Testbeispiels wird wie erwartet dargestellt (siehe Abbil-dung 6.13). Rufen Sie dazu einfach die Datei LoadVars03.htm in Ihrem Browser auf.

ABBILDUNG 6.13

Die Übergabe der Informationen von Flash an

die Datei ausgabe01.php hat also geklappt.

Beachten Sie bitte auch die Adresszeile – sie beinhaltet sämtliche Variablen und zuge-hörigen Werte:

http://fl ashphpajax.syneweb.com/Buchkapitel/Kap06/LoadVars/ausgabe01.php?Variante=LoadVars%2Esend%2C%20per%20GET&Nachname=Mutz&Vorname=Uwe

Listing 6.19: In der Adresszeile des Browsers fi nden Sie die übergebenen Variablen, da wir uns für die Vari-ante GET zum Versenden der Daten entschieden haben.

Daten versenden mit POST

Sel bstverstä ndlich werden wir die Probe aufs Exempel machen und die Daten per POST aus Flash heraus verschicken. Dazu bedarf es im Flash-Code nur einer geringfü-gigen Änderung – anstatt der Übergabemethode GET wird nun POST verwendet:

Page 276: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 263

getURL("ausg abe02.php", "_blank", "POST");

Des Weiteren wurde eine andere PHP-Datei geschrieben, denn im vorangegangenen Beispiel wurden von der PHP-Datei nur GET-Variablen ausgewertet:

if(count($_POST)>0) {

foreach($_POST as $variable=>$wert) {

echo("$variable=$wert<br/>");

}

}

else {

echo("Es wurden keine Daten &uuml;bergeben.");

}

Listing 6.20: Dieses Skript überprüft, ob Daten per POST gesendet wurden, und gibt diese aus.

ABBILDUNG 6.14

Entgegen dem vorangegan-genen Beispiel werden die Daten hier per POST an die PHP-Datei ausgabe02.php übergeben.

Wie Sie sehen, ist das Resultat dasselbe wie zuvor, jedoch werden – wie bei POST-Datenübergabe gewünscht – die Daten nicht sichtbar in der Adresszeile des Browsers übergeben.

Daten versenden mithilfe des LoadVars-Objekts

Damit haben wir die Methode getURL() ausgereizt, also wenden wir uns der zweiten Variante der Datenübergabe aus Flash heraus zu – nämlich dem Load Vars-Objekt und dessen Methode send(). Im Abschnitt über das Empfangen von Daten haben Sie gesehen, dass das LoadVars-Objekt alle eingelesenen Daten „in sich“ speichert. Entsprechend geht man auch beim Senden von Daten vor.

1. Zunächst wird ein LoadVars-Objekt angelegt:

Wie auch bei m Einlesen von Daten muss – sofern das LoadVars-Objekt zum Einsatz kommen soll – zunächst ein LoadVars-Objekt angelegt werden:

var mySender:LoadVars = new LoadVars();

2. Danach müssen im LoadVars-Objekt Variablen angelegt werden, die d ie zu versendenden Daten enthalten:

In vielen Fällen werden die zu versendenden Variablen zunächst in Flash als normale Variablen angelegt und ihnen so Werte zugewiesen. Einfacher und

Page 277: Flash cs3, ajax und php

K A P I T E L 6264

eleganter ist es jedoch in jedem Fall, wenn die zu versendenden Daten sofort als Variablen des LoadVars-Objekts deklariert werden. Da die zweite Variante auch nicht mehr Arbeit erfordert, ist ihr also der Vorzug zu geben:

mySender.Vorname = "Uwe";

mySender.Nachname = "Mutz";

3. Zu guter Letzt müssen die Daten nur noch versandt werden:

Hierbei steht uns die send()-Methode des LoadVars-Objekts hilfr eich zur Seite:

mySender.send("ausgabe01.php", "_blank", "GET");

bzw.

mySender.send("ausgabe02.php", "_blank", "POST");

Die beiden Zeilen unterscheiden sich nur in der Übergabe mit GET oder POST. Das Prozedere ist das gleiche wie auch bei der Übergabe mittels getURL(). Die vollständige Syntax unterscheidet sich – wenig überraschend – von getURL() in keiner Weise:

LoadVars.send("URL", "Fenster", "GET/POST");

Listing 6.21: Syntax zum Versenden der Daten mithilfe des LoadVars-Objekts

Das Fenster kann wiederum entweder ein HTML-Fenster (_self, _blank, _parent, _top) oder ein Frame sein. Die folgende Abbildung zeigt das Ergebnis sowohl der GET- als auch der POST-Übergabe.

ABBILDUNG 6.15

Datenübergabe durch die send-Methode des

LoadVars-Objekts – einmal per GET (oben)

und einmal per POST (unten). Die Abbildungen

unterscheiden von den Abbildungen Abbildung

6.13 und Abbildung 6.14 nur in der Reihenfolge der Variablenausgabe und der

Übergabevariante – die Daten sind selbstverständlich

gleich.

send oder sendAndLoad?

Zum Schluss sei noch erwähnt, dass das LoadVars-Objekt noch eine weitere Methode zum Senden und Empfangen von Daten besitzt – die Methode sendAndLoad. Diese erledigt genau das, was der Name verspricht: nämlich das Senden und das Laden von

Page 278: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 265

Daten in dem Sinne, wie Sie es oben kennengelernt haben. Ein wesentlicher Vorteil von sendAndLoad ist jedoch, dass die versendeten Daten nicht notwendigerweise in einem Browser-Fenster dargestellt werden müssen.

Die Klasse LoadVars und die ActionScript-ReferenzAn dieser Stelle möchte ich Ihnen noch einmal ans Herz legen, viel mit der ActionScript-Referenz von Flash zu arbeiten. Allein beim Durchsehen der Referenz stößt man nicht selten auf Klassen und Befehle, nach denen man schon lange gesucht hat.

Differenzierte Daten

Neben dem Senden von klassischen Formulardaten oder Variablen ist es hin und wie-der auch erforderlich, differenzierte Daten zu verschicken. Ein Klassiker solcher Daten ist beispielsweise eine Grafik oder eine PDF-D atei, die man auf ei nen Server hochladen möchte. Seit Flash 8 besteht die Möglichkeit, solche Aufgaben mithilfe der FileRefe-rence-Klasse zu erledigen.

Fassen wir noch einmal kurz zusammen:

Zum Versenden von Daten aus Flash heraus stehen uns die Möglichkeiten getURL und die Methode send des LoadVars-Objekts (genauer: der LoadVars-Klasse) zur Verfügung.

In beiden Varianten kann das Versenden per GET oder POST erfolgen.

Entscheidet man sich für die Variante getURL, so kann man beim Versenden mit GET die URL schon so aufbereiten, dass die Variablen an den URL-String ange-hängt werden. Beispielsweise so:

getURL("http://www.mydomain.at/mypage.php?myData=myValue;");

Oder man schickt automatisch alle in Flash verwendeten Variablen mithilfe des Parameters GET an die Seite. Beispielsweise so:

getURL("http://www.mydomain.at/mypage.php", "", "GET");)

Sollen die Variablen per POST verschickt werden, so muss in jedem Fall der Parameter POST verwendet werden.

Entscheidet man sich für die Variante mit der Methode send des LoadVars-Objekts, so hat man hier wieder die Wahl zwischen Versand per GET oder POST, wobei nur diejenigen Variablen verschickt werden, die dem LoadVars-Objekt zugewiesen wurden.

u

u

u

u

Page 279: Flash cs3, ajax und php

K A P I T E L 6266

6.3 Die Basis: das XML -Objekt & ActionScript 2.0 Die Herangehensweise an das Arbeiten mit XML-Daten hat sich zwischen ActionScript 2.0 und ActionScript 3.0 grundlegend geändert. Wurde in der Version 2.0 noch mit einer einzigen Klasse (XML) gearbeitet, sind die daraus bekannten Eigenschaften und Methoden in mehrere Klassen aufgeteilt worden, um Konflikte mit der in der Version 3.0 neu eingeführten XML-Klasse zu vermeiden. Seit ActionScript 3.0 wird nun im Rahmen der XML-Klasse ECMAScript for XML (E4X) unterstützt.

Ähnlich wie das LoadVars-Objekt aus dem vorigen Kapitel dient das XML-Objekt (exakt: die XML-Klasse) zum Einlesen und Versenden von Daten. XML bildet ebenso wie das LoadVars-Objekt eine Schnittstelle zwischen Flash und der „Außenwelt“, wobei XML als Bezeichnungssprache wesentlich umfassender und strukturierter ist als das Arbeiten mit GET- oder POST-Variablen.

Zunächst stellt sich für den Flash-Entwickler jedoch die Frage, wann die XML-Klasse und wann die LoadVars-Klasse eingesetzt werden. Man kann davon ausgehen, dass eine Datenübergabe per XML immer dann Sinn macht, wenn die Datenmenge eini-ge wenige Datensätze überschreitet. Spätestens bei mehr als 20 oder 30 Datensätzen (welcher Form auch immer) würden wir persönlich zur XML-Klasse greifen, da die Struktur von XML sehr viel übersichtlicher ist.

6.3.1 Grundlegende XML -BefehleDie Vorgehensweise beim Arbeiten mit der XML-Klasse ähnelt dem bei der LoadVars-Klasse. Auch hier muss zunächst eine neue Instanz der XML-Klasse erzeugt werden. Darauf aufbauend können dann unter anderem die Methoden load(), send() und sendAndLoad() verwendet werden.

Neben diesen grundlegenden Methoden bietet die XML-Klasse aufgrund des anders gearteten Aufbaus gegenüber der LoadVars-Klasse eine Reihe von Methoden und Eigenschaften, die das Parsen der eingelesenen Daten ermöglichen. An dieser Stelle möchten wir noch einmal auf den Grundlagenteil zu XML verweisen, wo die Struktur eines XML-Dokuments dargestellt und erläutert wird.

6.3.2 Einlesen von XML-Daten Grundsätzlich kann jede bestehende XML-Datei in Flash eingelesen werden, wobei die Dateiendung (.xml, .txt, .php ...) keine Rolle spielt. Entscheidend ist einzig und allein der Inhalt der verwendeten Datei. Dadurch wird uns das dynamische Erzeugen von XML-Content durch beispielsweise PHP ermöglicht. Andererseits ist es somit genauso legitim, einen XML-Content in einer Textdatei abzuspeichern und diese auszulesen.

ParsenMit Parsen meint man in

diesem Zusammenhang das (schrittweise) Auswerten der eingelesenen Daten.

Page 280: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 267

XML oder Textdatei?

Immer dann, wenn eine Datenübergabe von einer Datenbank zu Flash oder umgekehrt stattfinden soll, bei der die Daten strukturiert aufgebaut sind, empfiehlt sich die Ver-wendung von XML-Dokumenten. Denkt man beispielsweise an einfache Beispiele wie eine Kundenliste oder an komplexere Beispiele wie etwa das dynamische Generieren von Flash-Spielen für unterschiedliche Kunden, was unterschiedliche Gestaltung von Logos, Schriften, Level-Limits etc. mit sich bringt, so ist die Verwendung eines XML-Dokuments als Schnittstelle perfekt.

Laden von XML-Daten ausschließlich von derselben DomainSeit der Einführung von Flash 7 ist das Laden von XML-Daten nur noch von derselben Domain, in der auch die Flash-Datei liegt, erlaubt. Man kann diese Einschränkung umgehen, indem man eine lokale PHP-Datei verwendet, die eine entfernte URL in den Quellcode einliest – mehr dazu im Anwendungsteil beim RSS-Reader.

Einlesen einer XML-Datei

Beginnen wir also mit dem Einlesen einer Textdatei mit XML-Content mit folgendem Inhalt:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

<XML-Kundenliste>

<Kunden>

<Kunde>

<Vorname>Uwe</Vorname>

<Nachname>Mutz</Nachname>

<Firma>SYNE Marketing und Consulting GmbH</Firma>

<Adresse>Am Graben 29</Adresse>

<PLZ>4020</PLZ>

<Ort>Linz</Ort>

<Staat>AUT</Staat>

<email>[email protected]</email>

</Kunde>

</Kunden>

</XML-Kundenliste>

Listing 6.22: Listing einer Textdatei mit XML-Content (EinlesedatenXML01.txt)

Öffnet man diese Datei online (offline werden Sie mitunter die Datei nur in Textform erhalten) in einem Browser, so erhält man nachfolgende Abbildung.

Page 281: Flash cs3, ajax und php

K A P I T E L 6268

Man erkennt sehr schnell, dass der Internet Explorer nicht entsprechend der Datei-endung (hier: .txt), sondern entsprechend des Inhalts die geeignete Darstellungsform wählt. Beachten Sie jedoch bitte, dass die XML-konforme Art der Darstellung nicht alle Browser beherrschen – derzeit ist von den gängigen Browsern nur der Internet Explorer in der Lage, diese Darstellungsform auszugeben:

ABBILDUNG 6.16

Eine Textdatei mit XML-Content in der Browser-Darstellung im Internet

Explorer von Microsoft. Der XML-Content wird als sol-cher vom Browser erkannt und XML-konform darge-

stellt.

ABBILDUNG 6.17

Sowohl der Opera-Browser als auch der Firefox stellen

die Textdatei (mit XML-Content) als Textdatei dar.

Page 282: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 269

Letzten Endes ist es jedoch für uns unerheblich, ob die verschiedenen Browser den Inhalt als XML oder eben nicht interpretieren – wichtig für uns ist einzig und allein die Tatsache, dass der Inhalt XML-konform ist.

Möchte man diese XML-Datei in Flash einlesen, so sind folgende Schritte vorzuneh-men:

1. Anlegen einer Instanz der XML-Klasse

var myData:XML = new XML();

2. Ereignisprozedur für onLoad und Laden der Datei

Hier wird defi niert, was beim Auftreten des onLoad-Ereignisses geschehen soll. Hierfür verwenden wir wie auch schon aus dem vorigen Kapitel gewohnt eine native Funktion:

myData.onLoad = function(loadedOK:Boolean):Void {

//Ereignisbehandlungsroutine

}

Im nächsten Schritt muss dieser XML-Instanz eine Quelldatei zugewiesen werden, aus welcher die Daten geladen werden sollen. Diese Datei kann sowohl im selben als auch in einem Unterverzeichnis abgelegt sein. Der eigentliche Aufruf passiert erst ganz unten im Script (beachten Sie hierzu bitte auch die Ausführungen zur „Reihenfolge von Ereignisprozeduren beim Laden“ aus dem vorigen Kapitel):

myData.load("URL zur Quelldatei");

3. Überprüfen, ob das Laden erfolgreich war

Innerhalb der Ereignisbehandlungsroutine wird nun kontrolliert, ob das Laden der Datei erfolgreich war. Ein erfolgreiches Laden wird durch die Eigenschaft loadedOK==true (oder einfacher: loadedOK) des XML-Objekts dargestellt.

if(loadedOK) {

//beispielsweise Auslesen der Daten.

}

else {

//Fehler beim Laden aufgetreten. Evtl. erneuter Ladeversuch?

}

4. Überprüfen der eingelesenen Daten:

Sollte der Ladeversuch erfolgreich verlaufen sein, muss man sich darum kümmern, die so geladenen Daten auszuwerten. Dabei muss man sich bewusst sein, dass sämtliche eingelesenen Daten im Container myData gespeichert sind und von dort gelesen werden müssen.

Page 283: Flash cs3, ajax und php

K A P I T E L 6270

Um auf sehr schnelle Art und Weise zu testen, ob die eingelesenen Daten korrekt sind, kann man den gesamten eingelesenen XML-Baum in einen String um wandeln und als solchen ausgeben lassen:

myLoader.toString () ;

XML-Baum in Flash ausgeben

Angewandt in einem Flash-Skript würden die oben dargestellten Schritte wie folgt aussehen:

System.useCodepage = true;

var anzLadeversuche:Number = 0;

var maxLadeversuche:Number = 3;

var myLoader:XML = new XML();

var mySource:String = "EinlesedatenXML01_UTF-8.txt";

myLoader.ignoreWhite = true;

myLoader.onLoad = function(loadedOK:Boolean) {

//Ladevorgang abgeschlossen.

anzLadeversuche++;

if(loadedOK) {

//Daten wurden ERFOLGREICH geladen.

trace("[ SYSTEM ]: Daten erfolgreich geladen.\n\n");

trace("Die eingelesenen Daten waren:\n");

trace(myLoader.toString());

}

else {

if(anzLadeversuche<maxLadeversuche) { myLoader.load(mySource); }

else { trace("[ SYSTEM ]: Maximale Anzahl der Ladeversuche ("+anzLadeversuche+") erreicht. Weiteres Laden wird abgebrochen"); }

}

}

Page 284: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 271

myLoader.load(mySource);

stop();

Listing 6.23: Das Flash-Skript XMLLoad01.fl a zum Einlesen und Darstellen der XML-Daten in Form eines Strings liegt wie gewohnt auf der Buch-CD. Sollte die XML-Datei bereits UTF-8-codiert sein, so können Sie die erste Zeile des Scripts entfernen, da Flash standardmäßig bereits UTF-8-codiert arbeitet.

Leere Textknoten: ignoreWhite = trueIn vielen Fällen werden in Flash XML-Daten eingelesen, die Textknoten nur mit Leerzeichen enthalten. Erkennt Flash solche „leeren“ Textknoten, so werden diese normalerweise gelöscht und nicht geparst. Genau dieser Fall könnte aber fatal enden, denn leere Textknoten treten rela-tiv häufig auf – auch in unserem Beispiel. Setzen Sie deshalb die Eigenschaft ignoreWhite des XML-Objekts auf true, um das Löschen der leeren Textknoten zu verhindern.

Führt man dieses Skript in Flash aus, so erhält man im Ausgabefenster den kompletten XML-Baum angezeigt. Klarerweise sind die Daten in dieser Form nicht verwendbar – sie müssen in die einzelnen Bestandteile zerlegt werden. Hierzu muss man Stufe für Stufe den XML-Baum zerlegen, wobei die Struktur bzw. die Verschachtelungen nicht notwendigerweise bekannt sein müssen. Flash ist in der Lage, den Tag-Namen, die Attribute und den Wert jedes Tag auszulesen. Des Weiteren stehen hilfreiche Methoden zum Überprüfen zur Verfügung, beispielsweise ob ein Elternelement Kindelemente aufweist bzw. wie viele es aufweist. Aber fangen wir klein an!

ABBILDUNG 6.18

In der Testumgebung von Flash kann man auf einfache Art die eingelesenen Daten in Form eines Strings ausge-ben lassen.

Page 285: Flash cs3, ajax und php

K A P I T E L 6272

Vorgehensweise beim Einlesen der XML-Daten

Der aufwändigere Part ist nun das Zerlegen des XML-Baums in seine Bestandteile. Dazu ist es notwendig, sich Schritt für Schritt durch den XML-Baum zu arbeiten. Aus dem Grundlagenteil wissen Sie, dass die erste Zeile in einem XML-Dokument eine Kennzeichnung dieses Dokuments als XML-Dokument ist. Das darauffolgende Ele-ment repräsentiert das sogenannte Wurzelelement und umschließt alle weiteren Tags. In unserem Fall ist dies das Element <XML-Kundenliste>.

Des Weiteren kann man den Baum wie folgt zerlegen:

1. <XML-Kundenliste> ist das Wurzelelement und beinhaltet als erstes Kind („Child“) das Element <Kunden>.

2. <Kunden> beinhaltet ein Child-Element namens <Kunde>.

3. <Kunde> beinhaltet acht Child-Elemente: <Vorname>, <Nachname>, <Firma>, <Adresse>, <PLZ>, <Ort>, <Staat> und <email>.

4. Jedes der Child-Elemente von <Kunde> hat sieben (oben genannte) Geschwister-Elemente (im Englischen „Sibling“ genannt).

5. Jedes dieser Child-Elemente von <Kunde> weist Textelemente auf, also im Endeffekt Werte. Im Allgemeinen sind wir genau an diesen Werten interessiert.

Auf XML-Elemente zugreifen

U m nun ausgehend von den eingelesenen Daten auf die einzelnen Elemente zuzu-greifen, geht man folgendermaßen vor. Zunächst einmal ist die Kennzeichnung des Dokuments als XML-Dokument für uns nicht von Bedeutung. Trotzdem ist dies genau

ABBILDUNG 6.19

Das eingelesene XML-Dokument in Baumform

(Strukturdiagramm) dargestellt

Page 286: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 273

das erste eingelesene Element in unserer Liste, wobei es somit auch das übergeordnete Element im Baum darstellt. Demnach müssen wir auch auf ein erstes Child zugreifen, was wir mit folgendem Befehl erreichen:

myLoader.fi rstChild

S omit haben wir in der Baumstruktur des XML-Dokuments das Element <XML-Kun-denliste> erreicht.

Aus dem oben dargestellten Baum erkennt man, dass auch dieses Element nicht von allzu großem Interesse für uns ist, denn auch <XML-Kundenliste> beinhaltet nur ein weiteres Child-Element namens <Kunden>, welches wir wiederum durch den Befehl firstChild (diesmal vom Tag <XML-Kundenliste>) erreichen:

myLoader.fi rstChild.fi rstChild

In unserem Fall enthält das Tag <Kunden> nur einen einzigen Kunden (Uwe Mutz), dessen Daten wir auslesen können. Also ist unser nächster Schritt das Zugreifen auf die Daten des Tag <Kunde>, welches ein Child-Element von <Kunden> ist. Der Zugriff erfolgt wie schon bekannt per:

myLoader.fi rstChild.fi rstChild.fi rstChild

ABBILDUNG 6.20

Nach dem Einlesen eines XML-Dokuments arbeitet man sich Schritt für Schritt („Child für Child“) vom über-geordnetsten Element nach unten.

Zugriff über das Array childNodes

Über den Zugriff auf das Array ch ildNodes ei nes jeweiligen Knotens bz w. Elements hat man Zugriff auf alle Child-Elemente dieses Knotens. Standardmäßig wird im Array wie immer bei 0 zu zählen begonnen, die Anzahl der Werte im Array erhält man über dessen Eigenschaft length.

Page 287: Flash cs3, ajax und php

K A P I T E L 6274

Möchte man nun auf die einzelnen Kinder von <Kunde> zugreifen, so erledigt man dies am einfachsten über genau das oben beschriebene Array childNodes in Verbin-dung mit einer for-Schleife:

var theData:Array = myLoader.fi rstChild.fi rstChild.fi rstChild.childNodes;

for(var i:Number=0; i<theData.length; i++) {

trace("Child"+i+": <"+theData[i].nodeName+">");

trace("Wert="+theData[i].fi rstChild.nodeValue);

}

Listing 6.24: Auslesen aller Child-Elemente eines Knotens mithilfe einer for-Schleife

Inhalt der Knoten mit nodeValue

Im obigen Beispiel sieht man, dass auch die Werte eines Knotens wiederum ein Child-Element des Knotens sind. Aus diesem Grund musste in Zeile 5 per firstChild auf das Child-Element zugegriffen werden, bevor der Textwert per nodeValue au sgelesen werden kann. Erst dieses Child-Element stellt den ersehnten Textknoten mit dem eigentlich auszulesenden Wert dar.

Oft ist es hilfreich zu wissen, ob ein Knoten üb erhaupt Child-Elemente umfasst. Die Methode hasChildNodes() ei nes Knotens gibt uns darüber Auskunft. Würden wir diese Methode auf den ersten Knoten unseres XML-Dokuments, also die Definition des XML-Dokuments, anwenden, würde sie den Wert true zurückliefern, da der erste Knoten sehr wohl ein Child-Element umfasst, nämlich <XML-Kundenliste>.

myLoader.hasChildNodes(); //liefert den Wert true

Die nachfolgende Auflistung von Methoden und Eigenschaften der XML-Daten soll Ihnen helfen, sich beim Einlesen von XML-Daten zurechtzufinden:

Methoden Verwendung

hasChildNodes Gibt Auskunft darüber, ob ein Knoten über Kinder verfügt. Ist dem so, so liefert die Methode den Wert true zurück, andernfalls false.

Eigenschaften VerwendungfirstChild Verweist auf das erste Child-Element des angegebenen Knotens.

lastChild Verweist auf das letzte Child-Element des angegebenen Knotens.

nextSibling Verweist auf das nächste Geschwister-Element (den „Nachbarn links im XML-Baum“) des angegebenen Knotens.

previousSibling Verweist auf das vorherige Geschwister-Element (den „Nachbarn rechts im XML-Baum“) des angegebenen Knotens.

nodeName Gibt den Namen des aktuellen Knotens aus.

nodeType Gibt den Typ des aktuellen Knotens aus. Folgende Werte sind möglich: 1 steht für ein XML-Element und 3 für einen Textknoten.

nodeValue Gibt den Text des angegebenen Knotens aus, sofern es sich um einen Textknoten handelt.

parentNode Verweist auf den übergeordneten Knoten (das Eltern-Element).

Page 288: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 275

Arrays Verwendung

attributes Dies ist ein Objekt, welches alle Attribute des aktuellen Knotens beinhaltet.

childNodes Ein Array mit Bezügen auf sämtliche Child-Elemente des aktuellen Knotens.

Tabelle 6.1: Die wichtigsten Methoden, Eigenschaften und Arrays im Überblick – eine vollständige Auflistung aller Ereignisse, Methoden und Eigenschaften finden Sie in der ActionScript-Referenz von Adobe oder in der Flash-Hilfe.

Wie sieht es nun mit konkreten Anwendungen von XML-Daten aus? Zunächst einmal sei gesagt, dass es wenig Sinn macht, eine XML-Datei einzulesen, deren Aufbau man nicht kennt. Grundsätzlich ist es mithilfe von rekursiver Programmierung zwar mög-lich, auf alle eingelesenen Daten zuzugreifen, andererseits ist dies nutzlos, wenn man nicht weiß, was man mit den eingelesenen Daten nun anstellen soll.

Rekursive ProgrammierungMit rekursiver Programmierung ist eine Programmiertechnik gemeint, bei der sich Funktionen (Methoden) bei Bedarf selbst aufrufen. Beispielsweise beim Programmieren von Newsgroups wird gerne auf rekursive Programmierung zurückgegriffen, da man in diesem Fall etwa Kommentare zu Kommentaren von Einträgen finden muss und es von vorneherein nicht fest-steht, wie tief diese Verschachtelung von Kommentaren geht.

Auswerten von XML -Daten

Gehen wir das Einlesen und Auswerten der Daten an, denn hier ist noch ein bisschen Arbeit vonnöten. Gegenüber dem Einlesen der Textdatei aus dem ersten Beispiel (erin-nern Sie sich: Es wurden die „Kundendaten“ durchnummeriert, also beispielsweise „Nachname0“, „Nachname1“ usw.) muss jetzt der XML-Baum zerlegt werden. Am einfachsten wird das entweder durch Einlesen der Werte in entsprechende Variablen oder über das Verwenden von Arrays im Zusammenhang mit Objekten erledigt. Ent-scheidet man sich für die erste Variante, so muss man sich darüber im Klaren sein, dass man eventuell eine größere Anzahl von Variablen benötigt (in unserem Fall wären das bei nur einem Datensatz bereits acht Variablen: Vorname, Nachname, Firma, Adresse, PLZ, Ort, Staat, email). Die zweite Variante bietet den großen Vorteil, mit nur einer einzigen „Variablen“ – genau genommen dem Array – arbeiten zu müssen.

Wir werden uns beide Varianten ansehen und Sie können dann selbst entscheiden, welche Variante Ihnen eher zusagt bzw. auf Ihren speziellen Anwendungsfall am besten passt.

Idealerweise findet das Auslesen des XML-Baums gleich nach dem Laden statt. Das wäre in unserem Fall zu dem Zeitpunkt, wo das Ereignis onLoad auftritt und der Ladevorgang erfolgreich war:

myLoader.onLoad = function(loadedOK:Boolean):Void {

//Ladevorgang abgeschlossen.

anzLadeversuche++;

Page 289: Flash cs3, ajax und php

K A P I T E L 6276

if(loadedOK) {

//Daten wurden ERFOLGREICH geladen.

...

Listing 6.25: Auszug aus dem Skript des Ladevorgangs der XML-Datei. Hier sollte man mit dem Auswerten des XML-Baums beginnen.

XML-Daten über Variablen auswerten

Führen wir uns zunächst Variante 1 zu Gemüte, bei der wir den eingelesenen Datensatz in Variablen speichern. Hierzu gehen wir wie folgt vor:

1. Zunächst erzeugen wir die Variablen, in denen die eingelesenen Werte gespeichert werden sollen.

2. Danach springen wir im eingelesenen XML-Baum an die Stelle, wo die für uns relevanten Kundendaten beginnen.

3. Ab dieser Stelle gehen wir die Daten Schritt für Schritt durch, lesen die Werte aus und schreiben sie in die entsprechenden Variablen.

Nun denn – Schritt für Schritt: Daten aus einer XML-Datei lesen, Variante 1:

Basis dieses Beispiels ist wieder die Flash-Datei aus der Schritt-für-Schritt-Anleitung „Daten aus einer Textdatei mit Flash laden“. Sie finden die Datei auch auf der Buch-CD.

1. Anlegen der Variablen zum späteren Speichern der eingelesenen Werte

Wie oben bereits erwähnt, benötigen wir acht Variablen (pro Datensatz, wobei wir derzeit mit nur einem Datensatz arbeiten). Beachten Sie, dass die Variablen außerhalb der Funktion für das onLoad-Ereignis angelegt werden müssen, da sie sonst nur innerhalb der Funktion gültig sind (sollte Ihnen das unklar sein, so schlagen Sie bitte bei den Grundlagen der Programmierung nach):

var Vorname:String, Nachname:String, Firma:String, PLZ:String, Ort:String, Staat:String, email:String;

Alle Variablen sind vom Typ String – auch die Postleitzahl, denn es könnte sich um Kunden aus beispielsweise Großbritannien handeln, wo die Postleitzahlen aus Ziffern und Buchstaben bestehen.

2. Springen zu dem Punkt im XML-Baum, wo die relevanten Daten beginnen

Nehmen Sie hierzu bitte die Abbildung 6.19 zur Hand – hier sehen Sie, dass wir zum Tag <Kunde> springen müssen, um zu den relevanten Daten zu gelangen. Dies geschieht – wie in Listing 6.25 zu sehen – innerhalb der Funktion zum onLoad-Ereignis:

var theData:Array = myLoader.fi rstChild.fi rstChild.fi rstChild.childNodes;

Page 290: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 277

3. Speichern der XML-Daten in Variablen

Abschließend werden die Daten in der richtigen Reihenfolge in den dafür vorgesehenen Variablen gespeichert:

Vorname = theData[0].fi rstChild.nodeValue;

Nachname = theData[1].fi rstChild.nodeValue;

Firma = theData[2].fi rstChild.nodeValue;

Adresse = theData[3].fi rstChild.nodeValue;

PLZ = theData[4].fi rstChild.nodeValue;

Ort = theData[5].fi rstChild.nodeValue;

Staat = theData[6].fi rstChild.nodeValue;

email = theData[7].fi rstChild.nodeValue;

Listing 6.26: Die eingelesenen Daten werden in den dafür vorgesehenen Variablen gespeichert (Auszug).

Reihenfolge beachtenBitte beachten Sie, dass die Reihenfolge der Informationen (zuerst Vorname, dann Nachname, Firma usw.) von entscheidender Bedeutung ist und uns beim Einlesen bekannt sein muss. Das Speichern der Daten in genau der richtigen Reihenfolge ist natürlich eine lästige Angelegenheit, nicht zuletzt deshalb, weil es eine potenzielle Fehlerquelle darstellt.

4. Dynamische Variablennamen

Hier stellt sich unweigerlich die Frage, ob man nicht die schon in der XML-Datei verwendeten Tag-Namen <Vorname>, <Nachname> usw. direkt als Variablennamen heranziehen kann. Ja, dem ist so – es besteht in Flash die Möglichkeit, dynamisch Variablennamen zu erzeugen. Jedem Hierarchie-Objekt in Flash ist ein Array von Variablen zugeordnet – möchte man beispielsweise dem _root-Objekt dynamisch Variablen zuweisen, so ist dies über den Zugriff auf das Array-Objekt möglich:

_root["Variablenname"] = Wert;

Dies kann man sich zu Nutze machen, indem man den Variablennamen, der letzten Endes ein reiner String ist, aus dem Tagnamen der XML-Datei generiert:

_root[theData[x].nodeName] = Wert;

x stellt eine beliebige Stelle im Array der eingelesenen Daten dar. Angewandt auf unser konkretes Beispiel würde dies wie folgt aussehen:

for(var i:Number=0; i<theData.length; i++) {

_root[theData[i].nodeName] = theData[i].fi rstChild.nodeValue;

}

In dieser for-Schleife werden sämtliche eingelesenen Knoten als Werte des Arrays theData (hierin sind die einzelnen Einträge als Objekte angelegt) mit

Page 291: Flash cs3, ajax und php

K A P I T E L 6278

dem zugehörigen Knotennamen gespeichert. Beachten Sie, dass i (im Script fett geschrieben) der Index über alle Einträge des Arrays ist.

5. Das fertige Skript

Das vollständige Skript dieses Beispiels sieht wie folgt aus. Sie finden es auch noch ein-mal auf der Buch-CD (XMLLoad02a.fla). Wie bereits weiter oben besprochen, können Sie in diesem Script die erste Zeile entfernen, wenn ein Dokument bereits den UTF-8-Zeichensatz verwendet (Flash arbeitet standardmäßig mit dem UTF-8-Zeichensatz):

System.useCodepage = true;

var anzLadeversuche:Number = 0;

var maxLadeversuche:Number = 3;

var myLoader:XML = new XML();

var mySource:String = "EinlesedatenXML01_UTF-8.txt";

myLoader.ignoreWhite=true;

//var Vorname:String, Nachname:String, Firma:String, PLZ:String, Ort:String, Staat:String, email:String; //nicht mehr notwendig, da diese Variablen implizit deklariert werden

myLoader.onLoad = function(loadedOK:Boolean) {

//Ladevorgang abgeschlossen.

anzLadeversuche++;

if(loadedOK) {

var theData:Array = myLoader.fi rstChild.fi rstChild.fi rstChild.childNodes;

for(var i:Number=0; i<theData.length; i++) { _root[theData[i].nodeName] = theData[i].fi rstChild.nodeValue; }

gotoAndStop("LadevorgangErfolgreich");

}

else {

if(anzLadeversuche<maxLadeversuche) { myLoader.load(mySource); }

else { gotoAndStop("LadevorgangFehlgeschlagen"); }

}

}

myLoader.load(mySource);

Listing 6.27: Der Lohn unserer Mühen – das vollständige Einleseskript für die XML-Daten aus unserem Beispiel (XMLLoad02a.fl a)

Page 292: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 279

Das _root-ArrayDieses Array ist ideal für das dynamische Anlegen von eventuell nicht von vorneherein bekannt-en Variablennamen. Das _root-Array ist somit ein assoziatives Array, wobei die Elemente im Array die _root-Variablen darstellen. Variablen auf Root-Ebene sind für alle Scripts zugänglich und somit quasi „global“. (Hardcore-Programmierer würden mich jetzt zwar schimpfen, da man hier nicht von globalen Variablen spricht, aber mir ist an dieser Stelle der Sinn solcher Variablen wichtiger … liebe Programmierer, bitte verzeiht mit diesen kleinen Fehler!)

6. Daten in Flash ausgeben

Nun müssen wir uns nur noch um die Darstellung der gespeicherten Daten kümmern. Anders als im vorigen Beispiel mit der Textdarstellung der Daten können wir nun direkt Variablenwerte in den dynamischen Textfeldern darstellen. Die dynamischen Textfelder geben somit die Variablen Vorname, Nachname, Firma usw. aus.

Hierzu werden – wie in der folgenden Abbildung dargestellt – die Variablen Nachname, Vorname usw. als Ausgabevariablen der dynamischen Textfelder verwendet.

ABBILDUNG 6.21

Beim Ausgeben der gespei-cherten Daten muss gegen-über dem Einlesen von URL-kodierten Textdaten darauf geachtet werden, dass nun reine Variablenwerte ausge-geben werden.

XML-Daten über Arrays auswerten

Nun zu Variante 2 – das Einlesen der Daten in ein Array, das Objekte beinhaltet. Gra-fisch dargestellt würde das zu verwendende Array wie in der Abbildung 6.22 gezeigt aufgebaut sein.

Page 293: Flash cs3, ajax und php

K A P I T E L 6280

1. Zunächst wird ein Array erzeugt, das so viele Zellen beinhaltet wie – in unserem Fall – der XML-Baum Kunden beinhaltet. Derzeit ist dies nur ein einziger Kunde, jedoch sollte das Beispiel später auch für mehrere Kunden funktionieren. Die Anzahl der Array-Zellen kann natürlich auch dynamisch erzeugt werden, wenn von vorneherein nicht feststeht, wie viele Daten eingelesen werden.

2. Danach wird in jeder Zelle des Arrays pro Kunde ein Objekt angelegt, das alle Informationen zum Kunden speichert (Vorname, Nachname etc.).

Sinn macht das Speichern in Arrays u nd Objekten nur dann, wenn wir mehr als einen einzigen Datensatz einlesen, denn wozu sollten wir sonst ein Array an Objekten anlegen. Obwohl jedoch unsere eingelesene Datei aus nur einem einzigen Datensatz besteht, arbeiten wir dieses Beispiel trotzdem exemplarisch mit einem Datensatz ab. Im Workshop-Teil greifen wir dieses Beispiel noch einmal auf und laden mehrere Datensätze ein.

Schritt für Schritt: Daten aus einer XML-Datei lesen, Variante 2. Folgende Schritte sind vorzunehmen, um den XML-Baum einzulesen:

1. Array anlegen

In diesem Array werden die jeweiligen Informationen als Objekt gespeichert. Der Name des Arrays ist selbstverständlich frei wählbar – wir haben uns an dieser Stelle für theDataStore entschieden.

var theDataStore:Array = new Array();

2. for-Schleife über alle Datensätze

Unser Beispiel ist bereits so weit vorbereitet, dass eine Reihe von Datensätzen eingelesen werden könnten. Aus diesem Grund lassen wir eine for-Schleife über alle eingelesenen Datensätze laufen.

var theData:Array = myLoader.fi rstChild.fi rstChild.childNodes;

for(var i:Number=0; i<theData.length; i++) {

ABBILDUNG 6.22

Speichern der eingelesenen Daten in Objekten, die sich in

einem Array befinden.

ObjekteSelbst erzeugte Objekte sind zum Speichern von

strukturierten Daten her-vorragend geeignet. Dies

sollte man sich in Flash zu Nutze machen.

Page 294: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 281

3. Erzeugen eines Objekts pro Zelle im Array

Innerhalb der Schleife muss dann im Array an der jeweiligen Stelle (Zelle) ein Objekt angelegt werden.

Pro eingelesenem Datensatz (hier: pro Kunde) wird im Array eine eigene Zelle benötigt, der ein Objekt zugewiesen wird. Das Objekt selbst speichert die gewünschten Informationen, welche hier Vorname, Nachname usw. sind.

theDataStore[i] = new Object();

4. Speichern der XML-Daten im Objekt

Zu guter Letzt werden die Daten ins Objekt geschrieben:

theDataStore[i].Vorname = theData[i].childNodes[0].fi rstChild.nodeValue;

theDataStore[i].Nachname = theData[i].childNodes[1].fi rstChild.nodeValue;

theDataStore[i].Firma = theData[i].childNodes[2].fi rstChild.nodeValue;

theDataStore[i].Adresse = theData[i].childNodes[3].fi rstChild.nodeValue;

theDataStore[i].PLZ = theData[i].childNodes[4].fi rstChild.nodeValue;

theDataStore[i].Ort = theData[i].childNodes[5].fi rstChild.nodeValue;

theDataStore[i].Staat = theData[i].childNodes[6].fi rstChild.nodeValue;

theDataStore[i].email = theData[i].childNodes[7].fi rstChild.nodeValue;

Listing 6.28: Sämtliche zu speichernde Daten werden im Objekt abgelegt (Auszug).

5. Variablen anlegen

Da unser Beispiel einen Datensatz ausgeben soll, werden die darzustellenden Daten wie schon zuvor in Variablen gespeichert, die dann in dynamischen Textfeldern ausgegeben werden.

Vorname = theDataStore[0].Vorname;

Nachname = theDataStore[0].Nachname;

Firma = theDataStore[0].Firma;

Adresse = theDataStore[0].Adresse;

PLZ = theDataStore[0].PLZ;

Ort = theDataStore[0].Ort;

Staat = theDataStore[0].Staat;

email = theDataStore[0].email;

Listing 6.29: Einlesen der Informationen der XML-Datei (Auszug)

Eines ist am vorigen Beispiel zu beachten: Weil das Beispiel bereits so weit vorbereitet wurde, um mehr als nur einen Datensatz einzulesen, wurde nicht wie in

Page 295: Flash cs3, ajax und php

K A P I T E L 6282

den vorigen Beispielen direkt auf das Tag <Kunde>, sondern auf das Tag <Kunden> zugegriffen (<Kunden> ist das übergeordnete Tag zu <Kunde>).

Daher heißt es:

var theData:Array = myLoader.fi rstChild.fi rstChild.childNodes;

anstatt:

var theData:Array = myLoader.fi rstChild.fi rstChild.fi rstChild.childNodes;

Das gesamte Beispiel finden Sie wie gewohnt auf der Buch-CD als Datei mit dem Namen XMLLoad02b.fla.

XML-Daten mit Attributen

Wir möchten nun eine weitere Möglichkeit darstellen, wie ein XML-Baum aufgebaut werden kann. Letzten Endes ist die Möglichkeit der Wertübergabe nicht auf Textkno-ten beschränkt, sondern kann ebenso über Attribute e rfolgen. Die Anwendung gleicht der der bekannten Attribute aus XHTML, wobei wir in XML bei der Wahl der Attri-butnamen frei sind. Betrachtet man beispielsweise das Listing in Listing 6.29, so sieht man dort, dass anstelle der Textknoten <Vorname>, <Nachname> etc. die Attribute Vorname, Nachname usw. verwendet werden.

ABBILDUNG 6.23

Anstatt der Textknoten wurden dieses Mal Attribute eingesetzt. Die Auswertung in Flash muss entsprechend

geändert werden.

Um Attribute auswerten zu können, steht aus Flash da s Objekt attributes zu r Ver-wendung bereit. Auf die Werte des Objekts kann man über den Namen der verwen-deten Variable („Spaltenname“) zugreifen. In unserem Fall wären folgende Anwen-dungen gleichbedeutend und führen zum selben Ergebnis:

attributes["Vorname"]; //liefert "Uwe"

attributes.Vorname; //liefert "Uwe"

Für welche Variante Sie sich entscheiden, liegt bei Ihnen. Sollte etwa nicht bekannt sein, wie viele Attribute verwendet werden, empfiehlt sich eine Schleife über alle Attri-bute (attributes.length).

Vergleicht man das dazu notwendige Skript mit unserem Beispiel aus Listing 6.27, so muss dieses Listing durch das nachfolgende Skript ersetzt werden:

Page 296: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 283

theDataStore[i].Vorname = theData[i].attributes.Vorname;

theDataStore[i].Nachname = theData[i].attributes.Nachname;

theDataStore[i].Firma = theData[i].attributes.Firma;

theDataStore[i].Adresse = theData[i].attributes.Adresse;

theDataStore[i].PLZ = theData[i].attributes.PLZ;

theDataStore[i].Ort = theData[i].attributes.Ort;

theDataStore[i].Staat = theData[i].attributes.Staat;

theDataStore[i].email = theData[i].attributes.email;

Listing 6.30: Anstatt wie im letzten Beispiel auf einen Textknoten zuzugreifen, wird nun auf die Attribute eines Knotens zugegriffen.

Die Ausgabe der eingelesenen Daten ist dieselbe – hier sind keine Änderungen notwen-dig. Fassen wir also kurz zusammen, was wir soeben getan haben:

1. Anstatt mit Textknoten zu arbeiten, setzen wir Attribute ein.

2. Die „Werte“ der Textknoten werden zu Werten von Attributen, veranschaulicht dargestellt:

<Textknoten>Wert</Textknoten>

wird zu:

<Knoten Textknoten_Wert="Wert" />

3. Die Werte der Attribute kann man in Flash mithilfe des assoziativen Arrays attributes auslesen.

Ihnen als Webentwickler steht es frei, welche Art der Wertedarstellung (Textknoten oder Attribute) Sie verwenden. Natürlich können Sie die Darstellung auch mischen. Eine Generalaussage, wann welche Variante zum Einsatz gelangen sollte, kann und soll an dieser Stelle nicht getroffen werden, weil es von Fall zu Fall unterschiedlich ist.

Einlesen einer XML-konformen PHP-Datei

Wenden wir uns einer ähnlichen Thematik zu, nämlich dem Einlesen einer PHP-Datei, die Daten XML-konform darstellt. Wie zu erwarten, läuft dies exakt gleich ab wie das Einlesen einer Textdatei. Der einzige Unterschied für Flash besteht darin, dass man anstatt einer Datei mit der Endung „.txt“ eine Datei mit der Endung „.php“ einliest.

Der Aufwand hinsichtlich der Erstellung der einzulesenden Datei gestaltet sich natür-lich etwas anders, da der XML-Ba um durch PHP generiert werden muss. Die Vorge-hensweise hierbei entspricht der Vorgehensweise bei der Generierung eines „Textin-halts“. Da dies bereits am Anfang dieses Kapitels sehr ausführlich beschrieben wurde, beschränken wir uns hier auf die Zusammenfassung der wesentlichen Schritte.

Page 297: Flash cs3, ajax und php

K A P I T E L 6284

Das Generieren einer XML-Datei durch PHP ist im Wesentlichen nichts anderes als das Generieren irgendeines Inhalts eines Webdokuments. Entscheidend ist nur, was der Client zu sehen bekommt, und das ist in diesem Fall ein XML-konform aufge-bautes Dokument.

1. Defi nieren, welche Datenbank verwendet wird

myysql_select_db();

2. Auswahl der Datenbank prüfen

Sollte die Methode mysql_select_db() den Wert false zurückgeben, war die Auswahl der Datenbank nicht erfolgreich. Der Rückgabewert true signalisiert, dass die Auswahl der Datenbank in Ordnung war.

3. Absetzen eines SQL-Statements

$sql = "SELECT * FROM tbl_Kunden";

if(!$query = mysql_query($sql)) {

die('<div class="error">Das SQL-Statement konnte nicht durchgef&uuml;hrt werden. Errorcode: ‚.mysql_error().'</div>');

}

else {

//echo('<div class="success">Das SQL-Statement:<br/>'.$sql.'<br/>wurde erfolgreich abgesetzt.</div>');

}

4. Ausgeben der Daten in die PHP-Seite

Diesem Teil müssen wir doch etwas mehr Aufmerksamkeit zuteil werden lassen, denn anders als bei einer einzulesenden Textdatei muss dieses Dokument XML-konform aufbereitet werden. Zunächst wird das Dokument als XML-Dokument gekennzeichnet:

<?php echo(‚<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>'); ?>

Im nächsten Schritt fügt man die Struktur der XML-Datei in Form von Tags ein:

<XML-Kundenliste>

<Kunden>

Zuletzt werden die in der Datenbank gespeicherten Daten mithilfe einer Schleife ausgegeben:

<?php

while($theData = mysql_fetch_array($query)) {

echo("<Kunde>");

Page 298: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 285

echo("<Vorname>".$theData["vc_Vorname"]."</Vorname>");

echo("<Nachname>".$theData["vcP_Nachname"]."</Nachname>");

echo("<Firma>".$theData["vc_Firma"]."</Firma>");

echo("<Adresse>".$theData["vc_Adresse"]."</Adresse>");

echo("<PLZ>".$theData["vc_PLZ"]."</PLZ>");

echo("<Ort>".$theData["vc_Ort"]."</Ort>");

echo("<Staat>".$theData["vc_Staat"]."</Staat>");

echo("<email>".$theData["vc_email"]."</email>");

echo("</Kunde>");

}

?>

Danach schließt man die geöffneten Tags:

</Kunden>

</XML-Kundenliste>

Listing 6.31: Auszug aus dem Listing der Datei EinlesedatenXML02.php

Die clientseitige SichtMan muss sich immer vor Augen führen, dass Flash eine clientseitige Anwendung ist und dem-nach auch nur Informationen einlesen kann, die clientseitig (in irgendeiner Form) dargestellt werden können. In unserem Fall produziert der Server auf Anfrage durch PHP-Programmierung dieses XML-konforme Dokument, das – und das ist der springende Punkt – aus Sicht des Clients aus purem XML-Inhalt besteht.

5. Flash-Datei anpassen

Die Änderungen in Flash hinsichtlich des Einlesens der Datei sind gegenüber dem vorangegangenen Beispiel minimal. Es muss lediglich die Zeile:

var mySource:String = "EinlesedatenXML01_UTF-8.txt";

mit der einzulesenden Datei in EinlesedatenXML02.php geändert werden:

var mySource:String = "EinlesedatenXML02.php";

Damit wäre dieses Beispiel aus Flash- und PHP-Sicht abgeschlossen.

6. Attribute statt Textknoten

Page 299: Flash cs3, ajax und php

K A P I T E L 6286

Für den Fall, dass wir anstatt der Textknoten in PHP Attribute zur Darstellung der Werte verwenden (vgl. Listing 6.31), muss die PHP-Datei innerhalb der while-Schleife in nachfolgendes Skript geändert werden:

while($theData = mysql_fetch_array($query)) {

echo("<Kunde");

echo(" Vorname='".$theData["vc_Vorname"]."'");

echo(" Nachname='".$theData["vcP_Nachname"]."'");

echo(" Firma='".$theData["vc_Firma"]."'");

echo(" Adresse='".$theData["vc_Adresse"]."'");

echo(" PLZ='".$theData["vc_PLZ"]."'");

echo(" Ort='".$theData["vc_Ort"]."'");

echo(" Staat='".$theData["vc_Staat"]."'");

echo(" email='".$theData["vc_email"]."'");

echo(" />");

}

Listing 6.32: Anstatt der Textknoten werden auch beim Erzeugen der XML-Daten nun Attribute eingesetzt (Auszug aus dem Listing der Datei EinlesedatenXML03.php).

6.3.3 Ausgeben von XML-Daten in eine PHP-SeiteEbenso wie man Daten aus einer XML-Datei einlesen kann, besteht auch die Möglich-keit, XML-Daten an ein serverseitiges Dokument (in unserem Fall eine PHP-Datei) zu übergeben, das die Daten weiterverarbeitet und beispielsweise in eine Datenbank schreibt.

Man sollte an dieser Stelle nicht unerwähnt lassen, dass das Ausgeben von Informati-onen per XML aus Flash heraus bei weitem nicht so oft eingesetzt wird wie das Einle-sen von XML-Daten. Der Grund ist sicherlich auch der, dass auf Serverseite die Daten über ein geeignetes Skript erst noch geparst und aufbereitet werden müssen, wodurch ein (oft nicht unerheblicher) Mehraufwand bei der Entwicklung entsteht. Stattdessen

ABBILDUNG 6.24

Anstelle der Textknoten im vorigen Beispiel werden nun Attribute innerhalb der Tags

zum Einsatz kommen.

Page 300: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 287

könnte auch das LoadVars-Objekt zum Einsatz kommen. Nichtsdestotrotz stellt das Ausgeben von XML-Daten eine sehr elegante und auch zukunftsweisende Variante dar.

Vorgehensweise beim Ausgeben von XML-Daten

Im Wesentlichen erfolgt das Senden und Verarbeiten der Daten in drei Schritten:

1. Erzeugen eines XML-Baums inklusive Header-Informationen in Flash

Zunächst wird in Flash ein XML-Baum mit den zu sendenden Daten erstellt. Hierzu stehen uns in Flash alle notwendigen Hilfsmittel zur Verfügung – auf diese werden wir im Folgenden noch genauer eingehen.

2. Versenden der XML-Daten an eine PHP-Seite

Flash ist nicht in der Lage, direkt Daten an eine Datenbank zu senden, da Flash – wie Sie natürlich wissen – eine clientseitige Anwendung ist.

3. Parsen der übergebenen XML-Daten in PHP

Die aus Flash übergebenen Daten werden nun in der PHP-Datei geparst und beispielsweise in eine Datenbank geschrieben.

Der XML-Header Grundsätzlich kann jeder XML-Baum nach eigenen Regeln aufgebaut werden. Soll der Baum jedoch zur weiteren Verwendung an beispielsweise eine PHP-Datei übertragen werden, ist ein korrekter Header unabdingbar. Ein typischer XML-Header ist <?xml version='1.0' encoding='UTF-8'?>.

Erzeugen eines XML-Baums in Flash

Mal andersrum – im vorigen Abschnitt haben wir uns damit beschäftigt, einen XML-Baum in PHP zu erzeugen, um diesen dann in Flash einzulesen. In PHP haben wir auf XML-spezifische Befehle zum Erzeugen eines XML-Baums „verzichtet“, da einfach keine Befehle in PHP hierzu existieren, sieht man einmal von der Verwendung zusätz-licher Bibliotheken ab.

In Flash stellt sich die Sache etwas differenzierter dar, da Flash uns sehr wohl einige Möglichkeiten bietet. In der nachfolgenden Tabelle finden Sie diese aufgelistet und mit einer kurzen Erklärung versehen. Danach schreiten wir zur Tat und erzeugen anhand eines konkreten Beispiels einen XML-Baum.

Page 301: Flash cs3, ajax und php

K A P I T E L 6288

Methode Verwendung

new XML() Konstruktor zum Erstellen eines neuen XML-Objekts. Wie auch beim Einlesen von XML-Daten muss zunächst ein solches XML-Objekt angelegt werden.

createElement(Elementname) Erzeugt ein neues XML-Element (einen Knoten) mit dem angegebenen Namen (Elementname). Sämtliche Child- oder Parent-Knoten sowie Attribute müssen nachträglich erzeugt werden, da diese von vorneherein nicht existieren. Mithilfe von appendChild kann das Element danach an einen bestehenden XML-Baum angehängt werden.

createTextNode(Text) Erzeugt ähnlich der Methode createElement einen XML-Knoten, jedoch handelt es sich in diesem Fall um einen Textknoten. Der Inhalt dieses Textknotens ist der Wert aus Text. Wie auch bei createElement muss dieses Element nach dem Anlegen per appendChild an einen bestehenden XML-Baum angehängt werden.

appendChild(Childknoten) Fügt den angegebenen Child-Knoten (der zuvor per createElement oder createTextNode erzeugt wur-de) am Ende eines bestehenden XML-Baums an.

insertBefore(Childknoten, Vor-Knoten) Fügt den angegebenen Child-Knoten vor dem Vor-Knoten ein. Wird kein Vor-Knoten angegeben, so wird die Methode appendChild verwendet und der Knoten somit am Ende des XML-Baums angehängt.

firstChild Diese Eigenschaft ist bereits aus dem vorigen Kapitel bekannt. Mit ihrer Hilfe kann man von einem Parent- in einen Child-Knoten wechseln.

attributes Mithilfe dieses Objekts können für bestehende Knoten Attribute erzeugt werden.

xmlDecl Legt die grundlegenden Informationen zum XML-Dokument fest: Versionsnummer von XML, Kodiertyp etc.

contentType Legt den MIME-Type fest, der an den Server (bei send oder sendAndLoad) übermittelt wird. Wird typischer-weise auf „text/html“ gesetzt.

Tabelle 6.2: XML-Befehle in Flash zum Erzeugen eines XML-Baums

Unser Ziel ist es nun, die Theorie in die Praxis umzusetzen, und zwar anhand des von uns in den vorigen Kapiteln verwendeten Beispiels der Kundendatendarstellung. Wie schon weiter oben im Kapitel angedeutet, müssen wir zunächst einen neuen XML-Baum „erschaffen“, was mit dem Konstruktor new XML() möglich wird:

1. Erzeugen eines neuen XML-Baums inklusive Header

Damit das XML-Dokument auch seine Gültigkeit hat, benötigt es einen Header, der gleich mit der Deklaration des XML-Objekts angegeben werden kann:

var myXML:XML = new XML("<?xml version='1.0' encoding='UTF-8'?>");

Alternative: Deklaration als XML-Daten

Alternativ dazu (und für PHP besser verständlich) kann man auch wie folgt vorgehen:

Page 302: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 289

var myXML:XML = new XML();

myXML.ignoreWhite = true;

myXML.contentType = ‚text/html';

myXML.xmlDecl = "<?xml version='1.0' encoding='UTF-8' ?>";

Wie Sie sehen, wird im alternativen Skript im Prinzip dasselbe XML-Objekt erzeugt, mit dem Unterschied, dass die Defi nition (Deklaration) des XML über die Eigenschaft xmlDecl erfolgt.

Des Weiteren wird für das XML-Objekt der contentType defi niert sowie die schon bekannte Eigenschaft ignoreWhite=true gesetzt. Dies ist im Allgemeinen nur dann notwendig, wenn Sie damit rechnen müssen, dass leere Textknoten auftreten.

Wir würden an dieser Stelle empfehlen, die zweite Methode zu verwenden, da PHP beim Einlesen der XML-Daten aus Flash mit dieser Variante besser zurechtkommt.

2. Erzeugen des Hauptknotens

Danach wollen wir denselben XML-Baum wie in Abbildung 6.19 dargestellt aufbauen. Dies bedeutet also, dass zunächst der Hauptknoten <XML-Kundenliste> anzulegen ist. Hierzu wird zunächst mithilfe der Methode createElement ein neues (unabhängiges) Knoten-Element erzeugt und danach mittels appendChild an das Ende unseres (derzeit ohnehin noch leeren) XML-Baums angehängt.

Wie der Knoten benannt wird, steht Ihnen vollkommen frei – wir haben uns für rootNode entschieden:

var rootNode:XMLNode = myXML.createElement("XML-Kundenliste");

myXML.appendChild(rootNode);

Würde das Element rootNode nicht per appendCild an den XML-Baum angefügt, so wäre die ganze Arbeit umsonst gewesen.

ABBILDUNG 6.25

Das root-Element ist bereits erzeugt.

3. Erzeugen eines Knotens innerhalb eines bereits bestehenden Knotens

Um den nächsten Knoten <Kunden> innerhalb des Elements <XML-Kundenliste> anzulegen, müssen wir – nachdem wir wieder per createElement ein unabhängiges Element erzeugt haben – in das Element <XML-Kundenliste> selbst hineinspringen, also auf das erste Child des XML-Baums verweisen. Dies gelingt durch den Einsatz der Eigenschaft fi rstChild:

Page 303: Flash cs3, ajax und php

K A P I T E L 6290

var subNode1:XMLNode = myXML.createElement( "Kunden");

myXML.fi rstChild.appendChild( subNode1);

Somit haben wir also erreicht, dass innerhalb des Elements <XML-Kundenliste> ein Element namens <Kunden> angelegt wurde.

4. Erzeugen eines Child-Knotens im Knoten <Kunden>

Gleiches wie im Arbeitsschritt zum Erzeugen des Knotens <Kunden> ist auch für den Knoten <Kunde> (Child von <Kunden>) vorzunehmen.

var subNode2:XMLNode = myXML.createElement("Kunde");

myXML.fi rstChild.fi rstChild.appendChild(subNode2);

Wie Sie sehen, wird nun zweimal per fi rstChild vom XML-Objekt myXML ausgehend verwiesen. Dies hat den einfachen Grund, dass <Kunde> ein Child von <Kunden> und dieses wiederum ein Child von <XML-Kundenliste> ist – somit ist <Kunde> quasi das „Enkelkind“ von <XML-Kundenliste>.

ABBILDUNG 6.26

In den Hauptknoten <XML-Kundenliste> wurde

ein Child-Knoten namens <Kunden> eingefügt.

5. Erzeugen von Child-Knoten und Zuweisen von Werten im Knoten <Kunde>

Nun ist es an der Zeit, die Knoten für Nachname, Vorname, Firma usw. anzulegen und diese mit Werten (dies sind in unserem Fall Textknoten) zu füllen. Da die Vorgehensweise für alle Knoten gleich ist, demonstrieren wir dies anhand eines Knotens.

Im Folgenden werden wir dann Überlegungen anstellen, wie wir uns die Arbeit für diese Knoten doch erheblich vereinfachen können. Doch zunächst zum Anlegen der Knoten.

var subNode3:XMLNode = myXML.createElement("Vorname");

myXML.fi rstChild.fi rstChild.fi rstChild.appendChild(subNode3);

var subNode3a:XMLNode = myXML.createTextNode(Vorname);

myXML.fi rstChild.fi rstChild.fi rstChild.childNodes[0].appendChild(subNode3a);

Zunächst wird – wie schon hinlänglich bekannt – ein neues unabhängiges Element per createElement erzeugt. In unserem Fall ist das der Knoten <Vorname>. Dieser Knoten wird der „Urenkel“ von <XML-Kundenliste>, deshalb muss dreimal die Eigenschaft fi rstChild angewendet werden.

ABBILDUNG 6.27

Der Knoten <Kunden> hat ein Kind bekommen

– <Kunde>.

Page 304: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 291

Ist dies geschehen, wird zunächst ein neuer, wieder unabhängiger Textknoten erzeugt und dieser dann innerhalb des soeben neu erzeugten Knotens <Vorname> (dies ist ja der nullte Child-Knoten von <Kunde>) per appendChild eingefügt.

Der Wert des Textknotens wird aus der Variable Vorname ermittelt, die zuvor von uns angelegt und mit dem Wert [ Vorname ] versehen wurde. Das Ergebnis sehen Sie in Abbildung 6.28.

6. Weitere Knoten

Jetzt könnte man für alle weiteren Knoten (<Nachname>, <Firma> etc.) genau gleich verfahren. Dies bedingt jedoch eine relativ „unelegante“ Programmierung, was wir als erfahrene Programmierer ja eigentlich gar nicht so gerne sehen ... Wie das aussehen würde, sehen Sie im nachfolgenden Listing.

//Erzeugen eines neuen XML-Baums: ---------------------

var myXML:XML = new XML();

myXML.ignoreWhite = true;

myXML.contentType = "text/html";

myXML.xmlDecl = "<?xml version='1.0' encoding='UTF-8' ?>";

var rootNode:XMLNode = myXML.createElement("XML-Kundenliste");

myXML.appendChild(rootNode);

// -----------------------------------------------------

//Erzeugen des ersten Unterknotens: --------------------

var subNode1:XMLNode = myXML.createElement("Kunden");

myXML.fi rstChild.appendChild(subNode1);

// -----------------------------------------------------

//Erzeugen des ersten Unter-Unterknotens: --------------

var subNode2:XMLNode = myXML.createElement("Kunde");

myXML.fi rstChild.fi rstChild.appendChild(subNode2);

// -----------------------------------------------------

var subNode3:XMLNode = myXML.createElement("Vorname");

ABBILDUNG 6.25

Der Knoten <Vorname> wurde eingefügt und ihm wurde ein Wert mithilfe eines Textknotens zuge-wiesen.

Page 305: Flash cs3, ajax und php

K A P I T E L 6292

myXML.fi rstChild.fi rstChild.fi rstChild.appendChild(subNode3);

var subNode3a:XMLNode = myXML.createTextNode(Vorname);

myXML.fi rstChild.fi rstChild.fi rstChild.childNodes[0].appendChild(subNode3a);

subNode3 = myXML.createElement("Nachname");

myXML.fi rstChild.fi rstChild.fi rstChild.appendChild(subNode3);

subNode3a = myXML.createTextNode(Nachname);

myXML.fi rstChild.fi rstChild.fi rstChild.childNodes[1].appendChild(subNode3a);

subNode3 = myXML.createElement("Firma");

subNode3a = myXML.createTextNode(Firma);

myXML.fi rstChild.fi rstChild.fi rstChild.childNodes[2].appendChild(subNode3a);

myXML.fi rstChild.fi rstChild.fi rstChild.appendChild(subNode3);

subNode3 = myXML.createElement("Adresse");

myXML.fi rstChild.fi rstChild.fi rstChild.appendChild(subNode3);

subNode3a = myXML.createTextNode(Adresse);

myXML.fi rstChild.fi rstChild.fi rstChild.childNodes[3].appendChild(subNode3a);

subNode3 = myXML.createElement("PLZ");

myXML.fi rstChild.fi rstChild.fi rstChild.appendChild(subNode3);

subNode3a = myXML.createTextNode(PLZ);

myXML.fi rstChild.fi rstChild.fi rstChild.childNodes[4].appendChild(subNode3a);

subNode3 = myXML.createElement("Ort");

myXML.fi rstChild.fi rstChild.fi rstChild.appendChild(subNode3);

subNode3a = myXML.createTextNode(Ort);

myXML.fi rstChild.fi rstChild.fi rstChild.childNodes[5].appendChild(subNode3a);

subNode3 = myXML.createElement("Staat");

myXML.fi rstChild.fi rstChild.fi rstChild.appendChild(subNode3);

subNode3a = myXML.createTextNode(Staat);

myXML.fi rstChild.fi rstChild.fi rstChild.childNodes[6].appendChild(subNode3a);

Page 306: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 293

subNode3 = myXML.createElement("email");

myXML.fi rstChild.fi rstChild.fi rstChild.appendChild(subNode3);

subNode3a = myXML.createTextNode(email);

myXML.fi rstChild.fi rstChild.fi rstChild.childNodes[7].appendChild(subNode3a);

Listing 6.33: Ein etwas mühseliges Skript zum Erzeugen des XML-Baums – das muss doch auch einfacher gehen ...

Alternative: Schleife statt stures Programmieren

Aus diesem Grund haben wir uns dafür entschieden, den eleganteren Weg zu gehen und diese Knoten über eine Schleife zu erzeugen. Um dies zu bewerkstelligen, gehen wir folgendermaßen vor:

Zunächst erzeugen wir ein Array, in dem die Namen aller einzulesenden Tags gespeichert sind.

var theNodes:Array = new Array("Vorname", "Nachname", "Firma", "Adresse", "PLZ", "Ort", "Staat", "email");

Danach gehen wir in einer Schleife alle Einträge dieses Arrays durch und schreiben die entsprechenden Daten in den XML-Baum:

var subNode3:XMLNode, subNode3a:XMLNode;

for(var i:Number=0; i<theNodes.length; i++) {

subNode3 = myXML.createElement(theNodes[i]);

myXML.fi rstChild.fi rstChild.fi rstChild.appendChild(subNode3);

subNode3a = myXML.createTextNode(eval(theNodes[i]));

myXML.fi rstChild.fi rstChild.fi rstChild.childNodes[i].appendChild(subNode3a);

}

Listing 6.34: Auszug aus dem Skript zum Erzeugen des XML-Baums (alternative Arbeitsweise zu Listing 6.33). Das Beispiel fi nden Sie auf der Buch-CD unter dem Namen XMLSend01a.fl a.

Die Methode eval()Wichtig in diesem Skriptblock beim Erzeugen des subNode3a ist die Methode eval(). Mit ihr wird es möglich, einen String als Variablennamen anzusehen und somit den Inhalt der Variablen auszulesen. Mit anderen Worten kann man sagen, dass ein String als Variable interpretiert wird.

Page 307: Flash cs3, ajax und php

K A P I T E L 6294

7. Versenden der XML-Date n

In beiden Fällen – ob nun mühselig oder leicht – fehlt noch der entscheidende Schritt des Versendens der XML-Daten.

Dieser Schritt ist wohl derjenige, der am einfachsten fällt. Die dafür vorgesehene Methode heißt send() und erwartet von uns minimal einen Parameter – die URL, an die die Daten verschickt werden sollen – und maximal zwei Parameter – als zweiten Parameter den Fensternamen aus HTML, in dem die URL dargestellt werden soll.

Möchte man, dass das „Empfängerdokument“ nur am Server verarbeitet, jedoch nicht für den User sichtbar dargestellt wird, muss man nur auf den zweiten Parameter verzichten:

myXML.send("parserXML01.php");

In diesem Fall werden demnach alle Informationen dem Dokument parserXML01.php übermittelt.

Daten mit PHP auswerten

Mit dem Zeitpunkt des Versendens der Daten aus der Flash-Datei heraus ist sämtliche Arbeit für den Flash-Entwickler erledigt. Bleibt noch zu klären, wie die Daten per PHP ausgewertet werden können.

Bevor wir nun das XML-Objekt aus Flash weiterverarbeiten können, müssen wir uns kurz Gedanken darüber machen, in welchem Format diese Daten von Flash an PHP übergeben werden.

Normalerweise übergibt Flash Daten vom Typ application/x-www-form-url-encoded. Wäre dies der Fall, würde PHP die Daten parsen und von der Variable $HTTP_RAW_POST_DATA in ein assoziatives Array namens $_POST verschieben.

Da aber der Flash-Programmierer durch die Angabe von myXML.contentType='text/html' den Datentyp in text/html geändert hat, bleiben die Daten in der Variable $HTTP_RAW_POST_DATA. Sie wissen nun also, dass wir die Daten von Flash über die Variable $HTTP_RAW_POST_DATA ansprechen können. Nun geht es daran, diese Daten auszulesen und anschließend in die Datenbank zu speichern.

Kein Zugriff auf $HTTP_RAW_POST_DATA?Sollten Sie auf $HTTP_RAW_POST_DATA nicht zugreifen können, kontrollieren Sie in der php.ini, ob die Einstellung always_populate_raw_post_data auf on gesetzt ist.

ABBILDUNG 6.29

Hier nun das fertige XML-Dokument, das für das

Versenden an eine PHP-Datei bereitsteht

Page 308: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 295

Für das Auslesen haben wir mehrere Möglichkeiten. Wir könnten über das DOM die Informationen bekommen oder auch aber über die neuen Funktionen von Sim-pleXML. (Zur Erinnerung: SimpleXML ist eine Funktionsbibliothek von PHP.) Nähe-res dazu haben Sie schon im Grundlagenteil der Programmierung erfahren. Ich schlage Ihnen vor, SimpleXML zu benutzen, da es – so finde ich – um einiges einfacher ist.

Gehen wir es an: Daten auslesen und in eine Datenbank speichern.

1. Daten aus Flash in einer Variable speichern

$XMLData = $HTTP_RAW_POST_DATA;

Um die XML-Daten anzusehen, können wir ganz einfach die Variable $XMLData über den echo-Befehl anzeigen lassen. Somit können wir uns auch die XML-Struktur anschauen.

2. SimpleXML-Objekt anlegen

SimpleXML bietet uns die Möglichkeit, über simplexml_load_string() ein XML-Objekt zu erstellen. Dieses Objekt werden wir $objKunde zuweisen.

$objKunde = simplexml_load_string($XMLData);

3. Auf die Daten in $objKunde zugreifen

Wir wissen, dass wir folgende Daten bekommen:

Vorname

Nachname

Firma

Adresse

Staat

PLZ

Ort

E-Mail

Zusätzlich wissen wir, dass wir immer nur die Daten eines Kunden bekommen. Somit greifen wir auf die XML-Daten des jeweiligen Knotens an der Stelle 0 zu.

Stellen Sie sich eine XML-Struktur am besten wie eine Ordnerstruktur im Windows-Explorer vor. Somit wäre der erste Ordner der Ordner „Kunden“. In diesem Ordner gibt es einen weiteren namens „Kunde“. Im Kunde-Ordner gibt es dann acht zusätzliche Ordner auf der gleichen Ebene, nämlich einen für Vorname, Nachname, Firma, Adresse, Staat, PLZ, Ort und E-Mail. Nun müssen wir nur noch dieser Struktur folgend von außen nach innen in PHP wandern, um an die richtigen Daten zu kommen. Aber bestimmt sind Sie mit der XML-Struktur schon so weit vertraut, dass dieses Thema für Sie keine Hürde mehr darstellt.

Page 309: Flash cs3, ajax und php

K A P I T E L 6296

Beginnen wir mit dem Vornamen des Kunden: Wir wissen, im Objekt $objKunde sind unsere XML-Daten gespeichert. Zusätzlich kennen wir die Struktur von „Kunden“ über „Kunde“ zu „Vorname“:

$vorname = $objKunde->Kunden[0]->Kunde[0]->Vorname;

Den Vornamen des Kunden speichern wir nun nur noch in eine Variable namens $vorname. Jetzt ist sicher auch klar, wie wir an die anderen Daten „Kunden“ herankommen:

$nachname = $objKunde->Kunden[0]->Kunde[0]->Nachname;

$fi rma = $objKunde->Kunden[0]->Kunde[0]->Firma;

$adresse = $objKunde->Kunden[0]->Kunde[0]->Adresse;

$staat = $objKunde->Kunden[0]->Kunde[0]->Staat;

$plz = $objKunde->Kunden[0]->Kunde[0]->PLZ;

$ort = $objKunde->Kunden[0]->Kunde[0]->Ort;

$email = $objKunde->Kunden[0]->Kunde[0]->email;

Das war’s auch schon – ging doch sehr einfach. Ein Lob an SimpleXML. Als Nächstes müssen wir noch die gewonnenen Daten in unsere Datenbank sichern.

4. Verbindung zur Datenbank

Wie gewohnt nehmen wir Kontakt zum Datenbankserver auf und verbinden uns mit einer dort befi ndlichen Datenbank:

$hostname = "IHR HOSTNAME";

$username = "IHR USERNAME";

$password = "IHR PASSWORT";

if(!$conn = mysql_connect($hostname, $username, $password)) {

die('<div class="error">Verbindung zur Datenbank konnte nicht hergestellt werden. Errorcode: '.mysql_error().'</div>');

}

Wir speichern den Rückgabewert in der Variable $conn. Danach überprüfen wir, ob $conn false ist. Ist das der Fall, wird mit der Funktion die() das Ausführen des Skripts abgebrochen und der Text „Verbindung zur Datenbank konnte nicht hergestellt werden.“ sowie der entsprechende Fehlercode ausgegeben.

5. Datenbank auswählen

Wenn das Verbinden erfolgreich war, müssen wir noch unsere gewünschte Datenbank am Server auswählen. Dazu nutzen wir die Funktion mysql_select_db(). Diese erwartet den Datenbanknamen und die Verbindungskennung, die wir zuvor realisiert haben.

Page 310: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 297

$db = "IHRE DATENBANK";

if(!mysql_select_db($db)) {

die('<div class="error">Die Datenbank '.$db.' konnte nicht ausgewaehlt werden. Errorcode: '.mysql_error().'</div>');

}

Da wir nun die Verbindung zu unserer gewünschten Datenbank hergestellt haben, können wir die XML-Daten in diese speichern.

6. Speichern der XML-Daten in die Datenbank

Dazu müssen natürlich in der Datenbank eine Tabelle und die notwendigen Felder angelegt sein. Wir haben bereits im Vorfeld eine Tabelle namens „tbl_kunden“ mit den Feldern „idP_Kunde“, „vc_Vorname“, „vcP_Nachname“, „vc_Adresse“, „vc_Staat“, „vc_PLZ“, „vc_Ort“ und „vc_email“ angelegt. Diesen Schritt müssten Sie also an dieser Stelle noch dazwischenschieben.

Über INSERT INTO tabellenname (tabellenfelder) VALUES (‚werte') können wir die Daten in unsere Datenbank speichern. Wir speichern dies als String in die Variable $sql ab.

$sql = "

INSERT INTO tbl_kunden

(vc_Vorname,vcP_Nachname,vc_Firma,vc_Adresse,vc_Staat,vc_PLZ,vc_Ort,vc_email)

VALUES

(‚$vorname','$nachname','$fi rma','$adresse','$staat','$plz','$ort','$email')

";

7. Anfrage an die Datenbank senden

Jetzt müssen wir noch die Anfrage an die Datenbank senden. Dazu nutzen wir mysql_query(). Dieser Funktion müssen wir unseren Anfragestring als Parameter angeben. Ist das Speichern der Daten erfolgreich, so liefert auch diese Funktion true zurück. Wenn nicht, brechen wir das Ausführen des Skripts wieder mit die() ab.

$rs = mysql_query($sql) or die ("Die Daten konnten nicht gespeichert werden.");

Das war’s auch schon. Jetzt sind unsere Daten des Kunden in der Datenbank gespeichert. Sämtliche Daten dieses Beispiels fi nden Sie selbstverständlich auf der Website zum Buch sowie auf der Buch-CD.

Page 311: Flash cs3, ajax und php

K A P I T E L 6298

6.3.4 Die XMLConnector -KomponenteFlash hat im Zusammenhang mit XML noch mehr zu bieten als das sture Parsen von XML-Daten. Seit der Version Flash MX 2004 stellt uns Adobe die XMLConnector-Komponente zur Seite, um auf einfache Art und Weise mit XML-Daten arbeiten zu können.

Komponenten gehören zur Symbolgruppe der MovieClips und stellen die Möglichkeit dar, während der Entwicklung parametergestützt Eigenschaften und Methoden zu erhalten. Mithilfe von ActionScript ist es uns jedoch auch möglich, diese Parameter zur Laufzeit zu ändern (das ist Ihnen sicherlich noch in Zusammenhang mit der TextArea-Komponente im Gedächtnis).

Die XMLConnector-Komponente gehört zur Gruppe der Data-Komponenten:

ABBILDUNG 6.30

Sämtliche Daten wurden von Flash an die PHP-Datei

parserXML01.php übergeben. Diese Datei sorgt dafür, dass

die Daten in die Datenbank gespeichert werden.

ABBILDUNG 6.31

Die Gruppe der Data-Komponenten beinhaltet

die von uns benötigte XMLConnector-Komponente.

Page 312: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 299

Grundsätzlich bietet uns diese XMLConnector-Komponente Zugriff auf eine beliebige externe Datenquelle, die XML-basierte Daten mittels HTTP bereitstellen (oder auch empfangen) können. Mithilfe eines sogenannten „Schemas“ wird die XML-Quelle dann ausgelesen – auf das Thema der Schemata kommen wir etwas später noch einmal zurück.

Wie im Umgang mit Komponenten üblich, wird eine Komponente in der Flash-Ent-wicklungsumgebung auf die Bühne gezogen. Dies ist im Allgemeinen nicht unbedingt erforderlich, denn wir können auch zur Laufzeit mithilfe von ActionScript Kompo-nenten erstellen, jedoch gehen wir diesen Weg, um uns das Vorgehen zunächst so einfach wie möglich zu gestalten. An welcher Stelle Sie die Komponente auf der Bühne platzieren, ist vollkommen irrelevant, da diese selbstverständlich nicht sichtbar ist:

Als Tipp gilt: Legen Sie die Komponente außerhalb des (sichtbaren) Bühnenbereichs ab, damit Sie diese während der Arbeit nicht irritiert.

Wie läuft nun die Arbeit mit einem XMLConnector ab? Die nachfolgende Auflistung sorgt für Klarheit:

1. Es wird eine Instanz der XMLConnector-Komponente auf (oder außerhalb) der Bühne platziert.

2. Der Instanz wird ein Instanzname zugewiesen.

ABBILDUNG 6.32

An welcher Stelle Sie die XMLConnector-Komponente einfügen, bleibt gänzlich Ihnen überlassen, da diese (siehe swf-Datei) selbstver-ständlich nicht sichtbar ist.

Page 313: Flash cs3, ajax und php

K A P I T E L 6300

3. Die Instanzparameter werden angegeben:

URL: Adresse, von wo die Instanz die XML-Datei bezieht.

direction: je nachdem, ob gesendet und geladen (send/receive), nur gela-den (receive) oder nur gesendet (send) werden soll. In den meisten Fällen wird nur geladen, deshalb ist die Einstellung receive wohl die gängigste.

ignoreWhite: Um Zeilenumbrüche, Leerzeichen etc. aus den Daten zu elimi-nieren, wird dieser Parameter auf true gesetzt. Diese Einstellung ist in jedem Fall zu empfehlen und auch deshalb standardmäßig auf true gesetzt.

multipleSimultaneousAllowed: bestimmt, ob mehrere Anfragen gleich-zeitig ablaufen dürfen. Da nicht garantiert werden kann, dass genau in der Reihenfolge der Aufrufe auch die Antworten eintreffen, und alle gängigen Browser eine höchstzulässige Anzahl an gleichzeitig herunterzuladenden URLs besitzen, spricht nichts dagegen, diesen Parameterwert auf false zu setzen. Ist der Parameter auf false gesetzt, wird der Aufruf über die Methode trigger durchgeführt, die wiederum ein status-Ereignis (CallAlreadyInProgress) ausgibt. Details hierzu finden Sie im ActionScript 2.0-Referenzhandbuch.

supressInvalidCalls: Mithilfe dieses Parameters wird sichergestellt, dass bei dem Wert true Aufrufe mit ungültigen Parametern erst gar nicht durch-geführt werden.

Die nachfolgende Abbildung verdeutlicht die bisher getroffenen Einstellungen für ein erstes Beispiel (auf der Buch-CD zu finden unter dem Namen XMLConnector01.fla):

u

u

u

u

u

ABBILDUNG 6.33

Die XMLConnector-Komponente wurde auf der

Bühne platziert (im Weiteren werde ich diese neben die

Bühne stellen, damit sie mich nicht irritiert) und es

wurden ihr alle notwendigen Parameter zugewiesen.

Als Quelle dient die Datei XMLConnector01.xml.

Page 314: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 301

XML- vs. Textdatei für das SchemaAn dieser Stelle sprechen wir zum ersten Mal von einer „echten“ XML-Datei: In unserem Kontext verstehen wir darin eine Datei, die nicht nur „gültig“ und „wohlgeformt“ ist, sondern auch die Endung .xml trägt. Obwohl eine Text- und eine XML-Datei dieselben Inhalte aufweisen können, benötigt Flash eine Datei mit der Endung .xml für eine Schema-Datei. Die eigentliche einzule-sende Datei (also unsere XML-Quelle) kann nach wie vor die Endung .txt tragen!

Damit wären die notwendigen Schritte getan – bleibt nur noch zu klären, wohin die Daten nun gelangen, denn ein Laden von Daten ohne zugehöriges Darstellen ist wohl in den wenigsten Fällen zielführend. Werfen wir einmal einen Blick auf die einzu-lesende Datei XMLConnector01.xml (bzw. XMLConnector01.txt, wenn Sie eine Text-datei einlesen möchten):

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>

<Mitarbeiterliste>

<Mitarbeiter>

<Vorname>Uwe</Vorname>

<Nachname>Mutz</Nachname>

<Firma>SYNE Marketing & Consulting GmbH</Firma>

<Adresse>Am Graben 29</Adresse>

<PLZ>4020</PLZ>

<Ort>Linz</Ort>

<Staat>AUT</Staat>

<email>[email protected]</email>

</Mitarbeiter>

<Mitarbeiter>

<Vorname>Alexander</Vorname>

<Nachname>Grasser</Nachname>

<Firma>SYNE Marketing & Consulting GmbH</Firma>

<Adresse>Am Graben 29</Adresse>

<PLZ>4020</PLZ>

<Ort>Linz</Ort>

<Staat>AUT</Staat>

<email>[email protected]</email>

</Mitarbeiter>

<Mitarbeiter>

<Vorname>Doris</Vorname>

Page 315: Flash cs3, ajax und php

K A P I T E L 6302

<Nachname>Manzenreiter</Nachname>

<Firma>SYNE Marketing & Consulting GmbH</Firma>

<Adresse>Am Graben 29</Adresse>

<PLZ>4020</PLZ>

<Ort>Linz</Ort>

<Staat>AUT</Staat>

<email>[email protected]</email>

</Mitarbeiter>

</Mitarbeiterliste>

Listing 6.35: Eingelesen wird eine nicht allzu aufregend komplexe XML-Datei: eine Mitarbeiterliste mit drei Mitarbeitern (XMLConnector01.xml).

Es wird also Zeit, den nächsten Schritt zu tun: Wir müssen ein Schema angeben. Ein Schema gibt an, wie die einzulesende XML-Quelle aufgebaut ist oder mit anderen Worten: wie die XML-Quelle strukturiert ist (Verschachtelungen, Tags, Attribute). Hierzu blenden wir uns erst einmal den Komponenten-Inspektor ein (entweder in der Menüzeile auf FENSTER/KOMPONENTEN-INSPEKTOR oder unter Windows die Tastenkom-bination (ª)+(F7) bzw. unter Mac OS die Tastenkombination (†)+(F7)):

ABBILDUNG 6.34

Der Komponenten-Inspektor im Fall der XMLConnector-

Komponente

In der obigen Abbildung sehen Sie die erste Lasche PARAMETER des Komponenten-Inspektors, deren Einträge wir auch im Eigenschaften-Inspektor zur Komponenten-Instanz gefunden haben. Interessanter werden die Laschen BINDUNGEN und SCHEMA.

Beginnen wir mit der SCHEMA-Lasche: Markieren Sie den Eintrag < RESULTS : XML, kli-cken Sie auf das Flyout-Menü und wählen Sie dort den Eintrag XML-SCHEMA IMPOR-

Page 316: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 303

TIEREN aus. Es öffnet sich ein Fenster, in dem Sie eine XML-Datei auswählen können, woraus das XML-Schema importiert wird. Wie schon weiter oben erwähnt, können Sie nur Dateien mit der Endung .xml auswählen. Für unser Beispiel importieren wir also der Einfachheit halber genau unsere Quelldatei XMLConnector01.xml, deren Schema sofort auch im Komponenten-Inspektor angezeigt wird:

Wenn wir nun dieses Schema mit der Quelldatei vergleichen, fällt sofort auf, dass nur die Tags Mitarbeiterliste, Mitarbeiter, Vorname, Nachname und Firma einge-lesen wurden – da fehlt doch was?! Es fehlen die Tags PLZ, Ort, Staat und Email! Gehen wir der Sache auf den Grund.

Der Fehler liegt anscheinend am Inhalt der XML-Datei: Im Firmennamen „SYNE Marketing & Consulting GmbH“ wird ein kaufmännisches Und „&“ verwendet, das das Einlesen des Schemas blockiert. Um diese Fehlerquelle zu eliminieren, müssen wir das „&“ URL-codieren: Der entsprechende Code lautet %26. Somit würde sich unsere XML-Datei (das Schema!) wie folgt ändern (Auszug aus der Datei XMLConnector01b.xml):

...

<Mitarbeiter>

<Vorname>Uwe</Vorname>

<Nachname>Mutz</Nachname>

<Firma>SYNE Marketing %26 Consulting GmbH</Firma>

<Adresse>Am Graben 29</Adresse>

<PLZ>4020</PLZ>

Fehler in der Quelldatei oder im Schema?

Fehler in der Quelldatei oder im Schema?

ABBILDUNG 6.35

Nach dem Importieren des Schemas zeigt der Komponenten-Inspektor den Aufbau (= Schema) der XML-Datei an.

Page 317: Flash cs3, ajax und php

K A P I T E L 6304

<Ort>Linz</Ort>

<Staat>AUT</Staat>

<email>[email protected]</email>

</Mitarbeiter>

...

Listing 6.36: Auszug aus der nun URL-codierten Datei XMLConnector01b.xml: Das kaufmännische Und „&“ wurde durch den Code %26 ersetzt. Bitte beachten Sie jedoch die nachfolgende Aufl istung, denn nicht alles, was als Fehler erscheint, ist auch ein Fehler!

An dieser Stelle möchte ich Sie auf einen meines Erachtens sehr wichtigen Punkt hin-weisen, der immer wieder zu Verwechslungen führt:

Das Schema einer einzulesenden XML-Datei sollte idealerweise nur das „Gerüst“ (die Struktur) der einzulesenden XML-Quelle beinhalten – somit besitzt die Sche-ma-Datei keinerlei Inhalte. Im obigen Beispiel haben wir nur zu gut erfahren, zu welchen Problemen das führt! Des Weiteren müssen wir beachten, dass das Schema eine Datei mit der Endung .xml ist.

Die einzulesende XML-Quelle ist nach der von der Schema-Datei vorgegebenen Struktur aufgebaut und beinhaltet (klarerweise) sämtliche Inhalte. Diese Datei kann eine beliebige Dateiendung aufweisen (.xml, .txt, .php etc.), solange diese Daten XML-konform sind (Thema „Gültig“ und „Wohlgeformt“).

Somit würde sich als XML-Schema eine Datei mit folgendem Inhalt anbieten:

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>

<Mitarbeiterliste>

<Mitarbeiter>

<Vorname />

<Nachname />

<Firma />

<Adresse />

<PLZ />

<Ort />

<Staat />

<email />

</Mitarbeiter>

</Mitarbeiterliste>

Listing 6.37: Ein korrektes XML-Schema (und das wollten wir ja auch!), eine sinnlose XML-Quelle!

u

u

XML-Quelle vs. XML-Schema

XML-Quelle vs. XML-Schema

Page 318: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 305

Beim Importieren dieses Schemas sind jedoch ein paar zusätzliche Schritte erforder-lich:

1. Da die Felder nun ohne Inhalte sind, muss für jedes Feld der Feldtyp (Number, String etc.) angegeben werden, ansonsten würde Flash davon ausgehen, dass diese Felder leer sein müssen. Würden wir ein Schema mit Inhalten importieren, würde Flash die eingelesenen Inhalte analysieren und einen entsprechenden Feldtyp automatisch wählen.

2. Da das Tag <Mitarbeiterliste> aus nur einem verschachtelten Tag <Mitarbeiter> besteht, nimmt Flash automatisch an, dass immer nur ein Tag (und nicht eine Liste von Tags) eingelesen werden muss.

In der Abbildung 6.36 sehen Sie einen Screenshot, wie Flash mit diesem Schema arbei-ten würde:

Um den Tags einen Feldtypen zuzuweisen, klicken Sie auf den Feldnamen und wählen in der Parameterliste darunter den Eintrag DATA TYPE aus. In unserem Fall sind alle Einträge vom Typ STRING:

ABBILDUNG 6.36

Flash geht davon aus, dass die eingelesenen Tags Vorname, Nachname etc. immer leer sind. Unsere Aufgabe wird sein, den Feldern den zugehörigen Datentyp zuzuweisen.

Page 319: Flash cs3, ajax und php

K A P I T E L 6306

Diesen Vorgang müssen wir nun für alle Felder wiederholen. Ist dies geschehen, müs-sen wir Flash noch zu verstehen geben, dass wir mehr als nur einen einzelnen Eintrag einlesen werden. Hierzu markieren wir den Eintrag MITARBEITER : OBJECT und wählen in der Parameterliste als DATA TYPE den Typ ARRAY (anstatt OBJECT):

ABBILDUNG 6.37

Das Feld Vorname bekommt den Feldtyp String zuge-

wiesen.

ABBILDUNG 6.38

Mit Angabe des Datentyps Array geben wir Flash zu

verstehen, dass es sich nicht um ein einzelnes Objekt han-delt, das wir einlesen werden,

sondern vielmehr um eine Liste von Objekten.

Haben wir diesen Schritt geschafft, geht es daran, die eigentlichen Daten einzulesen und anzuzeigen. Wir machen uns die Sache einfach und wählen für die Anzeige eine Tabellenform. Zunächst einmal ein Screenshot des Ergebnisses:

Page 320: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 307

Unter den KOMPONENTEN finden Sie die Komponentengruppe USER INTERFACE und darin die Komponente DATAGRID. Ziehen Sie eine Instanz davon auf die Bühne, geben Sie ihr einen Namen (z.B. Mitarbeitertabelle) und weisen Sie ihr eine entspre-chende Größe zu (in meinem Fall waren das 590x350 Pixel bei einer Bühnengröße von 600x400 Pixel). Markieren Sie danach wieder die Instanz unseres XMLConnector und weisen Sie ihr – sollten Sie das nicht bereits gemacht haben – einen Instanznamen zu (beispielsweise myXMLConnector). Gehen Sie anschließend wie folgt vor:

1. Wählen Sie für myXMLConnector im Komponenten-Inspektor die Lasche BINDUNGEN aus.

2. Klicken Sie auf das blaue Symbol „+“ zum Hinzufügen einer neuen Bindung:

ABBILDUNG 6.39

Einlesen einer XML-Datei (basierend auf einem vor-gegebenen Schema) und Darstellen der Daten in Tabellenform (es kommt ein sogenanntes „DataGrid“ zur Verwendung). Eingelesen wird nach wie vor die Datei XMLConnector01.xml, die auch die kaufmännischen Und „&“ beinhaltet – diese waren ja nur für unser Schema gefährlich ...

ABBILDUNG 6.40

Hinzufügen einer neuen Bindung durch Klicken auf das blaue „+“

Page 321: Flash cs3, ajax und php

K A P I T E L 6308

3. Wählen Sie aus der möglichen Bindung den Eintrag MITARBEITER : ARRAY aus und bestätigen Sie mit OK:

4. Markieren Sie die so entstandene Bindung, wählen Sie in den Parametern zunächst für den Parameter DIRECTION den Wert out und klicken Sie dann im Parameterfeld BOUND TO auf die Suchlupe ganz rechts im Feld. Es öffnet sich ein Fenster mit den möglichen Komponenten, wo Sie die DataGrid-Komponente auswählen:

ABBILDUNG 6.41

Auswählen der Liste an Mitarbeitern (Array) für die

Anzeige im DataGrid

ABBILDUNG 6.42

Die Daten werden mithilfe des Parameters BOUND TO dem

DataGrid „Mitarbeitertabelle“ zugewiesen.

Somit haben wir sämtliche Arbeit an sowohl dem XML-Connector als auch dem DataGrid erledigt. Testen wir jedoch unser Beispiel, werden wir feststellen, dass trotz-dem nichts passiert. Das liegt daran, dass das Einlesen der Daten aus der XML-Quelle nicht automatisch passiert, sondern „angestoßen“ werden muss. Der geeignete Befehl ist hierfür der Befehl trigger, der auf di e Instanz der XMLConnector-Komponente myXMLConnector angewandt wird:

Page 322: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 309

myXMLConnector.trigger();

Listing 6.38: Erst die Methode trigger veranlasst Flash, die XML-Quelle einzulesen und in das DataGrid zu schreiben.

Das Ergebnis sahen Sie bereits in Abbildung 6.39.

Letzten Endes ist das Arbeiten mit Komponenten immer dann anzuraten, wenn es schnell gehen soll und man nicht allzu viel Zeit mit Programmierung „vergeuden“ möchte. Wenn wir ehrlich sind, war das letzte Beispiel mehr „Drag&Drop“ als ernste Entwicklung. Doch wie gesagt: Wenn es die Aufgabenstellung erfordert, ist auch gegen „Drag&Drop“ nichts einzuwenden!

Neben der hier vorgestellten DataGrid-Komponente existieren noch einige weitere User Interface-Komponenten, die für die Darstellung von XML-Daten hervorragend geeignet sind:

Komponente Beschreibung

Accordion Darstellen von Daten in Form von Bereichen, die angeklickt werden und sich dann wie ein Akkordeon aufklappen

Tree Darstellen von Daten in Form einer Baumstruktur (vergleichbar mit dem Windows Explorer, sollten Sie diesen kennen)

Tabelle 6.3: Komponenten zur Darstellung von (beispielsweise) XML-Daten

Ein guter Anhaltspunkt, das Arbeiten mit Komponenten zu intensivieren, ist die Beispielsammlung von Adobe, die Sie auf der Adobe-Website finden: http://www.adobe.com/de/devnet.

6.4 ActionScript 3.0: Neues und ÄnderungenIn diesem Kapitel befassen wir uns mit den Änderungen und Neuerungen, die Action-Script 3.0 mit sich bringt.

6.4.1 Das URLLoader - und URLRequest -ObjektIn den bisherigen Ausführungen (Verwendung von ActionScript 2.0) erfuhren Sie, wie man für ein gegebenes Objekt – sei es ein LoadVars- oder XML-Objekt – geeignete (objektspezifische) Methoden verwendet, um die benötigten Daten zu laden. Der Nachteil an diesen Methoden war, dass diese sich immer auf das Objekt selbst bezogen haben: XML.load() hatte mit LoadVars.load() bis auf den (zufälligerweise) glei-chen Namen nichts gemeinsam.

Drag&Drop oder Program-mierung?

Drag&Drop oder Program-mierung?

Page 323: Flash cs3, ajax und php

K A P I T E L 6310

Dies ändert sich mit ActionScript 3.0 gewaltig, denn ab nun existiert ein einziges Objekt zum Laden von externen Daten: das URLLoader-Objekt. Das bisher bekannte LoadVars-Objekt ist zur Gänze eliminiert worden. Im Klartext bedeutet dies, dass das Laden externer Daten nun vollständig über das URLLoader-Objekt (in Verbindung mit dem URLRequest-Objekt, auf das wir noch zu sprechen kommen) abgewickelt wird!

Die Übersicht der Eigenschaften, Methoden und Ereignisse liefert uns einen Hinweis über die Möglichkeiten dieses Objekts:

Eigenschaft Typ und Standardwert Beschreibung

bytesLoaded uint = 0 Stellt die Anzahl der Bytes dar, die bereits geladen wurden

bytesTotal uint = 0 Stellt die Anzahl der gesamt zu ladenden Bytes dar (sprich: die Dateigröße)

data * Repräsentiert die empfangenen Daten

dataFormat String = "text" Gibt an, von welchem Typ die zu ladenden Daten sind. Folgende Typen sind möglich:

TEXT

BINARY

VARIABLES

Tabelle 6.4: Eigenschaften des URLLoader-Objekts

Vorrangig wichtige Eigenschaften sind also data und dataFormat. Die Eigenschaften bytesLoaded und bytesTotal benötigen Sie für den Fall, dass Sie dem User eine Ladestandsanzeige darstellen wollen.

Methode Beschreibung

URLLoader(request:URLRequest = null) Erzeugt ein URLLoader-Objekt, dem ein URLRequest-Objekt zugewiesen werden kann

close():void Beendet einen laufenden Ladevorgang

load(request:URLRequest):void Sendet und lädt Daten von der im URLRequest angege-benen URL

Tabelle 6.5: Methoden des URLLoader-Objekts

Ereignis Ereignisobjekttyp und -eigenschaft

Beschreibung

complete Event.COMLETE Wird ausgelöst, wenn der Ladevorgang abgeschlossen und sämtliche Daten dekodiert wurden sowie sämtliche empfan-genen Daten in der Eigenschaft data des URLLoader gespeichert wurden. Dieses Ereignis gilt es also – wie auch schon weiter oben beschrieben – abzuwarten.

LoadVars in ActionScript

3.0 nicht mehr existent!

LoadVars in ActionScript

3.0 nicht mehr existent!

Page 324: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 311

httpStatus HTTPStatusEvent.HTTP_STATUS Sollte ein URLLoader-Objekt per HTTP auf Daten zugreifen wollen und der Flash-Player in der Lage sein, den Statuscode zu erkennen und zurückzugeben, wird dieses Ereignis ausgelöst. Die wichtige Eigenschaft in diesem Fall ist die Eigenschaft status.

ioError IOErrorEvent.IO_ERROR Tritt auf, wenn während eines Ladeversuchs ein schwerwie-gender Fehler auftritt und der Download abgebrochen werden musste. Wichtig ist die Eigenschaft text.

open Event.OPEN Tritt nach dem Aufruf der load-Methode auf.

progress ProgressEvent.PROGRESS Tritt auf, wenn Daten während eines Ladevorgangs empfan-gen werden. Die wichtigen Eigenschaften sind bytesLoaded und bytesTotal. Dieses Ereignis tritt wiederholt auf.

securityError SecurityErrorEvent.SECURITY_ERROR

Tritt auf, wenn versucht wird auf Daten zuzugreifen, die nicht innerhalb des Sicherheitskreises („Security Sandbox“) der Flash-Anwendung liegen. Wichtig ist in diesem Fall wie auch bei ioError die Eigenschaft text.

Tabelle 6.6: Übersicht der Ereignisse des URLLoader-Objekts

Das URLRequest-Objekt hält mehrere Eigenschaften für uns bereit, die in Tabelle 6.7 beschrieben sind.

Eigenschaften Typ Beschreibung

contentType String Liefert den MIME-Typ eventueller POST-Daten

data Object Die angeforderten Daten

method String Legt die Übertragungsmethode fest. Mögliche Werte sind „GET“ oder „POST“.

prototype Object Verweist auf das Prototypobjekt der Klasse

requestHeaders Array Mithilfe dieses Arrays lässt sich der HTTP-Header manipulieren.

url String Die URL, die für das Senden oder Empfangen von Daten verwendet wird

Tabelle 6.7: Eigenschaften des URLRequest-Objekts. Besonders interessant sind die Eigenschaften data, method und url.

Page 325: Flash cs3, ajax und php

K A P I T E L 6312

Laden von Daten

Werfen wir einen Blick auf die Vorgehensweise beim Laden von Daten:

1. Anlegen eines URLLoader-Objekts:

var myLoader:URLLoader = new URLLoader();

2. Anlegen eines URLRequest-Objekts zur Angabe einer Quelle:

var myURL:URLRequest = new URLRequest("URL_ZUR_QUELLE");

3. Defi nieren eines Eventhandler für den Fall, dass die Daten geladen wurden. Es kommt das Ereignis COMPLETE zum Einsatz:

function FUNKTIONSNAME_DES_HANDLERS(myEvent:Event):void {

...

}

myLoader.addEventListener(Event.COMPLETE, FUNKTIONSNAME_DES_HANDLERS);

Listing 6.39: Beachten Sie in diesem Listing bitte die Tatsache, dass der Typ void nun – im Gegensatz zu ActionScript 2.0 – klein geschrieben wird.

4. Ladevorgang starten, basierend auf den Angaben in der URLRequest-Instanz (myURL):

myLoader.load(myURL);

Wie Sie sehen, wird an dieser Stelle noch kein Wort darüber verloren, welche Art von Daten sich in der Datenquelle befinden. Lediglich die Voraussetzung, dass es sich um Text, Binärdaten oder URL-codierte Variablen handelt, muss erfüllt sein. Zusammen-gefasst sieht ein Ladevorgang nun also folgendermaßen aus:

var myLoader:URLLoader = new URLLoader();

var theURL:String = "URL_ZUR_QUELLE";

var myURL:URLRequest = new URLRequest(theURL);

function completelyLoaded(myEvent:Event):void {

...

}

myLoader.addEventListener(Event.COMPLETE, completelyLoaded);

myLoader.load(myURL);

Listing 6.40: Der Ladevorgang von Text, Binär- oder URL-codierten Daten in ActionScript 3.0. Den Umgang mit den Eventlistenern sehen Sie in Listing 6.41 sehr ausführlich.

Laden von Text, Binärdaten oder

URL-codierten Daten

Laden von Text, Binärdaten oder

URL-codierten Daten

Page 326: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 313

Erst im nächsten Schritt wird entschieden, was mit den eingelesenen Daten geschehen soll. Still und heimlich haben wir bisher noch vorausgesetzt, dass die einzulesenden Daten Textdaten sind – wären es Binär- oder URL-codierte Daten, so müssten wir das explizit angeben.

Um als Beispiel einmal die in Tabelle 6.6 aufgelisteten Ereignisse abzufragen, müssen diese über die Methode addEventListener einer URLLoader-Instanz zugewiesen werden. Das könnte folgendermaßen aussehen (das Beispiel finden Sie auf der Buch-CD unter dem Namen URLLoader02_AS3.fla):

var myLoader:URLLoader = new URLLoader();

var theURL:String = "URLLoader02_AS3.xml";

var myURL:URLRequest = new URLRequest(theURL);

function EOpen(myEvent:Event):void {

statusMsg.appendText("Ladevorgang gestartet\n");

}

function EProgress(myEvent:ProgressEvent):void {

statusMsg.appendText("Ladevorgang läuft... Fortschritt: "+Math.round(myEvent.bytesLoaded/myEvent.bytesTotal*100)+"%\n");

}

function EComplete(myEvent:Event):void {

statusMsg.appendText("Ladevorgang abgeschlossen\n");

}

function EHttpStatus(myEvent:HTTPStatusEvent):void {

statusMsg.appendText("Http-Status eingelangt: Status="+myEvent.status+"\n");

}

function EIOError(myEvent:IOErrorEvent):void {

statusMsg.appendText("IO-Error aufgetreten: Error="+myEvent.text+"\n");

}

function ESecurityError(myEvent:SecurityErrorEvent):void {

statusMsg.appendText("Security-Error aufgetreten: Error="+myEvent.text+"\n");

}

myLoader.addEventListener(Event.OPEN, EOpen);

myLoader.addEventListener(ProgressEvent.PROGRESS, EProgress);

myLoader.addEventListener(Event.COMPLETE, EComplete);

Page 327: Flash cs3, ajax und php

K A P I T E L 6314

myLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, EHttpStatus);

myLoader.addEventListener(IOErrorEvent.IO_ERROR, EIOError);

myLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, ESecurityError);

myLoader.load(myURL);

Listing 6.41: Für jedes auftretende Ereignis des URLLoader-Objekts wurde ein eigener Eventlistener defi -niert. Zu beachten ist vor allem, dass die verschiedenen Ereignisse von verschiedenen Ereignisobjekttypen abgearbeitet werden.

Hier einige Tipps für den Umgang mit den verschiedenen Ereignissen:

Ladefortschritt anzeigen

ProgressEvent.PROGRESS sowie die Eigenschaften bytesLoaded und bytesTotal geben Ihnen Auskunft über den Ladezustand. Da dieses Ereig-nis wiederholt auftritt, kann sehr einfach eine Ladefortschrittsanzeige erstellt werden.

Event.COMPLETE teilt Ihnen mit, wann das Laden der Daten beendet ist.

Errorhandling

IOErrorEvent.IO_ERROR und SecurityErrorEvent.SECURITY_ERROR mit dem Ereignis text (in beiden Fällen) lässt eine Fehlerabarbeitung zu.

Event.COMPLETE teilt Ihnen mit, wann das Laden der Daten zu Ende ist.

Kümmern wir uns im nächsten Schritt um die eingelesenen Daten. In den meisten Fällen wird es sich um textbasierte oder URL-codierte Daten handeln, deshalb ste-hen diese Anwendungsgebiete auch bei uns im Vordergrund. XML-Daten und deren Auswertung nehmen wir uns in Kapitel 6.4.2 sehr ausführlich zur Brust, den Part des Ladens der Variablen bzw. des Textes behandeln wir gleich hier.

Der Zugriff auf die geladenen Daten erfolgt in jedem Fall über die Eigenschaft data des URLLoader-Objekts, die idealerweise beim Auftreten des Eevent.COMPLETE-Ereignisses ausgelesen wird (target ist in diesem Fall das Netzwerkobjekt, über wel-ches der Ladevorgang abgewickelt wurde):

function EComplete(myEvent:Event):void {

trace(myEvent.target.data);

}

Listing 6.42: Zugriff auf die geladenen Daten

Laden von URL-codierten Daten (Variablen)

In diesem Fall muss der URLLoader-Instanz zunächst mitgeteilt werden, dass die zu ladenden Daten URL-codiert sind:

u

u

u

u

u

u

Page 328: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 315

var myLoader:URLLoader = new URLLoader();

myLoader.dataFormat = URLLoaderDataFormat.VARIABLES ;

Listing 6.43: Das Datenformat wird auf „URL-codierte Variablen“ (VARIABLES) gesetzt.

Als Beispiel einzulesender (URL-codierter) Daten soll uns die Datei URLLoader03_AS3.txt mit folgendem Inhalt dienen:

test=1&vorname=Uwe&nachname=Mutz

Der Zugriff auf die Variablen erfolgt wie in Listing 6.43 dargestellt über die data-Eigenschaft der URLLoader-Instanz:

function EComplete(myEvent:Event):void {

... = myEvent.target.data;

}

Um nun eine spezielle Variable aus der geladenen Datei abzufragen, kann die Variable direkt angesprochen werden. Wollen wir beispielsweise die Variable „nachname“ aus-lesen, geschieht dies wie folgt:

...

var nn:String = myEvent.target.data.nachname;

trace("nn="+nn);

...

Listing 6.44: Zugriff auf die Variable „nachname“

Damit sind wir auch schon wieder am Ende angelangt, denn sobald wir wissen, wie die Variablen angesprochen werden können, läuft das Spiel genau wie in den Beispielen aus Kapitel 6.2.

Laden von Textdaten

Da das Laden von textbasierten Daten standardmäßig vom URLLoader-Objekt ange-nommen wird, müssen wir dies nicht explizit angeben, obwohl man es theoretisch natürlich könnte:

var myLoader:URLLoader = new URLLoader();

myLoader.dataFormat = URLLoaderDataFormat.TEXT ;

Listing 6.45: Das Setzen des Datenformats ist im Fall von textbasierten Daten nicht notwendig, da dies die Standardeinstellung ist. Somit könnten Sie getrost auf Zeile 2 des obigen Listings verzichten.

Die einzulesende Datei URLLoader04_AS3.txt, die uns hier als Beispiel dient, hat fol-genden Inhalt:

Page 329: Flash cs3, ajax und php

K A P I T E L 6316

Dies ist Text, den es einzulesen gilt. Mal sehen, ob es uns gelingen wird... Zu allem Überfl uss kommen auch noch Umlaute und Sonderzeichen vor.

Uwe Mutz

SYNE Marketing & Consulting GmbH

Listing 6.46: Inhalt der Datei URLLoader04_AS3.txt – beachten Sie die Leer- und Sonderzeichen sowie die Umlaute.

Wie auch schon beim Laden von URL-codierten Daten greifen wir auf die Eigenschaft data der URLLoader-Instanz zu. Wir können uns glücklich schätzen, wie einfach das Laden von Textdaten ist, denn mit dem Zugriff auf data ist die Arbeit für uns getan – sogar Leer- und Sonderzeichen sowie Umlaute bereiten uns keine Sorgen. Sehen Sie selbst – zuerst der Code der Datei URLLoader04_AS3.fla, dann der Screenshot. Kurz noch zur Erklärung: statusMsg bezeichnet eine TextArea-Instanz, die uns zur Ausga-be der Daten dient.

var myLoader:URLLoader = new URLLoader();

//myLoader.dataFormat = URLLoaderDataFormat.TEXT; //Standardwert

var theURL:String = "URLLoader04_AS3.txt";

var myURL:URLRequest = new URLRequest(theURL);

function EComplete(myEvent:Event):void {

statusMsg.appendText("Ladevorgang abgeschlossen\n");

statusMsg.appendText("Eingelesener Text:\n"+myEvent.target.data);

}

myLoader.addEventListener(Event.COMPLETE, EComplete);

myLoader.load(myURL);

Listing 6.47: Laden von externen Textdaten – wie einfach die Welt doch sein kann! In der Datei auf der Buch-CD ist das Beispiel noch um ein Eventhandling erweitert.

Page 330: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 317

Vielleicht sollten wir an dieser Stelle einmal festhalten, dass dieses Verfahren ein Novum in der Geschichte von Flash darstellt: Ohne den Text innerhalb der Text datei einer Variable zuzuweisen und diese dann auszulesen, haben wir nun Zugriff auf Texte!

Senden von Daten

Gehen wir den umgekehrten Weg und betrachten das Senden von Daten an einen Ser-ver (sprich: ein serverseitiges Script). Da wir bisher noch keine Möglichkeit kennen-gelernt haben, die zu versendenden Variablen zu definieren (erinnern Sie sich: im Fall von ActionScript 2.0 und dem LoadVars-Objekt mussten wir lediglich die Variablen innerhalb einer LoadVars-Instanz anlegen – fertig!), muss es wohl einen anderen Weg geben ... dieser Weg heißt URLVariables. Mit anderen Worten: Eine Instanz des URL-Variables-Objekts dient uns nun als Container für die zu versendenden Variablen.

Nehmen wir an, wir wollen die Variablen „Vorname“ und „Nachname“ an ein server-seitiges Script übermitteln. Also nichts wie rein mit den Variablen in unseren Contai-ner:

var myVars:URLVariables = new URLVariables();

myVars.Vorname = "Uwe";

myVars.Nachname = "Mutz";

Listing 6.48: Die Verwendung des URLVariables-Objekts ist denkbar einfach: Instanz anlegen, Variablen darin anlegen und ihnen einen Wert zuweisen.

Wie wir wissen, wird das URLRequest-Objekt zum Laden und Senden von Daten ver-wendet. In Tabelle 6.7 haben wir uns über die Verwendung der Konstanten GET und POST Gedanken gemacht – genau dieses Thema müssen wir nun berücksichtigen: Sollen die Daten später per POST oder GET versandt werden?

ABBILDUNG 6.43

Na, was sagen Sie – Laden von Textdaten ohne umständliche Variablenzuweisung, wie es noch in ActionScript 2.0 not-wendig war!

Page 331: Flash cs3, ajax und php

K A P I T E L 6318

Schritt 2 in unserem Beispiel umfasst demnach das Anlegen einer neuen URLRequest-Instanz und das Festlegen der Übertragungsmethode über die Eigenschaft method:

var myURL:URLRequest = new URLRequest();

myURL.method = "GET";

Listing 6.49: Eine neue URLRequest-Instanz wurde erzeugt und es wurde ihr die Übertragungsmethode GET zugewiesen.

Jetzt müssen wir die beiden Objekte URLVariables und URLRequest noch „zusam-menbringen“, sodass die URLRequest-Instanz die angelegten Variablen später auch versenden kann. Das korrekte Decodieren der Daten (in beispielsweise URL-codierte Form) geschieht dabei ganz automatisch:

myURL.data = myVars;

Listing 6.50: Der URLRequest-Instanz myURL werden über die Eigenschaft data alle in myVars er-zeugten Variablen zugewiesen.

Alle Vorbereitungen für das Versenden der Daten sind nun erledigt – bleibt zu klären, zu welchem Zweck die Daten versandt werden sollen. Hier einige Möglichkeiten:

Daten an ein serverseitiges Script übergeben, das die Daten dann weiterverarbei-tet: Ein Beispiel dafür wäre das Speichern der Daten in einer Datenbank oder das Überprüfen der Daten für ein eventuelles Login.

Daten an ein Dokument übergeben und dieses in einem neuen Fenster öffnen. Soll-ten die Daten per GET übergeben worden sein, so können diese sowohl server- als auch clientseitig verarbeitet werden.

Variante 1: Daten senden mit dem URLLoader-Objekt

Vielleicht kommt es Ihnen eigenartig vor, dass wir ein Objekt mit dem Wort „Loa-der“ im Namen zum Versenden von Daten verwenden. Ganz so abwegig ist die Sache jedoch nicht, da ein URLLoader nach dem Senden eine etwaige Antwort des Servers empfängt und somit „lädt“. Alle weitere Arbeit mit dem URLLoader-Objekt erfolgt wie gehabt, denn dem URLRequest-Objekt wurden bereits alle Variablen zum Versenden zugewiesen:

var theURL:String = "urlvariables01.php";

myURL.url = theURL;

var myLoader:URLLoader = new URLLoader();

function EOpen(myEvent:Event):void {

statusMsg.appendText("Ladevorgang gestartet\n");

}

u

u

Page 332: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 319

function EComplete(myEvent:Event):void {

statusMsg.appendText("Ladevorgang abgeschlossen\n");

statusMsg.appendText("Rückgabetext der PHP-Datei:\n"+myEvent.target.data);

}

myLoader.addEventListener(Event.OPEN, EOpen);

myLoader.addEventListener(Event.COMPLETE, EComplete);

myLoader.load(myURL);

Listing 6.51: Fortsetzung des angefangenen Scripts. Den gesamten Code fi nden Sie in der Datei URLVaria bles01_AS3.fl a.

Die Eigenschaft url ist zwar schon hinlänglich bekannt, jedoch ist die hier angespro-chene URL ein Verweis auf die Datei (in unserem Fall handelt es sich um urlvariab-les01.php), welche die gesendeten Daten entgegennimmt und entsprechend auswertet. Hier deren Inhalt:

$returner = "ERROR (0)";

if(count($_REQUEST)>0) {

$returner = "empfangende Daten:\n";

foreach($_REQUEST as $itm=>$val) {

$returner.= "$itm=$val\n";

}

}

else { $returner = "ERROR (1)"; }

echo($returner);

Listing 6.52: Die Datei urlvariables01.php nimmt etwaig gesendete Daten gleich welcher Sendemethode (GET oder POST) entgegen und erzeugt hieraus eine Variable $returner, die im Weiteren per echo in den Ausgabepuffer der Datei geschrieben wird.

Das PHP-Script setzt zunächst eine Variable $returner auf den Wert „ERROR (0)“, der uns mitteilt, dass ein unbekannter Fehler aufgetreten ist. Danach wird überprüft, ob Daten per POST oder GET gesendet wurden (diese müssten sich dann im $_REQUEST-Array befinden und somit müsste das Array eine Länge größer null aufwei-sen). Ist dies nicht der Fall, dann wird $returner der Wert „ERROR (1)“ zugewiesen. Wurden jedoch Daten übermittelt, wird $returner dazu verwendet, einen String aus den gesandten Daten zusammenzustellen. Dieser String bzw. die Fehlerkennzeichnung „ERROR (0)“ oder „ERROR (1)“ wird am Ende des Scripts per echo ausgegeben: echo($returner);.

Page 333: Flash cs3, ajax und php

K A P I T E L 6320

Zurück zu Flash. Das URLLoader-Objekt nimmt den von der PHP-Datei erzeugten String entgegen und gibt den String in der TextArea statusMsg aus – all dies ist in der Funktion EComplete zu finden.

Nach einem Test online (diesmal benötigen wir ja wieder einen Server, der die PHP-Anweisungen verarbeiten kann) erhalten wir dieses Ergebnis:

Variante 2: Senden mit sendToURL

D ie Methode sendToURL ist vergleichbar mit der Methode send des LoadVars-Objekts: Es werden Variablen an einen Server übertragen, eine etwaige Antwort des Servers wird jedoch ignoriert (im Gegensatz zur obig beschriebenen Methode, die eine Antwort des Servers auswertet). Sie ist also ideal dafür geeignet, wenn man an einen Server Daten übermitteln will, die zwar serverseitig abgearbeitet werden sollen, wobei aber eine Antwort des Servers nicht notwendig ist – einfache Datenbankanwendungen wie Schreiben von statistischen Werten in Bezug auf das User-Verhalten oder zeitkri-tische Anwendungen sind Einsatzgebiete von sendToURL.

sendToURL ersetzt gemeinsam mit der Methode navigateToURL die getURL-Metho-de aus ActionScript 2.0.

Die Verwendung ist sehr ähnlich wie die zuvor mit dem URLLoader vorgestellte Variante. Es besteht jedoch keine Möglichkeit, eine abgeschlossene Übertragung abzu-warten, da der Server keinen Response gibt. Lediglich die Möglichkeit einer einfachen Fehlerüberprüfung mit der im AJAX-Kapitel bereits hinlänglich dargestellten try-catch-Methode ist möglich:

Ersatz eins für getURL aus

ActionScript 2.0

ABBILDUNG 6.44

Flash sendet die in URLVariables definierten

Variablen an die Datei urlvariables01.php, welche

wiederum einen (Rückgabe-)String zusammenbastelt, in

dem die gesandten Variablen vorkommen. Flash empfängt diesen String und gibt ihn in

der TextArea aus.

Page 334: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 321

var myVars:URLVariables = new URLVariables();

myVars.Vorname = "Uwe";

myVars.Nachname = "Mutz";

var myURL:URLRequest = new URLRequest();

myURL.method = "GET";

myURL.data = myVars;

var theURL:String = "sendtourl01.php";

myURL.url = theURL;

try {

sendToURL(myURL);

}

catch(myError:Error) {

statusMsg.appendText("FEHLER beim Versenden:\n\tMessage: "+myError.message+"\n\tName: "+myError.name+"\n\terrorID: "+myError.errorID);

}

Listing 6.53: Versenden von Daten an einen Server per sendToURL

Das Listing entspricht bis auf den try-catch-Abschnitt den Listings Listing 6.48 bis Listing 6.50:

Anlegen einer URLVariables-Instanz, um die zu übertragenen Daten zu definie-ren

Anlegen einer URLRequest-Instanz, um Daten versenden zu können. In unserem Fall werden die in myVars abgelegten Daten per GET an die Datei sendtourl01.php verschickt.

Im Grunde genommen hätte ein abschließender Aufruf von sendToURL ausgereicht, um die Daten zu übermitteln. Der umgebende try-catch-Bereich gibt uns die Mög-lichkeit, eine entsprechende Fehlermeldung in einer TextArea statusMsg auszuge-ben, sollte der sendToURL-Aufruf zu einem Fehler geführt haben. Benötigen Sie eine Fehlerabarbeitung nicht, so lassen Sie den try-catch-Bereich einfach weg und rufen lediglich die sendToURL-Methode auf.

Um unser Beispiel überprüfen zu können, ist die Datei sendtourl01.php so aufgebaut, dass sie die einkommenden Daten übernimmt und daraus eine E-Mail zusammen-stellt:

function create_email_header($name, $value) {

return ($name && $value) ? "$name: $value\r\n" : "";

u

u

Page 335: Flash cs3, ajax und php

K A P I T E L 6322

}

if(count($_REQUEST)>0) {

$mailfrom = "[email protected]";

$mailto = "[email protected]";

$subject = "TESTMAIL von sendtourl01.php";

$msg = "Uebertragene Daten:\n";

foreach($_REQUEST as $itm=>$val) {

$msg.= "$itm=$val\n";

}

$msg.= "\n(Versand per Email an: $mailto)";

$headers = "";

$headers .= create_email_header("From", $mailfrom);

$headers .= create_email_header("Reply-to", $mailto);

if(!mail($mailto, $subject, $msg, $headers)) {

die("ERROR: FEHLER beim Versand der Email");

}

}

Listing 6.54: sendtourl01.php empfängt die von Flash versendeten Daten, generiert daraus den Inhalt einer E-Mail (foreach-Schleife) und versendet die E-Mail an eine vorgegebene E-Mail-Adresse (hier: [email protected]) mithilfe der mail-Funktion.

Ignorieren wir einmal vorerst die Funktion create_email_header und wenden uns gleich dem Bereich darunter zu:

count($_REQUEST) gibt die Anzahl der (per GET oder POST) übermittelten Daten an. Waren es mehr als null Daten, so werden die Daten abgearbeitet.

Die Variablen $mailfrom, $mailto und $subject speichern den Absender, Empfänger und den Betreff respektive und dienen lediglich der Übersichtlichkeit (ebenso hätte man die Absender- und Empfängeradresse sowie den Betreff auch direkt im mail-Befehl unterbringen können).

$msg soll den Inhalt der E-Mail beinhalten. Zunächst weisen wir ihr den Text „Ueber-tragene Daten:\n“ zu, danach gehen wir in der foreach-Schleife alle erhaltenen Daten durch und erweitern die Variable $msg durch den Variablennamen ($itm)

u

u

u

Page 336: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 323

und den Variableninhalt ($val). Abschließend hängen wir an $msg noch den Text „\n(Versand per Email an: $mailto)“ an. Sie erinnern sich sicherlich, dass „\n“ einen Zeilenumbruch im Text erzeugt.

Die Variable $headers beinhaltet im weiteren die Header-Informationen für den Versand der E-Mail. Nachdem diese nach einem vorgegebenen Prinzip aufgebaut werden müssen, verwendet man gerne eine Funktion, die dies erledigt (somit sind wir bei der Funktion create_email_header angelangt, deren Erklärung ich zunächst übersprungen hatte).

Abschließend wird die E-Mail versandt (mail-Befehl) – sollte bei der Abarbeitung von mail ein Fehler auftreten, wird das Script abgebrochen und eine entspre-chende Fehlermeldung ausgegeben.

u

u

Variante 3: Senden mit navigateToURL

Die Variante mit navigateToURL ist im Wesentlichen die gleiche wie diejenige mit sendToURL, mit einem einzigen Unterschied: navigateToURL öffnet die von Flash aufgerufene (und an diese übergebene Daten) in einem Fenster.

navigateToURL erwartet bei einem Aufruf zwei Parameter:

navigateToURL(request:URLRequest, window:String):void

Er satz zwei für getURL

ABBILDUNG 6.45

Flash teilt der Datei send-tourl01.php mit, welche Daten in einer E-Mail gesammelt und versendet werden sollen. Fehler sind keine aufgetreten, eine Rückmeldung über einen positiven Versand der E-Mail haben wir jedoch auch nicht erhalten.

Page 337: Flash cs3, ajax und php

K A P I T E L 6324

request ist eine Instanz des URLRequest-Objekts und beinhaltet die Daten, die Sendemethode (GET oder POST) sowie die URL.

window bezeichnet das Fenster, in welchem die gegebene URL geöffnet werden soll. Die möglichen Werte kommen Ihnen sicherlich bekannt vor:

„_self“: Die URL wird im aktuellen Frame im aktuellen Fenster geöffnet.

„_blank“: Die URL wird in einem neuen Fenster geöffnet (Standardeinstel-lung).

„_parent“: Die URL wird im übergeordneten Frame des aktuellen Frame im aktuellen Fenster geöffnet.

„_top“: Die URL wird im obersten Frame des aktuellen Fensters geöffnet.

„FRAMENAME“: Die URL wird in dem von Ihnen benannten Frame geöffnet.

Inwieweit Sie noch mit Frames arbeiten, müssen Sie für sich selbst und für Ihre Kun-den entscheiden. Ich würde Ihnen den Tipp geben, keine neuen Webprojekte mit Frames anzugehen, da sie jetzt schon nicht mehr zum offiziellen Standard „strict“ von XHTML gehören.

Ändern wir das aus Listing 6.53 bekannte Beispiel entsprechend um, so erhalten wir:

...

var theURL:String = "navigatetourl01.php";

...

try {

navigateToURL(myURL);

}

catch(myError:Error) {

statusMsg.appendText("FEHLER beim Versenden:\n\tMessage: "+myError.message+"\n\tName: "+myError.name+"\n\terrorID: "+myError.errorID);

}

...

Listing 6.55: Aus Listing 6.53 haben sich lediglich der Methodenaufruf von sendToURL auf navigate-ToURL sowie die aufzurufende URL (jetzt: navigatetourl01.php) geändert.

Die Daten werden somit an die Datei navigatetourl01.php per GET versandt, wobei navigatetourl01.php in einem neuen Fenster (Standardeinstellung, sofern kein eigenes Fenster angegeben wurde) geöffnet wird:

u

u

u

u

u

u

u

Frames?

Page 338: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 325

6.4.2 Der Aufbau: das XML -Objekt & ActionScript 3.0 Mit Einführung von ActionScript 3.0 wurden an vielen Klassen Änderungen vor-genommen. Im Speziellen betrifft dies auch die XML-Klasse, die nun den Standard ECMAScript for XML (E4X) unterstützt. Da dies eine wesentliche Änderung gegenü-ber der bisherigen Handhabung von XML-Daten bedeutet, haben die Entwickler von Adobe kurzerhand die bisherige XML-Klasse in andere Klassen verschoben und eine neue XML-Klasse eingeführt. Die nachfolgende Tabelle soll Ihnen die Änderungen verdeutlichen (Quelle: Referenzhandbuch für ActionScript 3.0):

XML-Klasse fl ash.xml.XMLDocument Diese Klasse wurde in das fl ash.xml-Paket verschoben und der Name wurde in XMLDocument geändert, um einen Konfl ikt mit der neuen Top-Level XML-Klasse zu vermeiden, die ECMAScript für XML (E4X) implementiert.

contentType fl ash.net.URLRequest.contentType

docTypeDecl fl ash.xml.XMLDocument.docTypeDecl

idMap fl ash.xml.XMLDocument.idMap

ignoreWhite fl ash.xml.XMLDocument.ignoreWhite

loaded Entfernt Die Funktionen zum Laden einer Datei wurden aus der XMLDocument-Klasse entfernt. Verwenden Sie stattdessen URLLoader.

status Entfernt Fehler beim Parsen werden jetzt über Ausnahmefehler gemeldet.

ABBILDUNG 6.46

Ähnlich wie bei sendToURL werden die Daten an ein geeignetes Webdokument übergeben, wobei navigate ToURL dieses in einem Fenster darstellt.

Page 339: Flash cs3, ajax und php

K A P I T E L 6326

xmlDecl fl ash.xml.XMLDocument.xmlDecl

XML fl ash.xml.XMLDocument.XMLDocument()

addRequestHeader() fl ash.net.URLRequest.requestHeaders

createElement() fl ash.xml.XMLDocument.createElement()

createTextNode() fl ash.xml.XMLDocument.createTextNode()

getBytesLoaded() fl ash.net.URLLoader.bytesLoaded Die Funktionen zum Laden einer Datei wurden aus der XMLDocu-ment-Klasse entfernt. Verwenden Sie stattdessen URLLoader.

getBytesTotal() fl ash.net.URLLoader.bytesTotal Die Funktionen zum Laden einer Datei wurden aus der XMLDocu-ment-Klasse entfernt. Verwenden Sie stattdessen URLLoader.

load() Entfernt Die Funktionen zum Laden einer Datei wurden aus der XMLDocument-Klasse entfernt (in ActionScript 2.0 war dies die XML-Klasse). Verwenden Sie stattdes-sen URLLoader.

onData() fl ash.net.URLLoader dispatches event: complete

Die Funktionen zum Laden einer Datei wurden aus der XMLDocument-Klasse entfernt. Verwenden Sie stattdessen URLLoader. Wurde im neuen Ereignismodell durch ein com-plete-Ereignis ersetzt.

onHTTPStatus() fl ash.net.URLLoader dispatches event: httpStatus

Die Funktionen zum Laden einer Datei wurden aus der XMLDocument-Klasse entfernt. Verwenden Sie stattdessen URLLoader. Wurde im neuen Ereignismodell durch ein http-Status-Ereignis ersetzt.

onLoad() fl ash.net.URLLoader dispatches event: complete

Die Funktionen zum Laden einer Datei wurden aus der XMLDocument-Klasse entfernt. Verwenden Sie stattdessen URLLoader. Wurde im neuen Ereignismodell durch ein com-plete-Ereignis ersetzt.

parseXML() fl ash.xml.XMLDocument.parseXML()

send() Entfernt Die Funktionen zum Senden einer Datei wurden aus der XMLDocument-Klasse entfernt (in ActionScript 2.0 war dies die XML-Klasse). Verwenden Sie stattdes-sen die Funktionen und Klassen im fl ash.net-Paket.

sendAndLoad() Entfernt Die Funktionen zum Senden und Laden einer Datei wurden aus der XMLDocument-Klasse entfernt (in ActionScript 2.0 war dies die XML-Klasse). Verwenden Sie stattdes-sen URLRequest und URLLoader.

Tabelle 6.8: Änderungen in der XML-Klasse von ActionScript 2.0 zu ActionScript 3.0

Page 340: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 327

XMLNode-Klasse fl ash.xml.XMLNode Der Speicherort wurde geändert. Diese Klasse wurde in das fl ash.xml-Paket verschoben.

nodeType fl ash.xml.XMLNode.nodeType Der Datentyp wurde von Number zu uint geän-dert.

XMLNode fl ash.xml.XMLNode.XMLNode() Der Datentyp des type-Parameters wurde von Number zu uint geändert.

Tabelle 6.9: Änderungen in der XMLNode-Klasse von ActionScript 2.0 zu ActionScript 3.0

XMLSocket-Klasse fl ash.net.XMLSocket Diese Klasse wurde in das fl ash.net-Paket verschoben.

XMLSocket fl ash.net.XMLSocket.XMLSocket() Es wurden zwei optionale Parameter zum Festlegen von Host und Port hinzugefügt.

connect() fl ash.net.XMLSocket.connect() Der Datentyp des port-Parameters wurde in int geän-dert.

onClose() fl ash.net.XMLSocket dispatches event: close Wurde im neuen Ereignismodell durch ein close-Ereignis ersetzt.

onConnect() fl ash.net.XMLSocket dispatches event: connect Wurde im neuen Ereignismodell durch ein connect-Ereignis er-setzt.

onData() fl ash.net.XMLSocket dispatches event: data Wurde im neuen Ereignismodell durch ein data-Ereignis ersetzt.

onXML() Entfernt In ActionScript 3.0 wird nur das data-Ereignis ausgelöst, sodass Sie entweder E4X- oder den äl-teren XML-Parser (XMLDocument-Klasse) verwenden können. Die alte Ereignisprozedur onXML wurde nach dem Parsen des XML-Codes aufgerufen. Dies ergibt in ActionScript 3.0 keinen Sinn, weil Sie zum Parsen des XML-Codes jetzt zwischen der XML-Klasse (E4X) und der XMLDocument-Klasse (ältere Version) wählen können.

Tabelle 6.10: Änderungen in der XMLSocket-Klasse von ActionScript 2.0 zu ActionScript 3.0

Wie Sie aus den obigen Tabellen entnehmen können, betreffen viele Änderungen das Senden und Laden von XML-Dateien, die insgesamt in die Klasse URLLoader verscho-ben worden sind. Dementsprechend müssen wir das gesamte Prozedere des Ladens von XML-Daten in ActionScript 3.0 überdenken.

Im Fall von ActionScript 3.0 verhält sich das Laden von XML-Daten folgendermaßen (diese Vorgehensweise haben wir bereits in Kapitel 6.4.1 kennengelernt):

1. Anlegen eines URLLoader-Objekts: Dieses Objekt wird in ActionScript 3.0 generell zum Laden von Daten verwendet:

var myLoader:URLLoader = new URLLoader();

Page 341: Flash cs3, ajax und php

K A P I T E L 6328

2. Anlegen eines URLRequest-Objekts zum Angeben einer Quelle:

var myURL:URLRequest = new URLRequest("URL_ZUR_QUELLE");

3. Defi nieren eines Eventhandler für den Fall, dass die Daten geladen wurden. Es kommt das Ereignis COMPLETE zum Einsatz:

function FUNKTIONSNAME_DES_HANDLERS(myEvent:Event):void {

...

}

myLoader.addEventListener(Event.COMPLETE, FUNKTIONSNAME_DES_HANDLERS);

Listing 6.56: Ladevorgang mit dem URLLoader- und URLRequest-Objekt

4. Ladevorgang starten basierend auf den Angaben in der URLRequest-Instanz (myURL):

myLoader.load(myURL);

Wenn wir diese Vorgehensweise mit der von ActionScript 2.0 vergleichen, fallen uns folgende Punkte auf:

Während in ActionScript 2.0 im XML-Objekt eine eigene Methode zum Laden von Daten (XML.load) zur Verfügung stand, wird nun ein eigenes „Lade-Objekt“ URL-Loader verwendet. Dieses Objekt ist nicht auf das XML-Objekt beschränkt, sondern ist generell zum Laden von Text, Binär- oder URL-codierten Daten verwendbar. Eine genauere Beschreibung dieses Objekts finden Sie weiter oben.

In ActionScript 2.0 war die zu ladende Quelle ein einfacher Parameter der load-Methode (XML.load("URL ZUR QUELLE")), in ActionScript 3.0 wird hierfür ebenfalls ein eigenes Objekt URLRequest verwendet.

Entgegen dem für das bisherige XML-Objekt bereits vorhandenen Eventhandler onLoad muss in ActionScript 3.0 ein Eventhandler zugewiesen werden (addE-ventListener). Das Ereignis selbst wird aus der (Basis-)Klasse Event bezogen. Eine genaue Beschreibung der Event-Klasse finden Sie in der ActionScript 3.0-Referenz.

Beim gesamten Ladevorgang in ActionScript 3.0 wurde noch kein einziges Mal ein XML- oder ähnliches Objekt ins Spiel gebracht, denn der Ladevorgang ist unabhän-gig vom Inhalt der zu ladenden Daten. Erst nach dem Ladevorgang wird entschie-den, was mit den geladenen Daten eigentlich getan werden soll.

Bevor wir auf die gerade verwendeten neuen Objekte URLLoader und URLRequest zu sprechen kommen, sehen wir uns noch den weiteren Vorgang zum Auslesen der XML-Daten an. Wobei ich an dieser Stelle gleich vorausschicken möchte, dass wir in diesem ersten Beispiel beim Auswerten der XML-Daten lediglich an der Oberfläche kratzen werden – viel tiefer in die Materie gehen wir dann weiter unten im Kapitel.

u

u

u

u

Page 342: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 329

Die nächsten Schritte des Ladezyklus sind:

5. Anlegen eines XML-Objekts:

var myXML:XML;

6. Einlesen der XML-Daten in das XML-Objekt und Festlegen der grundlegenden Eigenschaften des XML-Objekts. Dieser Vorgang wird erst nach dem Laden durch den URLLoader durchgeführt und im Allgemeinen befi ndet sich dieser Teil innerhalb des Event.COMPLETE-Eventhandler:

myXML = new XML(myEvent.target.data);

myXML.ignoreWhitespace = true;

myXML.ignoreComments = true; //Standard: true

myXML.ignoreProcessingInstructions = true; //Standard: true

Neben der schon bekannten Eigenschaft ignoreWhitespace (Eliminieren/„Ignorieren“ von Zeilenumbrüchen, Leerzeichen etc.) sind die Eigenschaften igno-reComments (Eliminieren von XML-Kommentaren) und ignoreProcessingIn-structions (Ignorieren von Verarbeitungsanweisungen) hinzugekommen. Beide Eigenschaften sind standardmäßig bereits auf den Wert true gesetzt, deshalb müssen Sie diese Eigenschaften nicht noch einmal konkret auf true setzen. Jedoch wollte ich Ihnen diese Eigenschaften nicht vorenthalten, worauf ich sie kurzerhand eingebaut habe. In zukünftigen Beispielen werden wir diese Eigenschaften nicht mehr explizit auf true setzen.

Fassen wir die obigen Schritte in ein Script zusammen und wenden es auf eine XML-Datei namens XML01_AS3.xml an, so erhalten wir nachfolgendes Listing. Die eingele-senen XML-Daten wandeln wir mit toXMLString in einen String um und schreiben diesen in eine TextArea statusMsg. Der Inhalt der XML-Datei entspricht demjenigen aus Listing 6.35 mit dem Unterschied, dass die kaufmännischen Und „&“ durch ent-sprechende Escape-Zeichen ersetzt wurden:

...

<Firma>SYNE Marketing %26 Consulting GmbH</Firma>

...

Listing 6.57: Ein kaufmännisches Und „&“ wird in URL-Codierung mit %26 angegeben.

Wir bedienen uns der Funktion decodeURIComponent, um diese Escape-Zeichen wieder in die entsprechenden Zeichen rückzuwandeln. (Tipp: Schlagen Sie in der ActionScript-Referenz nach, um den Unterschied zwischen decodeURI und decodeU-RIComponent herauszufinden.)

var myLoader:URLLoader = new URLLoader();

var theURL:String = "XML01_AS3.xml";

ignore Comments und ignore-Processing-Instructions

Page 343: Flash cs3, ajax und php

K A P I T E L 6330

var myURL:URLRequest = new URLRequest(theURL);

var myXML:XML;

function completelyLoaded(myEvent:Event):void {

myXML = new XML(myEvent.target.data);

myXML.ignoreWhitespace = true;

myXML.ignoreComments = true; //Standard: true

myXML.ignoreProcessingInstructions = true; //Standard: true

statusMsg.appendText(decodeURIComponent(myXML.toXMLString()));

}

myLoader.addEventListener(Event.COMPLETE, completelyLoaded);

myLoader.load(myURL);

Listing 6.58: XML-Verarbeitung in ActionScript 3.0. Die Funktion decodeURIComponent sorgt dafür, dass die Escape-Zeichen in normale Zeichen umgewandelt werden.

Ein Screenshot liefert den Beweis der Funktionstüchtigkeit unseres Beispiels, welches Sie übrigens wie gewohnt auf der Buch-CD finden (XML01_AS3.fla):

ABBILDUNG 6.47

Einlesen und Ausgeben einer XML-Quelle mittels

ActionScript 3.0

Page 344: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 331

„Ur“-XML in ActionScript 3.0Falls Sie in ActionScript 3.0 entwickeln, jedoch auf die bisherige Arbeitsweise mit dem XML-Objekt aus ActionScript 2.0 nicht verzichten wollen, können Sie nach wie vor auf dieses zugrei-fen. Wie in den obigen Tabellen dargestellt, wurden sämtliche XML-Klassen in ein (extern einzu-bindendes) Paket flash.xml verschoben, wobei die aus ActionScript 2.0 bekannte XML-Klasse in XMLDocument umbenannt wurde, damit keine Kollisionen mit der neuen XML-Klasse aus ActionScript 3.0 auftreten können.

Irgendwann werden Sie sich wahrscheinlich die Frage stellen, was jetzt in ActionScript 3.0 im Umgang mit XML so viel besser geworden sein soll. Bis zu diesem Zeitpunkt ist die Frage auch ganz und gar nicht unberechtigt, haben wir uns denn noch gar keine wesentlichen Änderungen angesehen. Das gehen wir jetzt an!

Bisher hatten wir das „Problem“, dass die eingelesenen XML-Daten geparst werden mussten, was mitunter relativ aufwändig hatte sein können. Durch die Unterstützung von ECMAScript for XML gehört das Parsen mehr und mehr der Vergangenheit an. E4X definiert an sich eine große Menge an Klassen zur Verarbeitung von XML-Daten, von denen die Klassen XML, XMLList, QName und Namespace in ActionScript 3.0 über-nommen wurden, von denen wiederum zwei von größerem Interesse für uns sind:

XML: Das XML-Objekt enthält eine Anzahl von Methoden und Eigenschaften für die Verarbeitung der geladenen XML-Daten.

XMLList: Ein XMLList-Objekt ist für die Verarbeitung mehrerer XML-Objekte gedacht – es ist mehr oder weniger eine Sammlung einzelner XML-Objekte.

In den meisten Fällen werden wir uns ausschließlich mit dem XML-Objekt begnügen, lediglich in Projekten mit vielen XML-Objekten gleichzeitig macht das XMLList-Objekt Sinn.

Folgende XML-Datei soll uns als Quelle dienen:

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>

<Audioplayer>

<Player version="1.3" skin="2">

<Autoplay>1</Autoplay>

<verwendeReihenfolge>1</verwendeReihenfolge>

<Begruessungstext>Be my DJ</Begruessungstext>

</Player>

<Playliste>

<Song pos="1" useID3="1">

<Titel>Warriors of the wasteland</Titel>

<Interpret>Frankie goes to Hollywood</Interpret>

<Src>WarriorsOfTheWasteland.mp3</Src>

u

u

Warum ActionScript 3.0?

Page 345: Flash cs3, ajax und php

K A P I T E L 6332

</Song>

<Song pos="4" useID3="1">

<Titel>Be a Warrior</Titel>

<Interpret>Jestofunk</Interpret>

<Src>BeAWarrior.mp3</Src>

</Song>

</Playliste>

<Playliste>

<Song pos="5" useID3="0">

<Titel>Numb</Titel>

<Interpret>Linkin Park</Interpret>

<Src>Numb.mp3</Src>

</Song>

</Playliste>

</Audioplayer>

Listing 6.59: Diese XML-Datei ist ein wenig komplexer aufgebaut als die des vorigen Beispiels und dient uns somit als besseres Anschauungsobjekt.

Lesen wir doch mal mit ActionScript 3.0 die Daten aus dem XML-Objekt aus. Das Schöne an Version 3 ist, dass man nun direkt auf die einzelnen Tags zugreifen kann. Einige Beispiele:

Wir wollen auf Anhieb wissen, welche Player-Version (zu finden im Tag <Player version="1.3"...> als Attribut version) verwendet werden soll:

myXML.Player.@version;

Folgende Punkte möchte ich festhalten:

Das Tag <Player> kann direkt angesprochen werden – es muss lediglich auf die Verschachtelung geachtet werden. (<Player> liegt in der Hierarchie direkt unter dem Root-Tag <Audioplayer>, welches durch myXML repräsentiert wird.) Der Zugriff erfolgt direkt über den Tag-Namen. Es besteht also keine Notwendigkeit mehr, mit den Eigenschaften wie firstChild usw. zu arbei-ten.

Würde sich <Player> nicht an erster Stelle im Code befinden, sondern etwa am Ende des Listings (jedoch in derselben Hierarchiestufe wie jetzt), würde der Zugriff auf die gleiche Art und Weise erfolgen (lesen Sie hierzu die XML-Datei XML02a_AS3.xml in XML02_AS3.fla ein, um dies zu verifizieren):

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>

<Audioplayer>

u

u

u

Page 346: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 333

<Playliste>

...

</Playliste>

<Playliste>

...

</Playliste>

<Player version="1.3" skin="2">

...

</Player>

</Audioplayer>

Listing 6.60: Die Reihenfolge von <Player> und der <Playliste>-Tags wurde vertauscht – <Player> steht nun am Ende der Liste.

Ebenso kann direkt auf ein Attribut innerhalb eines Tag zugegriffen werden: Hierzu wird das „@“ mit dem darauffolgenden Attributnamen angegeben.

Wir wollen wissen, welchen Titel der zweite Song der ersten Playliste hat (das wäre in unserem Fall „Be a warrior“):

myXML.Playliste[0].Song[1].Titel;

Der Zugriff auf die erste <Playliste>-Gruppe erfolgt wie gewohnt über das Array Playliste (sobald ein Tag mehr als nur einmal vorkommt, wird es in Form eines Arrays dargestellt), und zwar im speziellen auf den nullten Eintrag dieses Arrays: myXML.Playliste[0]. Da das Tag <Song> ein untergeordnetes Tag von <Playliste> ist, greifen wir über die Punktnotation auf diese Gruppe zu und wählen den Eintrag 1 aus: myXML.Playliste[0].Song[1]. Bleibt nur noch das Tag <Titel> abzufragen: myXML.Playliste[0].Song[1].Titel.

Halten wir fest:

Wie schon oben erwähnt, ist die Position eines Tag in der XML-Struktur nicht mehr von Bedeutung für das Auslesen – lediglich die Verschachtelung der Tags muss beachtet werden.

Um den Wert (besser: Inhalt) eines Knotens auszulesen, muss nicht mehr wie in ActionScript 2.0 auf das erste Kind (firstChild) eines Knotens/Tag zuge-griffen und dort der nodeValue ausgelesen werden – vielmehr wird das Tag direkt angesprochen und so der Wert ermittelt.

u

u

u

u

Page 347: Flash cs3, ajax und php

K A P I T E L 6334

Textknoten mit mehreren TextteilenIn den obigen Überlegungen haben wir gesehen, dass man den Inhalt eines Knotens direkt über den Zugriff auf den Knoten erhält: XMLObjekt.Knoten liefert den Inhalt des Knotens. Sollten sich innerhalb dieses Knotens jedoch weitere Knoten befinden, so werden diese als Ganzes aus-gelesen. Sollten Sie nur auf die Textteile eines Knotens zugreifen wollen, so geschieht dies über die Methode text, also etwa: XMLObjekt.Knoten.text() liefert den gesamten Text eines Knotens zurück. Sollte dieser Text wiederum durch Knoten unterbrochen sein, so erhalten Sie ein Array an Textteilen.

Ein kleines Beispiel:

var myXML:XML = new XML("<p>Text 1.<br />Text 2</p>");

trace(myXML.text()[0]); //liefert "Text 1."

trace(myXML.text()[1]); //liefert "Text 2"

trace(myXML.text()); //liefert Text1.Text2

Da <p> der äußerste Knoten ist, wird dieser nicht explizit angegeben. Anders würde es sich verhalten, wenn <p> in ein <body> verschachtelt wäre – dann muss man das <p> explizit angeben (Thema Hierarchie):

var myXML:XML = new XML("<body><p>Text 1.<br />Text 2</p></body>");

trace(myXML.p.text()[0]); //liefert "Text 1"

trace(myXML.p.text()[1]); //liefert "Text 2"

trace(myXML.p.text()); //liefert Text1.Text2

Weitere sehr interessante Eigenschaften sind in nachfolgender Liste zu sehen:

length liefert nach wie vor die Anzahl von vorkommenden Knoten eines bestimm-ten Namens. Beispielsweise würde myXML.Playliste.length die Anzahl der vor-kommenden Tags <Playliste> liefern (in unserem Fall wäre das Ergebnis drei). Bitte beachten Sie jedoch, dass length nun eine Methode und keine Eigenschaft darstellt:

myXML.Playliste.length(); //liefert: 3

Mittels zweier Punkte „..“ kann man ein bestimmtes Tag (einen bestimmten Kno-ten) in beliebiger Hierarchietiefe ansprechen:

myXML..Song[2];

Diese Anfrage würde folgendes Ergebnis liefern:

<Song pos="5" useID3="0">

<Titel>Numb</Titel>

<Interpret>Linkin Park</Interpret>

<Src>Numb.mp3</Src>

</Song>

Listing 6.61: Die Anfrage für den dritten Song-Knoten (Song[2] – wir beginnen ja wie gewohnt bei Null zu zählen) liefert den gesamten Inhalt dieses Knotens. Bitte vergleichen Sie die Ausgabe mit dem Inhalt der XML-Quelle aus Listing 6.59.

u

u

Page 348: Flash cs3, ajax und php

S E R V E R S E I T I G E R D AT E N A U S TA U S C H – F L A S H , P H P & D AT E N B A N K 335

Eine sehr interessante Funktion ist eine Art „Suchfunktion“ innerhalb der XML-Daten: Über einen Vergleich kann auf bestimmte Knoten oder Attribute mit bestimmten Werten zugegriffen werden:

Zugriff auf einen (beliebigen) Song-Knoten, wo das pos-Attribut den Wert 1 besitzt: myXML..Song.(@pos=="1");

Zugriff auf einen (beliebigen) Titel-Knoten mit Textinhalt gleich „Be a Warri-or“: myXML..Titel.(text()=="Be a Warrior");

Solche Vergleiche können auch (nach den bekannten Verknüpfungs-regeln) verknüpft werden: myXML..Titel.(text()=="Be a Warrior" ||

text()=="Numb");

u

u

u

Ich hoffe, ich habe Ihnen das neue XML-Objekt schmackhaft machen können. Trotz aller Vorteile möchte ich an dieser Stelle trotzdem noch einmal konkret auf die Tatsa-che hinweisen, dass das Flash-Dokument nun mit ActionScript 3.0 aufgebaut werden muss, und dies bedarf schon einer gründlichen Einarbeitung in diese Sprache! Aus diesem Grund möchte ich Ihnen erneut die entsprechende Literatur zu ActionScript 3.0 ans Herz legen:

Selma-Caroline und Matthias Kannengießer: ActionScript 3.0. 1. Auflage. Bonn: Addi-son-Wesley 2007, ISBN 978-3827325365

Auch ist die ActionScript 3.0-Referenz in Flash eine sehr gute Quelle und ein unschätz-bares Nachschlagewerk!

ABBILDUNG 6.48

Die Ausgabe aller unserer Anweisungen in einer TextArea. XML goes ActionScript 3.0.

Page 349: Flash cs3, ajax und php
Page 350: Flash cs3, ajax und php

7AUDIO-JUKEBOX

Dieses und die folgenden Kapitel widmen sich ausschließlich der Praxis. Hier sollen Sie sehen, auf welche Arten wir uns ein Zusammenspiel von Flash und PHP vorstellen.

Anwendungsbeispiele gibt es wohl wie Sand am Meer, Ideen und Vorstellungen zu Anwendungen noch viele mehr. Aus diesem Grund werden Sie auch zu diesem Buch gegriffen haben. Die serverseitige Programmierung als (hauptsächlicher) Datenlieferant auf der einen Seite, Flash als das Animations- und Multimedia-Tool auf der Clientseite.

Zu den gängigsten Aufgabengebieten finden Sie im Folgenden konkret durchgeplante und durchprogrammierte Übungen. Ich habe in allen Workshops die Flash- und die PHP-Entwick-lung strikt getrennt, sodass Sie ein Optimum an Übersicht genießen können.

Die Audio-Jukebox wird zunächst in ActionScript 2.0 und spä-ter in ActionScript 3.0 entwickelt.

Viel Spaß beim Umsetzen und Anwenden!

Page 351: Flash cs3, ajax und php

K A P I T E L 7338

7.1 Abfragen serverseitiger InformationenEine Variante, sich PHP für Flash zunutze zu machen, liegt in der simplen Abfrage von Daten aus einer Datenbank oder einem Filesystem. Dieses Kapitel widmet sich genau dieser Thematik. Als konkrete Anwendungen habe ich an dieser Stelle bevorzugt an multimediale Anwendungen gedacht, da sie im Allgemeinen keine Rückgaben an den Server erfordern.

7.2 Multimediale AnwendungenWas ist Multimedia ? Multimedia ist das Verwenden verschiedener Ausgabemedien zur selben Zeit. Hierzu zählt man Inhalte wie Text, Audio, Video usw. Je mehr dieser Assets zur gleichen Zeit ausgegeben werden, desto interessanter gestaltet sich die Entwicklung in Flash. Einmal ganz ehrlich – kennen Sie ein Tool, das besser für Multimedia auf Clientseite geeignet ist als Flash? Wohl kaum.

7.3 Konzept der JukeboxAls erstes Beispiel dient dabei mein persönlicher Favorit. Kaum eine andere Anwen-dung hat mir in der Verwendung wie in der Entwicklung mehr Freude bereitet.

Am Anfang steht das Entwickeln eines Konzepts, also mehr oder weniger die Antwort auf die Frage: „Was soll das Tool eigentlich können?“ Hier die Anforderungen an unse-re Audio-Jukebox aus Flash-Sicht:

1. Die Audio-Jukebox soll in der Lage sein, gestreamt MP3-Dateien abzuspielen. Somit ist die erste Anforderung, dass MP3-Dateien dynamisch in Flash eingelesen werden sollen.

2. Innerhalb der Jukebox soll volle Kontrolle über das Abspielen der Songs gewährleistet sein. Dies schließt Buttons für: „Start“, „Stopp“, „Ein Song weiter“ und „Ein Song zurück“ ein. Des Weiteren muss die Lautstärke regelbar sein.

3. Die gängigen Informationen zu den Songs sollen direkt aus den ID3-Tags der MP3-Dateien ermittelt und ausgegeben werden.

4. Die Restabspielzeit zum jeweiligen Song soll ausgegeben werden.

5. Es soll eine parametergesteuerte Autostart-Möglichkeit vorhanden sein.

7.3.1 Playlist generierenGrundsätzlich stellt sich natürlich die Frage, wie Flash zu den Songs kommt, also woher die Playlist kommt bzw. wer sie generiert und wie sie eingelesen wird. Unser

ID3-TagsDie ID3-Tags sind

(be nannte) Informationen wie „Titel“, „Interpret“,

„Album“ usw., die mit der MP3-Datei gespeichert

werden können. Geeignete Programme – wie auch

Flash – können diese Tags auslesen.

Page 352: Flash cs3, ajax und php

A U D I O - J U K E B O X 339

Plan soll sein, dass sämtliche in einem Verzeichnis aufgelisteten MP3-Dateien verwen-det werden. Eine auf diese Art erzeugte Playlist soll per Aufruf von Flash eine XML-Datei generieren, die Flash wiederum einliest.

XML-Struktur

Aus Sicht von Flash ist es vollkommen irrelevant, „wer“ (der Webdesigner in Form einer Textdatei, ein Server basierend auf PHP-Code usw.) und auf welche Art die Playlist als XML-Datei generiert wird – Hauptsache, die Struktur ist bekannt und die XML-Daten stehen zur Verfügung. Punkt eins ist also, dass die Struktur der XML-Datei feststehen muss.

Abbildung 7.1 verdeutlicht, wie die Informationen an die Flash-Anwendung überge-ben werden sollen. Neben den Tags für die einzelnen Songs wird in zwei Attributen festgelegt, welches das Stammverzeichnis der Songs ist (rootDir) und ob ein Autostart – also ein automatisches Abspielen der Playlist – stattfinden soll (autostart). Wird die Variable autostart auf 0 gesetzt, so findet kein Autoplay statt, steht sie hingegen auf 1, erfolgt das Abspielen der Playlist automatisch.

Flash-Datei vorbereiten

Gehen wir’s an. Zunächst gliedern wir die Flash-Datei in drei gedachte Bereiche:

Im ersten Bereich soll das Laden der XML-Daten erfolgen.

Der zweite Bereich ist dafür gedacht, dem User eine Fehlermeldung auszugeben, sollte das Laden der XML-Daten nach einer gewissen Zahl von Wiederholungen nicht möglich gewesen sein.

Der dritte Bereich stellt die eigentliche Jukebox dar. Dort befinden sich die Abspiel-steuerung und die Informationsdarstellung der MP3-Daten.

u

u

u

ABBILDUNG 7.1

Auf diese Art und Weise wer-den die MP3-Informationen an die Flash-Datei überge-ben. XML is on its way.

Page 353: Flash cs3, ajax und php

K A P I T E L 7340

7.4 Jukebox in ActionScript 2.0Nachdem diese Vorkehrungen getroffen sind, konzentrieren wir uns nun wirklich auf das Programmieren. Zunächst muss definiert werden, aus welcher Datei die Playlist geladen werden soll – hierzu bedienen wir uns einer Stringvariablen namens mySource , die den Namen (oder auch eine komplette URL inklusive eventueller Unterverzeich-nisse) der Playlist-Datei speichert. Des Weiteren legen wir – wie auch schon in den Theoriekapiteln gezeigt – in einer Variable maxLadeversuche eine gewisse Anzahl an Ladeversuchen fest, sollte das Laden der Daten nicht beim ersten Mal klappen. Hierzu muss in weiteren Variablen mitgezählt werden, wie viele Ladeversuche bereits vorge-nommen wurden. Dies übernimmt die Variable anzLadeversuche.

var anzLadeversuche:Number = 0;

var maxLadeversuche:Number = 3;

var mySource:String = "playlist.php";

Listing 7.1: Die ersten drei wichtigen Variablen für die mitgezählte Anzahl an Ladeversuchen (anzLade-versuche), die maximale Anzahl an Ladeversuchen (maxLadeversuche) und die URL zur Playlist-Datei (mySource) sind somit angelegt.

Neben den oben angeführten Variablen werden wir im Weiteren noch einige zusätz-liche globale Variablen benötigen, nämlich ein Array, das alle unsere eingelesenen Songs speichert (theSongs), zwei Variablen für die Ausgabe von Informationen zu den Songs in dynamischen Textfeldern (theSongInfo1, theSongInfo2) sowie eine Variable für die Darstellung der verbleibenden Abspielzeit, ebenfalls in einem dyna-mischen Textfeld (theTimeInfo).

var theSongs:Array = new Array();

var songTitel:String = "loading Playlist...";

var songInterpret:String = "";

var songAlbum:String = "";

var theTimeInfo:String = "--:--";

Listing 7.2: Anlegen einiger wesentlicher Variablen, die wir für den weiteren Ablauf der Jukebox benötigen werden

Natürlich müssen die Variablen songTitel, songInterpret, songAlbum und the-TimeInfo nicht notwendigerweise genau zu diesem Zeitpunkt angelegt werden. Dies empfiehlt sich jedoch, da man (als guter Programmierer) davon ausgehen kann, dass man bis zum Abspielen der Songs kommt und somit diese Variablen auch benötigen wird.

Page 354: Flash cs3, ajax und php

A U D I O - J U K E B O X 341

7.4.1 XML-Daten ladenNun kümmern wir uns darum, dass die XML-Daten geladen werden können. Das Flash-Objekt XML wird diese Aufgabe für uns erledigen. Obwohl wir keine leeren Textknoten zu erwarten haben, ist das Setzen der Eigenschaft ignoreWhite des XML-Objekts auf den Wert true eine gute Wahl, denn so kann diese mögliche Fehlerquelle ausgeschlossen werden.

var myLoader:XML = new XML();

myLoader.ignoreWhite = true;

myLoader.load(mySource);

Listing 7.3: Es wird ein neues XML-Objekt erzeugt, die Eigenschaft ignoreWhite auf true gesetzt und von der zuvor defi nierten URL (mySource) werden XML-Daten eingelesen.

Über das Ereignis onLoad des XML-Objekts wird signalisiert, dass das Laden der Daten abgeschlossen ist. Dies bedeutet aber noch nicht, dass das Laden auch erfolgreich war. Das erfolgreiche Laden signalisiert erst die Eigenschaft loaded. Dies bedeutet für uns, dass wir zunächst das Ereignis onLoad auswerten (wir erzeugen eine sogenannte Ereig-nisroutine oder Ereignisprozedur ) und danach abprüfen müssen, ob die Eigenschaft loaded auf true gesetzt ist. Sollte dem nicht so sein, wird ein erneuter Ladeversuch gestartet. Das Definieren der Ereignisroutine muss kein zweites Mal vorgenommen werden, da beim erneuten Ladeversuch dasselbe XML-Objekt ein weiteres Mal verwen-det wird. In jedem Fall wird die Variable anzLadeversuche um eins erhöht.

myLoader.onLoad = function():Void {

anzLadeversuche++;

if(myLoader.loaded) {

//Hier folgt das Auslesen der Attribute und Tags.

//Der Code wird weiter unten erläutert.

}

else {

if(anzLadeversuche<maxLadeversuche) { myLoader.load(mySource); }

else {

//Code, falls Anzahl der Ladeversuche erreicht ist

}

}

}

Listing 7.4: Die Ereignisbehandlungsroutine wertet die Daten bei erfolgreichem Laden aus, bei nicht erfolgreichem Laden wird – sofern die Maximalanzahl an Ladeversuchen noch nicht erreicht ist (also anzLadeversuche<maxLadeversuche) – ein erneuter Ladeversuch gestartet. Ansonsten müssen wir uns etwas einfallen lassen.

onLoad versus loaded onLoad versus loaded

Page 355: Flash cs3, ajax und php

K A P I T E L 7342

Attribute speichern

War das Laden erfolgreich (und davon gehen wir einmal aus), werden zunächst alle im zweiten Tag (<Playlist>; siehe Abbildung 7.1) vorkommenden Attribute als globale Variablen gespeichert.

Eine for..in-Schleife empfiehlt sich hier: Alle im Objekt attributes vorkom-menden Eigenschaften (hier: Variablen) werden ausgelesen und durch die Funktion _global in die Kollektion der globalen Variablen übernommen.

Danach werden alle folgenden Tags angesprochen und das Attribut src wird aus-gelesen. In diesem befinden sich die Namen der MP3-Dateien. Vergleicht man den nachfolgenden Code mit der Abbildung der einzulesenden XML-Datei, so sieht man, dass das erste Child <Playlist> des Hauptknotens <?xml> eine gewisse Anzahl wei-terer Child-Knoten umfasst (die Tags <song>). Wie viele es sind, lässt sich über die Eigenschaft length dieser childNodes-Sammlung herausfinden. Diese Information verpackt man in eine for-Schleife, liest Zug um Zug jedes Tag und dessen Attribut src aus und speichert die ermittelten Werte im globalen Array theSongs.

Ist dieser Schritt vollzogen, ist sämtliches Einlesen der XML-Daten abgeschlossen und es kann mit dem weiteren Gang der Jukebox fortgefahren werden.

//Dieses Code-Fragment wird an oben erwähnter Stelle eingefügt

for(itm in myLoader.fi rstChild.attributes) {

_global[itm] = myLoader.fi rstChild.attributes[itm];

}

for(var i:Number=0; i<myLoader.fi rstChild.childNodes.length; i++) {

theSongs[i] = myLoader.fi rstChild.childNodes[i].attributes.src;

}

Listing 7.5: Das Auswerten und Speichern der eingelesenen Daten erfolgt in diesem Codefragment. Sobald dieses Prozedere abgeschlossen ist, ist der wesentlichste Schritt getan und es kann mit dem Abspielen der Songs begonnen werden.

Für den Fall, dass der Ladevorgang nicht erfolgreich beendet werden konnte und auch die weiteren Ladeversuche zu keinem positiven Ergebnis geführt haben, wird ein MovieClip eingeblendet, der eine entsprechende Fehlermeldung auf den Bildschirm ausgibt. Ob Sie hier nun dem User die Meldung ausgeben, dass das Laden nicht geklappt hat, oder zusätzlich einen Button einfügen, der bei Klick einen neuerlichen Ladezyklus einleitet, hängt von Ihrem persönlichen Geschmack ab. Wir sind der Ansicht, dass sofern drei Ladeversuche fehlgeschlagen sind, ein weiterer Ladezyklus auch keinen Sinn mehr macht. Natürlich ist es aber Ihnen überlassen, ob Sie diese Möglichkeit in Betracht ziehen wollen oder nicht.

Ich habe mich für die Variante „Fehlermeldung & Buttons zum Neuladen“ entschie-den, die wie folgt aussehen könnte:

Page 356: Flash cs3, ajax und php

A U D I O - J U K E B O X 343

Hierzu legt man einen MovieClip mcError an, der zwei Buttons (btnNein, btnJa) beinhaltet, und platziert ihn der Einfachheit halber neben der Bühne (quasi im unsichtbaren Bereich – siehe Abbildung 7.3). Um den MovieClip mcError gleich „am richtigen Platz“ zu haben, sollte er eingeblendet werden müssen, fügt man folgenden Code in der Aktionenebene ein:

mcError._visible = false;

mcError._x = 0;

mcError._y = 0;

ABBILDUNG 7.2

Der User erhält eine Fehlermeldung sowie die Möglichkeit, den Ladevorgang erneut einzuleiten.

ABBILDUNG 7.3

Der MovieClip mcError wird im unsichtbaren Bereich neben der Bühne platziert.

Sollte die Anzahl der Ladeversuche erreicht sein (siehe Listing 7.4), fügt man folgenden Code ein:

Page 357: Flash cs3, ajax und php

K A P I T E L 7344

...

if(anzLadeversuche<maxLadeversuche) { myLoader.load(mySource); }

else { mcError._visible = true; }

...

Listing 7.6: Die Zeile mcError._visible = true; wird dem Code aus Listing 7.4 hinzugefügt.

Nun verschaffen wir den beiden Buttons noch etwas „Intelligenz“, indem wir Ihnen den Code zuweisen, den sie auslösen sollen:

mcError.btnNein.onRelease = function():Void {

_root.mcError._visible = false;

_root.songTitel = "ERROR WHILE LOADING PLAYLIST";

}

mcError.btnJa.onRelease = function():Void {

_root.myLoader.load(mySource);

_root.mcError._visible = false;

}

Listing 7.7: Die Eventhandler der Buttons btnNein und btnJa

Wird der Nein-Button geklickt, blenden wir den MovieClip mcError aus und geben in den Textfeldern eine Fehlermeldung aus, im Fall des Ja-Buttons wird zusätzlich noch der Ladevorgang erneut gestartet.

7.4.2 Abspielen der SongsBefassen wir uns also nun mit dem wichtigen Thema des Abspielens der Songs. An dieser Stelle ist wieder etwas Konzept vonnöten. Überlegen wir uns, wie das Anwenden der Jukebox vonstatten gehen soll:

1. Über die globale Variable autostart wird entschieden, ob der erste Song abgespielt oder auf das Klicken des Play-Buttons durch den User gewartet werden soll.

2. Mithilfe der Buttons „Start“, „Stopp“, „Ein Song vor“, „Ein Song zurück“ soll man die Playlist abspielen und stoppen können. Des Weiteren wären kleine Icons (eines für jeden Song) nett, die bei Klick den Song gleich direkt aufrufen und abspielen.

3. Ein Lautstärkeregler muss ebenso vorhanden sein wie zwei Informationsfelder, eines zum abgespielten Song und eines zum Darstellen der verbleibenden Abspielzeit.

So weit der Plan. Programmiertechnisch ergeben sich hieraus vorerst einige wesent-liche Konsequenzen:

Page 358: Flash cs3, ajax und php

A U D I O - J U K E B O X 345

1. Klarerweise wird ein Soundobjekt benötigt, um überhaupt Songs abspielen zu können.

2. In jedem Fall müssen wir uns merken, der wievielte Song aus unserer Songliste des Arrays theSongs zu einem gewissen Zeitpunkt abgespielt wird. Hierfür werden wir eine Variable actualSong verwenden, die auf den Index des Arrays theSongs zeigt.

Variablen für die Jukebox

Die beiden Punkte werden uns die wenigsten Kopfschmerzen bereiten, sind sie doch mit wenigen Zeilen erledigt.

var mySong:Sound = new Sound();

var actualSong:Number = 0;

Listing 7.8: Anlegen der beiden Variablen mySong (Soundobjekt) und actualSong im Bild Ladevor-gangErfolgreich in der Ebene „Aktionen“

Autostart der Songs

Widmen wir uns wieder den einfacheren Aufgaben, nämlich dem Auswerten der autostart-Variable. Wie schon weiter oben angesprochen, wird im Fall von auto-start==1 der erste Song (entspricht dem Wert von actualSong) abgespielt, indem die Funktion playSong aufgerufen wird. Auf diese Funktion wird weiter unten einge-gangen. Ansonsten wird im oberen der beiden dynamischen Textfelder der Text „press the PLAY-Button to play songs …“ ausgegeben. Das zweite Textfeld bleibt nach wie vor leer.

Um diesen Vorgang in Gang zu setzen, muss zunächst in Listing 7.5 nach dem Auslesen der XML-Daten der Aufruf der Funktion initPlayer eingefügt werden:

initPlayer();

Diese Funktion erledigt dann die oben genannten Aufgaben:

function initPlayer():Void {

if(parseInt(autostart)==1) { playSong(0); }

else {

theSongInfo1 = "(press the PLAY-Button to play songs...)";

}

}

Listing 7.9: Die if-Bedingung entscheidet über autostart==1 darüber, ob der erste Song abgespielt wird oder ob bei autostart!=1 gewartet und eine entsprechende Meldung übergeben werden soll.

Page 359: Flash cs3, ajax und php

K A P I T E L 7346

Hauptfunktion der Jukebox: playSong()

Wenden wir uns nun der Funktion playSong zu, die einen wesentlichen Bestandteil der Jukebox darstellt. Wie bereits im letzten Listing gezeigt, wird an diese Funktion ein noch nicht näher beschriebener Parameter übergeben. Dieser Parameter wird verwen-det, um genau um den Wert dieses Parameters in der Liste der Songs weiterzuspringen. Dabei kann dieser Parameter drei Werte annehmen, wie Sie der nachfolgenden Tabelle entnehmen können:

Wert Bedeutung

0 Zum aktuellen Songindex (actualSong) wird der Wert 0 hinzugezählt und dieser Song abge-spielt. Dies bedeutet also nichts anderes, als dass der aktuelle Song erneut abgespielt wird.

1 Zum aktuellen Songindex (actualSong) wird der Wert 1 hinzugezählt und dieser Song abge-spielt. Es wird demnach in der Liste der Songs (theSongs) um einen Song weitergesprungen. Was geschehen soll, wenn das Ende der Liste erreicht ist, muss noch defi niert werden.

-1 Zum aktuellen Songindex (actualSong) wird der Wert -1 hinzugezählt und dieser Song ab-gespielt. Es wird demnach in der Liste der Songs (theSongs) um einen Song zurückgesprun-gen. Was geschehen soll, wenn der Anfang der Liste erreicht ist, muss noch defi niert werden.

Tabelle 7.1: Mögliche Übergabewerteparameter der playSong-Funktion

Anfang und Ende der Playlist

Innerhalb der Funktion playSong wird der Parameter als numerische Variable mit dem Namen dir (für „direction“ – Richtung) geführt. Was soll nun geschehen, wenn entweder das Ende oder der Anfang der Songliste überschritten wird? Wir haben uns entschieden, dass bei Überschreiten des Listenendes an den Anfang der Liste und bei Überschreiten des Listenanfangs an das Ende der Liste gesprungen werden soll.

Das Überschreiten des Listenendes erkennt man daran, dass der Listenindex von actualSong gleich der Länge der Liste ist – die Zählung der Listeneinträge im Array beginnt ja bekanntlich bei 0. Das Überschreiten des Listenanfangs erkennt man wie-derum daran, dass der Index den Wert -1 hat: actualSong==-1.

Songindex auslesen

Hat die Variable actualSong schlussendlich den gewünschten Wert erhalten, kann mit dem Laden des entsprechenden Songs aus der Liste begonnen werden. Man liest hierfür aus der Playlist theSongs den Wert aus, der über den Index actual-Song definiert ist: theSongs[actualSong]. Vor diesen Eintrag hängt man noch das Stammverzeichnis der Songs und einen Slash „/“. Das Stammverzeichnis wird über die globale Variable rootDir definiert, die aus der XML-Datei eingelesen wird, und ohne schließendes „/“ angegeben.

Fertig ist die URL, von der Flash die Songdatei beziehen soll. Die Methode loadSound des Soundobjekts erwartet diese URL als ersten Parameter sowie eine Kennzeichnung, ob (true) oder ob die Datei nicht (false) gestreamt geladen werden soll, als zweiten Parameter:

mySong.loadSound("URL", isStreaming)

Page 360: Flash cs3, ajax und php

A U D I O - J U K E B O X 347

Das nachfolgende Listing zeigt Ihnen einen Auszug der Funktion playSong, worin die soeben dargestellten Aufgaben erledigt werden. Das vollständige Listing wird am Ende dieses Abschnitts aufgeführt.

function playSong(dir:Number) {

...

actualSong += dir;

if(actualSong==theSongs.length) { actualSong = 0; }

if(actualSong==-1) { actualSong = theSongs.length-1; }

mySong.loadSound(rootDir+"/"+theSongs[actualSong],true);

...

}

Listing 7.10: Codefragment zum Setzen der Variable actualSong und Laden des entsprechenden Songs aus der Playlist theSongs

Zwischen zwei Songs

Bevor jedoch die MP3-Datei geladen wird, sind noch ein paar „administrative“ Punkte zu regeln:

1. Zwischenzeitlich (bis der neue Song gestartet ist) soll keine Restabspielzeit angezeigt werden, sondern etwas in der Art „--:--“:

theTimeInfo="--:--";

2. Gleiches gilt auch für die zwei Informationszeilen am Display:

songTitel = "getting MP3-Information...";

songInterpret = "";

songAlbum = "";

Somit erweitert sich die Funktion playSong um folgenden Code:

function playSong(dir:Number):Void {

theTimeInfo = "--:--";

songTitel = "getting MP3-Information...";

songInterpret = "";

songAlbum = "";

...

}

Listing 7.11: Codefragment zum Erledigen der „administrativen“ Angelegenheiten.

Page 361: Flash cs3, ajax und php

K A P I T E L 7348

Das vollständige Script zur Funktion playSong sieht somit wie folgt aus:

function playSong(dir:Number):Void {

theTimeInfo = "--:--";

songTitel = "getting MP3-Information...";

songAlbum = "";

songInterpret = "";

actualSong += dir;

if(actualSong==theSongs.length) { actualSong = 0; }

if(actualSong==-1) { actualSong = theSongs.length-1; }

mySong.loadSound(rootDir+"/"+theSongs[actualSong],true);

}

Listing 7.12: Die Funktion playSong in all ihrer Pracht!

Song beendet: nächsten Song abspielen

Nun müssen wir uns noch überlegen, was zu geschehen hat, wenn der nun abgespielte Song zu Ende ist. Wir haben uns entschieden, nach einem fertig abgespielten Song ganz einfach den nächsten Song in der Liste abzuspielen. Die Methode onSoundCom-plete des Soundobjekt s wird genau dann aktiv, wenn ein Song komplett wiedergege-ben wurde. Nichts ist leichter, als zu diesem Zeitpunkt den nächsten Song in der Liste abzuspielen, denn die dafür erforderliche Funktion haben wir bereits: playSong(1). Der Wert 1 als Übergabeparameter teilt der Funktion mit, dass das nächste Lied der Liste abgespielt werden soll.

mySong.onSoundComplete = function() {

playSong(1);

}

Listing 7.13: Codefragment für die Ereignisbehandlung von onSoundComplete, die direkt nach dem Anlegen der Sound-Instanz mySong defi niert werden kann.

Songs per Klick abspielen

Neben dem Abspielen des vorigen, aktuellen oder nächsten Songs soll eventuell auch noch die Möglichkeit bestehen, einen Song direkt anzuwählen. Dafür ist unsere Funk-tion playSong jedoch nicht ausgelegt – hierzu müsste man eine eigene Funktion pro-grammieren, wo etwa die Songs in einer ComboBox aufgelistet werden. Kein Problem für uns – öffnen Sie die Datei audioplayer_03.fla von der Buch-CD – die Erklärung finden Sie weiter unten im Kapitel, da diese Variante in ActionScript 3.0 umgesetzt wurde.

Page 362: Flash cs3, ajax und php

A U D I O - J U K E B O X 349

7.4.3 ID3-Tags auslesenAbschließend sollte man bei Auswahl eines neuen Songs natürlich auch die entspre-chenden Informationen zu ihm erhalten. Wurde beim Aufnehmen der MP3-Daten darauf geachtet, dass die Informationen zum Album mitgespeichert werden, so werden diese Informationen beim Aufnehmen mit in die MP3-Datei „verpackt“ und sind somit zu jeder Zeit verfügbar. Im Allgemeinen geschieht dies entweder durch automatisiertes Abfragen einer Datenbank (beispielsweise CDDB) durch Ihr Aufnahmeprogramm oder durch händisches Eingeben der Informationen vor der Aufnahme.

Da alle gängigen Aufnahmeprogramme wie zum Beispiel iTunes von Apple oder die Jukebox von MusicMatch (Yahoo) nach diesem Verfahren arbeiten, können wir Entwickler davon ausgehen, dass auch unsere MP3-Daten diese Informationen gespeichert haben. Flash kann – wie sollte es auch anders sein – auf diese Informa-tionen zugreifen. Hierzu existiert für ein Soundobjekt das Sub-Objekt id3 , dessen Eigenschaften genau die gewünschten Daten beinhaltet. Man nennt diese MP3-Infor-mationen auch die „ID3-Tags“, deshalb auch der Objektname id3. Die für uns interes-santen Eigenschaften sind in der folgenden Tabelle zusammengefasst. Eine komplette Auflistung aller Eigenschaften finden Sie in der ActionScript-Referenz , die Sie von der Macromedia-Site downloaden können: http://www.macromedia.com/support/documentation/de/flash/. Alternativ dazu könnte man natürlich die notwen-digen Informationen zum Song in die XML-Datei aufnehmen, da man – möchte man absolut sichergehen – nicht zu 100% davon ausgehen kann, dass die ID3-Tags wirklich in der MP3-Datei gespeichert sind.

Tag Enthaltene Information

id3.artist Name des Interpreten

id3.songname Songtitel

id3.album Name des Albums

id3.TLEN Länge des Songs (in Millisekunden)

Tabelle 7.2: Auflistung der für unsere Jukebox interessanten Eigenschaften des id3-Objekts der Version 1

Neben den hier dargestellten id3-Tags existieren noch weitere, die einer neueren Generation angehören. Sie sind in Flash unter der Bezeichnung id3 Version 2 zu finden – genauere Informationen hierzu entnehmen Sie bitte der Flash-Referenz.

In der ersten Zeile des Displays sollen die Informationen zum Titel in Zeile 2 und in Zeile 3 die Infos zu Interpret und dem Albumtitel stehen. Wie diese Informationen in die dynamischen Textfelder gelangen, wird hier nicht gesondert erläutert. Sollten Sie dazu Fragen haben, schauen Sie sich den Code am besten direkt in der fla-Datei von der Buch-CD an.

Page 363: Flash cs3, ajax und php

K A P I T E L 7350

Da die ID3-Informationen nicht sofort zur Verfügung stehen, sondern erst dann, wenn ein gewisser Teil der MP3-Datei geladen ist, müssen wir ein Ereignis abwarten, das uns das Vorhandensein dieser Informationen anzeigt: onID3.

mySong.onID3 = function():Void {

songInterpret = mySong.id3.artist;

songAlbum = mySong.id3.album;

songTitel = mySong.id3.songname;

showTimer(Math.fl oor(mySong.id3.TLEN/1000));

}

Listing 7.14: Codefragment zum Einlesen und Ausgeben der ID3-Informationen

Restspielzeit anzeigen

Die Darstellung der Restspielzeit gestaltet sich dabei auch etwas aufwändiger – hier werden wir eine eigene Funktion aufrufen, in der wir mit einem Intervall arbeiten. Dieser Funktion (showTimer) übergeben wir primär die Länge des Songs in Sekun-den, weshalb eine Division durch 1000 und eine Rundung des Ergebnisses erforderlich ist. Alles weitere passiert dann innerhalb dieser Funktion.

Idealerweise realisiert man dies mithilfe der Methode setInterval . Wie in der Funk-tion playSong ersichtlich, wird in der Ereignisbehandlungsroutine des Ereignisses onID3 die Funktion showTimer wie folgt aufgerufen:

showTimer(Math.fl oor(mySong.id3.TLEN/1000));

Der Übergabewert an showTimer ist die (abgerundete) Länge des MP3-File und wird innerhalb der Funktion in der Variable theLength gespeichert. Sobald die Funktion showTimer aufgerufen wird, wird zunächst ein (bis dato noch nicht verwendetes) Intervall gelöscht: clearInterval(itvTimer). Der Grund dafür ist, dass im Wei-teren über showTimer jede Sekunde dasselbe Intervall erneut gestartet wird, das wiederum die Funktion showTimer mit einem genau um eine Sekunde verminderten Wert für den Parameter aufruft.

Letzten Endes wird hier nicht die Funktionsweise des Intervalls, sondern vielmehr die eines Timers verwendet. Sollte theLength>=0 sein – also das Lied noch nicht zu Ende sein –, wird der Wert für die Restabspielzeit wie folgt berechnet:

1. Zunächst werden die Minuten ermittelt: Hierzu dividiert man die Restzeit in Sekunden durch 60 und rundet ab:

theTimeInfo = "-"+Math.fl oor(theLength/60)+":";

Vor diesen Wert wird noch ein „–“ (Minus) gesetzt, um die Restdauer anzudeuten. Hinter den Minutenwert wird ein Doppelpunkt gesetzt.

Page 364: Flash cs3, ajax und php

A U D I O - J U K E B O X 351

2. Danach werden die restlichen Sekunden ermittelt, indem man den Minutenwert mit 60 multipliziert und diesen Wert von den Gesamtsekunden (theLength) abzieht:

theLength-60*Math.fl oor(theLength/60)

Sollte dieser Wert kleiner als zehn sein, so sollte man der Sekundenanzeige eine Null vorsetzen („09“ wirkt besser als „9“):

if(theLength-60*Math.fl oor(theLength/60)<10) { theTimeInfo += "0"; }

Der Sekundenwert wird schlussendlich auch noch an den beinahe schon kompletten String für die Ausgabe angehängt:

theTimeInfo += theLength-60*Math.fl oor(theLength/60);

3. Nur zur Erinnerung: Die globale Variable theTimeInfo ist diejenige Variable, die im dynamischen Textfeld für die Restabspielzeit ausgegeben wird. Abschließend muss das Intervall nur noch erneut aufgerufen werden:

itvTimer = setInterval(showTimer,1000,theLength-1);

Das vollständige Listing der Funktion showTimer sieht wie folgt aus:

function showTimer(theLength:Number):Void {

clearInterval(itvTimer);

if(theLength>=0) {

theTimeInfo = "-"+Math.fl oor(theLength/60)+":";

if(theLength-60*Math.fl oor(theLength/60)<10) { theTimeInfo += "0"; }

theTimeInfo += theLength-60*Math.fl oor(theLength/60);

itvTimer = setInterval(showTimer,1000,theLength-1);

}

}

Listing 7.15: Das vollständige Listing der Funktion showTimer

7.4.4 AbspielsteuerungErfreulicherweise haben wir alle aufwändigeren Codes hinter uns gebracht und kön-nen uns nun einer einfacheren Funktion widmen: der Funktion stopSound, die für das Stoppen eines gerade abgespielten Songs verantwortlich ist. Dies geschieht über die einfache Methode stop() des Soundobjekts: mySong.stop();. Gleichzeitig mit dem Stoppen des Songs müssen noch zwei weitere Aufgaben erledigt werden:

Das laufende Intervall muss gelöscht werden:

clearInterval (itvTimer);

Page 365: Flash cs3, ajax und php

K A P I T E L 7352

Das Display muss aktualisiert werden:

theTimeInfo = "--:--";

theSongInfo1 = "(stopped)";

theSongInfo2 = "";

Erledigt. Abschließend noch das Listing:

function stopSong():Void {

mySong.stop();

clearInterval(itvTimer);

theTimeInfo = "--:--";

songTitel = "(stopped)";

songInterpret = "";

songAlbum = "";

}

Listing 7.16: Code der Funktion stopSong

Kommen wir zu den Buttons, also der Abspielsteuerung unserer Jukebox. Sie werden sehen, dass die Buttons mit Sicherheit die einfachste Aufgabe darstellen:

Button „Play“:

btnPlay.onRelease = function():Void {

playSong(0);

}

Button „Stopp“:

btnStop.onRelease = function():Void {

stopSong();

}

Button „Ein Song zurück“:

btnRWD.onRelease = function():Void {

playSong(-1);

}

Button „Ein Song vor“:

btnFWD.onRelease = function:Void {

playSong(1);

}

u

u

u

u

Page 366: Flash cs3, ajax und php

A U D I O - J U K E B O X 353

7.4.5 Lautstärkeregler Sie denken, wir hätten damit das Ende erreicht? Beinahe. Bleibt einzig noch der Laut-stärkeregler, der eigentlich ganz simpel zu programmieren ist. Aber zunächst einige Gedanken zur Funktionsweise:

1. Durch Klicken auf die Spur des Reglers soll die Lautstärke auf den entsprechenden Wert gesetzt werden.

2. Die Lautstärke soll mit der Maus per Drag&Drop gesetzt werden können, wobei sich während des Ziehens die Lautstärke kontinuierlich verändern soll.

Diese aufgelisteten Punkte werden uns zum Ende hin noch einmal ein wenig schwitzen lassen, aber dafür haben wir es dann geschafft – zumindest in Flash.

ABBILDUNG 7.4

Der Lautstärkeregler ist ein eigenes Symbol in der Bibliothek, ebenso wie die Spur & Maske des Reglers (MovieClip).

Das Symbol ist in vier Ebenen unterteilt:

Ebene „hg“: Diese beinhaltet den MovieClip mcSpur, der zu 50% transparent ist. Er dient dazu, dass der User beim Verstellen der Lautstärke immer noch weiß, wie hoch er die Lautstärke stellen kann. Des Weiteren werden wir die Spur dafür ver-wenden, dass der User auf diese klicken und somit die Lautstärke verstellen kann.

Ebene „Text“: Diese beinhaltet lediglich den Text „VOL“.

Ebene „Items“: Sie beherbergt die zehn blauen Striche, die zur symbolhaften Dar-stellung der Lautstärke dienen.

Ebene „Maske“: Sie legt fest, wie viel der Ebene „Items“ angezeigt wird. Als Maske wird derselbe MovieClip verwendet wie für die Spur (mcLautstaerkeMaske in der Bibliothek), da diese sowieso nie sichtbar sein wird.

u

u

u

u

Page 367: Flash cs3, ajax und php

K A P I T E L 7354

In der Listener-Ebene auf der Hauptbühne platzieren wir den Code, der beim Drücken und Loslassen der Maustaste über dem Lautstärkeregler ausgeführt werden soll:

var itvLautstaerke;

mcLautstaerke.mcSpur.onPress = function():Void {

itvLautstaerke = setInterval(setLautstaerke,50);

}

mcLautstaerke.mcSpur.onRelease = function():Void {

clearInterval(itvLautstaerke);

}

mcLautstaerke.mcSpur.onReleaseOutside = function():Void {

clearInterval(itvLautstaerke);

}

Listing 7.17: Der Code für die Lautstärkesteuerung ist relativ einfach, sehen wir einmal von der noch nicht defi nierten Funktion setLautstaerke ab.

Die Variable itvLautstaerke wird für ein Intervall verwendet, auf das wir später noch zu sprechen kommen. Interessanter wird es schon, wenn wir die Funktionenebe-ne etwas näher betrachten:

function setLautstaerke():Void {

var mousex:Number = mcLautstaerke._xmouse;

var maxX:Number = mcLautstaerke.mcSpur._width;

mcLautstaerke.mcMaske._width = mousex;

mySong.setVolume(mousex/maxX*100);

}

Listing 7.18: In der Funktionenebene wird die Funktion setLautstaerke defi niert.

Sobald die Funktion setLautstaerke aufgerufen wird, wird die Position der Maus innerhalb des Lautstärkereglers ermittelt (mcLautstaerke._xmouse). Da sich die Spur an der Position (0/0) befindet, entspricht die Mausposition in x-Richtung auch direkt der zu setzenden Lautstärke. Die Variable maxX fragt die maximale Lautstärke ab, indem sie die Breite der Spur ermittelt (mcLautstaerke.mcSpur._width). Danach wird die Breite der Maske für die Lautstärke-Items (siehe Erklärung zu Abbildung 7.4) noch auf genau den Wert gesetzt, wo die Maus des Users gerade steht. Abschließend errechnen wir aus Mausposition und maximaler Lautstärke die tatsächliche Lautstärke für den Song (in Prozent von 0–100) und weisen diese der Soundinstanz mySong zu (mousex/maxX*100).

Sprechen wir noch kurz über das Intervall itvLautstaerke. Das Problem mit einer Lautstärkeregelung in dieser Art und Weise ist, dass der Ablauf wie folgt sein soll:

Page 368: Flash cs3, ajax und php

A U D I O - J U K E B O X 355

1. Sobald der User auf den Lautstärkeregler klickt und die Maus noch gedrückt hält, soll die Lautstärke gesetzt werden – auch wenn der User dabei die Maus bewegt. Da das auftretende Ereignis das Ereignis onPress ist und dieses nur einmal auftritt (nämlich beim Hinunterdrücken der Maustaste), könnte die Lautstärke auch nur zu diesem Zeitpunkt gesetzt werden, unabhängig davon, wie lange er die Maustaste unten hält.

2. Beim Loslassen der Maustaste (innerhalb oder außerhalb des Reglers) soll das Setzen der Lautstärke wieder beendet werden. Die möglichen auftretenden Ereignisse nennen sich onRelease und onReleaseOutside – auch diese beiden treten nur einmal auf, was uns jedoch nicht behindert.

Der Ausweg aus der im ersten Punkt dargestellten Problematik ist, dass sobald der User die Maustaste nach unten drückt, ein Intervall itvLautstaerke startet, das in regel-mäßigen Abständen (bei uns sind das 50 Millisekunden – entspricht einer Framerate von 20 Bildern pro Sekunde: 1/20 Sekunde pro Bild) die Lautstärke setzt (über den Aufruf der Funktion setLautstaerke). Beim Loslassen der Maustaste muss dieses Intervall nur noch wieder gelöscht werden.

7.5 Der PHP-Part Nun geht’s endlich mit der PHP-Programmierung los. Unser Ziel ist es, alle MP3-Dateien eines bestimmten Verzeichnisses unseres Webservers auszulesen und diese Daten in XML-Form an Flash zu übergeben. Sie werden sehen, dass dies auf einfache Art und Weise zu realisieren ist.

Zuerst müssen wir natürlich eine PHP-Datei erstellen. Der Name wird uns in diesem Fall von Flash vorgegeben, da beim Einlesen der XML-Datei die Datei playlist.php gewünscht wird. Somit nennen wir unsere Datei auch entsprechend „playlist.php“.

Sofern Sie noch keinen Ordner mit MP3-Dateien auf Ihrem Server erstellt haben, sollten Sie das jetzt tun. Erstellen Sie den Ordner im gleichen Verzeichnis wie die Flash-Datei und nennen Sie ihn „songs“. Zur Sicherheit sollten Sie bei der Benennung der Files auf Leer- und Sonderzeichen verzichten. So weit, so gut.

Um in unserer Programmierung flexibel zu bleiben, speichern wir den Ordner der MP3-Files und auch die Einstellung für den Autostart in jeweils einer eigenen Variable ab. Würde sich später der Ordnername ändern, müssten wir bloß den Wert der Variable korrigieren und nicht an jeder Stelle im Skript, an der auf den Ordner verwiesen wird.

if(!isset($_GET["dir"])) { $dir = "songs"; }

else { $dir = $_GET["dir"]; }

if(!isset($_GET["autostart"]) || is_nan($_GET["autostart"])) { $autostart = 0; }

else { $autostart = $_GET["autostart"]; }

Listing 7.19: Anlegen der Variablen für den MP3-Ordner ($dir) und den Wert von $autostart

Page 369: Flash cs3, ajax und php

K A P I T E L 7356

Wie Sie sehen, kann per GET sowohl das auszulesende Verzeichnis der MP3-Files ($_GET["dir"]) als auch die Info über ein Autostart ($_GET["autostart"]) an die Datei übergeben werden, was unser Script sehr flexibel macht.

Verzeichnis auslesen

Um an die Dateien eines Verzeichnisses zu kommen und diese auszulesen, benötigen wir insgesamt drei PHP-Funktionen.

opendir(): Mit der Funktion opendir() können wir den gewünschten Ordner öffnen . Diese Funktion erfordert nur den Pfad zum Ordner und logischerweise auch den Ordernamen selbst.

readdir(): Mit readdir() können wir immer eine Datei des geöffneten Ordners auslesen. Um alle Files nacheinander auszulesen, werden wir uns einer Schleife bedienen. Auch readdir() benötigt allein den Pfad zum Ordner und den Ord-nernamen.

closdir(): Diese Funktion ist notwendig, um das geöffnete Verzeichnis wieder zu schließen.

Da wir nun die notwendigen PHP-Funktionen kennen, ist es nicht mehr schwer, unse-re MP3-Files auszulesen. Zuerst öffnen wir das benötigte Verzeichnis mit opendir(). Als Parameter geben wir einfach die Variable $dir aus Listing 7.19 an, da in dieser ja der Ordnername, in unserem Fall „songs“, gespeichert wurde.

$verz = opendir($dir);

Zur Erinnerung schauen wir uns noch einmal die gewünschte XML-Struktur an, die Flash benötigt.

<Playlist rootDir="Verzeichnis" autostart="0">

<song src="MP3-Filename"></song>

...

</Playlist>

Listing 7.20: Die notwendige XML-Struktur, die es zu erzeugen gilt

Bei Betrachten des ersten Knotens sehen Sie, dass wir mit diesem bereits alle notwen-digen Informationen angeben, also den Pfad zum Ordner, den Ordnernamen und den Wert für Autostart. Um später eine korrekte XML-Struktur mit der richtigen Forma-tierung erstellen zu können, speichern wir unsere Knoten in einer Variable $playlist. Diese Variable werden wir schlussendlich per echo in das Dokument ausgeben..

$playlist = ‚<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';

$playlist.= ‚<Playlist rootDir="'.$dir.'" autostart="'.$autostart.'">';

Listing 7.21: Erstellen der XML-Defi nition des Dokuments sowie des ersten Knotens <Playlist>

u

u

u

Page 370: Flash cs3, ajax und php

A U D I O - J U K E B O X 357

Als Nächstes müssen wir die MP3-Files aus unserem Ordner auslesen. Dazu bedienen wir uns der PHP-Funktion readdir(), mit der man immer eine Datei eines bestimm-ten Ordners auslesen kann. Um alle Dateien des Ordners auslesen zu können, werden wir eine while-Schleife nutzen.

Die Funktion readdir() gibt den booleschen Wert true zurück, wenn das Lesen im Verzeichnis erfolgreich war. In unserer while-Schleife soll der Knoten song so lange erstellt werden, wie Dateien im Ordner „songs“ gefunden werden. Die gefundenen Dateien speichern wir in der Variable $file ab.

while($fi le = readdir($verz)) {

...

}

Daten prüfen

Ein guter Programmierer sollte immer alle notwendigen Daten überprüfen. In unserem Fall möchten wir nur Dateien vom Typ .mp3 in unsere XML-Struktur auf-nehmen. Somit müssen wir zum einen kontrollieren, ob es sich generell um eine Datei (und keinen weiteren Ordner) handelt und ob diese vom Typ .mp3 ist. Dazu bietet uns PHP wieder Funktionen, die wir direkt nutzen können.

is_dir(): Mit is_dir() prüfen wir, ob es sich um ein Verzeichnis handelt. In unserem Fall werden wir diese Abfrage negieren, da wir wissen wollen, ob es sich nicht um einen weiteren Ordner handelt.

substr(): Diese Funktion gehört zu den Zeichenkettenfunktionen. substr() erwartet einen String und einen Startwert (Position im String), ab dem der Teilst-ring erzeugt werden soll. Als Rückgabe wird der restliche String ab dem definierten Startwert zurückgeben. Um die Zählung von hinten beginnen zu lassen, wird ein-fach der Startwert negativ gesetzt.

Somit ergibt sich folgender Code für die Abfrage:

if(!is_dir($fi le) && (substr ($fi le,-3)=="mp3"))

Innerhalb der Abfrage erweitern wir die bereits vorhandene Variable $playlist um die eingelesene Datei:

$playlist .= ‚<song src="'.$fi le.'" />';

Nachdem wir nun alle MP3-Files aus dem Ordner „songs“ gelesen haben, schließen wir außerhalb der while-Schleife den geöffneten Ordner wieder.

closedir($verz);

Abschließend wird das geöffnete <Playlist>-Tag wieder geschlossen, der Inhalt in eine UTF8-kodierte Form gebracht (sollte das nicht gewünscht sein, so entfernen Sie diese Zeile einfach aus Ihrem Script) und $playlist per echo ausgegeben:

u

u

Page 371: Flash cs3, ajax und php

K A P I T E L 7358

$playlist .= ‚</Playlist>';

$playlist = utf8_encode($playlist);

echo($playlist);

Das vollständige Skript sollte nun so aussehen:

if(!isset($_GET["dir"])) { $dir = "songs"; }

else { $dir = $_GET["dir"]; }

if(!isset($_GET["autostart"]) || is_nan($_GET["autostart"])) { $autostart = 0; }

else { $autostart = $_GET["autostart"]; }

$verz = opendir($dir);

$playlist = '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';

$playlist.= '<Playlist rootDir="'.$dir.'" autostart="'.$autostart.'">';

while($fi le = readdir($verz)) {

if(!is_dir($fi le) && (substr($fi le,-3)=="mp3")) {

$playlist .= '<song src="'.$fi le.'" />';

}

}

closedir($verz);

$playlist .= ‚</Playlist>';

$playlist = utf8_encode($playlist);

echo($playlist);

Listing 7.22: Erstellen der XML-Struktur durch Auslesen der MP3-Files aus einem gegebenen Ordner

Um die Jukebox zu testen, müsste die PHP-Datei in einer Serverumgebung (wie etwa dem XAMPP-Server oder online) getestet werden. Hierzu laden Sie die Datei inklusive der MP3-Dateien im angegebenen Ordner in das Verzeichnis, das Sie bei der Installa-tion als Root-Verzeichnis angegeben haben, und rufen Sie die php-Datei im Browser auf:

Page 372: Flash cs3, ajax und php

A U D I O - J U K E B O X 359

7.6 Jukebox in ActionScript 3.0In Kapitel 7.4 wurde die Jukebox in ActionScript 2.0 entwickelt – nun wenden wir uns ActionScript 3.0 zu und werden sehen, an welchen Stellen der Code (eventuell grundlegend) verändert werden muss. Idealerweise nehmen Sie sich die Datei audio-player_01.fla von der Buch-CD zur Hand und verfolgen dort die Änderungen.

7.6.1 Allgemeine ÄnderungenEin wesentlicher Unterschied von ActionScript 2.0 auf ActionScript 3.0 ist die geän-derte Schreibweise des reservierten Worts VOID:

ActionScript 2.0: VOID wird mit einem großen Anfangsbuchstaben geschrieben: Void.

ActionScript 3.0: VOID wird mit einem kleinen Anfangsbuchstaben geschrieben: void.

Dies betrifft alle unsere Funktionen ohne Rückgabewert und das sind 15 an der Zahl, die wir verteilt in den Ebenen Aktionen, Funktionen und Listener finden.

Weitere Änderungen sind:

Sämtliche Variablen, die innerhalb von ActionScript 3.0 Verwendung finden, müssen explizit deklariert werden – eine implizite Deklarierung ist nicht möglich. Somit müssen die Attribute autostart und rootDir, die in der XML-Datei im Tag <Playlist> verwendet werden, explizit deklariert werden.

u

u

u

ABBILDUNG 7.5

Die Erfolgsbilanz ist positiv: Der Audioplayer läuft auch im Browser ohne Probleme!

Page 373: Flash cs3, ajax und php

K A P I T E L 7360

Ein Zugriff auf globale Variablen ist nicht mehr möglich, da es keine globalen Vari-ablen mehr gibt. Damit entfällt der Verweis auf _global komplett.

Ebenso existiert der Zugriff auf _root nicht mehr – dieser lautet nun nur noch root (ohne Unterstrich am Anfang).

Im Allgemeinen werden Eigenschaften eines MovieClips nun nicht mehr mit einem beginnenden Unterstrich „_“ angegeben – der Unterstrich entfällt komplett.

Textfelder, die auf Variablennamen zugreifen, um so den Wert der Variable darzu-stellen, werden nicht mehr unterstützt – diese müssen nunmehr mit dem Feldna-men angesprochen werden.

7.6.2 Änderungen beim Laden der XML-DatenDa in ActionScript 3.0 ein allgemeines Objekt URLRequest in Verbindung mit URL-Loader zum Laden von Daten eingeführt wurde, läuft das Laden von XML-Daten nun auch anders ab – damit haben wir uns schon recht ausführlich im vorigen Kapitel befasst. Anstatt die load-Methode des XML-Objekts zu verwenden, wird nun mit URLLoader und URLRequest gearbeitet. Somit wird:

var myLoader:XML = new XML();

myLoader.ignoreWhite = true;

...

myLoader.load(mySource);

zu:

var myRequest:URLRequest = new URLRequest(mySource);

var myLoader:URLLoader = new URLLoader();

var myXML:XML;

...

myLoader.load(myRequest);

Die Eigenschaftszuweisung ignoreWhite = true darf erst dann passieren, wenn der XML-Instanz wirklich XML-Daten zugewiesen wurden.

Der Eventhandler, der beim vollständigen Laden der Daten aufgerufen wird, muss auch entsprechend abgeändert werden. Aus:

myLoader.onLoad = function():Void {

...

}

wird:

function EXMLComplete(myEvent:Event):void {

u

u

u

u

Page 374: Flash cs3, ajax und php

A U D I O - J U K E B O X 361

...

}

myLoader.addEventListener(Event.COMPLETE, EXMLComplete);

Innerhalb des Eventhandler EXMLComplete wird nun ebenfalls auf geänderte Art und Weise auf die XML-Daten zugegriffen. Anstatt die Elemente des XML-Baums Schritt für Schritt durchzuparsen, können wir direkt auf die Elemente zugreifen. Die gesamte Funktion erhält nun folgenden Inhalt:

function EXMLComplete(myEvent:Event):void {

myXML = new XML(myEvent.target.data);

myXML.ignoreWhite = true;

autostart = parseInt(myXML.@autostart);

rootDir = myXML.@rootDir;

for(var i:uint=0; i<myXML.song.length(); i++) {

theSongs[i] = myXML.song[i].@src;

}

}

Listing 7.23: Die Funktion EXMLComplete (Eventhandler für das Laden von Daten) enthält nun keine Fehlerbehandlung mehr.

Die Fehlerbehandlung (mehrmaliges Laden von Daten, falls der Ladeversuch fehl-geschlagen hat) ist hierin nicht mehr definiert, da die gesamte Fehlerbehandlung in ActionScript 3.0 nun anders verläuft. Ein Fehler, der am wahrscheinlichsten auftritt, ist ein IOError – diesen gilt es abzufangen:

function EIOError(myEvent:IOErrorEvent):void {

anzLadeversuche++;

if(anzLadeversuche<maxLadeversuche) { myLoader.load(myRequest); }

else {

mcError.visible = true;

}

}

myLoader.addEventListener(IOErrorEvent.IO_ERROR, EIOError);

Listing 7.24: Die Funktion EIOError verarbeitet einen IOError. Bitte beachten Sie auch, dass die Eigen-schaft visible nun ohne führendem Unterstrich „_“ geschrieben wird.

Page 375: Flash cs3, ajax und php

K A P I T E L 7362

Schaltflächenereignisse: addEventListener

Da wir mit dem MovieClip mcError arbeiten und den Buttons btnJa und btnNein in diesem MovieClip release-Ereignisse zugewiesen haben, müssen wir uns noch um diese kümmern. In ActionScript 3.0 lassen sich Schaltflächenereignisse nicht mehr direkt zuweisen – vielmehr muss der Weg über addEventListener führen:

Aus:

var songTitel:String = "loading Playlist...";

var songInterpret:String = "";

var songAlbum:String = "";

var theTimeInfo:String = "--:--";

mcError.btnNein.onRelease = function():Void {

_root.mcError._visible = false;

_root.songTitel = "ERROR WHILE LOADING PLAYLIST";

}

mcError.btnJa.onRelease = function():Void {

_root.myLoader.load(mySource);

_root.mcError._visible = false;

}

wird:

Titel.text = "loading Playlist...";

Interpret.text = "";

Album.text = "";

Restzeit.text = "--:--";

function ENeinUp(myEvent:MouseEvent):void {

mcError.visible = false;

Titel.text = "ERROR WHILE LOADING PLAYLIST";

}

function EJaUp(myEvent:MouseEvent):void {

myLoader.load(myRequest);

mcError.visible = false;

}

mcError.btnNein.addEventListener(MouseEvent.MOUSE_UP, ENeinUp);

mcError.btnJa.addEventListener(MouseEvent.MOUSE_UP, EJaUp);

Listing 7.25: ActionScript 3.0 erfordert addEventListener für die Zuweisung von Eventhandlern (auch bei Schaltfl ächen).

addEventListe-ner nun auch für

Schaltflächen

addEventListe-ner nun auch für

Schaltflächen

Page 376: Flash cs3, ajax und php

A U D I O - J U K E B O X 363

Diese Vorgehensweise gilt im Übrigen selbstverständlich auch für sämtliche anderen Buttons, die wir im Audioplayer verwenden: Play, Stop, FWD, RWD.

Die Variablen songTitel, songAlbum und songInterpret aus ActionScript 2.0 wurden durch den Zugriff auf die dynamischen Textfelder über deren Namen ersetzt, da der direkte Zugriff von dynamischen Textfeldern auf Variablen (zur Darstellung von deren Werten) nicht mehr möglich ist. Stattdessen greift man auf den Namen des Textfelds und dessen Eigenschaft text zu.

7.6.3 Änderungen im SoundobjektGrundsätzlich wurde die Sound-Klasse in das Paket flash.media.Sound verschoben. Jedoch ist dies bei weitem nicht die einzige Änderung, welche die neue ActionScript-Version mit sich bringt.

1. Laden von Sounddateien: Wie in ActionScript 3.0 üblich, erfolgt das gesamte Laden von Dateien über das URLRequest-Objekt. Somit wird beim Laden von Sounddateien einem Soundobjekt beim Laden eine Instanz eines URLRequest-Objekts zugewiesen.

2. Verwenden der Sound-Klasse: Diese wird zum Laden von Sounddateien, Verwalten allgemeiner Soundeigenschaften sowie zum Starten der Soundwiedergabe verwendet.

3. Verwenden der SoundChannel-Klasse: Sobald über die Sound-Klasse eine Sounddatei abgespielt wird, wird eine neue Instanz eines SoundChannel-Objekts erzeugt. Damit wird im Weiteren die Wiedergabe gesteuert.

Des Weiteren ist es nun möglich, auch gestreamte Sounds ab einer gewissen Position abspielen zu lassen – dies ermöglicht es uns, einen Pause-Button für Streaming-Sounds zu erstellen. (Dies ist in diesem Beispiel auch umgesetzt worden: Der Stop-Button wurde in einen Pause/Stop-Button umgewandelt – Details siehe weiter unten.)

7.6.4 Änderungen in der AbspielsteuerungDie Abspielsteuerung betrifft die Buttons Play, Stop, RWD und FWD. Hier sind Ände-rungen an den Eventhandlern der Buttons vorzunehmen, da die direkte Zuweisung von Ereignissen in ActionScript 3.0 nicht mehr funktioniert. Somit erhalten wir anstatt:

btnPlay.onRelease = function():Void { playSong(0); }

btnStop.onRelease = function():Void { stopSong(); }

btnRWD.onRelease = function():Void { playSong(-1); }

btnFWD.onRelease = function():Void { playSong(1); }

Listing 7.26: ActionScript-2.0-Code ...

Zugriff auf dyna-mische Textfelder über text

Zugriff auf dyna-mische Textfelder über text

Page 377: Flash cs3, ajax und php

K A P I T E L 7364

nun:

var isPaused:Boolean = false;

var isStopped:Boolean = false;

var pausingPos:Number = 0;

function EPlay(myEvent:MouseEvent):void { playSong(0); }

function EStop(myEvent:MouseEvent):void {

if(!isStopped) {

if(!isPaused) {

isPaused = true;

pausingPos = mySoundchannel.position;

}

else {

isPaused = false;

isStopped = true;

pausingPos = 0;

}

stopSong();

}

}

function ERWD(myEvent:MouseEvent):void { playSong(-1); }

function EFWD(myEvent:MouseEvent):void { playSong(1); }

btnPlay.addEventListener(MouseEvent.MOUSE_UP, EPlay);

btnStop.addEventListener(MouseEvent.MOUSE_UP, EStop);

btnFWD.addEventListener(MouseEvent.MOUSE_UP, EFWD);

btnRWD.addEventListener(MouseEvent.MOUSE_UP, ERWD);

Listing 7.27: ... im Gegensatz zu ActionScript-3.0-Code. Die Funktion EStop musste erweitert werden, da der Stop-Button nun zwei Funktionen (Pause und Stopp) übernehmen soll.

Wie Sie sehen, nennt sich das onRelease-Ereignis nun Mouse_UP und befindet sich in der Klasse MouseEvent. In der Funktion EStop finden Sie wesentlich mehr Code als im vergleichbaren Code in ActionScript 2.0. Dies hat hauptsächlich mit zwei Dingen zu tun:

Page 378: Flash cs3, ajax und php

A U D I O - J U K E B O X 365

1. Nachdem es in ActionScript 3.0 nun auch möglich ist, einen gestreamten Sound an einer gewissen Stelle starten zu lassen, kann ein „Pause“-Verhalten programmiert werden: Beim ersten Klick auf den Pause/Stop-Button wird der Song pausiert (bei Klick auf den Play-Button startet der Sound an der gestoppten Stelle), beim zweiten Klick wird er tatsächlich gestoppt und beginnt bei einem Klick auf den Play-Button von Neuem.

2. Da nun sowohl mit einem Sound- als auch mit einem SoundChannel-Objekt zu arbeiten ist, wird das Stoppen eines Sounds aufwändiger: Es muss einerseits (sofern der Datentransfer der Datei noch im Gange ist; betrifft die Sound-Instanz) der Datentransfer und andererseits das Abspielen des Songs (betrifft die SoundChannel-Instanz) gestoppt werden. Da nur ein laufender Transfer und nur ein gerade aktiver SoundChannel gestoppt werden kann, muss man sich – beispielsweise in Form einer Variable – „merken“, ob eben gerade abgespielt wird. Eine Alternative zu dieser Vorgehensweise ist die Variante mit try & catch, die in der Datei audioplayer_02a.fl a dargestellt ist.

Der Ablauf der EStop-Funktion ist also wie folgt:

Sofern der Song nicht schon gestoppt ist (das wäre bei isStopped==true), wird überprüft ob der Song noch nicht pausiert ist (isPaused==false).

Falls isPaused==false wird der Song „pausiert“ (natürlich wird das Abspielen komplett gestoppt, aber die Position des Abstoppens wird in der Variable pausing-Pos gespeichert).

Falls isPaused==true wird der Song gestoppt (dies bedeutet, dass pausingPos=0 gesetzt wird).

Wie Sie sehen, spielt die Variable pausingPos eine wesentliche Rolle: Grundsätzlich wird jeder Song über diese Variable pausingPos (Anzahl der Millisekunden ab Beginn der Sounddatei) gestartet. Aus diesem Grund muss im Fall eines tatsächlich gestoppten Sounds die Variable pausingPos den Wert 0 erhalten.

Des Weiteren müssen die Funktionen playSong und stopSong entsprechend ange-passt werden:

var mySound:Sound;

var mySoundchannel:SoundChannel;

function playSong(dir:Number):void {

if(isStopped || dir!=0) { Restzeit.text = "--:--"; }

Titel.text = "getting MP3-Information...";

Album.text = "";

Interpret.text = "";

u

u

u

Page 379: Flash cs3, ajax und php

K A P I T E L 7366

actualSong += dir;

if(actualSong==theSongs.length) { actualSong = 0; }

if(actualSong==-1) { actualSong = theSongs.length-1; }

isPaused = false;

isStopped = false;

if(dir!=0) { pausingPos = 0; }

if(mySound!=null && !isStopped) { stopSong(); }

myRequest.url = rootDir+"/"+theSongs[actualSong];

mySound = new Sound();

mySound.addEventListener(Event.ID3, EID3);

mySoundchannel = new SoundChannel();

mySoundchannel.addEventListener(Event.SOUND_COMPLETE, ESoundComplete);

mySound.load(myRequest);

mySoundchannel = mySound.play(pausingPos);

}

function stopSong():void {

mySoundchannel.stop();

if(mySound.bytesLoaded!=mySound.bytesTotal) { mySound.close(); }

clearInterval(itvTimer);

if(isStopped) {

Restzeit.text = "--:--";

Titel.text = "(stopped)";

Interpret.text = "";

Album.text = "";

}

}

Listing 7.28: Die „neuen“ Funktionen playSong und stopSong

Page 380: Flash cs3, ajax und php

A U D I O - J U K E B O X 367

Befassen wir uns zunächst mit der playSong-Funktion, welche die eingangs erzeugte Sound-Instanz mySound sowie die SoundChannel-Instanz mySoundchannel verwen-det (diese wurde – um Verwechslungen mit der ActionScript-2.0-Variante zu vermei-den – von mySong auf mySound umgetauft):

Zu Beginn werden die dynamischen Textfelder „zurückgesetzt“.

Danach wird der aktuell abzuspielende Song ermittelt (siehe hierzu auch die Erklä-rungen aus dem ActionScript-2.0-Teil: Listing 7.10).

Da beim Aufruf dieser Funktion in jedem Fall ein Song abgespielt werden soll, werden die Variablen isPaused und isStopped auf den Wert false gesetzt: isPaused = false; isStopped = false;.

Je nachdem, ob der aktuelle (dir==0) oder der nächste oder vorige Song abzuspielen ist, wird die Variable pausingPos auf 0 gesetzt, da nur im Fall des aktuellen Songs (Betätigen des Play-Buttons nach dem Betätigen des Pause/Stop-Buttons) ab einer gewissen Position abgespielt werden soll: if(dir!=0) { pausingPos = 0; }.

In jedem Fall muss ein derzeit abgespielter Song beendet werden: if(mySound!=null && !isStopped) { stopSong(); }. Da dies nur geschehen kann, wenn bereits ein Soundobjekt existiert (also ungleich null ist) und ein Stoppen nur dann Sinn macht, wenn der Song noch nicht gestoppt ist, werden diese beiden Eigenschaften bzw. Variablen zuvor abgefragt.

Nun folgt der eigentlich wichtige Teil beim Arbeiten mit Sounds:

Zunächst bedienen wir uns der bereits seit dem Laden der XML-Daten existen-ten URLRequest-Instanz myRequest und weisen der Eigenschaft url die URL zur Sounddatei aus dem Sound-Array zu: myRequest.url = rootDir+"/"+theSongs[actualSong];.

Danach wird eine Sound-Instanz gesetzt und dieser und der SoundChannel-Instanz ein Eventhandler (für das Ereignis ID3; Auslesen der ID3-Tags möglich) zugewiesen:

mySound = new Sound();

mySound.addEventListener(Event.ID3, EID3);

Zu guter Letzt wird das in der URLRequest-Instanz definierte MP3-File geladen, der SoundChannel mit dem Abspielen der Datei beauftragt und dem Sound-Channel mitgeteilt, was nach dem erfolgten Abspielen der Sounddatei gesche-hen soll (Ereignis SOUND_COMPLETE; Abspielen der Sounddatei beendet):

mySound.load(myRequest);

mySoundchannel = mySound.play(pausingPos);

mySoundchannel.addEventListener(Event.SOUND_COMPLETE, ESoundComplete);

Fassen wir noch kurz zusammen:

u

u

u

u

u

u

u

u

u

Page 381: Flash cs3, ajax und php

K A P I T E L 7368

1. Zum Laden von Daten (auch MP3-Files) wird generell das URLRequest-Objekt verwendet.

2. Das Soundobjekt erhält die Daten des URLRequest-Objekts und „verwaltet“ diese sozusagen. Im Gegensatz zu ActionScript 2.0 wird das Soundobjekt nun nicht mehr zum Abspielen des Sound-File verwendet.

3. Zum Steuern der Sounddaten wird das SoundChannel-Objekt verwendet.

Bleibt noch die Funktion stopSound:

Im ersten Schritt wird das Abspielen in der SoundChannel-Instanz mySoundchan-nel gestoppt: mySoundchannel.stop();.

Sollte in der Soundinstanz mySound noch ein Datentransfer aktiv sein (das wäre der Fall, wenn die geladenen Bytes der MP3-Datei noch nicht den zu übertragenen Bytes entsprechen), wird dieser ebenfalls beendet: if(mySound.bytesLoaded!=mySound.bytesTotal) { mySound.close(); }.

Danach wird das gerade laufende Intervall zum Anzeigen der Restzeit gestoppt: clearInterval(itvTimer);.

Falls der Sound nicht pausiert, sondern gestoppt wird, werden zusätzlich noch die Textfelder zurückgesetzt.

Alternative: try & catch in der Funktion stopSoundfunction stopSong():void {

try { mySoundchannel.stop(); }

catch(myError:Error) { trace("SoundChannel kann nicht gestoppt werden. Error="+myError.message); }

try { mySound.close(); }

catch(myError:Error) { trace("Soundtransfer kann nicht geschlossen werden, da er wahrscheinlich bereits abgeschlossen ist. Error="+myError.message); }

clearInterval(itvTimer);

if(isStopped) {

Restzeit.text = "--:--";

Titel.text = "(stopped)";

Interpret.text = "";

Album.text = "";

}

}

Listing 7.29: Alternative Abarbeitung der stopSound-Funktion in der Datei audioplayer_02a.fl a

u

u

u

u

Page 382: Flash cs3, ajax und php

A U D I O - J U K E B O X 369

Anstatt die SoundChannel-Instanz mySoundchannel „einfach so“ zu stoppen, wird dies mittels try versucht. Sollte der Versuch nicht klappen (was nicht tragisch wäre, sondern nur die Info, dass das Abspielen bereits gestoppt wurde), kann man im catch-Teil den Fehler ausgeben – unbedingt notwendig ist das jedoch nicht.

Dasselbe Prozedere durchläuft der Versuch, die Sound-Instanz mySound in ihrer Über-tragung zu beenden.

Kommen wir zum Auslesen der ID3-Tags sowie dem Timer für die Restzeitanzeige. Das Auslesen der ID3-Tags erfolgt nach wie vor im Sound-Objekt (wie in der Beschreibung der Funktion playSong beschrieben):

var itvTimer:Number;

function EID3(myEvent:Event):void {

Interpret.text = mySound.id3.TPE1;

Album.text = mySound.id3.TALB;

Titel.text = mySound.id3.TIT2;

itvTimer = setInterval(showTimer,1000);

}

function showTimer():void {

var theLength:Number = Math.fl oor((mySound.id3.TLEN-mySoundchannel.position)/1000);

var min:Number = Math.fl oor(theLength/60);

var sek:String = "";

if(theLength-60*min<10) { sek += "0"; }

sek += theLength-60*min;

Restzeit.text = "-"+min+":"+sek;

}

Listing 7.30: Die Funktion EID3 wird zum Anzeigen der ID3-Tags einer MP3-Datei benötigt, die Funktion showTimer dient zur Anzeige der Restzeit eines abspielenden Songs.

Diese beiden Funktion sind relativ straight forward:

Die Funktion EID3 dient als Eventhandler und wird aufgerufen, sobald eine Sound-Instanz die ID3-Tags aus einer MP3-Datei auslesen konnte, wobei wir uns hier lediglich auf die ID3-Tags der Version 2 beziehen. Sie liest die Tags TPE1 (Inter-pret), TALB (Album) und TIT2 (Titel) der MP3-Datei aus. Sobald dies geschehen ist, wird ein Intervall gesetzt, das in regelmäßigen Abständen (alle 1000 Millisekun-den, also jede Sekunde) die Funktion showTimer aufruft.

u

Page 383: Flash cs3, ajax und php

K A P I T E L 7370

Die Funktion showTimer errechnet aus der Länge der MP3-Datei (TLEN; in Mil-lisekunden) und der aktuellen Abspielposition (mySoundchannel.position; in Millisekunden) die aktuelle Restzeit in Sekunden. Daraus werden die Minuten und die Sekunden für die Anzeige berechnet, wobei den Sekunden eine führende Null angehängt wird, sollten die Sekunden weniger als zehn sein. Zum Schluss wird aus den berechneten Werten ein String der Form „-MM:SS“ gebastelt und dem Textfeld Restzeit zugewiesen.

7.6.5 Änderungen in der LautstärkeregelungDie letzte Änderung betrifft die Lautstärkeregelung. Da MovieClips in ActionScript 3.0 keine Button-Ereignisse mehr zugewiesen werden können, muss dem Lautstärkeregler im Design ein unsichtbarer Button hinzugefügt werden, den der User dann ankli-cken kann. Dieser Button wird die Größe der Spur des Hintergrunds haben – somit bekommt der User den Eindruck, er könnte direkt den Lautstärkeregler anklicken:

u

ABBILDUNG 7.6

Der Lautstärkeregler erhält einen zusätzlichen unsicht-

baren Button namens btnSpur.

Die Änderungen bezüglich des Lautstärkereglers ergeben sich dann wie nachfolgend. Aus:

var itvLautstaerke:Number;

mcLautstaerke.mcSpur.onPress = function():Void {

itvLautstaerke = setInterval(setLautstaerke,50);

}

mcLautstaerke.mcSpur.onRelease = function():Void {

clearInterval(itvLautstaerke);

Page 384: Flash cs3, ajax und php

A U D I O - J U K E B O X 371

}

mcLautstaerke.mcSpur.onReleaseOutside = function():Void {

clearInterval(itvLautstaerke);

}

wird:

var itvLautstaerke:Number;

function ELautstaerkePress(myEvent:MouseEvent):void {

itvLautstaerke = setInterval(setLautstaerke,50);

}

function ELautstaerkeRelease(myEvent:MouseEvent):void {

clearInterval(itvLautstaerke);

}

function ELautstaerkeRollOutside(myEvent:MouseEvent):void {

clearInterval(itvLautstaerke);

}

mcLautstaerke.btnSpur.addEventListener(MouseEvent.MOUSE_DOWN, ELautstaerkePress);

mcLautstaerke.btnSpur.addEventListener(MouseEvent.MOUSE_UP, ELautstaerkeRelease);

mcLautstaerke.btnSpur.addEventListener(MouseEvent.ROLL_OUT, ELautstaerkeRollOutside);

Listing 7.31: Die neue Ereignisbehandlung für den Lautstärkeregler

Letzten Endes hat sich lediglich der Aufruf der Eventhandler geändert, wobei uns das schon aus früheren Überlegungen bekannt ist. Da das Ereignis onReleaseOutside nicht mehr existiert, muss man auf das Ereignis ROLL_OUT zurückgreifen: Dieses Ereignis tritt auf, sobald der User mit der Maus aus einem bestimmten MovieClip herausrollt.

Die Funktion setLautstaerke hat sich gegenüber der ActionScript-2.0-Variante ebenfalls deutlich geändert. Aus:

function setLautstaerke():Void {

var mousex:Number = mcLautstaerke._xmouse;

var maxX:Number = mcLautstaerke.mcSpur._width;

mcLautstaerke.mcMaske._width = mousex;

mySong.setVolume(mousex/maxX*100);

}

Page 385: Flash cs3, ajax und php

K A P I T E L 7372

wird:

function setLautstaerke():void {

if(mySoundchannel!=null) {

var mousex:Number = mcLautstaerke.mouseX;

var maxX:Number = mcLautstaerke.mcSpur.width;

mcLautstaerke.mcMaske.width = mousex;

var myTransform:SoundTransform = mySoundchannel.soundTransform;

myTransform.volume = mousex/maxX;

mySoundchannel.soundTransform = myTransform;

}

}

Listing 7.32: Um die Lautstärke einer SoundChannel-Instanz zu verändern, bedarf es einer Sound-Transform-Instanz.

Grundsätzlich kann eine Veränderung der Lautstärke nur dann erfolgen, wenn es eine SoundChannel-Instanz gibt – in unserem Fall trägt diese den Namen mySoundchan-nel. Ist diese vorhanden, werden x- und y-Position der Maus innerhalb des MovieC-lips mcLautstaerke ausgelesen und die Maske zum Anzeigen der Lautstärkestriche wird entsprechend gesetzt.

Danach erfolgt der erste wichtige Schritt: die derzeitigen SoundTransform- Einstel-lungen werden aus der SoundChannel-Instanz mySoundchannel ausgelesen und der SoundTransform-Instanz myTransform zugewiesen:

var myTransform:SoundTransform = mySoundchannel.soundTransform;

Danach wird in dieser gerade erzeugten Instanz der Wert der Eigenschaft volume auf den entsprechenden Wert gesetzt. Bitte beachten Sie an dieser Stelle, dass die Eigen-schaft volume nun nicht mehr in Prozent, sondern in Werten zwischen 0 und 1 ange-geben werden muss:

myTransform.volume = mousex/maxX;

Ist dies erfolgt, schreibt man die geänderten Einstellungen wieder zurück in die SoundChannel-Instanz:

mySoundchannel.soundTransform = myTransform;

7.6.6 Songs aus einer ComboBox abspielenAls Erweiterung des aktuellen Players könnte man beispielsweise eine ComboBox mit allen Songs der Playlist füllen und durch Auswählen eines Songs aus der ComboBox

Page 386: Flash cs3, ajax und php

A U D I O - J U K E B O X 373

diesen direkt abspielen. Gesagt – getan: Ziehen Sie hierzu eine ComboBox aus den Komponenten auf die Bühne und geben Sie dieser den Namen „myPlaylist“.

Nachdem dies erledigt ist, muss die Funktion EXMLComplete vor dem Aufruf der Funktion initPlayer wie folgt erweitert werden, um die ComboBox mit Inhalt zu füllen:

...

myPlaylist.addEventListener(Event.CHANGE, EChange);

myPlaylist.addItem({ label:"Bitte wählen Sie:", data:-1 });

for(i=0; i<myXML.song.length(); i++) {

myPlaylist.addItem({ label:myXML.song[i].@src, data:i });

}

initPlayer();

}

Listing 7.33: Befüllen der ComboBox myPlaylist mit den MP3-Dateien aus der Playlist

Bevor die for-Schleife das Befüllen der ComboBox übernimmt, wird noch ein Eintrag mit der Beschriftung „Bitte wählen Sie“ in die ComboBox geschrieben. Der zugehörige Wert dieses Eintrags ist -1 (dieser Wert wird später benötigt, da die Wahl des Users auch auf diesen Eintrag fallen kann, jedoch dann kein Song geladen werden soll).

Innerhalb der for-Schleife werden alle Einträge der XML-Datei-Tags <song> als Beschriftung (label) in die ComboBox geschrieben. Die zugehörigen Werte (data) der Einträge sind die fortlaufenden Zahlen der for-Schleife (und somit der Index innerhalb der Playlist theSongs).

Der Eventhandler EChange bestimmt, was beim Auswählen eines Songs aus der Com-boBox geschehen soll:

function EChange(myEvent:Event):void {

if(myPlaylist.selectedItem.data!=-1) {

var dir:Number = myPlaylist.selectedItem.data-actualSong;

playSong(dir);

}

}

Listing 7.34: Der Eventhandler EChange, der aufgerufen wird, sobald der User eine neue Auswahl in der ComboBox getroffen hat

Sollte die Auswahl einen Wert ungleich -1 haben (-1 war der Wert für den Eintrag „Bitte wählen Sie:“), so wird in der Variable dir die Anzahl der Songs ermittelt, um

Page 387: Flash cs3, ajax und php

K A P I T E L 7374

die in der Playlist zurück (falls kleiner 0) oder vor (falls größer 0) gesprungen werden muss. Dieser Wert wird dann an die Funktion playSong übergeben – fertig.

7.7 Mögliche ErweiterungenNeben der Abspielsteuerung in Flash kann selbstverständlich auch eine Abspielsteue-rung in XHTML erfolgen. Dabei müssen in XHTML entsprechende Buttons angelegt werden, die in Flash freigegebene Funktionen aufrufen (wie Sie das realisieren können, erfahren Sie im Kapitel Clientseitiger Datenaustausch).

Eine andere Erweiterung wäre etwa, dass per AJAX in regelmäßigen Abständen in der Datenbank nachgesehen wird, ob sich an der Playlist etwas verändert hat – wäre dies der Fall, so könnte die Playlist in Flash nachgeladen werden. Ein entsprechendes Bei-spiel finden Sie im Anschluss: der Videoplayer. Viel Spaß dabei!

Page 388: Flash cs3, ajax und php

8VIDEOPLAYER (ACTIONSCRIPT 3.0)

Ziel dieses Workshops ist die Erstellung eines Videoplayers, der die abzuspielenden Videos aus einer XML-Datei entnimmt und nacheinander anzeigt. Die XML-basierte Abspielliste soll per PHP dynamisch generiert werden und entweder alle in einem Verzeichnis befindlichen Flash-Videodateien (.FLV) oder eine über eine Datenbank generierte Liste an Videos beinhalten.

Weiters sei vorausgeschickt, dass der Videoplayer in ActionS-cript 3.0 entwickelt wird und somit mit älteren Playern nicht abgespielt werden kann.

Gleich vorwegschicken möchte ich auch eine Quellenangabe sowie ein Copyright zu allen Videos, die in diesem Work-shop verwendet wurden: Die Videos wurden mit freundlicher Genehmigung von TV1.at zur Verfügung gestellt. Herzlichen Dank!

Page 389: Flash cs3, ajax und php

K A P I T E L 8376

8.1 Das Konzept des Videoplayers1. Der Videoplayer soll in der Lage sein, gestreamt FLV-Dateien abzuspielen. Somit

ist die erste Anforderung, dass FLV-Dateien dynamisch in Flash eingelesen werden sollen.

2. Innerhalb des Videoplayers soll volle Kontrolle über das Abspielen der Videos gewährleistet sein. In diesem Fall werden wir die Möglichkeiten der Video-Skins von Flash nutzen.

3. Es soll eine parametergesteuerte Autostart-Möglichkeit vorhanden sein.

4. Des Weiteren soll in der XML-Datei die Möglichkeit bestehen, im Falle einer datenbankgenerierten XML-Datei Informationen zu Autor, Inhalt usw. zu beinhalten.

Wir werden den Videoplayer in mehreren Schritten entwickeln:

Zunächst lernen wir, wie man generell mit FLV-basierten Videodaten in Flash arbeitet (an dieser Stelle lernen wir die Komponente „FLV Playback“ kennen).

Danach werden wir den Player so erweitern, dass er mehr als nur ein Video abspie-len kann.

Ist dies geschehen, werden wir per PHP eine XML-basierte Abspielliste generieren, welche wir im Weiteren in die Flash-Datei laden.

Anschließend bringen wir noch AJAX ins Spiel und lassen uns überraschen, wie AJAX uns im Fall eines neuen Videos informiert.

Zu guter Letzt greifen wir das Thema der Cue-Points auf, um zu sehen, wie man auf diese zugreifen kann.

8.2 Flash & VideoSinnvoll mit Video arbeiten kann Flash im Prinzip seit Version 6. Jedoch besteht mit Einführung von Flash 8 die Möglichkeit, neben dem Sorenson Spark Codec den (bes-seren und leistungsfähigeren) On2VP6 Codec zu verwenden.

Grundsätzlich sollte man sich für den On2 VP6 Codec entscheiden, da dieser bei glei-cher Datenrate das (qualitativ) wesentlich bessere Ergebnis liefert. Auf der Habenseite steht jedoch, dass der Flash-Player beim Decodieren während der Anzeige beim User wesentlich mehr Prozessorleistung benötigt. Nicht zuletzt auch aus diesem Grund ist beim Einsatz von Video ein Grundsatz wesentlich und entscheidend: „Kenne deine User“. Gerade im Fall von Video müssen an den User sehr hohe Anforderungen gestellt werden:

u

u

u

u

u

„Kenne deine User“

„Kenne deine User“

Page 390: Flash cs3, ajax und 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 ) 377

1. Der User sollte über eine entsprechend gute Internetanbindung verfügen: DSL mit einer Download-Rate von mind. 400 Kbit/S für Videos in einer Standardgröße von 320x240 Pixel ist ideal. Bitraten á la ISDN oder gar Modem fallen gänzlich durch den Rost (außer die Videos sind in ihren Abmessungen relativ klein: beispielsweise 160x120 Pixel).

2. Des Weiteren ist in jedem Fall der Flash8-Player auf Userseite vorauszusetzen.

3. Außerdem wird wie oben erwähnt relativ viel Prozessorleistung beim Decodieren eines FLV-Videos benötigt.

Ziehen Sie in jedem Fall eine Useranalyse in Erwägung – Ihre Kunden und vor allem Ihre User werden es Ihnen danken! Eine entsprechende „Warnmeldung“ für User mit schlechteren Internetanbindungen bzw. älteren Rechnern ist sowieso Pflicht.

Aus Sicht von ActionScript spielt die Wahl des Decoder keine entscheidende Rolle, vielmehr ist die Wahl des korrekten Videoformats von entscheidender Bedeutung: Hier sollte in jedem Fall die Wahl auf das FLV-Format fallen – von der Möglichkeit, Videos in SWF-Dateien zu importieren und diese SWF-Datei dynamisch hinzuzula-den, möchte ich aus mehrerlei Gründen abraten:

1. Bildrate von Video und Flash-Datei (zumeist) unterschiedlich:

Bettet man Videos in die Zeitleiste einer Flash-Datei ein, so tritt unweigerlich das Problem auf, dass die Bildraten von Video und Flash-Datei nicht zusammenpassen. Typischerweise werden Videos mit einer Bildrate von 25 Bildern pro Sekunde erstellt (B/s) – diese Bildrate ist jedoch für den Flash-Player (bzw. das Flash-Plug-in – Sie kennen den Unterschied …) zu hoch, was dann zu einem Ruckeln im Abspielen des Videos führt. Der Ausweg wäre, einen ganzzahligen Teiler zu verwenden, wodurch beispielsweise nur jedes zweite oder dritte Bild aus dem Video in die Flash-Datei übernommen wird (vergleiche hierzu auch die nachfolgende Abbildung). Leider existiert kein sinnvoller Teiler, denn ein Teiler 2 würde zu einer Bildrate von 12.5 Bildern pro Sekunde führen, ein Teiler 3 zu 8.333 B/s, ein Teiler 4 zu 6.25 B/s usw. Erst ein Teiler 5 würde zu einer ganzzahligen Bildrate in Flash führen – nur eine Bildrate von 5 B/s ist eindeutig zu wenig. Ich denke, da geben Sie mir Recht – das menschliche Auge würde es in jedem Fall tun, denn erst ab einer Bildrate von 22 B/s erkennt das menschliche Auge den Unterschied zwischen Einzelbildern (ein Video ist ja schlussendlich eine Abfolge von Einzelbildern) und einem fortlaufenden Bild nicht mehr. Der Grund dafür, dass wir in Flash typischerweise mit einer Bildrate von 10–15 B/s arbeiten, ist in der geringen Leistungsfähigkeit des Flash-Players begründet.

2. Probleme in der Synchronisierung von Audio- und Videospur:

Da Flash beim Einbetten von Videos letzten Endes nichts andres tut, als das Video in Form von Einzelbildern abzuspielen, werden die Audio- und „Video“-Spur

Page 391: Flash cs3, ajax und php

K A P I T E L 8378

voneinander getrennt. In diesem Fall wird die Audiospur konventionell als Sound abgespielt und dadurch ergeben sich die üblichen Probleme beim gleichzeitigen Abspielen von Audio und Animation. Bitte schlagen Sie in der Referenz zu Flash nach, um hierzu weiterführende Informationen zu erhalten.

3. Der Produktionszyklus: vom Video zur SWF- bzw. FLV-Datei

Das Einbetten von Videos in eine Flash-Datei erfordert einen zusätzlichen Arbeitsschritt, der zeitlich gesehen mitunter nicht zu unterschätzen ist. Auf der anderen Seite können Flash-Videos (FLV-Dateien) oft direkt aus den Videobearbeitungsprogrammen exportiert werden.

ABBILDUNG 8.1

Unterschiedliche Bitraten zwischen der Quelldatei

und der SWF-Datei führen beim Einbetten des Videos

dazu, dass aus der Quelldatei unregelmäßig Bilder in das

eingebettete Video der SWF-Datei übernommen werden. Der Grund dafür ist, dass in

unserem Fall die Bildrate der Quelldatei (25 B/s) und der SWF-Datei (15 B/s) keinen

sinnvollen gemeinsamen Teiler besitzen (der größte

gemeinsame Teiler wäre 5, jedoch ist eine Bildrate von

5 B/s nicht sinnvoll).

Aus diesem Grund entscheidet man sich gerne für FLV- anstatt für eingebettete Videos in SWF-Dateien. Bitte beachten Sie jedoch, dass erst mit der Einführung von Flash 7 das Arbeiten mit FLV-Dateien möglich wurde.

Ein weiterer wesentlicher Vorteil von FLV- gegenüber SWF-Dateien sind die in die FLV-Dateien integrierten Metadaten (vergleichen Sie hierzu auch den Workshop „Audio-Jukebox“ und die dort verwendeten MP3-Dateien), die abgerufen und somit angezeigt werden können.

8.3 Die Umsetzung

8.3.1 Flash und die FLVPlayback -KomponenteFlash bietet uns seit Version 7 die Möglichkeit, Videodateien im FLV-Format mit einer geeigneten Komponente abzuspielen. Es empfiehlt sich an dieser Stelle, die Kom-ponente nicht per ActionScript zu erstellen, sondern diese direkt auf der Bühne zu platzieren, da dies sehr einfach und komfortabel geschieht: Unter den Komponenten (das entsprechende Register können Sie über den Menüpunkt FENSTER/KOMPONENTEN einblenden) finden Sie die Komponenten für „User Interface“ und eben „Video“. Zie-hen Sie die Komponente FLVPlayback auf die Bühne:

Page 392: Flash cs3, ajax und 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 ) 379

In der Registerkarte PARAMETER hat man die Möglichkeit, die benötigten Buttons für die Abspielsteuerung in Form von sogenannten Skins zu wählen. In unserem Fall genügen die Buttons Play, Stopp, Rewind, Forward, Lautstärke (inklusive Regelung) und eine Abspielleiste. Neben den Elementen kann man noch wählen, ob diese über oder unter dem Video liegen. (Kleiner Tipp: Testen Sie mal durch, welche der Skins Ihnen zusagt.) Des Weiteren ist auch die Hintergrundfarbe der Skins frei wählbar (ich habe mich an dieser Stelle für ein dunkles Grau entschieden).

SkinsSkins

ABBILDUNG 8.2

Eine Instanz der FLVPlayback-Komponente wurde auf der Bühne platziert. Welche Buttons zur Abspielsteuerung angezeigt und verwendet werden, kön-nen Sie im Register PARAMETER wählen.

ABBILDUNG 8.3

Wahl der Abspielbuttons (skin) und der Hintergrund-farbe (skinBackgroundColor). An dieser Stelle empfehle ich Ihnen, ein bisschen mit den Parametern zu experimen-tieren (beispielsweise erzeugt das Setzen des Alphakanals skinBackgroundAlpha auf den Wert 0.7 einen besseren Effekt als der Wert 1, da so das Video im Hintergrund noch sichtbar bleibt).

Page 393: Flash cs3, ajax und php

K A P I T E L 8380

Um für ActionScript Zugriff auf die Komponenten-Instanz zu erhalten, müssen wir der Komponente noch einen Instanznamen zuweisen:

ABBILDUNG 8.4

Zuweisen eines Instanz-namens für die zuvor

auf der Bühne platzierte Komponente

Wählen Sie für die Bühne eine Größe von 600x500 Pixel und legen Sie die FLV-Playback-Komponente mittig auf die Bühne (aus X-Richtung gesehen) und an die Y-Position 10 Pixel. Als Größe der FLVPlayback-Komponente habe ich 512x416 Pixel gewählt:

ABBILDUNG 8.5

Alle Vorkehrungen sind getroffen (Bühnengröße

600x500 Pixel, Größe der FLVPlayback-Komponente 512x416 Pixel) – kümmern

wir uns um die Videos.

Die FLVPlayback-Komponente per ActionScript erstellen

Wie oben bereits erwähnt, kann eine FLVPlayback-Komponente auch zur Laufzeit erzeugt werden. Voraussetzung dafür ist, dass sich die Komponente bereits in der Bibliothek befindet. Dies bewerkstelligt man am einfachsten, indem man das Kompo-nentenfenster öffnet und die entsprechende Komponente in die Bibliothek zieht:

Page 394: Flash cs3, ajax und 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 ) 381

Diese Vorgehensweise mit ActionScript bedeutet zwar etwas mehr an Code, ist dafür flexibler und für Programmierer zumeist „sympathischer“. Natürlich können Sie auf alle Eigenschaften zugreifen, die die FLVPlayback-Komponente für uns bereithält.

Sehen wir uns die nötigen Schritte an:

Zunächst benötigt man einmal die Klasse FLVPlayback, die sich innerhalb der fl.video-Klasse befindet. Da wir aus dieser Klasse noch weitere Klassen benöti-gen, importieren wir idealerweise gleich die gesamte Klasse fl.video:

import fl .video.*;

Danach definiert man eine neue FLVPlayback-Instanz:

var myVideoplayer:FLVPlayback = new FLVPlayback();

Ist dies getan, kann man sofort auf sämtliche Eigenschaften der Instanz my Videoplayer zugreifen. Im Folgenden lege ich jede Eigenschaft fest, die wir auch im vorigen Abschnitt festgelegt haben, jedoch dort noch über die Parameter der Komponente:

X- und Y-Position: myVideoplayer.x = 44; myVideoplayer.y = 10;

Breite und Höhe: myVideoplayer.width = 512; myVideoplayer.height = 418;

Auto-Play deaktivieren: myVideoplayer.autoPlay = false;

Skin zuweisen: myVideoplayer.skin = "SkinOverAllNoVolNoCaptionNo-Full.swf"; myVideoplayer.skinBackgroundAlpha = 0.7; myVideoplay-er.skinBackgroundColor = 0x333333;

u

u

u

u

u

u

u

ABBILDUNG 8.6

Die FLVPlayback-Komponente wird in der Bibliothek der Flash-Anwendung benötigt – ansonsten ist es auch mit ActionScript nicht möglich, dynamisch eine Instanz davon zu erzeugen.

Page 395: Flash cs3, ajax und php

K A P I T E L 8382

Alle diese Schritte würden uns nicht viel helfen, würden wir unser virtuelles Display-Objekt nicht noch unserer Bühne zuweisen:

Display-Objekt der Bühne (oder einem anderen Objekt) zuweisen: this.addChild(myVideoplayer);

Vergleichen Sie beide Vorgehensweisen (Arbeiten mit Komponenten direkt auf der Bühne oder Erzeugen einer Komponenten-Instanz per ActionScript) – Sie werden feststellen, dass sie ein identisches Ergebnis liefern. Welche Variante Sie bevorzugen, ist Ihnen überlassen – das Ergebnis ist gleichwertig.

Die eben dargestellte Variante ist auf der Buch-CD im aktuellen Kapitel unter dem Namen videoplayer_02a.flv zu finden. Da wir noch keine Videoquelle zugewiesen haben, wird das Beispiel zwar eine Playback-Komponente erzeugen, aber eben kein Video darstellen. In den nächsten Ausführungen entwickeln wir das Beispiel immer weiter, sodass Sie den Fortschritt gut mitverfolgen können.

Damit sind wir mal fürs Erste gerüstet und können uns um die Videodatei kümmern.

8.3.2 Videos im FLV-FormatNun, an dieser Stelle stellt sich zunächst einmal die Frage, von welchen Vorausset-zungen wir ausgehen können:

1. Das Video wird bereits als FLV-Datei geliefert:

In seltenen Fällen kann es vorkommen, dass Sie als Webentwickler bereits fertige FLV-Dateien (vom Kunden) zur Verfügung gestellt bekommen. In diesem Fall müssen wir keine vorbereitenden Maßnahmen mehr treffen. Gehen wir einmal davon aus, dass dies die Ausnahme ist.

2. Sie selbst sind der Videoproduzent:

Für den Fall, dass Sie selbst das Video produzieren, unterstützt Flash Ihr Videobearbeitungsprogramm mit einem eigens mitgelieferten Plug-in namens „FLV QuickTime Export Plug-in“ (bei Flash 8 gilt dies nur für die Professional-Variante), sofern Sie mit einem der folgenden Videobearbeitungsprogramme arbeiten:

Adobe After Effects (Windows und Macintosh)

Apple Final Cut (Macintosh)

Apple QuickTime Pro (Windows und Macintosh)

Avid XPress DV (Windows und Macintosh)

Mithilfe dieses Plug-ins sind Sie in der Lage, direkt aus Ihrem Video-bearbeitungsprogramm eine entsprechende FLV-Datei zu exportieren.

u

u

u

u

u

Page 396: Flash cs3, ajax und 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 ) 383

3. Sie besitzen das Video im Rohformat und müssen es selbst in ein FLV-Format konvertieren:

In diesem Fall haben Sie zwei Möglichkeiten:

1. Sie verwenden die Importmöglichkeit von Flash: Hierzu erzeugen Sie zunächst eine neue Flash-Datei, klicken dann auf DATEI/IMPORTIEREN/VIDEO IMPORTIEREN… Danach öffnet sich der Importassistent für Videos.

2. Sie verwenden den Flash Video Encoder, der im Lieferumfang von Flash CS3 Professional (oder Flash 8 Professional) enthalten ist. Sie finden ihn als eigenständiges Programm, das zusätzlich zu Flash installiert wurde.

Bleibt nur zu klären, mit welchen Videoformaten Flash umgehen kann. Diese sind:

Macintosh mit installiertem QuickTime 7:

Audio Video Interleaved: AVI

Digital Video: DV

Motion Picture Experts Group: MPG, MPEG

QuickTime-Video: MOV

Windows mit installiertem DirectX ab Version 9:

Audio Video Interleaved: AVI

Motion Picture Experts Group: MPG, MPEG

QuickTime-Video: MOV (nur bei zusätzlich installiertem QuickTime 7)

Windows Media-Datei: WMV, ASF

Wenn Sie grundsätzlich mit dem QuickTime-Videoformat oder dem AVI-Format arbeiten, sind Sie auf beiden gängigen Betriebssystemen also „auf der sicheren Seite“. Achten Sie darauf, dass das Video möglichst unkomprimiert und somit in einer hohen Qualität zur Verfügung steht. Sollten Sie beispielsweise ein bereits codiertes und komprimiertes Video verwenden, so wurde durch die Komprimierung schon ein Teil der Qualität eingebüßt. Nachdem jedoch Flash das Video erneut komprimieren wird, hätte man eine doppelte Komprimierung – das schlägt sich dann in jedem Fall auf die Qualität der Darstellung nieder.

u

u

u

u

u

u

u

u

u

u

Page 397: Flash cs3, ajax und php

K A P I T E L 8384

Variante 1 (Importieren eines Videos in eine leere Flash-Datei) hat gegenüber Variante 2 (Arbeiten mit dem Flash Video Encoder) den Nachteil, dass das Importieren von Videos im Allgemeinen sehr viel Zeit in Anspruch nimmt und Sie in der Zwischenzeit Flash nicht verwenden können. Da der Flash Video Encoder ein eigenständiges Pro-gramm ist (und dieser noch dazu in der Lage ist, mehrere Videos hintereinander in einem sogenannten „Batch-Modus“ abzuarbeiten), können Sie so weiterhin ungestört mit Flash arbeiten und nebenbei die Videos konvertieren. Langer Rede kurzer Sinn: Verwenden Sie den Flash Video Encoder. Infos zum Importieren von Videos in Flash

Erste Wahl: der Flash Video

Encoder

Erste Wahl: der Flash Video

Encoder

ABBILDUNG 8.7

Variante 1: Importieren eines Videos in ein noch leeres

Flash-Dokument

ABBILDUNG 8.8

Variante 2: Verwenden des Flash Video Encoder, der als

eigenständiges Programm mit der Installation von Flash

installiert wird

Page 398: Flash cs3, ajax und 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 ) 385

finden Sie im Flash CS3-Handbuch (PDF-Datei), das Sie von der Adobe-Website (www.adobe.de) downloaden können.

Der Flash Video Encoder

E inmal gestartet, präsentiert sich der Flash Video Encoder wie in der nachfolgenden Abbildung.

ABBILDUNG 8.9

Schön aufgeräumt und übersichtlich – der Flash Video Encoder wartet auf Ihre Videos.

Über den Button HINZUFÜGEN… können Sie ein oder mehrere Videos auswählen, die Sie konvertiert haben möchten. Einmal der Warteschlange (so nennt sich die Liste an abzuarbeitenden Videos) hinzugefügt, können Sie ein oder mehrere Videos auswählen und über den Button EINSTELLUNGEN… die entsprechenden Einstellungen für den Export des Videos treffen:

Page 399: Flash cs3, ajax und php

K A P I T E L 8386

Betrachten wir die einzelnen Registerkarten dieses Fensters einmal ein bisschen genauer:

Registerkarte KODIERUNGSPROFILE

In dieser Registerkarte haben Sie zunächst einmal die Möglichkeit, aus vordefi nierten Profi len zu wählen. Wie schon weiter oben erwähnt, würde ich Ihnen in jedem Fall Flash 8 Profi le empfehlen, da diese mit dem On2 VP6 Codec arbeiten. Die Einstellung „Flash 8 – Mittlere Qualität (400 Kbit/s)“ trifft unsere Erwartungen schon relativ gut. Detaileinstellungen zu diesem Profi l treffen Sie dann in den weiteren Registerkarten.

Registerkarte VIDEO

Hierin treffen Sie die Einstellungen zur Codierung der Videospur (die Einstellungen zur Codierung der Audiospur fi nden Sie in der nächsten Registerkarte). Neben der Qualität bzw. Datenrate (diese beiden Einstellungen hängen zusammen) und dem Video-Codec ist vor allem das Kontrollkästchen ALPHAKANAL CODIEREN interessant: Ist dieses Kontrollkästchen aktiviert, so werden eventuell im Video vorhandene Alphakanäle (beispielsweise bei Blue-Box-Aufnahmen) transparent gemacht, sodass Sie nach dem Einbinden der FLV-Datei den Hintergrund Ihrer SWF-Datei durch das Video hindurch sehen.

Ebenso wichtig ist die Einstellung zur Bildrate: Wie schon weiter oben ausgeführt, ist von einer Veränderung der Bildrate eines Videos abzuraten, da dadurch Bilder im Video verloren gehen. Da in SWF-Dateien verknüpfte FLV-Videos nicht dieselbe Bildrate aufweisen müssen wie die SWF-Datei selbst, rate ich zur Einstellung „Wie Quelle“.

u

u

ABBILDUNG 8.10

In diesem Fenster können Sie alle Einstellungen treffen, die

für den Export des Videos in eine FLV-Datei notwendig

sind. Video-Copyright: TV1.at – www.tv1.at.

Page 400: Flash cs3, ajax und 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 ) 387

Das Kontrollkästchen DEINTERLACE wird verwendet, um das Video in ein Vollbildformat umzuwandeln. Sämtliche weitere Information hierzu entnehmen Sie bitte dem Flash-Handbuch.

Registerkarte AUDIO

Hierin bestimmen Sie die Datenrate, wie qualitativ hochwertig die Audiospur im Video sein soll. Eine Datenrate von beispielsweise 96 Kbit/s (stereo) ist von relativ hoher Qualität (CD-Qualität liegt bei etwa 128–160 Kbit/s) – eine etwas geringere Bitrate ist für Videos im Internet immer noch ausreichend.

Registerkarte CUE-POINTS

Cue-Points sind eine sehr interessante Angelegenheit in Videos. Mithilfe von Cue-Points sind Sie in der Lage, Ereignisse in der SWF-Datei zu erzeugen, in der die FLV-Datei eingebunden ist. So sind Sie etwa in der Lage, gleichzeitig mit dem Erreichen einer bestimmten Position im Video in der SWF-Datei Texte, Grafi ken etc. anzuzeigen. Ebenso eignen sich Cue-Points als Navigationspunkte innerhalb des Videos. Mehr dazu weiter unten.

Registerkarte ZUSCHNEIDEN UND GRÖSSE ÄNDERN

Die letzte Registerkarte dient dazu, das Video in Größe (Cropping bzw. Breite und Höhe) und Länge zu beschneiden.

Werfen wir noch einen etwas genaueren Blick auf die Registerkarte CUE-POINTS. Um einen neuen Cue-Point hinzuzufügen, wählen Sie über die Abspielleiste zunächst ein-mal die Position aus, die Sie im Video als Cue-Point wählen wollen (natürlich können Sie beliebig viele Cue-Points setzen). Danach geben Sie einen Namen für den Cue-Point sowie einen Typ (Ereignis oder Navigation) an. Zu guter Letzt haben Sie noch die Möglichkeit, diesem Cue-Point einen oder mehrere Parameter inklusive Werten zuzuweisen. Diese werden innerhalb der FLV-Datei gespeichert. Zusätzlich haben Sie die Möglichkeit, die Cue-Points in einer separaten XML-Datei zu speichern.

Der Cue-Point Typ ist wie folgt zu wählen:

Typ „Ereignis“: Es wird ein ActionScript-Ereignis namens CUE_POINT ausgelöst. Zumeist werden solche Cue-Points für die Synchronisation mit anderen Animatio-nen in der Flash-Anwendung verwendet.

Typ „Navigation“: Es wird neben dem Auslösen des CUE_POINT-Ereignisses in der FLV-Datei ein Schlüsselbild an dieser Position angelegt. Da zusätzliche Schlüs-selbilder im Video die Gesamtqualität beeinträchtigen können, sollten derartige Cue-Points nur dann verwendet werden, wenn dem User beim Abspielen eine Art „Navigation“ zur Verfügung gestellt werden soll (beispielsweise wenn der User nach einer bestimmten Stelle im Video suchen können soll). Dieser Typ von Cue-Point wird im Allgemeinen zumeist verwendet.

u

u

u

u

u

Page 401: Flash cs3, ajax und php

K A P I T E L 8388

Beachten Sie, dass es zwischen ActionScript 2 und 3 Unterschiede in der Handhabung von Cue-Points gibt. Darauf kommen wir weiter unten noch zu sprechen.

Unterschiede bei Cue-Points

zwischen ActionScript 2

und 3

Unterschiede bei Cue-Points

zwischen ActionScript 2

und 3

ABBILDUNG 8.11

Cue-Points in FLV-Dateien. Video-Copyright: TV1.at

– www.tv1.at

In den meisten Fällen verwenden Sie Cue-Points vom Typ „Navigation“, um diese per ActionScript später auch einfach anspringen zu können:

Page 402: Flash cs3, ajax und 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 ) 389

Sind Sie mit den gesetzten Cue-Points zufrieden, so können Sie diese bei Bedarf in Form einer XML-Datei mit Hilfe des Speichern-Buttons abspeichern:

ABBILDUNG 8.12

Die meist verwendeten Cue-Points sind vom Typ „Navigation“.

ABBILDUNG 8.13

Die Cue-Points werden in Form einer (separaten) XML-Datei abgespeichert.

Page 403: Flash cs3, ajax und php

K A P I T E L 8390

Der Inhalt der XML-Datei spricht für sich:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>

<FLVCoreCuePoints Version="1">

<CuePoint>

<Time>0</Time>

<Type>navigation</Type>

<Name>Die schönste Monster</Name>

</CuePoint>

<CuePoint>

<Time>34355</Time>

<Type>navigation</Type>

<Name>Interview Andreas Wolfesberger</Name>

</CuePoint>

<CuePoint>

<Time>81017</Time>

<Type>navigation</Type>

<Name>Interview Zweitplatzierter</Name>

</CuePoint>

<CuePoint>

<Time>106143</Time>

<Type>navigation</Type>

<Name>Interview Rupert Kaspar</Name>

</CuePoint>

<CuePoint>

<Time>155369</Time>

<Type>navigation</Type>

<Name>Interview Gaetano Spagnolo</Name>

</CuePoint>

<CuePoint>

<Time>193314</Time>

<Type>navigation</Type>

<Name>Interview Andreas Czejka</Name>

</CuePoint>

<CuePoint>

Page 404: Flash cs3, ajax und 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 ) 391

<Time>233823</Time>

<Type>navigation</Type>

<Name>Interview Freundin von Rupert Kaspar</Name>

</CuePoint>

<CuePoint>

<Time>264589</Time>

<Type>navigation</Type>

<Name>Interview Julia Roiss</Name>

</CuePoint>

<CuePoint>

<Time>286638</Time>

<Type>navigation</Type>

<Name>Interview Chris Zaiser</Name>

</CuePoint>

<CuePoint>

<Time>329711</Time>

<Type>navigation</Type>

<Name>Abschluss</Name>

</CuePoint>

</FLVCoreCuePoints>

Listing 8.1: Die XML-Datei beinhaltet sämtliche gesetzte Cue-Points mit Zeitpunkt des Cue-Point (angege-ben in Millisekunden), Typ und Namen.

Diese XML-Datei hängt grundsätzlich nicht mit der FLV-Datei zusammen. Dies soll bedeuten, dass Sie selbst auch eine derartige XML-Datei erstellen können bzw. eine gegebene XML-Datei jederzeit ändern können. Derartige XML-Dateien werden bei Bedarf zusätzlich zur FLV-Datei (und nicht gemeinsam mit ihr) in die SWF-Datei geladen. Einzig die Syntax der XML-Daten muss erhalten bleiben.

Zurück zum Flash Video Encoder. Nachdem wir alle Einstellungen zum Video getrof-fen haben und zurück in der Dateiübersichtsmaske sind, können Sie entweder weitere Videos hinzufügen (und wieder die entsprechenden Einstellungen treffen) oder über den Button WARTESCHLANGE STARTEN den Codiervorgang in Gang setzen. Flash arbeitet dann alle in der Warteschlange befindlichen Videos ab und speichert diese im selben Verzeich-nis wie die Quelldaten. Bedenken Sie bitte, dass der Codiervorgang mitunter relativ lange dauern kann (dies ist auch abhängig davon, welches Format Ihre Quelldatei aufweist) – beispielsweise dauerte bei mir das Codieren eines Videos mit einer Länge von etwa 5:30 Minuten im Format MP4 (Codierung: Video: h264, Audio: mp3) etwa 40 Minuten. Dasselbe Video im QuickTime-Format dauerte bei der Codierung etwa 3 Minuten.

Page 405: Flash cs3, ajax und php

K A P I T E L 8392

8.3.3 Dynamisches Verknüpfen der FLVPlayback- Komponente mit einem VideoDa wir neben dem reinen Anzeigen des Videos auch die Möglichkeit haben wollen, das Video zu steuern (und somit auch alle Ereignisse, Eigenschaften und Methoden der FLVPlayback-Komponente zu nutzen), laden wir zunächst einmal die zugehörigen Klassen (sollten Sie die Komponente per ActionScript eingebunden haben, haben Sie die benötigten Klassen bereits geladen):

import fl .video.*;

Danach weisen wir der Playback-Komponente (ihr Name war myVideoplayer) eine Videoquelle zu – in diesem Fall liegt die Videoquelle im selben Verzeichnis wie die SWF-Datei:

myVideoplayer.source = "FestaDucati2006.fl v";

Mit diesen beiden Codezeilen hätten wir schon alle Arbeiten erledigt und wären somit fertig. Ich möchte Ihnen jedoch an dieser Stelle noch einige Eventhandler zeigen, die für die Arbeit mit Videos von Vorteil sein können:

VideoEvent-Klasse:

COMPLETE: wird ausgelöst, wenn das Video fertig abgespielt wurde

READY: wird ausgelöst, wenn das Video bereit zum Abspielen ist

Neben den beiden genannten Ereignissen existiert noch eine größere Liste an weiteren Ereignissen, die Sie im Komponenten-Referenzhandbuch nachlesen können.

Ich möchte Ihnen an dieser Stelle zeigen, wie Sie die beiden Ereignisse verwenden kön-nen. Offensichtlich ist zunächst das READY-Ereignis von Interesse, denn bevor dieses Ereignis nicht aufgetreten ist, kann das Video auch nicht gestartet/verwendet werden. In diesem Fall sollte natürlich die Abspielkonsole – die Skin – auch nicht sichtbar sein. „Nicht sichtbar“ wäre im einfachsten Fall so zu realisieren, dass der Alphawert der Skin zunächst auf den Wert 0 gesetzt wird und erst nach Eintreten des READY-Ereignisses den vorgegebenen Wert von – in unserem Fall – 0.7 bekommt.

Hierfür sind drei Schritte notwendig:

1. Den Alphawert der Skin zunächst auf den Wert 0 setzen:

myVideoplayer.skinBackgroundAlpha = 0;

2. Einen Eventhandler defi nieren, der bei Auftreten des READY-Ereignisses den Alphakanal auf 0.7 setzt:

function EReady(myEvent:VideoEvent):void {

myVideoplayer.skinBackgroundAlpha = 0.7;

}

u

u

u

Page 406: Flash cs3, ajax und 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 ) 393

3. Den Eventhandler unserer FLVPlayback-Instanz zuweisen:

myVideoplayer.addEventListener(VideoEvent.READY, EReady);

Nach Auftreten des COMPLETE-Ereignisses wäre es beispielsweise nett, wenn dem User eine entsprechende Meldung im Fenster ausgegeben wird. Hierzu ein Beispiel:

ABBILDUNG 8.14

Teilen Sie dem User zusätz-lich mit, wann das Ende eines Videos erreicht ist (auch wenn er es vielleicht in der Abspielleiste sehen könnte ...). Video-Copyright: TV1.at – www.tv1.at

Der eingeblendete Text befindet sich in einem MovieClip mcFinish, der als Instanz auf der Bühne den Namen mcFinished erhalten hat (siehe Abbildung 8.15):

ABBILDUNG 8.15

Der MovieClip mcFinish erhält als Instanzname auf der Bühne den Namen mcFinished.

Page 407: Flash cs3, ajax und php

K A P I T E L 8394

Um die Instanz zunächst auszublenden, wird die Eigenschaft visible a uf den Wert false gesetzt:

mcFinished.visible = false;

Bitte beachten Sie an dieser Stelle wieder den Unterschied von ActionScript 2.0 und ActionScript 3.0: Trug die Eigenschaft in ActionScript 2.0 noch den Namen _visible ( inklusive Unterstrich „_“ am Anfang) und war eine Eigenschaft innerhalb der Movie-Clip-Klasse, so wurde der Unterstrich in ActionScript 3.0 entfernt und die Eigenschaft in die DisplayObject-Klasse verschoben.

Bei Auftreten des Ereignisses COMPLETE wird die Instanz wieder eingeblendet:

function EComplete(myEvent:VideoEvent):void {

mcFinished.visible = true;

}

myVideoplayer.addEventListener(VideoEvent.COMPLETE, EComplete);

Listing 8.2: Sobald das COMPLETE-Ereignis auftritt, wird die MovieClip-Instanz mcFinished eingeblendet.

Das entsprechende Beispiel finden Sie auf der Buch-CD unter dem Namen videoplay-er_01a.flv im Verzeichnis des aktuellen Kapitels.

Im Hinblick auf die weitere Entwicklung des Videoplayers werden wir das COMPLETE-Ereignis dahingehend verwenden, dass nach dem Abspielen eines Videos das nächste Video gestartet wird.

8.3.4 Schritt 1: Abspielen einer Liste von Videos (Array)Nachdem wir es nun vollbracht haben, ein Video dynamisch einzubinden, kann das nächste Ziel nur sein, mit einer Liste von Videos zu arbeiten. Mit anderen Worten wollen wir Folgendes:

Nachdem ein Video fertig abgespielt wurde, soll das nächste Video abgespielt wer-den.

Es soll die Möglichkeit bestehen, aus einer Liste von Videos eine Auswahl zu treffen und somit ein Video direkt auszuwählen.

Es soll von einem Video zum nächsten bzw. zum vorigen gesprungen werden können.

Punkt eins ist relativ einfach realisiert, nachdem wir zuvor gerade das COMPLETE-Ereignis kennengelernt haben. Der zweite Punkt wird über eine ComboBox realisiert, Punkt drei über entsprechende Tasten in der Skin.

u

u

u

_visible in ActionScript

2.0, visible in ActionScript 3.0

_visible in ActionScript

2.0, visible in ActionScript 3.0

Page 408: Flash cs3, ajax und 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 ) 395

Bevor wir die Punkte nacheinander angehen, müssen wir aber erst mal für eine Video-liste und einen Index sorgen:

var videoList:Array = new Array ("videos/Dueringer.fl v"," videos/Faak2005.fl v"," videos/FestaDucati2006.fl v"," videos/Juvenile.fl v");

var videoIndex:uint = 0;

Listing 8.3: videoList und videoIndex defi nieren die Liste an abzuspielenden Videos und den Index des Videos aus der Liste, das gerade abgespielt wird.

Den Index verwenden wir dazu, um uns zu merken, welches Video aus der Liste gerade abgespielt wird (oder werden soll) – der Index zeigt also genau auf die Position des aktuellen Videos im Array videoList.

So, dann gehen wir die drei Punkte aus der obigen Liste an. Punkt eins war die Forde-rung nach dem Abspielen des nächsten Videos, sobald ein Video komplett abgespielt wurde. Stellt sich nur noch die Frage, was passieren soll, wenn das Ende der Videoliste erreicht ist ... Wir handhaben diesen Fall derart, dass wir in einer Variablen loopAtEnd uns diesen Fall offen lassen: Ist loopAtEnd==true, so wird beim Erreichen des Endes der Liste das erste Video in der Liste abgespielt (und somit eine Schleife erzeugt). Ist loopAtEnd==false, beenden wir das Abspielen am Ende der Liste und blenden die MovieClip-Instanz mcFinished ein.

Sämtliche oben genannte Änderungen betreffen den Eventhandler EComplete:

var loopAtEnd:Boolean = true;

function EComplete(myEvent:VideoEvent):void {

videoIndex++;

if(videoIndex==videoList.length) {

if(loopAtEnd) { videoIndex = 0; }

else { mcFinished.visible = true; return; }

}

myVideoplayer.source = videoList[videoIndex];

}

Listing 8.4: Änderungen an dem Eventhandler loopAtEnd

Bei Eintreten des Ereignisses COMPLETE wird die Funktion EComplete aufgerufen. Hierin wird zunächst der videoIndex um eins erhöht und kontrolliert, ob so even-tuell das Ende der Liste erreicht wurde. Ist dies der Fall, müssen wir überprüfen, ob wir in der Videoliste wieder von vorne beginnen (loopAtEnd==true) oder nicht (loopAtEnd==false). Wenn ja, wird also der Index (videoIndex) auf null gesetzt. Bei nein blenden wir mcFinished ein und brechen die Funktion mit return ab. Sollte das Ende der Liste noch nicht erreicht gewesen sein oder die Liste wieder von vorne

Page 409: Flash cs3, ajax und php

K A P I T E L 8396

abgespielt werden, weisen wir der FLVPlayback-Instanz myVideoplayer eine neue Quelle aus der Liste zu und weiter geht’s mit Abspielen ...

Auf zur nächsten Aufgabe: Aus der Liste an Videos soll eine Kombo-Box (ComboBox-Komponente) gefüllt werden. Wie auch schon zuvor werden wir in einem Beispiel (dasjenige mit der 1 im Dateinamen: videoplayer_01x.fla) eine Komponente auf die Bühne ziehen und im anderen Beispiel (dasjenige mit der 2 im Dateinamen: videoplay-er_02x.fla) die Komponente mit ActionScript erstellen.

In den User Interface-Komponenten finden Sie die ComboBox-Komponente. Plat-zieren Sie eine Instanz auf der Bühne an der Position (44/436), ändern Sie die Breite auf 200 Pixel und weisen Sie ihr den Namen myCombobox zu. Um die ComboBox mit Daten zu füllen, benötigen wir dennoch ActionScript:

var theObject:Object = new Object();

for(var i:Number = 0; i<videoList.length; i++) {

theObject = { label:videoList[i], data:i };

myCombobox.addItem(theObject);

}

Listing 8.5: Listing zum Generieren der Inhalte der ComboBox-Instanz myCombobox

Das Füllen der Daten erfolgt mithilfe eines Objekts, das eine klare Struktur aufweist:

{ label:BESCHRIFTUNG, data:WERT }

label bezeichnet die Beschriftung, die in der ComboBox abgelesen werden kann.

data bestimmt den Wert der ComboBox, der beim Auswählen eines Eintrags gesetzt wird.

Der Code kann entweder sehr ausführlich geschrieben werden (wie im obigen Script dargestellt) oder auch sehr kompakt:

for(var i:Number = 0; i<videoList.length; i++) {

myCombobox.addItem({ label:videoList[i], data:i });

}

Listing 8.6: Alternative Kurzschreibweise von <?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>

<Playlist rootDir="videos" autostart="0">

<File src="FestaDucati2006.fl v">

<Author>www.tv1.at</Author>

<Content>Festa Ducati 2006</Content>

<Date>2006-07-08</Date>

</File>

<File src="Faak2005.fl v">

u

u

Page 410: Flash cs3, ajax und 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 ) 397

<Author>www.tv1.at</Author>

<Content>Motorradtreffen Faak am See 2005</Content>

<Date />

</File>

<File src="Tattooconvention.fl v">

<Author>www.tv1.at</Author>

<Content>Tattoo Convention 2006</Content>

<Date />

</File>

<File src=»Juvenile.fl v»>

<Author>www.tv1.at</Author>

<Content>HipHop-Festival Wels</Content>

<Date />

</File>

<File src="Dueringer.fl v">

<Author>www.tv1.at</Author>

<Content>Dueringer ab 4.99</Content>

<Date />

</File>

</Playlist>

Listing 8.6.

Das Füllen der ComboBox hätten wir geschafft, jedoch hilft uns das wenig, wenn die Auswahl eines Videos in der ComboBox nichts bewirkt. Mit anderen Worten: Die ComboBox muss ein bisschen „Intelligenz“ erhalten: Sobald eine Änderung in der Auswahl der ComboBox erfolgt, soll eine Funktion aufgerufen werden, die das neu gewählte Video abspielt. Ein geeigneter Event für diese Aufgabe ist CHANGE, das bei jeder Änderung der Auswahl in einer ComboBox auftritt:

function EChange(myEvent:Event):void {

videoIndex = myCombobox.selectedIndex;

myVideoplayer.source = videoList[videoIndex];

myVideoplayer.play();

}

myCombobox.addEventListener(Event.CHANGE, EChange);

Listing 8.7: Der Eventhandler für das CHANGE-Ereignis setzt den Index auf den gewählten Eintrag der ComboBox, setzt die Videoquelle auf die entsprechende Videodatei aus der Liste und lässt das Video abspielen.

Page 411: Flash cs3, ajax und php

K A P I T E L 8398

Der Ablauf ist relativ einfach und übersichtlich:

1. Es wird eine Funktion EChange defi niert, die bei Aufruf den Wert der ComboBox myCombobox ausliest und den Index (videoIndex) auf genau diesen Wert setzt.

2. Aus der Videoliste videoList wird die entsprechende URL zur Videodatei gelesen und der FLVPlayback-Instanz myVideoplayer als Quelle zugewiesen.

3. Das Video wird abgespielt (myVideoplayer.play();).

Wie würde der Code aussehen, würden wir die ComboBox per ActionScript generie-ren? Nun, auch nicht sehr viel aufwändiger. Lediglich die folgenden Zeilen müssten den Listings Listing 8.6 und Listing 8.7 vorangestellt werden, um den ActionScript-Part abzudecken:

import fl .controls.ComboBox;

var myCombobox:ComboBox = new ComboBox();

myCombobox.move(44,436);

myCombobox.width = 200;

addChild(myCombobox);

Listing 8.8: Generieren einer ComboBox per ActionScript. Alternativ hätten Sie die ComboBox auch über die Eigenschaften x und y verschieben können (myCombobox.x = 44; myCombobox.y = 436).

Wie auch im Fall der FLVPlayback-Komponente muss die ComboBox-Komponente von der Komponentenübersicht in die Bibliothek gezogen werden, um im Weiteren für ActionScript verfügbar zu sein:

ABBILDUNG 8.16

Um per ActionScript zur Laufzeit eine Komponente erstellen zu können, muss

sich diese in der Bibliothek befinden.

Page 412: Flash cs3, ajax und 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 ) 399

Folgendes ist also geschehen: Die ComboBox-Komponente wurde für den Einsatz mit ActionScript zur Laufzeit bereitgestellt. Diese Informationen finden Sie, wenn Sie die Eigenschaften der ComboBox in der Bibliothek aufrufen:

ABBILDUNG 8.17

In den Eigenschaften der ComboBox erfahren Sie, dass diese für den „Export für ActionScript“ bereitgestellt wurde.

Es wird Zeit, dass wir mal ein bisschen rekapitulieren. Mittlerweile existieren in unserem Script schon zwei Aufrufe für das Zuweisen einer Quelle und das Abspielen des aktuellen Videos. Besser wäre es, wir würden eine Funktion schreiben, welche diese Aufgabe erledigt, dass unser Code so übersichtlicher wird. Die Daten bis zu diesem Punkt finden Sie in der Datei videoplayer_01b.fla (sowie videoplayer_02b.fla), die „bes-ser strukturierte und aufgeräumte Datei“ ist videoplayer_01c.fla (videoplayer_02c.fla).

Die neue Funktion loadVideo zum Laden und Abspielen eines Videos erhält zwei Parameter übergeben:

function loadVideo(increaseIndex:uint, playVideo:Boolean):void {

...

}

increaseIndex: ein numerischer Wert, um wie viel der aktuelle videoIndex erhöht oder verringert wird. (Typischerweise ist dieser Wert gleich eins, da nach einem komplett abgespielten Video das nächste Video der Liste abgespielt wird.)

playVideo: eine boolesche Variable, die angibt, ob das nun geladene Video auch gleich gestartet werden soll.

u

u

Page 413: Flash cs3, ajax und php

K A P I T E L 8400

Die Funktion selbst wird auch dafür Sorge tragen, dass, sofern das Ende der Videoliste erreicht ist, entweder das Abspielen beendet oder von vorne begonnen werden soll (siehe hierzu auch Listing 8.4):

function loadVideo(increaseIndex:uint, playVideo:Boolean):void {

videoIndex+=increaseIndex;

if(videoIndex==videoList.length) {

if(loopAtEnd) { videoIndex = 0; }

else { mcFinished.visible = true; return; }

}

myVideoplayer.source = videoList[videoIndex];

if(playVideo) { myVideoplayer.play(); }

}

Listing 8.9: Die neu eingeführte Funktion entspricht im Wesentlichen Listing 8.4, jedoch wird videoIn-dex um den übergebenen Wert von increaseIndex erhöht und das Video nur dann abgespielt, wenn playVideo==true ist.

Somit verändern sich die Eventhandler für die ComboBox (Ereignis CHANGE) und die FLVPlayback-Komponente (Ereignis COMPLETE):

function EChange(myEvent:Event):void {

videoIndex = myCombobox.selectedIndex;

loadVideo(1,true);

}

function EComplete(myEvent:VideoEvent):void {

loadVideo(1,true);

}

Listing 8.10: Änderungen in den Eventhandlern CHANGE und COMPLETE

Zu guter Letzt ändert sich auch die letzte Zeile des Scripts von:

myVideoplayer.source = videoList[videoIndex];

in:

loadVideo(0,false);

Page 414: Flash cs3, ajax und 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 ) 401

8.3.5 Schritt 2: Abspielen einer Liste von Videos (XML)Alternativ zu einer fest vorgegebenen Liste an Videos bietet sich XML als „Listen-Geber“ an.

Die XML-Datei können wir im Wesentlichen in ihrer Struktur der Audio-Jukebox entnehmen – in diesem Workshop haben wir uns schon sehr ausführlich mit der Idee des Aufbaus der XML-Struktur befasst.

Werfen wir noch einmal einen kurzen Blick auf die Struktur:

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>

<Playlist rootDir="videos" autostart="0">

<File src="FestaDucati2006.fl v">

<Author>www.tv1.at</Author>

<Content>Festa Ducati 2006</Content>

<Date>2006-07-08</Date>

</File>

<File src="Faak2005.fl v">

<Author>www.tv1.at</Author>

<Content>Motorradtreffen Faak am See 2005</Content>

<Date />

</File>

<File src="Tattooconvention.fl v">

<Author>www.tv1.at</Author>

<Content>Tattoo Convention 2006</Content>

<Date />

</File>

<File src=»Juvenile.fl v»>

<Author>www.tv1.at</Author>

<Content>HipHop-Festival Wels</Content>

<Date />

</File>

<File src="Dueringer.fl v">

<Author>www.tv1.at</Author>

<Content>Dueringer ab 4.99</Content>

<Date />

Page 415: Flash cs3, ajax und php

K A P I T E L 8402

</File>

</Playlist>

Listing 8.11: Die XML-Struktur für die Playlist unseres Videoplayers (Beispieldatei playlist.txt). Sämtliche Videos sind im Verzeichnis „videos“ untergebracht.

Wie schön öfter erwähnt, ist einer der großen Vorteile von XML-Dateien, dass es (fast) keine Vorgaben bezüglich des Aufbaus gibt, also auch kein „richtig“ und „falsch“. Aus diesem Grund ist auch die obig dargestellte Struktur nur eine von vielen Möglich-keiten. Alternativ dazu könnte man beispielsweise auch das Attribut src als eigenes Tag führen oder die Tags <Author>, <Content> und <Date> als Attribute führen:

...

<File>

<src>Video01.fl v</src>

<Author>Ducati Club Linz</Author>

<Content>1. Mai Ausfahrt 2007</Content>

<Date>2007-05-01</Date>

</File>

...

Listing 8.12: Variante 1 ...

...

<File src="Video01.fl v" Author="Ducati Club Linz" Content="1. Mai Ausfahrt 2007" Date="2007-05-01 />

...

Listing 8.13: ... und Variante 2. Welche Variante Sie bevorzugen, liegt an Ihnen.

Da wir die in Abschnitt 8.3.4 erzeugte Liste nun nicht mehr in der damaligen Form benötigen, ändern wir die Zeile

var videoList:Array = new Array("videos/Dueringer.fl v","videos/Faak2005.fl v","videos/FestaDucati2006.fl v","videos/Juvenile.fl v");

in

var videoList:Array = new Array();

um. Somit ist das Array derzeit noch leer – das Füllen des Arrays erledigen wir, nach-dem die XML-Daten aus der entsprechenden Datei gelesen wurden. Weiter unten wird die Definition des Arrays von dieser Stelle entfernt und an eine andere Stelle im Code gesetzt. Wie eine XML-Datei gelesen wird, haben wir sehr ausführlich im Kapitel „Ser-verseitiger Datenaustausch“ gesehen – nun wollen wir die Früchte dessen ernten und das Laden von Videolisten über eine XML-Datei spielen.

„Richtige“ und „falsche“ XML-

Strukturen?

„Richtige“ und „falsche“ XML-

Strukturen?

Page 416: Flash cs3, ajax und 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 ) 403

Das Grundgerüst stellt sich wie folgt dar:

System.useCodePage = true;

var myLoader:URLLoader = new URLLoader();

var theURL:String = "URL_ZUR_XML-DATEI";

var myURL:URLRequest = new URLRequest(theURL);

var myXML:XML;

function EXMLComplete(myEvent:Event):void {

myXML = new XML(myEvent.target.data);

myXML.ignoreWhitespace = true;

...

}

myLoader.addEventListener(Event.COMPLETE, EXMLComplete);

myLoader.load(myURL);

Listing 8.14: Grundgerüst zum Laden von XML-Daten aus einer gegebenen Datei

Die wesentlichen Punkte sind also folgende:

Zeichensatz auf den in der XML-Datei definierten setzen: System.useCodePage = true;

URLLoader-Instanz zum Laden von (textbasierten) Daten anlegen: myLoader

URLRequest-Instanz zum Angeben einer Datenquelle anlegen: myURL

XML-Objekt definieren, das die geladenen Daten erhält: myXML

Eventhandler definieren, der reagieren soll, sobald die Daten aus der Quelle geladen wurden: EXMLComplete.

Angewandt auf unser Beispiel muss zunächst einmal nur die Variable theURL gesetzt werden:

var theURL:String = "playlist.txt";

Listing 8.15: Es soll die Datei playlist.txt geladen werden.

Der einfachste (aber manchen Hardcore-Programmierern eher widerstrebende) Weg zum Laden von XML-Daten ist der, dass der Ladevorgang der XML-Daten in einem Bild der Zeitleiste (oder sogar einer eigenen Szene) und das Abspielen der Videos in einem zweiten Bild erfolgt:

u

u

u

u

u

Page 417: Flash cs3, ajax und php

K A P I T E L 8404

Eine weitere Alternative wäre:

1. XML-Daten laden

2. Erst nach dem vollständigen Laden der XML-Daten den Bildschirm inklusive FLVPlayback-Komponente, ComboBox etc. aufbauen

Da ich jedoch großen Wert darauf lege, dass die Programmierung noch nachvollzieh-bar und übersichtlich bleibt, möchte ich trotz aller Unkenrufe aus der Hardcore-Pro-grammierer-Abteilung diesen Weg beschreiten.

Vor den derzeit vorhandenen Bildern in der Flash-Datei legen Sie bitte daher ein neues Bild an (siehe Abbildung 8.18). In der Elementeebene wurde lediglich der statische Text „Lade XML-File – bitte einen Moment Geduld…“ eingefügt. Die Aktionenebene erhält folgenden Code:

// ---- XML-Daten laden: ----

System.useCodePage = true;

var videoList:Array = new Array();

var myLoader:URLLoader = new URLLoader();

var theURL:String = "playlist.txt";

var myURL:URLRequest = new URLRequest(theURL);

ABBILDUNG 8.18

Laden der XML-Daten und Abspielen der Videos ist

in der Zeitleiste in Bildern getrennt.

Page 418: Flash cs3, ajax und 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 ) 405

var myXML:XML;

function EXMLComplete (myEvent:Event):void {

myXML = new XML(myEvent.target.data);

myXML.ignoreWhitespace = true;

for(var i:uint=0; i<myXML.File.length(); i++) {

videoList[i] = myXML.@rootDir+"/"+myXML.File[i].@src;

}

gotoAndStop(2);

}

myLoader.addEventListener(Event.COMPLETE, EXMLComplete);

myLoader.load(myURL);

// ENDE XML-Daten laden: ----

stop();

Listing 8.16: Vollständiges Listing der Aktionenebene (Bild 1)

Zu dem in Listing 8.14 vorgestellten Gerüst sind folgende Fragmente hinzugekom-men:

Das Anlegen der Videoliste wurde von Bild 2 der Aktionenebene in Bild 1 über-nommen:

var videoList:Array = new Array();

Innerhalb des Eventhandler EXMLComplete werden in einer for-Schleife alle File-Knoten durchgegangen und deren Attribut src (aus dem Tag <Playlist>, welches dem Objekt myXML entspricht, da es das Root-Element ist) zusammen mit dem Attribut rootDir in das Array videoList geschrieben.

Abschließend wird nach dem Füllen des Arrays auf das zweite Bild der Zeitleiste gesprungen.

Im zweiten Bild der Zeitleiste musste aus der Aktionenebene lediglich die Definition der Videoliste gelöscht werden. So weit sollte alles klappen – mehr ist vorerst nicht zu tun:

u

u

u

Page 419: Flash cs3, ajax und php

K A P I T E L 8406

Details zum Video anzeigen

Aus Listing 8.11 können Sie entnehmen, dass neben der Videoquelle noch mehr an Informationen zum Video in der XML-Datei versteckt sind, die es darzustellen gilt. Beispielsweise könnte man die ComboBox aus Abbildung 8.19 mit dem Videotitel (<Content>Tattoo Convention 2006</Content>) statt dem Namen der Quellda-tei füllen. Auch sollten der Autor und das Aufnahmedatum (sofern vorhanden) nicht verschwiegen werden.

Bisher war unsere Vorgehensweise folgende:

Die Beschriftung (label) innerhalb der ComboBox beinhaltet den Namen der Video-Quelldatei.

Der Wert (data) der Combobox war der Index des Videos in der Videoliste video-List.

Den Wert werden wir so beibehalten, die Beschriftung soll sich auf den Videotitel ändern. Hierzu müssen wir jedoch ein bisschen weiter ausholen, da wir den Videotitel bisher noch gar nicht gespeichert haben. Daher wird unsere videoList eine kleine Änderung durchmachen müssen: Anstatt nur die Videoquelle zu speichern, speichern wir die videoList gar nicht mehr, sondern greifen direkt auf die eingelesenen XML-Daten in myXML zu! Dank ActionScript 3.0 ist das nun denkbar einfach.

u

u

Titel statt Videoquelle in der ComboBox

anzeigen

Titel statt Videoquelle in der ComboBox

anzeigen

ABBILDUNG 8.19

Das Laden der XML-Daten war erfolgreich – alles andere ist wie gehabt.

Page 420: Flash cs3, ajax und 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 ) 407

Im Eventhandler zum Laden der XML-Daten entfernen wir folgende Teile komplett:

var videoList:Array = new Array();

Listing 8.17: Das Array wird nicht mehr benötigt.

for(var i:uint=0; i<myXML.File.length(); i++) {

videoList[i] = myXML.@rootDir+"/"+myXML.File[i].@src;

}

Listing 8.18: Dieser Teil wird aus dem Eventhandler EXMLComplete vollständig entfernt.

Beim Füllen der ComboBox (Bild 2 der Aktionenebene) ändern wir die for-Schleife von

for(var i:Number = 0; i<videoList.length; i++) {

myCombobox.addItem({ label:videoList[i], data:i });

}

in

for(var i:Number = 0; i<myXML.File.length(); i++) {

myCombobox.addItem({ label:myXML.File[i].Content, data:i });

}

Listing 8.19: Anstatt auf die videoList zuzugreifen, nehmen wir gleich den Inhalt der XML-Daten aus myXML.

myXML.File greift auf alle Knoten mit dem Namen „File“ zu, die wir Eintrag für Ein-trag auslesen, um aus diesen Knoten jeweils auf den Sub-Knoten namens „Content“ zuzugreifen.

Am Laden und Abspielen der Videodaten muss auch noch ein bisschen gefeilt werden, da dort immer noch auf die Videoliste videoList zugegriffen wird. In der Funktion loadVideo in Bild 2 der Funktionenebene müssen zwei Änderungen vorgenommen werden. Aus den Zeilen

if(videoIndex==videoList.length) {

...

myVideoplayer.source = videoList[videoIndex];

wird

if(videoIndex==myXML.File.length()) {

...

myVideoplayer.source = myXML.@rootDir+"/"+myXML.File[videoIndex].@src;

Listing 8.20: Aus videoList.length wird myXML.File.length() und aus dem Inhalt von videoList[i] wird myXML.@rootDir+"/"+myXML.File[videoIndex].@src.

Page 421: Flash cs3, ajax und php

K A P I T E L 8408

Letzten Endes wurde das Array videoList nicht mehr benötigt, da myXML mehr oder weniger auch als Liste angesehen werden kann. Da der Zugriff auf XML-Daten seit ActionScript 3.0 nun denkbar einfach ist, sollte man davon auch Gebrauch machen.

ABBILDUNG 8.20

Nun ist der Inhalt der ComboBox auch informa-

tiver und sprechender.

Autor und Aufnahmedatum anzeigen

Kümmern wir uns noch um die Ausgabe von Autor und Aufnahmedatum. Hier offen-baren sich mehrere mögliche Wege:

Es werden dynamische Textfelder angelegt und diese beim Laden einer Videoquelle mit Inhalt gefüllt.

Die Textfelder werden nicht vorab angelegt, sondern bei jedem Laden einer Video-quelle neu erzeugt.

Sämtliche Informationen werden in einer TextArea-Komponente angezeigt.

Wir werden den dritten Weg einschlagen und eine TextArea-Komponente verwen-den, die wir einerseits (videoplayer_01e.fla) direkt auf der Bühne platzieren und ande-rerseits (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:

editable: false

horizontalScrollPolicy: off

u

u

u

u

u

Page 422: Flash cs3, ajax und 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 ) 409

Breite: 300 Pixel

Höhe: 40 Pixel

Position (x/y): (256/436)

u

u

u

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üss-ten wir folgendermaßen vorgehen:

ABBILDUNG 8.21

Eine Instanz der TextArea-Komponente wurde auf der Bühne in der Elementeebene eingefügt.

Page 423: Flash cs3, ajax und php

K A P I T E L 8410

TextArea-Komponente in die Bibliothek ziehen

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 hinzuge-fü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 zuge-wiesen, 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:

u

u

Page 424: Flash cs3, ajax und 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 ) 411

Tabelle Feld Typ Details Beschreibung

tbl_08playlist idP_Playlist int(11) auto-increment, Primary Key, not null

ID der Playlist

vcP_Bezeichnung varchar(128) not null Eine interne Playlist-Bezeichnung, die innerhalb der XML-Struktur nicht verwendet wird

vcP_Rootdir varchar(128) not null URL zum Root-Verzeichnis der Videos in der Playlist

bitP_chk_autostart tinyint(1) not null, Standard = 1

Kennzeichnung, ob Autostart der Playlist an (1) oder aus (0) ist

tbl_08videos idP_video int(11) auto-increment, Primary Key, not null

ID des Videos

fi dP_select_Bezeichnung_Playlist

int(11) not null Ein Feld, das als Foreign Key zur Tabelle tbl_08play-list verwendet wird

vcP_Src varchar(128) not null URL zur Videoquelle

vcP_Content varchar(128) not null Name des Videos

vc_Author varchar(64) null Name des Autors (sofern vorhanden)

dt_Date date null Aufnahmedatum (sofern vorhanden)

tmP_Uploadtimestamp timestamp not null, CURRENT_TIMESTAMP

Timestamp des Eintrags des Videos in die Tabelle

Tabelle 8.1: Aufbau der beiden Tabellen für unser Beispiel

Eine solche PHP-Datei zum Generieren von XML-Content aus den beiden oben defi-nierten Tabellen könnte folgendermaßen aussehen:

function createXML($idP_Playlist) {

$dbData = array(

"dbServer" => "mysql.syneweb.com",

"dbUser" => "usr_mysql2",

"dbPWD" => "456mysql!",

"dbName" => "db_fl ashphpajax"

);

if(!$conn = mysql_connect($dbData["dbServer"],$dbData["dbUser"],$dbData["dbPWD"])) {

die('<div class="Error">Der Datenbankserver konnte nicht erreicht werden.<br/>ERROR='.mysql_error().'</div>');

}

Page 425: Flash cs3, ajax und php

K A P I T E L 8412

if(!mysql_select_db($dbData["dbName"])) {

die('<div class="Error">Die Datenbank konnte nicht ausgewaehlt werden.<br/>ERROR='.mysql_error().'</div>');

}

$sql = "SELECT * FROM tbl_08playlist WHERE(idP_Playlist=$idP_Playlist)";

$query = mysql_query($sql) or die('<div class="Error">Die Query konnte nicht abgesetzt werden.<br/>ERROR='.mysql_error().'</div>');

$data = mysql_fetch_array($query);

$msg = ‚<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>';

$msg.= ‚<Playlist rootDir="'.$data["vc_Rootdir"].'" autostart="'.$data["bitP_chk_autostart"].'">';

$sql = "SELECT * FROM tbl_08videos WHERE(fi dP_select_Bezeichnung_Playlist=$idP_Playlist)";

$query = mysql_query($sql) or die('<div class="Error">Die Query konnte nicht abgesetzt werden.<br/>ERROR='.mysql_error().'</div>');

while($data = mysql_fetch_array($query)) {

$msg.= '

<File src="'.$data["vcP_Src"].'">

<Author>'.$data["vc_Author"].'</Author>

<Content>'.$data["vcP_Content"].'</Content>

<Date>'.$data["dt_Date"].'</Date>

</File>

';

}

$msg.= '</Playlist>';

return $msg;

}

if(count($_GET)>0 && isset($_GET["idP_Playlist"])) { echo(createXML($_GET["idP_Playlist"])); }

else { echo('<div class="Error">Sie haben keine Berechtigung f&uuml;r diese Site.</div>'); }

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.

Page 426: Flash cs3, ajax und 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 ) 413

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 defi niert 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 = ‚<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>';

$msg.= ‚<Playlist rootDir="'.$data["vc_Rootdir"].'" autostart="'.$data["bitP_chk_autostart"].'">';

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.= ‚

<File src="'.$data["vcP_Src"].'">

<Author>'.$data["vc_Author"].'</Author>

<Content>'.$data["vcP_Content"].'</Content>

<Date>'.$data["dt_Date"].'</Date>

</File>

‚;

5. Zuletzt wird noch das geöffnete Tag <Playlist> 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:

Page 427: Flash cs3, ajax und php

K A P I T E L 8414

Flash muss demnach eine XML-basierte PHP-Datei playlist.php einlesen, die über einen GET-Parameter die korrekten Daten aus einer Datenbank ausliest. Nun offen-baren 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 Flash-Datei 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 vor-nehmen.

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 Tat-sache, 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 Aktionenebe-ne in Bild 1 die Zeile

var theURL:String = "playlist.txt";

ABBILDUNG 8.22

Nun wurde die XML-Datei nicht mehr „von Hand“

geschrieben, sondern per PHP aus einer Datenbank

und zwei Tabellen erzeugt.

Page 428: Flash cs3, ajax und 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 ) 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 erzeug-ten 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 Webdoku-ment zunächst die ID der Playlist an Flash übergeben – erst dann kann Flash die XML-Daten 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;

Page 429: Flash cs3, ajax und php

K A P I T E L 8416

nextFrame();

}

Listing 8.24: Die Funktion loadXLMVideodata erhält als Übergabeparameter die Playlist-ID von Java-Script.

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 fl ash.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 defi nierte Funktion loadXMLVideodata wird als sogenannte „Callback-Funktion“ für JavaScript registriert. Die Flash-Datei fi nden Sie auf der Buch-CD unter dem Namen videoplayer_01g.fl a.

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 zugewie-sen wird. Sollte das ExternalInterface verfügbar sein, wird versucht, die Callback-Funk-tion 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 defi niert, die beim Laden der XML-Daten an das entsprechende PHP-Script angehängt wird.

Page 430: Flash cs3, ajax und 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 ) 417

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(<?php echo($_GET["idP_Playlist"]); ?>);

}

Listing 8.27: Übergabe der per GET defi nierten 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 Übergabepa-rameter 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 fi ndet 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:

Page 431: Flash cs3, ajax und php

K A P I T E L 8418

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 Select-Box 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 sendData-ToFlash ü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('<div class="Error">Fehler beim Absetzen der Query.<br/>ERROR='.mysql_error().'</div>');

if(mysql_num_rows($query)>0) {

$returner = '

<select name="selPlaylist" id="selPlaylist" onchange="setPlaylistID();">

<option value="-1">Bitte w&auml;hlen Sie aus:</option>

‚;

while($data = mysql_fetch_array($query)) {

$returner.= '

<option value="'.$data["idP_Playlist"].'">'.$data["vcP_Bezeichnung"].'</option>

';

}

$returner.= '</select>';

}

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 Proze-dere hinlänglich bekannt ist. Die Datei fi nden Sie auf der Buch-CD unter videoplayer_01h.php.

Page 432: Flash cs3, ajax und 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 ausge-lö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 getrof-fen, lädt Flash die Videos zur Playlist und stellt diese in der ComboBox dar.

Page 433: Flash cs3, ajax und php

K A P I T E L 8420

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).

Page 434: Flash cs3, ajax und 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 ) 421

Schritt 3: Hat sich der User dafür entschieden, das Video in seine Abspielliste zu über-nehmen, wird die Abspielliste entsprechend erweitert (Abbildung 8.28).

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.

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:

Page 435: Flash cs3, ajax und php

K A P I T E L 8422

...

$sql = "SELECT tmP_Uploaddatum FROM tbl_08videos WHERE(fi dP_select_Bezeichnung_Playlist=".$_GET["idP_Playlist"].") ORDER BY tmP_Uploaddatum DESC LIMIT 1";

$query = mysql_query($sql) or die('<div class="Error">ERROR='.mysql_error().'</div>');

$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 neu-este 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 erwei-tert:

var fi rstShow = true;

var itv;

function setPlaylistID() {

var idP_Playlist = document.forms["frmVideoplayer"].elements["selPlaylist"].value;

if(idP_Playlist!=-1) {

if(fi rstShow) { 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 AJAX-Abfrage 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) gestar-tet, das alle 60 Sekunden eine Funktion sendRequest mit dem Übergabeparameter

Page 436: Flash cs3, ajax und 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 ) 423

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 Verbin-dung zur Datei getnewestvideo.php geöffnet (myXMLHttpRequest.open), der Instanz ein Eventhandler zugewiesen (myXMLHttpRequest.onreadystatechange) und die Anfrage versandt werden (myXMLHttpRequest.send). Der Eventhandler handleRe-quest, der bei jeder Änderung des Status der AJAX-Anfrage aufgerufen wird, stellt sich folgendermaßen dar:

function handleRequest() {

if(myXMLHttpRequest.readyState==4) {

if(fi rstShow) {

fi rstShow = 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 abgeschlos-sen), 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-

Page 437: Flash cs3, ajax und php

K A P I T E L 8424

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 befi ndet 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

Page 438: Flash cs3, ajax und 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 ) 425

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 Einfach-heit 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 (mcNew-VideoInfo) 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 ...

Page 439: Flash cs3, ajax und php

K A P I T E L 8426

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-Variab-len vorgegaukelt wird:

var dStr:String = "&timestamp="+new Date().getTime();

var theURL:String = "playlist.php?idP_Playlist="+PlaylistID+"&CacheBuster="+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:

Flash-Datei: videoplayer_03.fla

XHTML-Datei: videoplayer_01i.php

XML-basierte PHP-Datei (Playlist): playlist.php

Ermitteln neuer Videos in der Datenbank: getnewestvideo.php

Include-Datei zum Verbindungsaufbau mit der Datenbank: includes/connectdb.inc.php

8.3.6 Arbeiten mit Cue-PointsHierzu 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:

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.

Aus dem Array FLVPlayback.metadata.cuePoints können sämtliche Cue-Points ausgelesen werden. Diese sind darin als Objekte abgelegt:

type:String: Typ des CuePoint. Mögliche Werte sind „event“ oder „navigati-on“. Siehe hierzu auch die Ausführungen im Abschnitt 8.3.2.

name:String: Name des CuePoint

time:Number: Eine auf drei Kommastellen genaue Zahl, die den Zeitpunkt des CuePoint angibt

u

u

u

u

u

u

u

u

u

u

XML im Cache?XML im Cache?

Page 440: Flash cs3, ajax und 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 ) 427

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 Combo-Box 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

u

Page 441: Flash cs3, ajax und php

K A P I T E L 8428

Die Funktion createComboBoxCuePoints wird beim Auftreten des COMPLETE-Ereig-nisses 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(fi rstShow) {

fi rstShow = false;

createTextArea();

createFLVPlayback();

createComboBox();

createComboBoxCuePoints();

}

loadComboBoxData();

}

Das Ergebnis spricht wie immer für sich:

Viel Spaß beim Umsetzen!

ABBILDUNG 8.29

Die geladenen CuePoints, über die man direkt

Abschnitte in der FLV-Datei anspringen kann

Page 442: Flash cs3, ajax und php

Stichwortverzeichnis

Symbole$-Zeichen 8$_GET 261$HTTP_GET_VARS 262$HTTP_POST_VARS 262

AAC_FL_RunContent 178ActionScript 1.0 6ActionScript 2.0 6ActionScript-Referenz 349addEventListener 362Addition 18Aktionen auslösen 172all 170appendChild 290Array 10, 24

assoziatives 25, 257attributes 282auslesen 257Elementanzahl 36erstellen 24, 25indiziertes 24in Flash 282Länge 36superglobales 14übergeben 45

Attribute 282Ausgeben von XML-Daten

286Auskommentieren 7Automatische Typisierung 13

BBedingungen 28break 41

CCache 426Caching 53

verhindern 54

Case-sensitive 10Child 272childNodes 273classid 169clearInterval 351closdir() 356codebase 169contentType 289continue 41Cookies 47

Gültigkeit 49Session 50setzen 48Verfallsdatum 49

count () 261createElement 290

Ddata 314Daten

an Browser 181an Flash 168an Flash senden 172aus Datenbank 253Datenbank speichern 295schreiben 260übergeben 260verschicken 241versenden, GET 260versenden, POST 262von Flash auslesen 295

Datenbankauswählen 255Verbindungsaufbau 255

Datentypen 8, 10Flash 11PHP 10

Datum 54Dekrement 18die 255do..while-Schleife 39

Document Object Model 170DOM 56, 170

EEbenen

Bildnamen 172embeds 171Endlosschleife 32Entwicklung

Anforderungen 338Ereignisbehandlungs-

routine 245Ereignisparameter 245Ereignisprozedur 245, 250,

341Ereignisroutinen 341ExternalInterface 184

available 187Rekursion 202

Ffi rstChild 273Flash

Datenübergabe 294JavaScript aufrufen 182

Flash Video Encoder 385FlashVars 179FLV-Format 377FLVPlayback 378for-Schleife 31

Abbruchbedingung 32Syntax 33

for...each-Schleife 37Syntax 37

for...in-Schleife 37, 342Formulardaten

versenden 15Formulare 176

Daten verschicken 260function 42

Page 443: Flash cs3, ajax und php

S T I C H W O R T V E R Z E I C H N I S430

Funktionen 41Arrays 45aufrufen 44deklarieren 42lokale Variablen 45

GGET 15, 260getElementById 170getURL 181getURL() 260

GET 261POST 263

Gleichheitstrikte 22

Grafi kenhochladen 265

Grunddatentypen 11

HhasChildNodes () 274Header 53header() 53HTML

JavaScript ausführen 181HTTP 47https 49

Iid3-Objekt 349ID3-Tag 338

auslesen 349if

Syntax 28if-Bedingungen 28ignoreComments 329ignoreProcessingInstructions

329ignoreWhite 271ignoreWhitespace 329Inkrement 18innerHTML 150int 12Integer 10is_dir() 357

JJavaScript 6, 158, 167

Flash ansprechen 172Flash-Aktion auslösen 172Wert übergeben 172

KKlammern

geschweifte 30Kommentare 7, 58

einzeilige 7mehrzeilige 7

KomponenteXMLConnector 298

LLadevorgang

fehlgeschlagen 251wiederholen 244

Lautstärkeregler 353length 334list 261loaded 243, 341loadVariables 72LoadVars 72, 165, 225, 241,

243, 263Daten versenden 264

LoadVars-Klasse 72LoadVars-Objekt

anlegen 263Variablen anlegen 263

MModulo 19MP3 338, 376

streamen 346Multimedia 338mysql_fetch_array 257mysql_pconnect 255mysql_query 256mysql_select_db 255

NnavigateToURL 323nodeValue 274Null 12

OOn2VP6 376onLoad 243, 341opendir() 356Operatoren 17, 18

arithmetisch 17Bit 21logische 21Rangordnung 21, 22Vergleich 22Zuweisung 18

Ordner öffnen 356

Pparsen 266PDF-Datei

hochladen 265PHP

XML generieren 283PHP-Referenz 15POST 15, 262Programmieren

objektorientiert 6

Rreaddir() 356readyState 127Referenzdatentypen 11, 12register_globals 15Regular Expression 160responseText 127, 234responseXML 127, 234return 43, 45RSS 72

SSchleifen 31

break 41

Page 444: Flash cs3, ajax und php

S T I C H W O R T V E R Z E I C H N I S 431

continue 41Durchläufe 31

send 294send() 260, 263sendAndLoad() 264sendToURL 320Server

Verbindung abgebrochen 244

Session 50initialisieren 51löschen 53Variablen entfernen 53Variablen speichern 51

Session-ID 50setInterval 350setRequestHeader 136SetVariable 170SGML 168Sibling 272SimpleXML 56Skins 379Sonderzeichen 242Soundobjekt 345

loadSound 346onSoundComplete 348

SoundTransform 372Streaming 346String 9, 10, 262

verketten 261verknüpfen 20

substr 357substr() 357Subtraktion 18switch

Syntax 30switch-Bedingungen 30switch-case 30

TTEXT

URLLoaderDataFormat 315text 334TextArea 175

TextdateiDaten einlesen 241einlesen 267

toString 270

Uuint 12undefi ned 12Ungleichheit

strikte 22URL-Codierung 241, 242URLLoader 309URLRequest 309Usability 253

VVariablen 8

einlesen 241globale 13Gültigkeitsbereiche 13in Arrays 280 lokale 13nicht deklarierte 14superglobale 14

Variablendeklaration 8explizit 9globale 16implizit 14lokale 16

Variablennamen 9dynamisch erzeugen 277

Variablentypen 9VARIABLES

URLLoaderDataFormat 315Verzeichnisse

auslesen 356volume 372

WWerte zuweisen 19WHILE-Schleife 40Wurzelelement 58, 272

XXHTML 167XML 56, 168, 233, 266, 325

Arrays auslesen 273Attribute 339Attribute auslesen 61auf Elemente zugreifen 272auswerten 275Befehle 266Child 272Dokumente 56einlesen 266encoding 57erstellen 62Gültigkeit 57Inhalt 57 in String umwandeln 270Knoten 273, 274Knoten auslesen 62Prolog 57Sibling 272standalone 57Syntax 59versenden 294version 57Wohlgeformtheit 57

XML-Attributespeichern 342

XML-Baum 270in Flash erzeugen 287

XMLConnector 298xmlDecl 289XML-Header 287XMLHttpRequest 125XML-Klasse 72XML-konform 268XML-Objekt 266, 325, 341XML-Struktur 339

ZZählvariable 31, 257Zeitleistenvariablen 13Zustände 21

Page 445: Flash cs3, ajax und php

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