Сегодняшний мир переполнен сокращениями. Вспомните такие аббревиатуры, как HTML, XML, HTTP, не забудьте и про Flash MX. Я хочу представить вам еще одно сокращение, о котором пойдет речь в данной лекции. PHP означает Hypertext Pre-Processor, это один из наиболее мощных языков сценариев серверной части. Примите это к сведению как веб-разработчик.
В этой лекции мы начнем с того, что представляет собой PHP, и немного поговорим о его истории.
Язык PHP был создан в конце 1994 года, когда Rasmus Lerdorf объединил набор сценариев Perl для сохранения записи посетителей его сетевого резюме. Эти сценарии заинтересовали посетителей его сайта, и в 1995 году они были опубликованы под названием "Personal Home Page Tools".
Использование PHP быстро распространялось, так же как и количество разработчиков, занимающихся проектами PHP. На момент написания этой книги последней версией PHP является PHP 4, которая имеет доступ к большому числу дополнительных средств, некоторые из которых даже реализуют динамическое создание SWF-файлов, что называется, "с нуля".
Есть несколько моментов, которые необходимо иметь в виду при рассмотрении "движка" PHP (программа, непосредственно выполняющая сценарии PHP по команде веб-сервера).
Свежую информацию о PHP можно найти на сайтах www.php.net и www.zend.com.
Прежде чем приступать к работе с PHP, нужно познакомится с тем, что такое сценарий на стороне сервера и когда он должен использоваться. В этом параграфе я отвечу на поставленные вопросы и расскажу о том, как все "навороченные" сайты находят путь на ваш веб-браузер.
Ниже приведено определение сценария на стороне сервера.
Сценарий на стороне сервера - это программа, выполняющаяся на сервере. Она может обрабатывать запросы на информацию и отвечать посредством возврата соответствующего документа по определенному критерию.
Сценарий на стороне сервера позволяет выполнять некоторые процедуры на сервере перед возвратом веб-документа в браузер. Это может быть все, что угодно, начиная с управления файлами данных и заканчивая доступом к базе данных и динамической генерацией содержимого.
В стандартной настройке клиент-сервер клиентская программа (обычно это веб-браузер) открывает соединение с сервером и запрашивает файл. Сервер после этого возвращает файл клиентской части и соединение закрывается. Этот тип соединения используется при запросе, к примеру, HTML-файлов.

С помощью сценария на стороне сервера клиент может запросить файл сценария на сервере, и ответом сервера будет выполнение этого сценария и возврат результатов согласно инструкциям сценария. С помощью этого принципа можно осуществлять получение данных из внешних источников, таких как текстовые файлы или базы данных.

Чтобы вам было понятнее, рассмотрим простой пример. Я уверен, что вы уже более чем знакомы с различными поисковыми системами интернета. Я предпочитаю систему www.google.com, и если вы перейдете на этот сайт и выполните поиск по строке "Macromedia Flash", вы будете перенаправлены на список соответствующих сайтов. В данный момент результаты поиска нам не интересны. Вместо этого следует обратить внимание на адрес URL в адресной строке вашего браузера. Он будет выглядеть примерно так.
http://www.google/search?hl=enq=Macromedia+Flash
Этот адрес можно разбить на две части. Первая из них означает страницу, которая нам нужна, в данном случае, это поисковая страница Google.http://www.google.com/search
Эта страница и есть сценарий на стороне сервера, созданный для поиска в бесчисленном множестве веб-сайтов любого текста, удовлетворяющего отдельным словам, которые мы только что указали. Слова и выбранный язык прилагаются к URL в виде строки запроса следующим образом.
hl=enq=Macromedia+Flash
Здесь мы имеем дело с двумя переменными hl и q, устанавливаемыми на значения en и Macromedia+Flash, соответственно. Первая из них указывает язык поиска, вторая является критерием поиска или запросом и передается сценарию на стороне сервера или программе, используемой Google для поиска в базах данных. В данном случае это не сценарий PHP, однако важно понимать, что это мог быть именно PHP. Итак, поисковая система Google просто сопоставляет два источника информации - введенные пользователем данные и базу данных Google - после чего результаты передаются клиенту в виде HTML-страницы.
Самым замечательным является то, что сценарии на стороне сервера позволяют динамически создавать веб-содержимое. Можно изменять и адаптировать содержимое для определенного времени дня, для учета пользовательских предпочтений, для автоматического отображения списка последних новостей, для обновления сайтов. Все это можно проделывать без редактирования вручную указанных объектов.
Более того, с помощью сценариев на стороне сервера можно работать не только со страницами HTML - можно также создавать сценарии, возвращающие данные клиентам Flash, что значительно расширяет наши возможности. Этому и посвящена данная лекция.
Для работы с этой лекцией вам понадобится доступ к PHP веб-серверу. Если у вас есть свой собственный сервер, то вам нужно загрузить соответствующие файлы установки с сайта www.php.net, где также можно найти подробное руководство по установке. Имейте в виду, что для загрузки доступно несколько различных пакетов PHP с различными уровнями функциональности, однако пусть это вас не смущает - наиболее сокращенная версия как раз подойдет для работы в этой лекции.
Если у вас нет своего собственного сервера или вы не знаете, как превратить в сервер ваш собственный компьютер, вам нужно будет узнать в службе технической поддержки или у владельца компьютера, поддерживает ли он PHP и, если это не так, попробуйте уговорить их установить для вас эту поддержку!
Если у вас нет сервера, вы можете загрузить сервер apache с сайта www.apache.org.
В предыдущей лекции вы изучали искусство загрузки данных в фильмы Flash из специально отформатированного текстового файла с использованием нового метода loadVars. Все это очень полезно и нужно, однако в определенный момент понадобится обновить данные в этом текстовом файле. Сейчас единственным способом сделать это является создание новой копии текстового файла. Несмотря на то, что в таком подходе нет ничего непоследовательного, он может стать несколько неудобным при обновлении больших объемов данных. Можно предположить, что должное форматирование данных может стать довольно сложным мероприятием, даже с использованием кодировщика, рассмотренного в лекции 15.
К счастью, из этого положения есть выход. Вместо обновления текстового файла вручную можно получить специальные программы на стороне сервера для автоматического выполнения этих действий с использованием информации, предоставляемой в виде Flash или стандартного HTML-представления. Примечательно то, что данные программы на стороне сервера могут выполнять все необходимое форматирование перед обновлением текстового файла. Программы на стороне сервера очень полезны!
В данном параграфе мы создадим отдельный фильм Flash, который можно будет использовать для обновления текстового файла для одного из приложений предыдущей лекции. Для этого понадобится сценарий PHP, но так как мы еще не изучали PHP, это может показаться аналогичным ремонту атомной электростанции с помощью отвертки и молотка. Могу вас успокоить: вы не нанесете большого вреда, экспериментируя с PHP, и двигаться мы будем последовательно, шаг за шагом.
Для забывчивых предлагаю краткий обзор того, как исходное приложение выполняет свою работу.
Для простоты мы используем одно из наиболее простых приложений из последней лекции - приложение "Message of the Day". Мы будем работать с наиболее полной версией этого приложения - с текстом HTML и фотографией.
Итак, если вы помните, код ActionScript для этого примера выглядел так.
messageURL = "message.txt";
myVars = new loadVars();
myVars.onLoad = function(success) {
if (success) {
loadMovie(this.photofile, "imgPlace1");
message = this.message;
} else {
message = "Error loading message";
}
};
myVars.load(messageURL);
Мы работаем с переменной message, содержащей текущее сообщение дня, а также с переменной photofile, указывающей изображение, которое должно загружаться в фильм.
Создадим отдельный фильм, предназначенный для обновления текстового файла. Очевидно, мы используем сценарий PHP для непосредственной записи новых данных в текстовый файл (так как Flash не может делать это самостоятельно), однако фильм Flash будет играть роль дружественного интерфейса для всего приложения.

message_txt, image_txt и status_txt в порядке сверху вниз.Я здесь просто использую обыкновенные текстовые кнопки. Я присвоил им имена инстансов load_btn и save_btn, и это позволит установить управляющие элементы событий из кадра в слое Actions.
Теперь перейдем к самой "изюминке" - к работе со слоем Actions. Мы будем последовательно изучать все выполняемые действия, чтобы вы поняли, для чего предназначен каждый фрагмент ActionScript.
Сначала нужно создать управляющие элементы событий onLoad, которые могут быть присвоены объекту loadVars. На самом деле мы собираемся создать два отдельных управляющих элемента, так как нам нужно выполнять различные действия в зависимости от того, загружаем ли мы или сохраняем текст.
displayMessage, которая будет использоваться при загрузке данных сообщения прямо из текстового файла.displayMessage = function (success) {
if (success) {
message_txt.text = this.message;
image_txt.text = this.photofile;
status_txt.text = "Data file loaded";
} else {
status_txt.text = "Could not load data file";
}
};
Здесь видно, что мы проверяем успешность выполнения операции. Если она была завершена успешно, переменные копируются из объекта loadVars в два текстовых поля, и затем текст состояния устанавливается соответствующим образом. Если возникла ошибка, пользователь информируется с помощью текста состояния.
checkSuccess = function (success) {
if (success this.result == "Okay") {
status_txt.text = "Data saved successfully";
} else {
status_txt.text = "An error has occurred";
}
};
Эта функция имеет почти такой же формат, как и предыдущая. Однако при детальном рассмотрении можно видеть, что здесь присутствует дополнительная проверка переменной в условной части выражения if. Это необходимо, так как стандартная переменная управляющего элемента дает лишь обозначение того, найден и загружен ли конечный файл. Это подходит для простых текстовых файлов, однако здесь нельзя определить, была ли процедура в сценарии на стороне сервера успешной.
Для проверки этого мы будем возвращать результирующую переменную из нашего сценария, с обозначением успешного или неудачного завершения операции. Если значением будет Okay, тогда операция выполнилась успешно, и текст состояния настраивается соответствующим образом. Если сценарий не был найден или загружен, или если процедура не удалась по какой-либо причине, пользователь информируется с помощью текста состояния.
onPress кнопок Load и Save. Первой будет кнопка load_btn, и здесь нужно установить соответствующий управляющий элемент события onLoad (displayMessage) и загрузить текстовый файл.load_btn.onRelease = function() {
dataLoader.onLoad = displayMessage;
dataLoader.load("message.txt");
};
Обратите внимание, что мы еще не создали объект dataLoader (это будет сделано в следующем шаге). Мы будем использовать объект loadVars для загрузки всех данных и вызова PHP-сценария.
save_btn немного сложнее, так как нам нужно копировать переменные из текстовых полей в объект dataLoader. Теперь можно установить управляющий элемент и вызвать сценарий PHP.save_btn.onRelease = function() {
dataLoader.message = _root.message_txt.text;
dataLoader.photofile = _root.image_txt.text;
dataLoader.onLoad = checkSuccess;
dataLoader.sendAndLoad("update.php", dataLoader, "POST");
};
Если вы раньше не встречали метод sendAndLoad: он позволяет передавать данные сценарию на стороне сервера и считывать возвращенную информацию.
dataLoader, который мы только что использовали.dataLoader = new loadVars();
На этом создание фильма Flash завершено. Фильм достаточно прост, но это несколько обманчивое впечатление, так как всю основную работу проделывает PHP-сценарий.
update.php. Убедитесь, что текстовый редактор не добавил свое собственное расширение файла, и, если это произошло, удалите его - оно лишнее.<?
// update.php
// Flash MX Studio - Steve Webster
// Data file name
$datafile = "message.txt";
// Create data string for message
$data = "message=" . urlencode($HTTP_POST_VARS['message']);
// Add photofile variable to data string
$data . = "photofile=" .x urlencode($HTTP_POST_VARS ['photofile']);
// Open data file in write mode
$file = @fopen($datafile, 'w');
// If file not opened...
if (!$file) {
// Report error and exit
print "result-Fail";
exit;
}
// Write data string to file and close
fwrite($file, $data);
fclose ($file);
// Report success to Flash
print "result=Okay";
?>
Этот сценарий перезаписывает текущее содержимое файла данных со значениями переменных, переданных из фильма Flash. Если сценарий не смог открыть файл данных в режиме правки, в фильм Flash возвращается сообщение об ошибке, и работа сценария прекращается. В противном случае, данные, как и планировалось, перезаписываются.
Помните, что если вы попытаетесь загрузить фильм при отсутствии присвоенных переменным значений в текстовом файле, возникнет ошибка из-за неправильной установки.
Если вы столкнулись с проблемами записи данных в файл, вам может понадобиться установить права доступа на этот файл, чтобы разрешить сценарию PHP открывать его в режиме записи. Для этого используется команда CHMOD, встроенная в большинство FTP-клиентов. Вы можете найти хорошее руководство по этой теме на сайте www.phpforflash.com.
В этом разделе мы рассмотрим основы языка PHP. Не волнуйтесь, если одна мысль об этом вызывает испуг - PHP на самом деле во многом похож на ActionScript, поэтому изучение его основ не трудно. Этот параграф не является законченным руководством по PHP, так как места здесь хватило только лишь на изучение некоторых его частей. В конце этой лекции вы уже сможете создавать ваши собственные несложные сценарии, однако если вы хотите серьезно заняться изучением PHP, вам понадобится книга, посвященная этой тематике. Так получилось, что я написал такую книгу для Friends of ED, поэтому вам будет легко ее найти! Книга называется Foundation PHP for Flash, и в ней дается полное руководство по использованию преимуществ PHP совместно с Flash для создания динамического содержимого в ваших фильмах.
Итак, довольно лирики, приступим к делу.
Файлы PHP, по существу, являются просто файлами ASCII (или обычным текстом), как документы HTML, поэтому вам понадобится текстовый редактор. Многие люди предпочитают вводить PHP-код в окнах текстовых редакторов Блокнот или BBEdit, но я предпочитаю редактор EditPlus. Это коммерческий редактор, который включает в себя выделение синтаксиса для многих языков серверной части, включая PHP.
Давайте рассмотрим простой сценарий PHP. Введите следующий текст в пустой документ, сохраните файл с именем hello_world.php и отгрузите его на веб-сервер.
<? print "Hello World!"; ?>
Чтобы проверить его в действии, нужно открыть веб-браузер и вызвать адрес файла, который будет выглядеть примерно так.
http://www.somewhere.com/path/to/hello_world.php
В окне браузера появится следующее.

Разберем структуру этого простого сценария.
print просто выводит аргумент в браузере, в данном случае - строку Hello World!Результаты всех выражений вывода PHP передаются в браузер постоянно, поэтому несколько команд вывода в данном случае выведут результаты своей работы на одной странице.
<?
for ($count = 0; $count < 10; $count++) {
print "Hello, world!<br>";
}
?>
Это простой цикл PHP for, который очень похож на свой аналог в ActionScript и работает точно так же. Действие этого кода сводится к печати строки Hello, world! десять раз с тегом <br> между строками. Здесь мы используем тег <br> вместо символа новой строки, так как браузер интерпретирует выходные данные как HTML, поэтому нужно форматировать их с использованием тегов HTML.
PHP использует переменные почти так же, как Flash, и в этой части PHP является довольно свободным языком. Это означает, что любая переменная может содержать любой тип данных, а также то, что тип данных может временно конвертироваться в процессе работы в зависимости от контекста, в котором он используется. Однако, в отличие от ActionScript, в PHP имя переменной отделяется с помощью символа доллара $. В последнем примере мы установили переменную $count на значение 0 и затем выполнили цикл, увеличивая ее с каждым разом на единицу. Как видите, на данном этапе структура языка сильно похожа на ActionScript.
Существует ряд областей, в которых PHP и ActionScript отличаются друг от друга, и одной из них является способ конкатенации (слияния) строк. Когда нужно объединить две строки в ActionScript, используемтся оператор +. Однако в PHP оператор + предназначен только для математических операций, и вместо него используется "." (точка).
$myVar = "Hello,"."world";
Изучив основные моменты, посмотрим, как можно использовать этот язык.
Хотите вы того или нет, но настало время сделать что-нибудь, используя знания, полученные в этой лекции. В этом параграфе мы создадим полнофункциональное приложения Flash, которое станет полезным дополнением практически к любому веб-сайту.
Мы создадим систему обратной связи Flash, которая будет брать информацию из формы Flash и передавать ее по соответствующему адресу электронной почты. Мы также добавим некоторые дополнения в это приложение, поэтому это не будет просто "голая" программа для отправки электронных писем, более того, мы уделим некоторое время планированию создания нашего приложения. Перед тем, как приступить к работе, посмотрим, что должно получиться в итоге (см. рис. вверху следующей страницы).
Это приложение мы будем создавать в несколько этапов. Сначала создадим компонент кнопки для пользовательского интерфейса в нашей форме. После этого рассмотрим ActionScript, который необходим для выполнения самой программы, а уже потом перейдем к изучению сценария PHP, необходимого для реализации самой сути программы.

Перед тем, как приступить к работе, нужно непосредственно спланировать наше приложение: выяснить, чего мы хотим добиться от приложения и как при помощи имеющихся у нас средств это реализовать. Проектирование является одним из самых важных (если не самым важным) этапов создания приложения. Основное правило разработки гласит:
Если ваша программа не работает на бумаге, то она вообще не будет работать.
Это возвращает нас к традиционным представлениям о разработке программного обеспечения, но это неоспоримая правда для случая с Flash-приложениями для интернета. Если вы не знаете, куда нужно идти (т.е. не проектируете ваше приложение), как же вы доберетесь туда, куда вам нужно?
Довольно теоретического материала, приступим к разработке. Главной целью нашего приложения является выбор данных из фильма Flash (т.е. данных, вводимых пользователем) и отправка их по указанному адресу электронной почты. Вот возможности, которые должны быть в нашем приложении. Приложение должно:
Идем дальше!
Перед тем как приступить к созданию фильма Flash, нужно создать компонент кнопки, который мы сможем использовать для построения части пользовательского интерфейса. Компоненты были рассмотрены в лекции этой книги, так что у вас не должно возникнуть больших проблем при выполнении следующих шагов. Не забывайте, что вы можете в любой момент свериться с исходными файлами для этой лекции, если вы запутались на каком-либо этапе.
На данный момент я просто скажу вам, что мы не собираемся особо "наворачивать" этот компонент, и что здесь мы не будем добавлять его на панель Component в среде разработки Flash MX.
Наш компонент использует новую возможность Flash MX для реализации "кнопочных" действий, и в этом непосредственную роль играют метки кадров _up, _over и _down. Также возможно добавление кадра _hit для определения области щелчка для кнопки, однако здесь эта возможность не используется.
Когда фильму присвоен управляющий элемент onPress или onRelease, он действует, как кнопка и будет автоматически отображен в соответствующем кадре временной шкалы, изображенной на рисунке выше. Это немного сократит количество необходимого кода, поэтому я решил использовать здесь эту возможность, хотя выключенное состояние придется создавать вручную, так как оно не является одним из состояний стандартной кнопки.
Caption с именем инстанса caption_txt. Не беспокойтесь о цвете текста (мы решим этот вопрос в коде ActionScript через некоторое время), однако установите текстовое поле так, чтобы оно было точно отцентрировано и перекрывало всю ширину кнопки.FSimpleButton. Введите следующий код в кадр 1 слоя Definitions.#initclip 1
// Constructor
FSimpleButton = function(){
// Initialise component
this.init();
};
// Inherit from MovieClip object
FSimpleButton.prototype = new MovieClip();
// Register component class
Object.registerClass("FSimpleButton", FSimpleButton);
Весь этот код почти в точности повторяет реализацию компонента Tool Tip в лекции 4. Не будем больше на этом останавливаться. Если вам что-то непонятно, обратитесь к лекции 4.

init, который будет вызываться при создании нового инстанса нашего компонента и подготавливать его к использованию.// Initialise component
FSimpleButton.prototype.init = function(){
// Set caption text and color
this.caption_txt.text = this.captionText;
this.caption_txt.textColor = this.captionColor;
// Setup cursor and disable tabbing
this.useHandCursor = this.showHand;
this.tabEnabled = false;
// Set event handlers
this.onRollOut = this.myRollOut;
this.onRollOver = this.myRollOver;
this.onPress = this.myPress;
this.onRelease = this.myRelease;
this.onDragOut = this.myDragOut;
this.onDragOver = this.myDragOver;
this.onReleaseOutside = this.myReleaseOutside;
};
Здесь мы устанавливаем текст и цвет текста для текстового поля caption_txt. Использованные для этого переменные находятся среди параметров, установленных в предыдущем шаге.
Далее, мы устанавливаем указатель мыши согласно showHand и после этого прерываем прием кнопкой входного фокуса с использованием ключа TAB. Так было сделано потому, что раздражающий желтый прямоугольник фокуса портит внешний вид приложения, но это не обязательно.
Наконец, мы устанавливаем управляющие элементы событий мыши для нашего компонента, и, так как осуществляется наследование из объекта , нужно предусмотреть немало деталей. Мы, на самом деле, не будем здесь обрабатывать все события, но я включил их на тот случай, если вы захотите реализовать нечто отличное с применением вашего компонента кнопки.
onRollOut и onRollOver, и мы будем использовать их для установки переменной состояния в родительской временной шкале.FSimpleButton.prototype.myRollOut = function() {
this._parent [this.statusVar] = _global.oldStatusText;
};
FSimpleButton.prototype.myRollOver = function() {
_global.oldStatusText = this._parent[this.statusVar];
this._parent[this.statusVar] = this.statusText;
};
Переменная состояния указывается в виде еще одного параметра компонента, как и непосредственный текст состояния. Мы используем глобальную переменную oldStatusText для хранения и получения предыдущего текста состояния. Причина этому станет ясна, когда мы перейдем к работе над фильмом Flash.
onPress и onRelease. Из кода ниже можно заметить, что последний элемент на самом деле здесь не используется. Это один из тех управляющих элементов "на всякий случай", о которых я говорил ранее. Он может быть полезным при желании расширить функциональные возможности компонента.FSimpleButton.prototype.myPress = function() {
};
FSimpleButton.prototype.myRelease = function() {
// Execute callback
this._parent[this.clickHandler](this);
};
Управляющий элемент onRelease, вероятно, наиболее важный элемент управления во всем компоненте. Это элемент управления, вызывающий функцию, указанную в clickHandler.
Здесь мы передаем ссылку на текущий объект функции обратной связи. Это полезно в том случае, если у вас есть одна функция обратной связи для нескольких кнопок, и необходимо определять, какой кнопкой была инициализирована обратная связь. Мы не будем использовать это непосредственно в нашем приложении, но, тем не менее, иметь такую возможность достаточно полезно.
onDragOut.FSimpleButton.prototype.myDragOut = function() {
this.gotoAndStop("_up");
};
Я использовал его для устранения одного небольшого препятствия при реализации работы кнопок во Flash. В наиболее распространенных операционных системах, когда вы удерживаете кнопку мыши в момент нахождения указателя над кнопкой, и затем перетаскиваете указатель за пределы кнопки и отпускаете ее, это действие не воспринимается как нажатие кнопки. Однако во Flash кнопка останется в "нажатом" состоянии _down. Чтобы обойти эту особенность, я реализовал возврат кнопки в кадр _up при перетаскивании мыши за пределы области кнопки. Вам решать, применят этот способ здесь или нет, однако я бы на вашем месте не отказывался от этого дополнения.
FSimpleButton.prototype.myDragOver = function() {
};
FSimpleButton.prototype.myReleaseOutside = function() {
};
_disabled.FSimpleButton.prototype.disable = function() {
this.caption_txt.textColor = this.captionDisabledColor;
this.gotoAndStop("disabled");
this.enabled = false;
};
Из этого кода видно, что здесь мы всего лишь меняем цвет текста метки на текст, указанный в captionDisabledColor, переходя к кадру выключения и выключая компонент. При выключенном компоненте события не будут обрабатываться, и компонент будет оставаться в указанном кадре.
FSimpleButton.prototype.enable = function() {
this.enabled = true;
this.gotoAndStop("_up");
this.caption_txt.textColor = this.captionColor;
};
Метод enable просто обращает изменения, сделанные в методе disable, включая кнопку, перемещая ее обратно в кадр _up и заново устанавливая цвет текста метки.
isEnabled, который позволит определять состояние кнопки. Эту возможность мы не будем использовать в приложении, однако она может пригодиться при создании другой программы.// Public: isEnabled
FSimpleButton.prototype.isEnabled = function() {
return this.enabled;
};
#endinitclip
stop();
Мы закончили определение компонента, и он готов к использованию. Переименуйте компонент в библиотеке, если вы еще этого не сделали. Назовите его FSimpleButton и установите его связи следующим образом.

Разобравшись с дизайном кнопки, которая теперь готова к использованию, можно приступить к построению фильма Flash для нашего приложения. Начнем с графической оболочки и затем перейдем к рассмотрению ActionScript.
Используйте слой Background для создания любых графических объектов, нужных в приложении. Можете, например, поэкспериментировать с несколькими значениями цвета, упомянутыми ранее в этом параграфе.
Эти текстовые поля имеют имена инстансов name_txt, email_txt, subject_txt и message_txt, работающих поочередно сверху вниз. Я также добавил дополнительное текстовое поле внизу рабочего места для отображения текста состояния. Я присвоил ему имя инстанса status_txt и связал его с переменной statusText, так как она больше всего подходит для установки содержимого текстового поля вне компонента кнопки.

В следующем шаге мы создадим функции resetForm и submitForm. Этим мы закончим создание части фильма, не требующей применения кода. Сверьте ваше рабочее место с рисунком вверху следующей страницы, чтобы убедиться в правильности ваших действий.
Результат вашей работы может отличаться от этой иллюстрации, так как я добавил текущий просмотр в компонент кнопки, о котором вам не говорил. Он обновляет заголовок, меняя его на тот, который указан в livePreview.fla на компакт-диске.

Разобравшись с графическими элементами нашего приложения, мы переключаем наше внимание на код ActionScript в слое Actions. Здесь как раз будет выполняться вся основная работа, начиная от отправки введенных пользователем данных сценарию PHP, и заканчивая созданием и отображением окна сообщения, показанного на первой иллюстрации приложения.
loadVars. Оно позволит очищать все переменные объекта, чтобы форма могла подтверждаться более, чем один раз, без возможности "сохранения" какой-либо информации с момента предыдущего подтверждения.loadVars.prototype.clear = function() {
for (element in this) {
if (typeof(this[element]) != "function") {
delete this[element];
}
}
};
Мне было нелегко поверить, что это не стандартный метод объекта loadVars, но, по всей видимости, Macromedia решили, что нам ничто похожее не понадобится. Тем не менее, они оставили нам возможность самостоятельно расширять функциональность.
Как вы можете видеть, мы используем цикл for:in для прохождения через каждый элемент объекта loadVars и удаляем все, что не является функцией. Необходимо проверять, что удаляемый нами объект не является функцией, так как управляющий элемент onLoad и метод clear будут включены в обрабатываемые элементы.
status_text.// Set status text
setStatus = function(statusText) {
_root.status_txt.text = statusText;
};
// Fetch status text
getStatus = function() {
return __root.status__txt.text;
};
Для обозначения присутствия в текстовом поле фокуса ввода мы используем некоторые управляющие элементы событий нового объекта TextField, изменяющие цвет фона текстового поля при размещении в нем и удалении фокуса ввода. Это также позволяет устанавливать текст состояния.
onSetFocus и onKillFocus для каждого текстового поля, однако сейчас мы просто создадим сами функции.// Focus handler for form fields
setFocusHandler = function () {
// Set status text
setStatus(this.statusText);
// Highlight field
this.backgroundColor = 0xCACED5;
};
setFocusHandler будет вызываться каждый раз при получении текстовым полем фокуса ввода. Она устанавливает текст состояния на параметр statusText (с которым мы разберемся позднее) текстового поля, вызвавшего управляющий элемент события, и изменяет цвет фона текстового поля на более темный.// Kill Focus handler for form fields
killFocusHandler = function() {
// Clear status
setStatus("");
// Lose field highlight
this.backgroundColor = 0xDEE0E4;
};
killFocusHandler вызывается каждый раз при потере полем фокуса ввода. Эта функция очищает текст состояния и устанавливает цвет фона обратно на исходный.
Теперь рассмотрим проблему, возникающую при необдуманном нажатии пользователями различных кнопок. Например, не следует нажимать кнопку Reset, если форма уже является пустой, также следует предотвратить нажатие клавиши Submit до тех пор, пока пользователем не будут заполнены все поля формы. Вместо создания функций кнопки, которые будут проверять, что необходимые условия выполнены, перед продолжением работы, мы реализуем активацию/деактивацию кнопок в зависимости от состояния формы. Для этого применим еще один управляющий элемент события TextField: onChanged.
onChanged для каждого текстового поля несколько позже, а здесь просто определим саму функцию.// Changed handler for form fields
changedHandler = function() {
var submitCheck = true;
var resetCheck = false;
for (var count = 0; count < textFields.length; count++) {
if (_root [textFields[count]].length == 0) {
submitCheck = false;
} else {
resetCheck = true;
}
}
if (submitCheck) {
submitBtn.enable();
} else {
submitBtn.disable();
}
if (resetCheck) {
resetBtn.enable();
} else {
resetBtn.disable();
}
};
Этот код требует некоторого доверия с вашей стороны, так как он ссылается на массив textFields, который еще не создан. На данный момент достаточно сказать, что он содержит имена инстансов каждого из текстовых полей ввода данных. Вышеуказанный код обрабатывает циклом каждое из текстовых полей и проверяет, был ли введен какой-либо текст. Если обнаруживается пустое текстовое поле, кнопка Submit выключается, а если встречается непустое текстовое поле, активируется кнопка Reset.
Обратите внимание, что здесь используется параметр length самого объекта TextField для определения того, были ли введены какие-либо данные. Согласно Macromedia, здесь получается тот же результат, что и при использовании TextField.text.length, однако наш вариант на самом деле работает немного быстрее. Он также требует меньше нажатий клавиш, поэтому здесь все только в выигрыше!
// Function to disable form fields and buttons
disableForm = function() {
// Disable all form fields
for(var count = 0; count < textFields.length; count++) {
_root [textFields[count]].selectable = false;
_root [textFields[count]].border = false;
}
// Disable submit and reset buttons
submitBtn.disable();
resetBtn.disable();
};
Установив параметр selectable для каждого текстового поля на значение false, мы предотвращаем размещение в них фокуса ввода. Мы также удаляем границу текстового поля, которая является визуальным обозначением активности поля, а также делаем недоступными кнопки.
resetForm и submitForm, упомянутые ранее.// Function to reset form to initial state
resetForm = function() {
// Clear status text
setStatus("");
_global.oldStatusText = "";
// Clear and enable textfields
for(var count = 0; count < textFields.length; count++) {
_root[textFields[count]].selectable = true;
_root[textFields[count]].border = true;
_root[textFields[count]].text = "";
}
// Disable buttons
resetBtn.disable();
submitBtn.disable();
};
Эта функция очищает текст состояния и затем осуществляет очистку и активацию всех текстовых полей. Так как все текстовые поля пусты, обе кнопки должны быть недоступны. К сожалению, событие onChanged текстового поля происходит только тогда, когда пользователь изменяет значение, следовательно, нам необходимо настроить состояния кнопки вручную.
submitForm.// Function to submit form data to the server
submitForm = function() {
// Disable form fields buttons
disableForm();
// Clear dataHandler data...
dataHandler.clear();
// Load data into dataHandler...
for (var count = 0; count < textFields.length; count++) {
dataHandler[textFields[count]] = __root[textFields[count]].text;
}
// Send data to PHP script and set status text
dataHandler.sendAndLoad("simplemailer.php", dataHandler, "POST") ;
setStatus("Contacting server...please wait!");
};
Здесь мы сначала делаем форму недоступной с помощью функции, созданной ранее, далее удаляем все данные из объекта dataHandler (являющийся инстансом loadVars, который мы создадим позже) с использованием нового метода clear, рассмотренного в самом начале этой лекции. После этого нужно переместить все данные из различных текстовых полей в объект dataHandler перед использованием метода sendAndLoad для задействования нашего PHP-сценария и отправкой данных с помощью метода POST. Наконец, устанавливаем текст состояния для информирования пользователя о происходящем.
Осталась последняя функция. Перед тем, как вы начнете прыгать до потолка от радости, хочу сообщить вам, что эта функция несколько больше, чем рассмотренные до сих пор. Тем не менее, в ней нет ничего того, что не было рассмотрено в книге до данного момента, поэтому все будет в порядке! Назначением функции является информирование пользователя об успешном или неуспешном завершении процедуры sendAndLoad. Эта функциональность реализуется при помощи средств рисования API, возможности динамического создания фильмов и текстовых полей, а также компонента кнопки.
// Popup message box function
messageBox = function(message) {
var maxWidth = 200;
var msgBox_mc = _root.createEmptyMovieClip("msgBox_mc", 0);
Обратите внимание, что мы добавили параметр message для функции, который будет текстом, отображаемым в окне сообщения. Также определили другую переменную maxWidth, которая используется для определения ширины окна сообщения (высота определяется количеством текста) и которая может быть изменена по вашему желанию.
msgBox_mc.createTextField("body_txt", 1, 5, 5, maxWidth - 10, 10);
msgBox_mc.body_txt.multiline = true;
msgBox_mc.body_txt.autoSize = true;
msgBox_mc.body_txt.wordWrap = true;
msgBox_mc.body_txt.selectable = false;
msgBox_mc.body_txt.textColor = 0x676767;
msgBox_mc.body_txt.text = message;
Мы присвоили новому текстовому полю 5-пиксельную границу от края нашего фильма и установили начальную высоту на значение 10. Затем мы настроили текстовое поле таким образом, что оно расширяться вертикально в зависимости от количества находящегося в нем текста.
var format = new TextFormat(); format.align = "left"; format.font = "_sans"; format.size = 10; msgBox_mc.body_txt.setTextFormat(format); var currentHeight = msgBox_mc.body_txt.textHeight + 10;
После этого можно определить высоту текстового поля с помощью параметра textHeight. Он будет также определить место размещения кнопки и место рисования границы окна сообщения с учетом 5-пиксельной линии по краям фильма.
var closeBtn = msgBox_mc.attachMovie("FSimpleButton", "closeBtn", 0);
closeBtn._x = (maxWidth - closeBtn._width) / 2;
closeBtn._y = currentHeight;
closeBtn.captionText = "Close";
closeBtn.showHand = false;
closeBtn.captionColor = 0x676769;
closeBtn.init();
closeBtn.onRelease = function() {
resetForm();
this._parent.removeMovieClip();
};
Кнопка отцентрирована горизонтально и настроена на очистку фильма окна сообщения после отпускания кнопки.
currentHeight для определения полной высоты фильма.currentHeight += closeBtn._height + 5;
msgBox_mc._x = (Stage.width - maxWidth) / 2;
msgBox_mc._y = (Stage.height - currentHeight) / 2;
msgBox_mc.moveTo(0, currentHeight);
msgBox_mc.lineStyle(1, 0xF5F6F8, 100);
msgBox_mc.beginFill(0xEBECF0, 75);
msgBox_mc.lineTo(0, 0);
msgBox_mc.lineTo(maxWidth, 0);
msgBox_mc.lineStyle(1, 0xC2C2C4, 100);
msgBox_mc.lineTo(maxWidth, currentHeight);
msgBox_mc.lineTo(0, currentHeight);
msgBox_mc.endFill();
};
С помощью рисования API рисуем рельефную границу вокруг фильма и закрашиваем ее светло-зеленым цветом с интенсивностью 75%. Создание функции messageBox завершено.
dataHandler и установить его управляющий элемент события onLoad на вызов функции messageBox, которую мы только что создали с использованием разных сообщений, в зависимости от успешного или неуспешного завершения процедуры.// Create data handler and set onLoad event handler
dataHandler = new LoadVars();
dataHandler.onLoad = function(success) {
if (success) {
messageBox("Your data has been mailed by the server. Thank
Кyou for your feedback, and someone will be in touch with
Кyou shortly regarding your query");
} else {
messageBox ("You data was not able to be sent due to a
Кproblem on the server. Please try again later!");
}
}
textFields и связанные с ним строки состояния и инициализировать текстовые поля.// Array of textfield names and status strings
textFields = new Array("name_txt", "email_txt",
"subject_txt", "message_txt");
statusStrings = new Array("Enter your name here",
"You should enter your email
Кaddress here", "This is the subject of your email",
"Enter Кthe main body of your message here");
// For each textfield
for (count = 0; count < textFields.length; count++) {
// Set properties
textField_txt = this [textFields[count]];
textField_txt.border = true;
textField_txt.borderColor = 0xB1B1B1;
textField_txt.background = true;
textField_txt.backgroundColor = 0xDEE0E4;
textField_txt.onSetFocus = setFocusHandler;
textField_txt.onKillFocus = killFocusHandler;
textField_txt.onChanged = changedHandler;
textField_txt.statusText = statusStrings[count];
}
Весь этот код говорит сам за себя. Мы уже создали текстовые поля и управляющие элементы событий, поэтому наши старания здесь сводятся к установке параметров и управляющих элементов событий для каждого текстового поля. Единственная строка, заслуживающая здесь особого внимания, это последняя строка, в которой мы сохраняем текст состояния для данного текстового поля в качестве параметра самого текстового поля. Мы уже использовали этот параметр в функции setFocusHandler для установки текста состояния.
changedHandler.// Set initial button states and halt movie changedHandler(); stop ();
Вот и все. Мы рассмотрели весь код ActionScript, необходимый для создания и выполнения нашего приложения. Запустив его, вы увидите результат ваших стараний во всей красе. Подтверждение формы на данном этапе генерирует сообщение об ошибке, так как сценарий PHP еще не существует. Также обратите внимание на то, что при тестировании приложения внутри среды разработки Flash окно сообщения не будет появляться в центре фильма. Это по той причине, что в среде разработки объект Stage представляет собой все окно тестирования, и поэтому код позиционирования в функции messageBox игнорируется. Если вы протестируете приложение в браузере, все будет работать, как положено!
Выходим на финишную прямую и начинаем разбирать сценарий PHP, реализующий наибольшую часть функциональности нашего приложения. Рассмотрим его шаг за шагом. Здесь все уже должно быть знакомо из описания PHP, приведенного ранее в этой лекции. Если вы почувствуете себя неуверенно на любом из этапов, просто пролистайте книгу назад и обратитесь к этому параграфу. PHP-сценарий для этого приложения будет не очень большим, так как значительная часть работы выполняется в фильме Flash. Нужно создать тело сообщения из списка переменных, передаваемых сценарию PHP, и затем отправить сообщение электронной почты с использованием функции mail.
simplemailer.php. Сначала нужно ввести начальный PHP-тег. Здесь мы также укажем адрес электронной почты получателя.<?php // simplemailer.php // Flash MX Studio - Steve Webster // Set recipient for email $recipient = "you@yourisp.com";
В этом фрагменте кода можно увидеть несколько комментариев. Как и в случае с ActionScript, всегда лучше сопровождать код исчерпывающими комментариями; неизвестно, когда вам придется снова разбираться в этом коде.
Необходимо обработать небольшую особенность объекта loadVars. При использовании методов send и sendAndLoad управляющий элемент события onLoad и новый метод clear будут передаваться вместе с любыми другими данными в объект. Так как одной из целей создания этого приложения было обеспечение его максимальной гибкости в отношении числа поддерживаемых переменных, используем цикл для добавления каждой переменной, передаваемой из фильма Flash в тело сообщения электронной почты.
// Remove methods from data... unset($HTTP_POST_VARS["onLoad"]); unset($HTTP_POST_VARS["clear"]);
Это реализуется с помощью функции unset для удаления соответствующих элементов массива . Этот массив содержит все переменные, которые были переданы PHP-сценарию с помощью метода POST.
// Setup body text $body = "The following information was submitted...\n\n";
Мы устанавливаем ее, указав начальный текст, который будет отображаться вверху сообщения электронной почты.
HTTP_POST_VARS , прибавляя их по мере продвижения к нашей переменной $body.// Add each key/value pair to the body text
foreach($HTTP_POST_VARS as $key => $value) {
$key = substr($key, 0, -4);
$body .= "$key: $value\n";
}
Из кода видно, что мы использовали цикл foreach. Он аналогичен циклу for:in в ActionScript, который использовался в новом методе clear объекта loadVars. В примере выше, каждая итерация цикла считывает ключ (имя переменной) и значение следующего элемента массива, выбираемое и сохраняемое в переменных $key и $value, соответственно.
После этого мы используем функцию substr для отбрасывания расширения _txt, которое имеют в данный момент имена всех наших переменных. Это, на самом деле, необязательный шаг, однако указание расширения в электронной почте довольно бессмысленно, поэтому мы избавляемся от него. В PHP функция substr работает несколько иным образом, нежели ее аналог в ActionScript, так как здесь мы можем указывать отрицательное значение конечной точки подстроки. В данном случае, подстрока начинается из начального индекса и продолжается на протяжении n символов с конца исходной строки. В переводе на русский язык, эта строка кода будет звучать следующим образом.
Берем все символы в $key с позиции от 0 до 4 с конца строки и записываем результат в переменную $key.
После этого добавляем текущий ключ и значение в переменную $body и переходим к следующему элементу массива.
Далее нужно создать адресную строку From: для сообщения электронной почты. Мы реализуем указание имени отправителя в сообщении, получаемом адресатом. Это будет сделано не с помощью PHP, а с использованием прилагаемых деталей имени и адреса электронной почты. Правильный формат поля From: сообщения электронной почты таков.
"Name" <email@whatever.com>
// Set from address $from = $HTTP_POST_VARS["name_txt"] . " <" . $HTTP_POST_VARS["email_txt"] . ">" ;
// Set subject for email $subject = $HTTP_POST_VARS["subject_txt"]; // Send email mail($recipient, $subject, $body, "From: $from"); ?>
Если у вас возникли проблемы и сценарий PHP работает неправильно, следует проверить следующее.
http://.../simplemailer.php?name_txt=Bobemail_txt=...
error_reporting (E_ALL ^ E_NOTICE);
Если вы обнаружите какие-либо ошибки, проверьте ваш сценарий и исправьте их. Если вы все еще не уверены в себе, просто скопируйте сценарий, находящийся на компакт-диске этой книги.
Теперь, когда приложение уже создано, я хочу упомянуть некоторые дополнительные возможности, которые могут быть очень полезны в этом приложении.
Первым прекрасным дополнением, которое пришло мне в голову, является расширение сценария PHP для реализации отправки электронного сообщения пользователю, заполнившему форму, с выражением благодарности за потраченное время или каким-либо другим содержимым. Вам решать, добавлять эту функциональность или нет, но хочу развеять ваши опасения - реализовать ее совсем просто.
Также полезно обеспечить пользователя возможностью выбора получателя определенного сообщения электронной почты. Например, вы можете использовать компонент поля со списком для перечисления различных отделов вашей организации в качестве получателей. С каждым выбранным элементом будет ассоциироваться свой адрес электронной почты, который будет передаваться в сценарий PHP.
Существуют и другие возможности, которые вы могли бы реализовать в этом приложении, однако это я уже оставляю на ваше усмотрение.
Сегодняшний мир переполнен сокращениями. Вспомните такие аббревиатуры, как HTML, XML, HTTP, не забудьте и про Flash MX. Я хочу представить вам еще одно сокращение, о котором пойдет речь в данной лекции. PHP означает Hypertext Pre-Processor, это один из наиболее мощных языков сценариев серверной части. Примите это к сведению как веб-разработчик.
В этой лекции мы начнем с того, что представляет собой PHP, и немного поговорим о его истории.
Язык PHP был создан в конце 1994 года, когда Rasmus Lerdorf объединил набор сценариев Perl для сохранения записи посетителей его сетевого резюме. Эти сценарии заинтересовали посетителей его сайта, и в 1995 году они были опубликованы под названием "Personal Home Page Tools".
Использование PHP быстро распространялось, так же как и количество разработчиков, занимающихся проектами PHP. На момент написания этой книги последней версией PHP является PHP 4, которая имеет доступ к большому числу дополнительных средств, некоторые из которых даже реализуют динамическое создание SWF-файлов, что называется, "с нуля".
Есть несколько моментов, которые необходимо иметь в виду при рассмотрении "движка" PHP (программа, непосредственно выполняющая сценарии PHP по команде веб-сервера).
Свежую информацию о PHP можно найти на сайтах www.php.net и www.zend.com.
Прежде чем приступать к работе с PHP, нужно познакомится с тем, что такое сценарий на стороне сервера и когда он должен использоваться. В этом параграфе я отвечу на поставленные вопросы и расскажу о том, как все "навороченные" сайты находят путь на ваш веб-браузер.
Ниже приведено определение сценария на стороне сервера.
Сценарий на стороне сервера - это программа, выполняющаяся на сервере. Она может обрабатывать запросы на информацию и отвечать посредством возврата соответствующего документа по определенному критерию.
Сценарий на стороне сервера позволяет выполнять некоторые процедуры на сервере перед возвратом веб-документа в браузер. Это может быть все, что угодно, начиная с управления файлами данных и заканчивая доступом к базе данных и динамической генерацией содержимого.
В стандартной настройке клиент-сервер клиентская программа (обычно это веб-браузер) открывает соединение с сервером и запрашивает файл. Сервер после этого возвращает файл клиентской части и соединение закрывается. Этот тип соединения используется при запросе, к примеру, HTML-файлов.

С помощью сценария на стороне сервера клиент может запросить файл сценария на сервере, и ответом сервера будет выполнение этого сценария и возврат результатов согласно инструкциям сценария. С помощью этого принципа можно осуществлять получение данных из внешних источников, таких как текстовые файлы или базы данных.

Чтобы вам было понятнее, рассмотрим простой пример. Я уверен, что вы уже более чем знакомы с различными поисковыми системами интернета. Я предпочитаю систему www.google.com, и если вы перейдете на этот сайт и выполните поиск по строке "Macromedia Flash", вы будете перенаправлены на список соответствующих сайтов. В данный момент результаты поиска нам не интересны. Вместо этого следует обратить внимание на адрес URL в адресной строке вашего браузера. Он будет выглядеть примерно так.
http://www.google/search?hl=enq=Macromedia+Flash
Этот адрес можно разбить на две части. Первая из них означает страницу, которая нам нужна, в данном случае, это поисковая страница Google.http://www.google.com/search
Эта страница и есть сценарий на стороне сервера, созданный для поиска в бесчисленном множестве веб-сайтов любого текста, удовлетворяющего отдельным словам, которые мы только что указали. Слова и выбранный язык прилагаются к URL в виде строки запроса следующим образом.
hl=enq=Macromedia+Flash
Здесь мы имеем дело с двумя переменными hl и q, устанавливаемыми на значения en и Macromedia+Flash, соответственно. Первая из них указывает язык поиска, вторая является критерием поиска или запросом и передается сценарию на стороне сервера или программе, используемой Google для поиска в базах данных. В данном случае это не сценарий PHP, однако важно понимать, что это мог быть именно PHP. Итак, поисковая система Google просто сопоставляет два источника информации - введенные пользователем данные и базу данных Google - после чего результаты передаются клиенту в виде HTML-страницы.
Самым замечательным является то, что сценарии на стороне сервера позволяют динамически создавать веб-содержимое. Можно изменять и адаптировать содержимое для определенного времени дня, для учета пользовательских предпочтений, для автоматического отображения списка последних новостей, для обновления сайтов. Все это можно проделывать без редактирования вручную указанных объектов.
Более того, с помощью сценариев на стороне сервера можно работать не только со страницами HTML - можно также создавать сценарии, возвращающие данные клиентам Flash, что значительно расширяет наши возможности. Этому и посвящена данная лекция.
Для работы с этой лекцией вам понадобится доступ к PHP веб-серверу. Если у вас есть свой собственный сервер, то вам нужно загрузить соответствующие файлы установки с сайта www.php.net, где также можно найти подробное руководство по установке. Имейте в виду, что для загрузки доступно несколько различных пакетов PHP с различными уровнями функциональности, однако пусть это вас не смущает - наиболее сокращенная версия как раз подойдет для работы в этой лекции.
Если у вас нет своего собственного сервера или вы не знаете, как превратить в сервер ваш собственный компьютер, вам нужно будет узнать в службе технической поддержки или у владельца компьютера, поддерживает ли он PHP и, если это не так, попробуйте уговорить их установить для вас эту поддержку!
Если у вас нет сервера, вы можете загрузить сервер apache с сайта www.apache.org.
В предыдущей лекции вы изучали искусство загрузки данных в фильмы Flash из специально отформатированного текстового файла с использованием нового метода loadVars. Все это очень полезно и нужно, однако в определенный момент понадобится обновить данные в этом текстовом файле. Сейчас единственным способом сделать это является создание новой копии текстового файла. Несмотря на то, что в таком подходе нет ничего непоследовательного, он может стать несколько неудобным при обновлении больших объемов данных. Можно предположить, что должное форматирование данных может стать довольно сложным мероприятием, даже с использованием кодировщика, рассмотренного в лекции 15.
К счастью, из этого положения есть выход. Вместо обновления текстового файла вручную можно получить специальные программы на стороне сервера для автоматического выполнения этих действий с использованием информации, предоставляемой в виде Flash или стандартного HTML-представления. Примечательно то, что данные программы на стороне сервера могут выполнять все необходимое форматирование перед обновлением текстового файла. Программы на стороне сервера очень полезны!
В данном параграфе мы создадим отдельный фильм Flash, который можно будет использовать для обновления текстового файла для одного из приложений предыдущей лекции. Для этого понадобится сценарий PHP, но так как мы еще не изучали PHP, это может показаться аналогичным ремонту атомной электростанции с помощью отвертки и молотка. Могу вас успокоить: вы не нанесете большого вреда, экспериментируя с PHP, и двигаться мы будем последовательно, шаг за шагом.
Для забывчивых предлагаю краткий обзор того, как исходное приложение выполняет свою работу.
Для простоты мы используем одно из наиболее простых приложений из последней лекции - приложение "Message of the Day". Мы будем работать с наиболее полной версией этого приложения - с текстом HTML и фотографией.
Итак, если вы помните, код ActionScript для этого примера выглядел так.
messageURL = "message.txt";
myVars = new loadVars();
myVars.onLoad = function(success) {
if (success) {
loadMovie(this.photofile, "imgPlace1");
message = this.message;
} else {
message = "Error loading message";
}
};
myVars.load(messageURL);
Мы работаем с переменной message, содержащей текущее сообщение дня, а также с переменной photofile, указывающей изображение, которое должно загружаться в фильм.
Создадим отдельный фильм, предназначенный для обновления текстового файла. Очевидно, мы используем сценарий PHP для непосредственной записи новых данных в текстовый файл (так как Flash не может делать это самостоятельно), однако фильм Flash будет играть роль дружественного интерфейса для всего приложения.

message_txt, image_txt и status_txt в порядке сверху вниз.Я здесь просто использую обыкновенные текстовые кнопки. Я присвоил им имена инстансов load_btn и save_btn, и это позволит установить управляющие элементы событий из кадра в слое Actions.
Теперь перейдем к самой "изюминке" - к работе со слоем Actions. Мы будем последовательно изучать все выполняемые действия, чтобы вы поняли, для чего предназначен каждый фрагмент ActionScript.
Сначала нужно создать управляющие элементы событий onLoad, которые могут быть присвоены объекту loadVars. На самом деле мы собираемся создать два отдельных управляющих элемента, так как нам нужно выполнять различные действия в зависимости от того, загружаем ли мы или сохраняем текст.
displayMessage, которая будет использоваться при загрузке данных сообщения прямо из текстового файла.displayMessage = function (success) {
if (success) {
message_txt.text = this.message;
image_txt.text = this.photofile;
status_txt.text = "Data file loaded";
} else {
status_txt.text = "Could not load data file";
}
};
Здесь видно, что мы проверяем успешность выполнения операции. Если она была завершена успешно, переменные копируются из объекта loadVars в два текстовых поля, и затем текст состояния устанавливается соответствующим образом. Если возникла ошибка, пользователь информируется с помощью текста состояния.
checkSuccess = function (success) {
if (success this.result == "Okay") {
status_txt.text = "Data saved successfully";
} else {
status_txt.text = "An error has occurred";
}
};
Эта функция имеет почти такой же формат, как и предыдущая. Однако при детальном рассмотрении можно видеть, что здесь присутствует дополнительная проверка переменной в условной части выражения if. Это необходимо, так как стандартная переменная управляющего элемента дает лишь обозначение того, найден и загружен ли конечный файл. Это подходит для простых текстовых файлов, однако здесь нельзя определить, была ли процедура в сценарии на стороне сервера успешной.
Для проверки этого мы будем возвращать результирующую переменную из нашего сценария, с обозначением успешного или неудачного завершения операции. Если значением будет Okay, тогда операция выполнилась успешно, и текст состояния настраивается соответствующим образом. Если сценарий не был найден или загружен, или если процедура не удалась по какой-либо причине, пользователь информируется с помощью текста состояния.
onPress кнопок Load и Save. Первой будет кнопка load_btn, и здесь нужно установить соответствующий управляющий элемент события onLoad (displayMessage) и загрузить текстовый файл.load_btn.onRelease = function() {
dataLoader.onLoad = displayMessage;
dataLoader.load("message.txt");
};
Обратите внимание, что мы еще не создали объект dataLoader (это будет сделано в следующем шаге). Мы будем использовать объект loadVars для загрузки всех данных и вызова PHP-сценария.
save_btn немного сложнее, так как нам нужно копировать переменные из текстовых полей в объект dataLoader. Теперь можно установить управляющий элемент и вызвать сценарий PHP.save_btn.onRelease = function() {
dataLoader.message = _root.message_txt.text;
dataLoader.photofile = _root.image_txt.text;
dataLoader.onLoad = checkSuccess;
dataLoader.sendAndLoad("update.php", dataLoader, "POST");
};
Если вы раньше не встречали метод sendAndLoad: он позволяет передавать данные сценарию на стороне сервера и считывать возвращенную информацию.
dataLoader, который мы только что использовали.dataLoader = new loadVars();
На этом создание фильма Flash завершено. Фильм достаточно прост, но это несколько обманчивое впечатление, так как всю основную работу проделывает PHP-сценарий.
update.php. Убедитесь, что текстовый редактор не добавил свое собственное расширение файла, и, если это произошло, удалите его - оно лишнее.<?
// update.php
// Flash MX Studio - Steve Webster
// Data file name
$datafile = "message.txt";
// Create data string for message
$data = "message=" . urlencode($HTTP_POST_VARS['message']);
// Add photofile variable to data string
$data . = "photofile=" .x urlencode($HTTP_POST_VARS ['photofile']);
// Open data file in write mode
$file = @fopen($datafile, 'w');
// If file not opened...
if (!$file) {
// Report error and exit
print "result-Fail";
exit;
}
// Write data string to file and close
fwrite($file, $data);
fclose ($file);
// Report success to Flash
print "result=Okay";
?>
Этот сценарий перезаписывает текущее содержимое файла данных со значениями переменных, переданных из фильма Flash. Если сценарий не смог открыть файл данных в режиме правки, в фильм Flash возвращается сообщение об ошибке, и работа сценария прекращается. В противном случае, данные, как и планировалось, перезаписываются.
Помните, что если вы попытаетесь загрузить фильм при отсутствии присвоенных переменным значений в текстовом файле, возникнет ошибка из-за неправильной установки.
Если вы столкнулись с проблемами записи данных в файл, вам может понадобиться установить права доступа на этот файл, чтобы разрешить сценарию PHP открывать его в режиме записи. Для этого используется команда CHMOD, встроенная в большинство FTP-клиентов. Вы можете найти хорошее руководство по этой теме на сайте www.phpforflash.com.
В этом разделе мы рассмотрим основы языка PHP. Не волнуйтесь, если одна мысль об этом вызывает испуг - PHP на самом деле во многом похож на ActionScript, поэтому изучение его основ не трудно. Этот параграф не является законченным руководством по PHP, так как места здесь хватило только лишь на изучение некоторых его частей. В конце этой лекции вы уже сможете создавать ваши собственные несложные сценарии, однако если вы хотите серьезно заняться изучением PHP, вам понадобится книга, посвященная этой тематике. Так получилось, что я написал такую книгу для Friends of ED, поэтому вам будет легко ее найти! Книга называется Foundation PHP for Flash, и в ней дается полное руководство по использованию преимуществ PHP совместно с Flash для создания динамического содержимого в ваших фильмах.
Итак, довольно лирики, приступим к делу.
Файлы PHP, по существу, являются просто файлами ASCII (или обычным текстом), как документы HTML, поэтому вам понадобится текстовый редактор. Многие люди предпочитают вводить PHP-код в окнах текстовых редакторов Блокнот или BBEdit, но я предпочитаю редактор EditPlus. Это коммерческий редактор, который включает в себя выделение синтаксиса для многих языков серверной части, включая PHP.
Давайте рассмотрим простой сценарий PHP. Введите следующий текст в пустой документ, сохраните файл с именем hello_world.php и отгрузите его на веб-сервер.
<? print "Hello World!"; ?>
Чтобы проверить его в действии, нужно открыть веб-браузер и вызвать адрес файла, который будет выглядеть примерно так.
http://www.somewhere.com/path/to/hello_world.php
В окне браузера появится следующее.

Разберем структуру этого простого сценария.
print просто выводит аргумент в браузере, в данном случае - строку Hello World!Результаты всех выражений вывода PHP передаются в браузер постоянно, поэтому несколько команд вывода в данном случае выведут результаты своей работы на одной странице.
<?
for ($count = 0; $count < 10; $count++) {
print "Hello, world!<br>";
}
?>
Это простой цикл PHP for, который очень похож на свой аналог в ActionScript и работает точно так же. Действие этого кода сводится к печати строки Hello, world! десять раз с тегом <br> между строками. Здесь мы используем тег <br> вместо символа новой строки, так как браузер интерпретирует выходные данные как HTML, поэтому нужно форматировать их с использованием тегов HTML.
PHP использует переменные почти так же, как Flash, и в этой части PHP является довольно свободным языком. Это означает, что любая переменная может содержать любой тип данных, а также то, что тип данных может временно конвертироваться в процессе работы в зависимости от контекста, в котором он используется. Однако, в отличие от ActionScript, в PHP имя переменной отделяется с помощью символа доллара $. В последнем примере мы установили переменную $count на значение 0 и затем выполнили цикл, увеличивая ее с каждым разом на единицу. Как видите, на данном этапе структура языка сильно похожа на ActionScript.
Существует ряд областей, в которых PHP и ActionScript отличаются друг от друга, и одной из них является способ конкатенации (слияния) строк. Когда нужно объединить две строки в ActionScript, используемтся оператор +. Однако в PHP оператор + предназначен только для математических операций, и вместо него используется "." (точка).
$myVar = "Hello,"."world";
Изучив основные моменты, посмотрим, как можно использовать этот язык.
Хотите вы того или нет, но настало время сделать что-нибудь, используя знания, полученные в этой лекции. В этом параграфе мы создадим полнофункциональное приложения Flash, которое станет полезным дополнением практически к любому веб-сайту.
Мы создадим систему обратной связи Flash, которая будет брать информацию из формы Flash и передавать ее по соответствующему адресу электронной почты. Мы также добавим некоторые дополнения в это приложение, поэтому это не будет просто "голая" программа для отправки электронных писем, более того, мы уделим некоторое время планированию создания нашего приложения. Перед тем, как приступить к работе, посмотрим, что должно получиться в итоге (см. рис. вверху следующей страницы).
Это приложение мы будем создавать в несколько этапов. Сначала создадим компонент кнопки для пользовательского интерфейса в нашей форме. После этого рассмотрим ActionScript, который необходим для выполнения самой программы, а уже потом перейдем к изучению сценария PHP, необходимого для реализации самой сути программы.


Перед тем, как приступить к работе, нужно непосредственно спланировать наше приложение: выяснить, чего мы хотим добиться от приложения и как при помощи имеющихся у нас средств это реализовать. Проектирование является одним из самых важных (если не самым важным) этапов создания приложения. Основное правило разработки гласит:
Если ваша программа не работает на бумаге, то она вообще не будет работать.
Это возвращает нас к традиционным представлениям о разработке программного обеспечения, но это неоспоримая правда для случая с Flash-приложениями для интернета. Если вы не знаете, куда нужно идти (т.е. не проектируете ваше приложение), как же вы доберетесь туда, куда вам нужно?
Довольно теоретического материала, приступим к разработке. Главной целью нашего приложения является выбор данных из фильма Flash (т.е. данных, вводимых пользователем) и отправка их по указанному адресу электронной почты. Вот возможности, которые должны быть в нашем приложении. Приложение должно:
Идем дальше!
Перед тем как приступить к созданию фильма Flash, нужно создать компонент кнопки, который мы сможем использовать для построения части пользовательского интерфейса. Компоненты были рассмотрены в лекции этой книги, так что у вас не должно возникнуть больших проблем при выполнении следующих шагов. Не забывайте, что вы можете в любой момент свериться с исходными файлами для этой лекции, если вы запутались на каком-либо этапе.
На данный момент я просто скажу вам, что мы не собираемся особо "наворачивать" этот компонент, и что здесь мы не будем добавлять его на панель Component в среде разработки Flash MX.
Наш компонент использует новую возможность Flash MX для реализации "кнопочных" действий, и в этом непосредственную роль играют метки кадров _up, _over и _down. Также возможно добавление кадра _hit для определения области щелчка для кнопки, однако здесь эта возможность не используется.
Когда фильму присвоен управляющий элемент onPress или onRelease, он действует, как кнопка и будет автоматически отображен в соответствующем кадре временной шкалы, изображенной на рисунке выше. Это немного сократит количество необходимого кода, поэтому я решил использовать здесь эту возможность, хотя выключенное состояние придется создавать вручную, так как оно не является одним из состояний стандартной кнопки.
Caption с именем инстанса caption_txt. Не беспокойтесь о цвете текста (мы решим этот вопрос в коде ActionScript через некоторое время), однако установите текстовое поле так, чтобы оно было точно отцентрировано и перекрывало всю ширину кнопки.FSimpleButton. Введите следующий код в кадр 1 слоя Definitions.#initclip 1
// Constructor
FSimpleButton = function(){
// Initialise component
this.init();
};
// Inherit from MovieClip object
FSimpleButton.prototype = new MovieClip();
// Register component class
Object.registerClass("FSimpleButton", FSimpleButton);
Весь этот код почти в точности повторяет реализацию компонента Tool Tip в лекции 4. Не будем больше на этом останавливаться. Если вам что-то непонятно, обратитесь к лекции 4.

init, который будет вызываться при создании нового инстанса нашего компонента и подготавливать его к использованию.// Initialise component
FSimpleButton.prototype.init = function(){
// Set caption text and color
this.caption_txt.text = this.captionText;
this.caption_txt.textColor = this.captionColor;
// Setup cursor and disable tabbing
this.useHandCursor = this.showHand;
this.tabEnabled = false;
// Set event handlers
this.onRollOut = this.myRollOut;
this.onRollOver = this.myRollOver;
this.onPress = this.myPress;
this.onRelease = this.myRelease;
this.onDragOut = this.myDragOut;
this.onDragOver = this.myDragOver;
this.onReleaseOutside = this.myReleaseOutside;
};
Здесь мы устанавливаем текст и цвет текста для текстового поля caption_txt. Использованные для этого переменные находятся среди параметров, установленных в предыдущем шаге.
Далее, мы устанавливаем указатель мыши согласно showHand и после этого прерываем прием кнопкой входного фокуса с использованием ключа TAB. Так было сделано потому, что раздражающий желтый прямоугольник фокуса портит внешний вид приложения, но это не обязательно.
Наконец, мы устанавливаем управляющие элементы событий мыши для нашего компонента, и, так как осуществляется наследование из объекта , нужно предусмотреть немало деталей. Мы, на самом деле, не будем здесь обрабатывать все события, но я включил их на тот случай, если вы захотите реализовать нечто отличное с применением вашего компонента кнопки.
onRollOut и onRollOver, и мы будем использовать их для установки переменной состояния в родительской временной шкале.FSimpleButton.prototype.myRollOut = function() {
this._parent [this.statusVar] = _global.oldStatusText;
};
FSimpleButton.prototype.myRollOver = function() {
_global.oldStatusText = this._parent[this.statusVar];
this._parent[this.statusVar] = this.statusText;
};
Переменная состояния указывается в виде еще одного параметра компонента, как и непосредственный текст состояния. Мы используем глобальную переменную oldStatusText для хранения и получения предыдущего текста состояния. Причина этому станет ясна, когда мы перейдем к работе над фильмом Flash.
onPress и onRelease. Из кода ниже можно заметить, что последний элемент на самом деле здесь не используется. Это один из тех управляющих элементов "на всякий случай", о которых я говорил ранее. Он может быть полезным при желании расширить функциональные возможности компонента.FSimpleButton.prototype.myPress = function() {
};
FSimpleButton.prototype.myRelease = function() {
// Execute callback
this._parent[this.clickHandler](this);
};
Управляющий элемент onRelease, вероятно, наиболее важный элемент управления во всем компоненте. Это элемент управления, вызывающий функцию, указанную в clickHandler.
Здесь мы передаем ссылку на текущий объект функции обратной связи. Это полезно в том случае, если у вас есть одна функция обратной связи для нескольких кнопок, и необходимо определять, какой кнопкой была инициализирована обратная связь. Мы не будем использовать это непосредственно в нашем приложении, но, тем не менее, иметь такую возможность достаточно полезно.
onDragOut.FSimpleButton.prototype.myDragOut = function() {
this.gotoAndStop("_up");
};
Я использовал его для устранения одного небольшого препятствия при реализации работы кнопок во Flash. В наиболее распространенных операционных системах, когда вы удерживаете кнопку мыши в момент нахождения указателя над кнопкой, и затем перетаскиваете указатель за пределы кнопки и отпускаете ее, это действие не воспринимается как нажатие кнопки. Однако во Flash кнопка останется в "нажатом" состоянии _down. Чтобы обойти эту особенность, я реализовал возврат кнопки в кадр _up при перетаскивании мыши за пределы области кнопки. Вам решать, применят этот способ здесь или нет, однако я бы на вашем месте не отказывался от этого дополнения.
FSimpleButton.prototype.myDragOver = function() {
};
FSimpleButton.prototype.myReleaseOutside = function() {
};
_disabled.FSimpleButton.prototype.disable = function() {
this.caption_txt.textColor = this.captionDisabledColor;
this.gotoAndStop("disabled");
this.enabled = false;
};
Из этого кода видно, что здесь мы всего лишь меняем цвет текста метки на текст, указанный в captionDisabledColor, переходя к кадру выключения и выключая компонент. При выключенном компоненте события не будут обрабатываться, и компонент будет оставаться в указанном кадре.
FSimpleButton.prototype.enable = function() {
this.enabled = true;
this.gotoAndStop("_up");
this.caption_txt.textColor = this.captionColor;
};
Метод enable просто обращает изменения, сделанные в методе disable, включая кнопку, перемещая ее обратно в кадр _up и заново устанавливая цвет текста метки.
isEnabled, который позволит определять состояние кнопки. Эту возможность мы не будем использовать в приложении, однако она может пригодиться при создании другой программы.// Public: isEnabled
FSimpleButton.prototype.isEnabled = function() {
return this.enabled;
};
#endinitclip
stop();
Мы закончили определение компонента, и он готов к использованию. Переименуйте компонент в библиотеке, если вы еще этого не сделали. Назовите его FSimpleButton и установите его связи следующим образом.

Разобравшись с дизайном кнопки, которая теперь готова к использованию, можно приступить к построению фильма Flash для нашего приложения. Начнем с графической оболочки и затем перейдем к рассмотрению ActionScript.
Используйте слой Background для создания любых графических объектов, нужных в приложении. Можете, например, поэкспериментировать с несколькими значениями цвета, упомянутыми ранее в этом параграфе.
Эти текстовые поля имеют имена инстансов name_txt, email_txt, subject_txt и message_txt, работающих поочередно сверху вниз. Я также добавил дополнительное текстовое поле внизу рабочего места для отображения текста состояния. Я присвоил ему имя инстанса status_txt и связал его с переменной statusText, так как она больше всего подходит для установки содержимого текстового поля вне компонента кнопки.

В следующем шаге мы создадим функции resetForm и submitForm. Этим мы закончим создание части фильма, не требующей применения кода. Сверьте ваше рабочее место с рисунком вверху следующей страницы, чтобы убедиться в правильности ваших действий.
Результат вашей работы может отличаться от этой иллюстрации, так как я добавил текущий просмотр в компонент кнопки, о котором вам не говорил. Он обновляет заголовок, меняя его на тот, который указан в livePreview.fla на компакт-диске.

Разобравшись с графическими элементами нашего приложения, мы переключаем наше внимание на код ActionScript в слое Actions. Здесь как раз будет выполняться вся основная работа, начиная от отправки введенных пользователем данных сценарию PHP, и заканчивая созданием и отображением окна сообщения, показанного на первой иллюстрации приложения.
loadVars. Оно позволит очищать все переменные объекта, чтобы форма могла подтверждаться более, чем один раз, без возможности "сохранения" какой-либо информации с момента предыдущего подтверждения.loadVars.prototype.clear = function() {
for (element in this) {
if (typeof(this[element]) != "function") {
delete this[element];
}
}
};
Мне было нелегко поверить, что это не стандартный метод объекта loadVars, но, по всей видимости, Macromedia решили, что нам ничто похожее не понадобится. Тем не менее, они оставили нам возможность самостоятельно расширять функциональность.
Как вы можете видеть, мы используем цикл for:in для прохождения через каждый элемент объекта loadVars и удаляем все, что не является функцией. Необходимо проверять, что удаляемый нами объект не является функцией, так как управляющий элемент onLoad и метод clear будут включены в обрабатываемые элементы.
status_text.// Set status text
setStatus = function(statusText) {
_root.status_txt.text = statusText;
};
// Fetch status text
getStatus = function() {
return __root.status__txt.text;
};
Для обозначения присутствия в текстовом поле фокуса ввода мы используем некоторые управляющие элементы событий нового объекта TextField, изменяющие цвет фона текстового поля при размещении в нем и удалении фокуса ввода. Это также позволяет устанавливать текст состояния.
onSetFocus и onKillFocus для каждого текстового поля, однако сейчас мы просто создадим сами функции.// Focus handler for form fields
setFocusHandler = function () {
// Set status text
setStatus(this.statusText);
// Highlight field
this.backgroundColor = 0xCACED5;
};
setFocusHandler будет вызываться каждый раз при получении текстовым полем фокуса ввода. Она устанавливает текст состояния на параметр statusText (с которым мы разберемся позднее) текстового поля, вызвавшего управляющий элемент события, и изменяет цвет фона текстового поля на более темный.// Kill Focus handler for form fields
killFocusHandler = function() {
// Clear status
setStatus("");
// Lose field highlight
this.backgroundColor = 0xDEE0E4;
};
killFocusHandler вызывается каждый раз при потере полем фокуса ввода. Эта функция очищает текст состояния и устанавливает цвет фона обратно на исходный.
Теперь рассмотрим проблему, возникающую при необдуманном нажатии пользователями различных кнопок. Например, не следует нажимать кнопку Reset, если форма уже является пустой, также следует предотвратить нажатие клавиши Submit до тех пор, пока пользователем не будут заполнены все поля формы. Вместо создания функций кнопки, которые будут проверять, что необходимые условия выполнены, перед продолжением работы, мы реализуем активацию/деактивацию кнопок в зависимости от состояния формы. Для этого применим еще один управляющий элемент события TextField: onChanged.
onChanged для каждого текстового поля несколько позже, а здесь просто определим саму функцию.// Changed handler for form fields
changedHandler = function() {
var submitCheck = true;
var resetCheck = false;
for (var count = 0; count < textFields.length; count++) {
if (_root [textFields[count]].length == 0) {
submitCheck = false;
} else {
resetCheck = true;
}
}
if (submitCheck) {
submitBtn.enable();
} else {
submitBtn.disable();
}
if (resetCheck) {
resetBtn.enable();
} else {
resetBtn.disable();
}
};
Этот код требует некоторого доверия с вашей стороны, так как он ссылается на массив textFields, который еще не создан. На данный момент достаточно сказать, что он содержит имена инстансов каждого из текстовых полей ввода данных. Вышеуказанный код обрабатывает циклом каждое из текстовых полей и проверяет, был ли введен какой-либо текст. Если обнаруживается пустое текстовое поле, кнопка Submit выключается, а если встречается непустое текстовое поле, активируется кнопка Reset.
Обратите внимание, что здесь используется параметр length самого объекта TextField для определения того, были ли введены какие-либо данные. Согласно Macromedia, здесь получается тот же результат, что и при использовании TextField.text.length, однако наш вариант на самом деле работает немного быстрее. Он также требует меньше нажатий клавиш, поэтому здесь все только в выигрыше!
// Function to disable form fields and buttons
disableForm = function() {
// Disable all form fields
for(var count = 0; count < textFields.length; count++) {
_root [textFields[count]].selectable = false;
_root [textFields[count]].border = false;
}
// Disable submit and reset buttons
submitBtn.disable();
resetBtn.disable();
};
Установив параметр selectable для каждого текстового поля на значение false, мы предотвращаем размещение в них фокуса ввода. Мы также удаляем границу текстового поля, которая является визуальным обозначением активности поля, а также делаем недоступными кнопки.
resetForm и submitForm, упомянутые ранее.// Function to reset form to initial state
resetForm = function() {
// Clear status text
setStatus("");
_global.oldStatusText = "";
// Clear and enable textfields
for(var count = 0; count < textFields.length; count++) {
_root[textFields[count]].selectable = true;
_root[textFields[count]].border = true;
_root[textFields[count]].text = "";
}
// Disable buttons
resetBtn.disable();
submitBtn.disable();
};
Эта функция очищает текст состояния и затем осуществляет очистку и активацию всех текстовых полей. Так как все текстовые поля пусты, обе кнопки должны быть недоступны. К сожалению, событие onChanged текстового поля происходит только тогда, когда пользователь изменяет значение, следовательно, нам необходимо настроить состояния кнопки вручную.
submitForm.// Function to submit form data to the server
submitForm = function() {
// Disable form fields buttons
disableForm();
// Clear dataHandler data...
dataHandler.clear();
// Load data into dataHandler...
for (var count = 0; count < textFields.length; count++) {
dataHandler[textFields[count]] = __root[textFields[count]].text;
}
// Send data to PHP script and set status text
dataHandler.sendAndLoad("simplemailer.php", dataHandler, "POST") ;
setStatus("Contacting server...please wait!");
};
Здесь мы сначала делаем форму недоступной с помощью функции, созданной ранее, далее удаляем все данные из объекта dataHandler (являющийся инстансом loadVars, который мы создадим позже) с использованием нового метода clear, рассмотренного в самом начале этой лекции. После этого нужно переместить все данные из различных текстовых полей в объект dataHandler перед использованием метода sendAndLoad для задействования нашего PHP-сценария и отправкой данных с помощью метода POST. Наконец, устанавливаем текст состояния для информирования пользователя о происходящем.
Осталась последняя функция. Перед тем, как вы начнете прыгать до потолка от радости, хочу сообщить вам, что эта функция несколько больше, чем рассмотренные до сих пор. Тем не менее, в ней нет ничего того, что не было рассмотрено в книге до данного момента, поэтому все будет в порядке! Назначением функции является информирование пользователя об успешном или неуспешном завершении процедуры sendAndLoad. Эта функциональность реализуется при помощи средств рисования API, возможности динамического создания фильмов и текстовых полей, а также компонента кнопки.
// Popup message box function
messageBox = function(message) {
var maxWidth = 200;
var msgBox_mc = _root.createEmptyMovieClip("msgBox_mc", 0);
Обратите внимание, что мы добавили параметр message для функции, который будет текстом, отображаемым в окне сообщения. Также определили другую переменную maxWidth, которая используется для определения ширины окна сообщения (высота определяется количеством текста) и которая может быть изменена по вашему желанию.
msgBox_mc.createTextField("body_txt", 1, 5, 5, maxWidth - 10, 10);
msgBox_mc.body_txt.multiline = true;
msgBox_mc.body_txt.autoSize = true;
msgBox_mc.body_txt.wordWrap = true;
msgBox_mc.body_txt.selectable = false;
msgBox_mc.body_txt.textColor = 0x676767;
msgBox_mc.body_txt.text = message;
Мы присвоили новому текстовому полю 5-пиксельную границу от края нашего фильма и установили начальную высоту на значение 10. Затем мы настроили текстовое поле таким образом, что оно расширяться вертикально в зависимости от количества находящегося в нем текста.
var format = new TextFormat(); format.align = "left"; format.font = "_sans"; format.size = 10; msgBox_mc.body_txt.setTextFormat(format); var currentHeight = msgBox_mc.body_txt.textHeight + 10;
После этого можно определить высоту текстового поля с помощью параметра textHeight. Он будет также определить место размещения кнопки и место рисования границы окна сообщения с учетом 5-пиксельной линии по краям фильма.
var closeBtn = msgBox_mc.attachMovie("FSimpleButton", "closeBtn", 0);
closeBtn._x = (maxWidth - closeBtn._width) / 2;
closeBtn._y = currentHeight;
closeBtn.captionText = "Close";
closeBtn.showHand = false;
closeBtn.captionColor = 0x676769;
closeBtn.init();
closeBtn.onRelease = function() {
resetForm();
this._parent.removeMovieClip();
};
Кнопка отцентрирована горизонтально и настроена на очистку фильма окна сообщения после отпускания кнопки.
currentHeight для определения полной высоты фильма.currentHeight += closeBtn._height + 5;
msgBox_mc._x = (Stage.width - maxWidth) / 2;
msgBox_mc._y = (Stage.height - currentHeight) / 2;
msgBox_mc.moveTo(0, currentHeight);
msgBox_mc.lineStyle(1, 0xF5F6F8, 100);
msgBox_mc.beginFill(0xEBECF0, 75);
msgBox_mc.lineTo(0, 0);
msgBox_mc.lineTo(maxWidth, 0);
msgBox_mc.lineStyle(1, 0xC2C2C4, 100);
msgBox_mc.lineTo(maxWidth, currentHeight);
msgBox_mc.lineTo(0, currentHeight);
msgBox_mc.endFill();
};
С помощью рисования API рисуем рельефную границу вокруг фильма и закрашиваем ее светло-зеленым цветом с интенсивностью 75%. Создание функции messageBox завершено.
dataHandler и установить его управляющий элемент события onLoad на вызов функции messageBox, которую мы только что создали с использованием разных сообщений, в зависимости от успешного или неуспешного завершения процедуры.// Create data handler and set onLoad event handler
dataHandler = new LoadVars();
dataHandler.onLoad = function(success) {
if (success) {
messageBox("Your data has been mailed by the server. Thank
Кyou for your feedback, and someone will be in touch with
Кyou shortly regarding your query");
} else {
messageBox ("You data was not able to be sent due to a
Кproblem on the server. Please try again later!");
}
}
textFields и связанные с ним строки состояния и инициализировать текстовые поля.// Array of textfield names and status strings
textFields = new Array("name_txt", "email_txt",
"subject_txt", "message_txt");
statusStrings = new Array("Enter your name here",
"You should enter your email
Кaddress here", "This is the subject of your email",
"Enter Кthe main body of your message here");
// For each textfield
for (count = 0; count < textFields.length; count++) {
// Set properties
textField_txt = this [textFields[count]];
textField_txt.border = true;
textField_txt.borderColor = 0xB1B1B1;
textField_txt.background = true;
textField_txt.backgroundColor = 0xDEE0E4;
textField_txt.onSetFocus = setFocusHandler;
textField_txt.onKillFocus = killFocusHandler;
textField_txt.onChanged = changedHandler;
textField_txt.statusText = statusStrings[count];
}
Весь этот код говорит сам за себя. Мы уже создали текстовые поля и управляющие элементы событий, поэтому наши старания здесь сводятся к установке параметров и управляющих элементов событий для каждого текстового поля. Единственная строка, заслуживающая здесь особого внимания, это последняя строка, в которой мы сохраняем текст состояния для данного текстового поля в качестве параметра самого текстового поля. Мы уже использовали этот параметр в функции setFocusHandler для установки текста состояния.
changedHandler.// Set initial button states and halt movie changedHandler(); stop ();
Вот и все. Мы рассмотрели весь код ActionScript, необходимый для создания и выполнения нашего приложения. Запустив его, вы увидите результат ваших стараний во всей красе. Подтверждение формы на данном этапе генерирует сообщение об ошибке, так как сценарий PHP еще не существует. Также обратите внимание на то, что при тестировании приложения внутри среды разработки Flash окно сообщения не будет появляться в центре фильма. Это по той причине, что в среде разработки объект Stage представляет собой все окно тестирования, и поэтому код позиционирования в функции messageBox игнорируется. Если вы протестируете приложение в браузере, все будет работать, как положено!
Выходим на финишную прямую и начинаем разбирать сценарий PHP, реализующий наибольшую часть функциональности нашего приложения. Рассмотрим его шаг за шагом. Здесь все уже должно быть знакомо из описания PHP, приведенного ранее в этой лекции. Если вы почувствуете себя неуверенно на любом из этапов, просто пролистайте книгу назад и обратитесь к этому параграфу. PHP-сценарий для этого приложения будет не очень большим, так как значительная часть работы выполняется в фильме Flash. Нужно создать тело сообщения из списка переменных, передаваемых сценарию PHP, и затем отправить сообщение электронной почты с использованием функции mail.
simplemailer.php. Сначала нужно ввести начальный PHP-тег. Здесь мы также укажем адрес электронной почты получателя.<?php // simplemailer.php // Flash MX Studio - Steve Webster // Set recipient for email $recipient = "you@yourisp.com";
В этом фрагменте кода можно увидеть несколько комментариев. Как и в случае с ActionScript, всегда лучше сопровождать код исчерпывающими комментариями; неизвестно, когда вам придется снова разбираться в этом коде.
Необходимо обработать небольшую особенность объекта loadVars. При использовании методов send и sendAndLoad управляющий элемент события onLoad и новый метод clear будут передаваться вместе с любыми другими данными в объект. Так как одной из целей создания этого приложения было обеспечение его максимальной гибкости в отношении числа поддерживаемых переменных, используем цикл для добавления каждой переменной, передаваемой из фильма Flash в тело сообщения электронной почты.
// Remove methods from data... unset($HTTP_POST_VARS["onLoad"]); unset($HTTP_POST_VARS["clear"]);
Это реализуется с помощью функции unset для удаления соответствующих элементов массива . Этот массив содержит все переменные, которые были переданы PHP-сценарию с помощью метода POST.
// Setup body text $body = "The following information was submitted...\n\n";
Мы устанавливаем ее, указав начальный текст, который будет отображаться вверху сообщения электронной почты.
HTTP_POST_VARS , прибавляя их по мере продвижения к нашей переменной $body.// Add each key/value pair to the body text
foreach($HTTP_POST_VARS as $key => $value) {
$key = substr($key, 0, -4);
$body .= "$key: $value\n";
}
Из кода видно, что мы использовали цикл foreach. Он аналогичен циклу for:in в ActionScript, который использовался в новом методе clear объекта loadVars. В примере выше, каждая итерация цикла считывает ключ (имя переменной) и значение следующего элемента массива, выбираемое и сохраняемое в переменных $key и $value, соответственно.
После этого мы используем функцию substr для отбрасывания расширения _txt, которое имеют в данный момент имена всех наших переменных. Это, на самом деле, необязательный шаг, однако указание расширения в электронной почте довольно бессмысленно, поэтому мы избавляемся от него. В PHP функция substr работает несколько иным образом, нежели ее аналог в ActionScript, так как здесь мы можем указывать отрицательное значение конечной точки подстроки. В данном случае, подстрока начинается из начального индекса и продолжается на протяжении n символов с конца исходной строки. В переводе на русский язык, эта строка кода будет звучать следующим образом.
Берем все символы в $key с позиции от 0 до 4 с конца строки и записываем результат в переменную $key.
После этого добавляем текущий ключ и значение в переменную $body и переходим к следующему элементу массива.
Далее нужно создать адресную строку From: для сообщения электронной почты. Мы реализуем указание имени отправителя в сообщении, получаемом адресатом. Это будет сделано не с помощью PHP, а с использованием прилагаемых деталей имени и адреса электронной почты. Правильный формат поля From: сообщения электронной почты таков.
"Name" <email@whatever.com>
// Set from address $from = $HTTP_POST_VARS["name_txt"] . " <" . $HTTP_POST_VARS["email_txt"] . ">" ;
// Set subject for email $subject = $HTTP_POST_VARS["subject_txt"]; // Send email mail($recipient, $subject, $body, "From: $from"); ?>
Если у вас возникли проблемы и сценарий PHP работает неправильно, следует проверить следующее.
http://.../simplemailer.php?name_txt=Bobemail_txt=...
error_reporting (E_ALL ^ E_NOTICE);
Если вы обнаружите какие-либо ошибки, проверьте ваш сценарий и исправьте их. Если вы все еще не уверены в себе, просто скопируйте сценарий, находящийся на компакт-диске этой книги.
Теперь, когда приложение уже создано, я хочу упомянуть некоторые дополнительные возможности, которые могут быть очень полезны в этом приложении.
Первым прекрасным дополнением, которое пришло мне в голову, является расширение сценария PHP для реализации отправки электронного сообщения пользователю, заполнившему форму, с выражением благодарности за потраченное время или каким-либо другим содержимым. Вам решать, добавлять эту функциональность или нет, но хочу развеять ваши опасения - реализовать ее совсем просто.
Также полезно обеспечить пользователя возможностью выбора получателя определенного сообщения электронной почты. Например, вы можете использовать компонент поля со списком для перечисления различных отделов вашей организации в качестве получателей. С каждым выбранным элементом будет ассоциироваться свой адрес электронной почты, который будет передаваться в сценарий PHP.
Существуют и другие возможности, которые вы могли бы реализовать в этом приложении, однако это я уже оставляю на ваше усмотрение.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.