Создание взаимодействующих с сервером приложений в Silverlight
Все элементы UI размещаются в контейнере и все они должны иметь в XAML уникальные имена. Как видите, в этом примере XAML имя каждого TextBlock определятся атрибутом x:Name. При клонировании контейнера XAML должен обеспечивать уникальные имена для этих узлов. Алгоритм присваивания имен будет прост- в конце каждого имени будет добавляться индекс элемента. Итак, например, записанное в шаблоне значение x:Name txtState для первой строки базы данных превратиться в txtState1, для второй строки - txtState2, и т.д.
Как будет показано в следующем разделе, размножить эти элементы в PHP очень просто.
Формирование XAML из PHP и MySQL
Синтаксический разбор страницы выполняет PHP. Это означает, что когда сервер получает запрос на страницу, PHP записывает форматированные данные в буфер ответов. Когда PHP встречает специальный открывающий тег ( <?php ), он передает обработку синтаксическому анализатору PHP. Анализатор выполняет код, выявляемый процессором PHP, пока не встретит закрывающий тег ( ?> ). Это делает связку MySQL и PHP идеальным сочетанием для отображения содержимого, формируемого по шаблону. Шаблон для формирования содержимого просто помещается в файл с расширением .php, а там, где требуется вставить некоторые связанные с данными поля подстановки, добавляется необходимая PHP-логика, заключенная в открывающий и закрывающий теги ( <?php и ?>, соответственно).
PHP-код может содержать циклы. Если после выражения цикла следует некоторое содержимое, оно будет выведено многократно. В теле цикла могут присутствовать открывающий/закрывающий теги РНР. Например, можно сделать следующее:
<?php
for($i =0; $i<100; $i ++)
{ // Открывающая скобка цикла
// Выходим из PHP, хотя цикл еще не закрыт!
?>
<H1>My Text Line is <?php echo $i; ?></H1>
<?php
} // Теперь закрываем наш цикл
?>Это обеспечит повторение HTML-содержимого (текста, заключенного в элемент <H1> ) 100 раз. Как видите, не обязательно заключать весь текст в теги <?php ... ?>. Это полезное свойство при объединении PHP и XAML
В XAML холст-контейнер может быть помещен в цикл:
<?php
for($i =0; $i<100; $i ++)
{ // Открывающая скобка цикла
// Выходим из PHP, хотя цикл еще не закрыт!
?>
<Canvas>
...
</Canvas>
<?php
} // Теперь закрываем наш цикл
?>Выполнение этого кода обеспечит запись XAML 100 раз! Это делает PHP мощным языком описания шаблонов для Silverlight.
Возвращаясь к нашему примеру, рассмотрим, как установить подключение к базе данных, выполнить запрос к ней и записать то количество XAML-элементов Canvas, которое соответствует числу возвращенных результатов. Также отредактируем содержимое элементов TextBlock холста-контейнера, чтобы они отображали информацию, полученную из базы данных, а также обеспечим уникальность имен TextBlock.
В итоге должна получиться PHP-страница, формирующая XAML, который будет использоваться как источник для элемента управления Silverlight. Но чтобы было немного интересней, изменим PHP и введем параметр state (штат), который обеспечит возвращение сведений только для людей, проживающих в заданном штате. Это превратит наш код в настоящий динамический генератор XAML
Во-первых, необходимо, чтобы Silverlight распознавал вывод PHP какXML. Для этого задаем тип MIME содержимого вывода. Это делается в PHP с помощью команды header (заголовок):
header('Content-type: text/xml');Извлечение параметра строки запроса (т.е. http://server/script.php?param =value) в PHP обеспечивается массивом $ REQUEST. Итак, чтобы прочитать значение параметра State, используем следующий код:
$State=$ REQUEST['State'];
В PHP версии 4.x имеется встроенный набор команд MySQL Для версий 5.x и выше набор команд MySQL должен задаваться как расширение. Независимо от используемой версии, синтаксис PHP аналогичен.
Подключение к серверу localhost с использованием имени пользователя user и пароля password выполняется с помощью команды mysql connect:
$con = mysql connect("localhost", "user", "password");На сервере может располагаться несколько баз данных. Для выбора необходимой базы данных используется команда mysql select db:
mysql select db("test", $con); // "test" имя базы данныхЗатем, чтобы выполнить запрос к этой базе данных, используется команда mysql query, в которую передается строка, содержащая фактический запрос SQL Результат запроса будет представлять собой массив массивов значений. Приведем пример:
$sqlString = "SELECT * from addresses"; $result = mysql query($sqlString);
Затем массив mysql fetch array разбивается на строки. С помощью цикла while можно обойти каждую строку, как показано в следующем примере:
while($row = mysql fetch array($result))
{
...
}таким образом, исходя из данного сценария, получаем такой алгоритм действий:
Задаем тип MIME text/xml. Принимаем входной параметр (штат). Записываем начальный тег "корневого" Canvas. Используем входной параметр для построения запроса. Выполняем запрос и получаем результирующее множество. Для каждой строки результирующего множества:
- a. Создаем XAML-шаблона.
- b. Заполняем атрибуты Text элементов TextBlock данными из соответствующих полей базы данных.
- c. Заполняем атрибуты x:Name уникальными ID, полученными на основании порядкового номера
строки.
Закрываем тег "корневого" Canvas.
Код PHP-страницы полностью приведен в листинге 10.2. Разметка PHP в блоке XAML выделена жирным шрифтом.
<?php
header('Content-type: text/xml');
$State=$ REQUEST['State'];
?>
<Canvas xmlns=" http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xam l"
Width="640" Height="480" Background = "#FF460608">
<?php
$height=128; $top=8; $i=0;
$con = mysql connect("localhost", "root", "root");
mysql select db("test",$con);
$sqlString = "SELECT * from addresses";
if($State! = "") {
$sqlString = $sqlString . " WHERE State = '" . $State . "'"; }
$result = mysql query($sqlString); while($row = mysql fetch array($result)) { ?>
<Canvas Width="352" Height="128" Canvas.Left="10" Canvas.Top =" <"?php echo($top="" + ($height*$i="")); ?>" >
<Rectangle Fill="#FF693B3D" Stroke="#FF000000" StrokeThickness="0" RadiusX="16" RadiusY="16"
Width = "352" Height="128" Canvas.Top="1"/>
<Rectangle Stroke="#FF000000" StrokeThickness="0" RadiusX="8" RadiusY="8"
Width="336" Height="40" Canvas.Left="8" Canvas.Top="8">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.518,0.175" StartPoint="0.515,0.825">
<GradientStop Color="#FF460608" Offset="0"/>
<GradientStop Color="#FF841316" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock x:Name="txtName"<?php echo="" $i=""; ?>"
Width="312" Height="24" Canvas.Left="16" Canvas.Top="16" FontFamily="Arial Unicode MS"
FontSize="18" FontWeight="Normal" Foreground="#FFFFFFFF" Text="<?php echo($row['Name']); ?>"
TextWrapping ="Wrap"/>
<Rectangle Stroke="#FF000000" StrokeThickness="0" RadiusX="8" RadiusY="8" Width="336" Height="23"
Canvas.Left="8" Canvas.Top="48">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.518,0.175" StartPoint="0.515,0.825">
<GradientStop Color="#FF460608" Offset="0"/>
<GradientStop Color="#FF841316" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock x:Name="txtAddr1"
<?php echo="" $i=""; ?>"
Width="312" Height="24" FontFamily="Arial Unicode MS" FontSize="12"
FontWeight="Normal" Foreg round="#FFFFFFFF"
Text="<?php echo($row['Address1']); ?>" TextWrapping ="Wrap" Canvas.Left="14" Canvas.Top="48"/>
<Rectangle Stroke="#FF000000" StrokeThickness="0" RadiusX="8" RadiusY="8"
Width="336" Height="23" Canvas.Left="8" Canvas.Top="71">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.518,0.175" StartPoint="0.515,0.825">
<GradientStop Color="#FF460608" Offset="0"/>
<GradientStop Color="#FF841316" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock x:Name="txtAddr2"
<?php echo="" $i=""; ?>" Width = "312" Height="24" FontFamily="Arial Unicode MS"
FontSize="12" FontWeight="Normal" Foreground="#FFFFFFFF"
Text="<?php echo($row['Address2']); ?>" TextWrapping="Wrap"
Canvas.Left="15" Canvas.Top="72"/>
<Rectangle Stroke="#FF000000" StrokeThickness="0" RadiusX="8" RadiusY="8"
Width="168" Height="23" Canvas.Left="176" Canvas.Top="94">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.518,0.175" StartPoint="0.515,0.825">
<GradientStop Color="#FF460608" Offset="0"/>
<GradientStop Color="#FF841316" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Stroke="#FF000000" StrokeThickness="0" RadiusX="8" RadiusY="8"
Width="168" Height="23" Canvas.Left="8" Canvas.Top="94">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.518,0.175" StartPoint="0.515,0.825">
<GradientStop Color="#FF460608" Offset="0"/>
<GradientStop Color="#FF841316" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock x:Name="txtCity"
<?php echo="" $i=""; ?>" Width = "144" Height="24" FontFamily="Arial Unicode MS"
FontSize="12" FontWeight="Normal" Foreground="#FFFFFFFF"
Text="<?php echo($row['City']); ?>" TextWrapping= "Wrap"
Canvas.Left="15" Canvas.Top="96"/>
<TextBlock x:Name="txtState"
<?php echo="" $i=""; ?>" Width="144" Height="24" FontFamily="Arial Unicode MS"
FontSize="12" FontWeight="Normal" Foreground="#FFFFFFFF"
Text="<?php echo($row['State']); ?>" TextWrapping = "Wrap"
Canvas.Left="182" Canvas.Top="96"/>
</Canvas>
<?php $i++; }?>
</Canvas>
Листинг
10.2.
2 PHP код для формирования XAML
Создание PHP-страницы для отображения Silverlight
Как было показано в предыдущем разделе, сервер выводит содержимое напрямую, пока не встречает открывающий тег ( <?php ). Встретив этот тег, сервер обращается к интерпретатору PHP, который выполняет код, заключенный в открывающий и закрывающий теги ( ?> ).
PHP-код обычно используется для создания динамического HTML-кода. Поскольку Silverlight отображается с помощью HTML, HTML-страница просто редактируется: в нее добавляются теги PHP, и меняется имя файла с добавлением расширения .php. Итак, чтобы реализовать отображение Silverlight, используя PHP, необходимо, чтобы страница, включающая Silverlight.js и createSilverlight.js, вызывала createSilverlight для создания экземпляра элемента управления Silverlight.
Мы хотим, чтобы пользователь мог выбирать имена и адреса в базе данных по штату. Таким образом, эта страница должна принимать параметр и применять его при создании содержимого Silverlight с использованием XAML-источника, сформированного PHP, который был представлен в предыдущем разделе. К счастью, это очень просто сделать в PHP. Чтобы вывести на экран, сформированный XAML, необходимо всего лишь присвоить в качестве значения свойства content элемента управления Silverlight Uniform Resource Indicator (URI) вашего приложения. Silverlight будет подключаться к серверу по этому URI, принимать результирующий XAML и формировать его визуальное представление.
Далее представлен полный код примера PHP-страницы, формирующей HTML:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SilverlightJSApplication2</title>
<script type="text/javascript" src="Silverlight.js">
</script>
<script type="text/javascript" src="createSilverlight.js">
</script>
<script type="text/javascript">
function handleLoad(control, userContext, rootElement)
{
<?php
if(!isset($_REQUEST['State']))
$State="";
else $State=$_REQUEST['State'];
?>
control.source = "http://localhost/phptest/xaml.php?State=
<?php echo($State) ?>";
}
</script>
</head>
<body>
<div id="SilverlightControlHost">
<script type="text/javascript">
createSilverlight();
</script>
</div>
</body>
</html>На рис. 10.6 и 10-7 показано, как эта PHP-страница отображается в браузере с использованием Silver-light для адресов в Нью-Йорке (NY в базе данных) и Вашингтоне (WA).

