Опубликован: 24.03.2009 | Доступ: свободный | Студентов: 2286 / 115 | Оценка: 4.24 / 3.93 | Длительность: 17:47:00
Лекция 10:

Создание взаимодействующих с сервером приложений в 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. Используем входной параметр для построения запроса. Выполняем запрос и получаем результирующее множество. Для каждой строки результирующего множества:

  1. a. Создаем XAML-шаблона.
  2. b. Заполняем атрибуты Text элементов TextBlock данными из соответствующих полей базы данных.
  3. 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).

 Содержимое, сформированное приложением PHP для адресов в Нью Йорке

Рис. 10.6. Содержимое, сформированное приложением PHP для адресов в Нью Йорке
 Содержимое, сформированное приложением PHP для адресов в Вашингтоне

Рис. 10.7. Содержимое, сформированное приложением PHP для адресов в Вашингтоне