close

Вход

Забыли?

вход по аккаунту

?

MU k lab rab web-programmirovanie

код для вставкиСкачать
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ, МОЛОДЕЖИ И СПОРТА УКРАИНЫ
ДОНБАССКАЯ ГОСУДАРСТВЕННАЯ МАШИНОСТРОИТЕЛЬНАЯ АКАДЕМИЯ
КАФЕДРА КОМПЬЮТЕРНЫХ ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ
"Web-программирование"
МЕТОДИЧЕСКИЕ УКАЗАНИЯ
к лабораторным работами и самостоятельной работе
для студентов очной формы обучения специальности 6.050101 "Компьютерные науки"
"Информационные технологии проектирования"
В печать экз.
Первый проректор _____________А.Н. Фесенко
Утверждено
на заседании
методического совета ДГМА
Протокол N __
от __.__.2012 г.
Краматорск 2012
УДК 004.412.2
"Web-программирование" методические указания методические указания к контрольным работам и самостоятельной работе для студентов заочной формы обучения специальности 6.050101 "Компьютерные науки" "Информационные технологии проектирования" /сост. А.В. Алтухов, С.В. Таран. - Краматорск: ДГМА, 2013. - 56 с.
Методические указания содержат задания к выполнению лабораторных работ и самостоятельной работе, выполняемых студентами очной форм обучения специальности 6.050101 "Компьютерные науки" "Информационные технологии проектирования" по дисциплине "Web-программирование".
Составитель А.В. Алтухов, ст. преп.
С.В. Таран, ассистент
Ответственный за выпуск: А.Ф. Тарасов, проф.
СОДЕРЖАНИЕ
Введение.............................................................................4Лабораторная работа №1. Разработка приложений с помощью PHP...5Лабораторная работа №2. Работа с файлами в PHP........................10Лабораторная работа №3. Разработка приложений БД на cервере MySQL с помощью PHP.........................................................13Лабораторная работа №4. Разработка сайта с использованием MVC фреймворка.........................................................................22Лабораторная работа №5. Работа с таблицами БД с использованием MVC фреймворка..................................................................26Лабораторная работа №6. Прототипирование веб-сайта с использованием технологий "классического" PHP и шаблонизатора Smarty.....................31Лабораторная работа №7. Использование Ajax и JS библиотек.................40Лабораторная работа №8. Разработка компонент для CMS Joomla. Разработка простого компонента для пользовательской части..................57Лабораторная работа №9. Разработка компонент для CMS Joomla. Разработка компонента с использованием базы данных...........................66Лабораторная работа №10. Разработка компонент для CMS Joomla. Разработка компонента с административной частью..............................77Лабораторная работа №11. Разработка приложения с помощью технологии ASP.NET............................................................103Лабораторная работа №12. Авторизация. Поддержка сеанса пользователя........................................................................109Лабораторная работа №13. Работа с БД в ASP.NET........................119Лабораторная работа №14. Оформление дизайна страниц в ASP.NET..121Список рекомендованной литературы .........................................127
ВВЕДЕНИЕ
С момента своего появления web изменил компьютерный мир. Масса разрозненных компьютеров и пользователей стали объединяться для обмена информацией в виде простых HTML-документов. Такова была начальная концепция web. Взаимодействие web-сервера и клиента, с помощью браузера, позволило пользователям всего мира просматривать HTML-документы с любого сервера.
Появление динамических сайтов на основе web-приложений заложило новый этап в развитии мировой паутины, теперь web-сервер мог хранить информацию в базе данных, выполнять ее поиск и динамически формировать HTML-документы по запросам пользователей. Использование языка JavaScript позволило оживить HTML-документы.
Огромный толчок в развитии web дало появление электронной коммерции. Развитие среды web сказалось на прикладном программном обеспечении. Браузер стал неотъемлемой частью операционной системы. Будущее операционных систем связывают именно с сетью Интернет и средой web. В ближайшие годы ожидается появление операционных систем с браузером интегрированным в рабочий стол, что говорит о том, что основная работа в системе будет вестись через Интернет.
Пройдя этапы развития и становления, изменилась концепция web, появился web 2.0, в котором web-сайт структурированное хранилище информации, которой управляют пользователи. Идея наполнения контента пользователями послужила толчком для создания таких сервисов как блоги, фото и видео-галереи социальные сети и другие. Для придания дружественного вида информации появились новые технологии пользовательского интерфейса Flash и AJAX.
Появление онлайновых сервисов, таких как электронная флешка, онлайновые офисные пакеты, задает новое направление развития среды web. Web-среда продолжает развиваться, намечаются новые направления, разрабатывается новая концепция web 3.0, в которой будет преобладать персонализация получаемой информации. О каждом пользователе будет собираться информация в виде социального графа - интересы, увлечения, место проживания. Это позволит выдавать пользователю информацию наиболее нужную для него.
Лабораторная работа №1
Разработка приложений с помощью PHP
Цель работы: получить практические навыки развертывания и базовой настройки АМР-платформы, изучить функции PHP для получения данных формы, работы со строками и массивами.
Теоретические сведения
Виртуальная платформа AMP = Apache + MySQL + PHP. АМР это не совсем платформа, скорее среда выполнения. Но под неё написано большинство WEB-приложений. Поэтому решено, что AMP - это платформа для WEB-приложений. На AMP работают CMS, различные движки блогов, Интернет магазинов, такие как Joomla, WordPress. Все WEB приложения работают в определённой среде, необязательно AMP, это может быть и среда Tomcat, GlassFish, JBoss при использовании Java.
Apache является кроссплатформенным ПО, поддерживая операционные системы GNU/Linux, BSD, Mac OS, Microsoft Windows, Novell NetWare, BeOS.
Программа на PHP (да и на любом другом языке программирования) - это набор команд (инструкций). Обработчику программы (парсеру) необходимо как-то отличать одну команду от другой. Для этого используются специальные символы - разделители. В PHP инструкции разделяются так же, как и в Cи или Perl, - каждое выражение заканчивается точкой с запятой. Закрывающий тег "?>" также подразумевает конец инструкции, поэтому перед ним точку с запятой не ставят. Например, два следующих фрагмента кода эквивалентны: 1.php (расположить на сервере Webservers/home/localhost/www/1.php)
<?php
echo "Hello, world!"; // точка с запятой в конце команды обязательна
?>
Переменная в PHP обозначается знаком доллара, за которым следует ее имя. Например: $my_var
Имя переменной чувствительно к регистру, т.е. переменные $my_var и $My_var различны. Имена переменных соответствуют тем же правилам, что и остальные наименования в PHP: правильное имя переменной должно начинаться с буквы или символа подчеркивания с последующими в любом количестве буквами, цифрами или символами подчеркивания. <?php
$first = ' Text '; // Присваиваем $first значение ' Text '
$second = $first; // Присваиваем $second значение переменной $first
$first = ' New text '; // Изменяем значение $first на ' New text '
echo "Переменная с именем first " .
"равна $first <br>"; // выводим значение $first
echo "Переменная с именем second " .
"равна $second"; // выводим значение $second
?>
Результат работы этого скрипта будет следующим: Переменная с именем first равна New text Переменная с именем second равна Text Массив - это тип данных, с данными этого типа должны быть определены операции. Какие же операции можно производить с массивами? Массивы можно складывать и сравнивать.
Определить массив можно с помощью конструкции array() или непосредственно задавая значения его элементам. array ([key] => value,
[key1] => value1, ... )
Языковая конструкция array() принимает в качестве параметров пары ключ => значение, разделенные запятыми. Символ => устанавливает соответствие между значением и его ключом. Ключ может быть как целым числом, так и строкой, а значение может быть любого имеющегося в PHP типа. Числовой ключ массива часто называют индексом. Индексирование массива в PHP начинается с нуля. Значение элемента массива можно получить, указав после имени массива в квадратных скобках ключ искомого элемента.
Складывают массивы с помощью стандартного оператора "+". Вообще говоря, эту операцию по отношению к массивам точнее назвать объединением. Если у нас есть два массива, $a и $b, то результатом их сложения (объединения) будет массив $c, состоящий из элементов $a, к которым справа дописаны элементы массива $b. Причем, если встречаются совпадающие ключи, то в результирующий массив включается элемент из первого массива, т.е. из $a. Таким образом, если складываются массивы в языке PHP, от перемены мест слагаемых сумма меняется.
<?
$a = array("и"=>"Информатика", "м"=>"Математика");
$b = array("и"=>"История","м"=>"Биология", "ф"=>"Физика");
$c = $a + $b;
$d = $b + $a;
print_r($c); /* получим: Array([и]=>Информатика [м]=>Математика [ф]=>Физика) */
print_r($d); /* получим: Array([и]=>История [м]=>Биология [ф]=>Физика) */
?>
Массив в PHP представляет собой упорядоченную карту - тип, который преобразует значения в ключи. Этот тип оптимизирован в нескольких направлениях, поэтому вы можете использовать его как собственно массив, список (вектор), хеш-таблицу (являющуюся реализацией карты), стэк, очередь и т.д. Поскольку вы можете иметь в качестве значения другой массив PHP, можно также легко эмулировать деревья. Функция in_array
in_array("искомое значение","массив", ["ограничение на тип"]);
позволяет установить, содержится ли в заданном массиве искомое значение. Если третий аргумент задан как true, то в массиве нужно найти элемент, совпадающий с искомым не только по значению, но и по типу. Если искомое значение - строка, то сравнение чувствительно к регистру.
Например, имеется массив не изученных нами языков программирования. Мы хотим узнать, содержится ли в этом массиве язык PHP. Напишем следующую программу:
<?php
$langs = array("Lisp","Python","Java",
"PHP","Perl");
if (in_array("PHP",$langs,true)) echo "Надо изучить PHP<br>"; // выведет сообщение "Надо изучить PHP"
if (in_array("php",$langs)) echo "Надо бы изучить php<br>";
// ничего не выведет, поскольку в массиве есть строка "PHP", а не "php"
?>
В качестве искомого значения этой функции может выступать и массив. Правда, это свойство было добавлено только начиная с PHP 4.2.0.
Например:
<?php
$langs = array("Lisp","Python",array("PHP","Java"),"Perl");
if (in_array(array("PHP","Java"),$langs))
echo "Надо бы изучить PHP и Java<br>";
?>
Функция array_search
Это еще одна функция для поиска значения в массиве. В отличие от in_array в результате работы array_search возвращает значение ключа, если элемент найден, и ложь - в противном случае. А вот синтаксис у этих функций одинаковый:
array_search("искомое значение","массив", ["ограничение на тип"]);
Сравнение строк чувствительно к регистру, а если указан опциональный аргумент, то сравниваются еще и типы значений. До PHP 4.2.0, если искомое значение не было найдено, эта функция возвращала ошибку или пустое значение NULL.
<?php
$langs = array("","Lisp","Python","Java", "PHP","Perl");
if (!array_search("PHP",$langs)) echo "Надо бы изучить PHP<br>";
else {
$k = array_search("PHP",$langs);
echo "PHP я изучил $k-м";
}
?>
В результате мы получим строчку: PHP я изучил 4-м
Очевидно, что эта функция более функциональна, чем in_array, поскольку мы не только получаем информацию о том, что искомый элемент в массиве есть, но и узнаем, где именно в массиве он находится. А что будет, если искомых элементов в массиве несколько? В таком случае функция array_search() вернет ключ первого из найденных элементов. Чтобы получить ключи всех элементов, нужно воспользоваться функцией array_keys(). Считывание данных формы:
my1.php
<?php
print "hello! ";
?>
<form action=my1.php method=post>
Вввод имени <input type=text name=login> <br> <input type=submit name=ok value=Отправить>
</form>
<?php $method = $_SERVER["REQUEST_METHOD"]; // получить метод
$name=$_REQUEST["login"]; // получение данных из поля login
echo "<br>Вы ввели имя $name " ;
echo "<br>Данные передали по методу $method";
?>
Задание к работе:
Ознакомиться с теоретическим материалом.
Cоздать скрипт на php для выполнения ввода информации в элементы формы, обработать введены данные, выдать информацию пользователю. Использовать элементы диалога таблицы 1. Оформить отчет согласно требованиям.
Таблица 1- Индивидуальное задание для выбора элементов диалога №Текст задания№Текст задания1Text, password, textarea7Radio, select2Select, textarea8Text, password3radio, textarea9reset, select4Image (кнопка), textarea10Text, radio5Text, select, reset11Select, text6Text, checkbox12Radio, text Отчет должен содержать:
1 Название и цель работы.
2 Ход работы с детальным описанием выполненных действий с рисунками, листингом кода.
3 Экранные формы браузера с загруженными страницами.
4 Выводы о проделанной работе.
Вопросы для подготовки к защите работы:
1 Какие элементы диалога можно располагать на форме?
2 Методы передачи данных формы?
3 Как обработать данные, введенные в элементы диалога?
4 Можно ли передавать данные формы разным модулям? Как организовать такой вид передачи? 5 Какие вы знаете функции для работы со строками?
Лабораторная работа №2
Работа с файлами в PHP
Цель работы: получить практические навыки работы с файлами и директориями с помощью PHP.
Теоретические сведения
Работа с файлами
?php
$h = fopen("1.txt","w"); /* открывает на запись файл 1.txt если он существует, или создает пустой файл с таким именем, если его еще нет */
$h = fopen("dir/2.txt","w+"); /* открывает на запись и чтение или создает файл 2.txt в директории dir */
$h = fopen( "http://www.server.ru/dir/file.php","r");
/* открывает на чтение файл, находящийся по указанному адресу*/
?>
<?php
$h = fopen("my_file.html","w");
$text = "Этот текст запишем в файл.";
if (fwrite($h,$text)) echo "Запись прошла успешно";
else echo "Произошла ошибка при записи данных";
fclose($h);
?>
В результате работы этого скрипта в браузере мы увидим сообщение о том, что запись прошла успешно, а в файле my_file.html появится строка "Этот текст запишем в файл.". Если бы этот файл существовал до того, как мы выполнили этот скрипт, все находящиеся в нем данные были бы удалены.
Если же мы напишем такой скрипт:
<?php
$h = fopen("my_file.html","a"); $add_text = "Добавим текст в файл.";
if(fwrite($h,$add_text,7)) echo "Добавление текста прошло успешно<br>";
else echo "Произошла ошибка при добавлении данных<br>";
fclose($h);
?>
то к строке, уже существующей в файле my_file.html, добавится еще семь символов из строки, содержащейся в переменной $add_text, т.е. слово "Добавим" Считывание всех строк файла my_file.txt:
<?php $h = fopen("my_file.html","r"); while (!feof ($h)) {
$content = fgets($h);
echo $content,"<br>";} ?>
Функция stat( ) возвращает индексируемый массив с подробной информацией о файле с заданным именем: stat(string имя_файла) В элементах массива возвращается следующая информация: 0 Устройство 1 Индексный узел (inode) 2 Режим защиты индексного узла 3 Количество ссылок 4 Идентификатор пользователя владельца 5 Идентификатор группы владельца 6 Тип устройства индексного узла 7 Размер в байтах 8 Время последнего обращения 9 Время последней модификации 10 Время последнего изменения 11 Размер блока при вводе/выводе в файловой системе 12 Количество выделенных блоков Таким образом, если вы хотите узнать время последнего обращения к файлу, обратитесь к элементу 8 возвращаемого массива. Например: $file = "datafile.txt"; list($dev, $inode, $inodep, $nlink, $uid, $gid, $inodev, $size, $atime, $mtime, $ctime, $bsize) = stat($file); echo(date("F d Y H:i:s.", fileatime("1.html")); // вывод в формате даты
Задание к работе:
Ознакомиться с теоретическим материалом.
Cоздать скрипт на php для выполнении индивидуального задания (варианты 1-5 решают задачу 1, варианты 6-10 решают задачу 2, варианты 11-15 решают задачу 3, варианты 16-20 решают задачу 4). Использовать элементы диалога таблицы 1.
Оформить отчет согласно требованиям.
Задачи:
1 Создать скрипт для работы гостевой книги: использовать указанные элементы диалога для ввода информации о пользователях сайта и оставляемых комментариях, которая будет записывается в файл. Создать страницу с просмотром всех сообщений.
2 Создать текстовый файл с информацией о товарах (название, цена, фирма), в котором отдельная строка соответствует одному товару. Создать скрипт, который выводит на страницу прайс товаров с возможностью заказа товара по нажатию кнопки возле соответствующей строки. При заказе товара, обязательно пользователь вводит свое имя и требуемое количество товара. Список заказов хранить в другом файле, например "zakazi.txt".
Использовать следующую функцию для разбития строки файла на составляющие: list($name,$price)= split (":", $srt,2);
3 Создать список файлов указанной директории, с указанием размеров каждого файла и датой последнего обращения к файлу. Полученную информацию записать в файл statistic_files.txt.
4 В выбранном файле подсчитать кол-во ссылок, таблиц и рисунков. Отчет должен содержать:
1 Название и цель работы.
2 Ход работы с детальным описанием выполненных действий с рисунками, листингом кода.
3 Экранные формы браузера с загруженными страницами.
4 Выводы о проделанной работе.
Вопросы для подготовки к защите работы:
1 Какие вы знаете функции для работы со строками?
2 Как открыть файл на чтение, для записи в начало, для записи в конец
3 Функциям работы с директориями?
4 Обработка ошибок при подключении к файлам?
Лабораторная работа №3
Разработка приложений БД на cервере MySQL с помощью PHP
Цель работы: изучить настройки сервера БД MySQL, возможности подключения к БД с помощью PHP
Краткие теоретические сведения
MySQL - это реляционная система управления базами данных. То есть данные в ее базах хранятся в виде логически связанных между собой таблиц, доступ к которым осуществляется с помощью языка запросов SQL. MySQL - свободно распространяемая система Кроме того, это достаточно быстрая, надежная и простая в использовании СУБД, вполне подходящая для не слишком глобальных проектов. Работать с MySQL можно в текстовом режиме (рис. 3.1), и в графическом (рис. 3.2). Существует очень популярный визуальный интерфейс (написанный на PHP) для работы с этой СУБД - называется PhpMyAdmin. Этот интерфейс позволяет значительно упростить работу с базами данных в MySQL. В текстовом режиме работа с базой данных выглядит просто как ввод команд в командную строку, а результаты выборок возвращаются в виде своеобразных таблиц, поля в которых налезают друг на друга, если данные не помещаются на экран .
Рисунок 3.1 - Работа с MySQL в коммандной строке. Команда show databases - вывести все имеющиеся базы данных
PhpMyAdmin позволяет пользоваться всеми достоинствами браузера, включая прокрутку изображения, если оно не умещается на экран. Многие из базовых SQL-функций работы с данными в PhpMyAdmin сведены к интуитивно понятным интерфейсам и действиям, напоминающим переход по ссылкам в Internet.
Сервер MySQL очень распространен и часто используется в Веб-технологиях. На этом сервере базируются большинство сайтов и решений в Интернете.
По настройке сервера MySQL можно посмотреть здесь: http://www.netbeans.org/kb/docs/ide/install-and-configure-mysql-server_ru.html
Пример:
1 Для создания новой БД на сервере (http://localhost/denwer/) выбрать ссылку: phpMyAdmin - администрирование СУБД MySQL :
Рисунок 3.2 - Страница phpMyAdmin 2 Создать таблицу в БД, например для хранения информации о кофе (info_coffee)
Рисунок 3.3 - Создание таблицы
3 Создать набор полей, указать типы данных, размер текстовых полей. Если необходимо указать "auto_increment" для ключевого поле (предварительно его создав - primary key)
Рисунок 3.3 - Создание набора полей
Нажать "Сохранить"
4 Для добавления данных нажать "Вставить":
Рисунок 3.4 - Созданная структура таблицы "info_coffee"
Рисунок 3.5 - Добавление записей в таблицу
Для просмотра всех записей нажать "Обзор":
Рисунок 3.6 - Просмотр всех записей
Взаимодействие PHP и MySQL
Чтобы построить интерфейс для добавления информации в эту таблицу, нужно ее структуру (т.е. набор ее полей) отобразить в html-форму.
Разобьем эту задачу на следующие подзадачи:
* установка соединения с БД;
* выбор рабочей БД;
* получение списка полей таблицы;
* отображение полей в html-форму.
После этого данные, введенные в форму, нужно записать в базу данных. Рассмотрим все эти задачи по порядку.
Установка соединения
Итак, первое, что нужно сделать, - это установить соединение с базой данных. Воспользуемся функцией mysql_connect:
ресурс mysql_connect ( [строка server [, строка username [, строка password
[, логическое new_link [, целое client_flags]]]]])
Данная функция устанавливает соединение с сервером MySQL и возвращает указатель на это соединение или FALSE в случае неудачи. Для отсутствующих параметров устанавливаются следующие значения по умолчанию:
server = 'localhost:3553' (если по умолчанию используется порт 80, то ничего указывать не нужно)
username = имя пользователя владельца процесса сервера (по умолчанию root)
password = пустой пароль <?
$conn = mysql_connect("localhost", "root","")
or die("Невозможно установить соединение: ". mysql_error());
echo "Соединение установлено";
mysql_close($conn);
?>
Соединение с сервером закрывается при завершении исполнения скрипта, если оно до этого не было закрыто с помощью функции mysql_close().
Выбор базы данных
После установки соединения нужно выбрать базу данных, с которой будем работать. Наши данные хранятся в базе данных coffee.В PHP для этого существует функция mysql_select_db. Синтаксис mysql_select_db:
логическое mysql_select_db (строка database_name[, ресурс link_identifier])
Эта функция возвращает TRUE в случае успешного выбора базы данных и FALSE - в противном случае.
mysql_select_db("coffee");
Получение списка полей таблицы
Как получить список полей таблицы? В PHP есть своя команда - mysql_list_fields.
Синтаксис mysql_list_fields
ресурс mysql_list_fields ( строка database_name, строка table_name [, ресурс link_identifier])
Эта функция возвращает список полей в таблице table_name в базе данных database_name. Результат работы этой функции - переменная типа ресурс. Это ссылка, которую можно использовать для получения информации о полях таблицы, включая их названия, типы и флаги.
Функция mysql_field_name возвращает имя поля, полученного в результате выполнения запроса. Функция mysql_field_len возвращает длину поля. Функция mysql_field_type возвращает тип поля, а функция mysql_field_flags возвращает список флагов поля, записанных через пробел. Типы поля могут быть int, real, string, blob и т.д. Флаги могут быть not_null, primary_key, unique_key, blob, auto_increment и т.д.
Синтаксис у всех этих команд одинаков:
строка mysql_field_name ( ресурс result, целое field_offset)
строка mysql_field_type ( ресурс result, целое field_offset)
строка mysql_field_flags (ресурс result, целое field_offset)
строка mysql_field_len ( ресурс result, целое field_offset)
Здесь result - это идентификатор результата запроса (например, запроса, отправленного функциями mysql_list_fields или mysql_query, а field_offset - порядковый номер поля в результате.
То, что возвращают функции типа mysql_list_fields или mysql_query, представляет собой таблицу, а точнее, указатель на нее. Чтобы получить из этой таблицы конкретные значения, нужно задействовать специальные функции, которые построчно читают эту таблицу. К таким функциям и относятся mysql_field_name и т.п. Чтобы перебрать все строки в таблице результата выполнения запроса, нужно знать число строк в этой таблице. Команда mysql_num_rows(ресурс result) возвращает число строк во множестве результатов result.
А теперь попробуем получить список полей таблицы info_coffee (коллекция экспонатов).
<? $conn = mysql_connect("localhost","root","")
or die("Невозможно установить соединение: ". mysql_error());
echo "Соединение установлено";
mysql_select_db("info_coffee");
$list_f = mysql_list_fields ("coffee","info_coffee",$conn);
$n = mysql_num_fields($list_f);
for($i=0;$i<$n; $i++){
$type = mysql_field_type($list_f, $i);
$name_f = mysql_field_name($list_f,$i);
$len = mysql_field_len($list_f, $i);
$flags_str = mysql_field_flags (
$list_f, $i);
echo "<br>Имя поля: ". $name_f;
echo "<br>Тип поля: ". $type;
echo "<br>Длина поля: ". $len;
echo "<br>Строка флагов поля: ".
$flags_str . "<hr>";
}
?>
Создадим форму для наполнения БД:
<form action=insert.php method=post>
введите название <input type=text name=name_c> <br>
введите цену <input type=text name=price_c> <br>
выберите фирму <select name=firma_c> <option> nescafe
<option> jacobs
<option> tchibo
</select>
<br><input type=submit name=ok value=insert_c>
</form>
Теперь нужно сделать самое главное - отправить данные из этой формы в нашу базу данных. Как вы уже знаете, для того чтобы записать данные в таблицу, используется команда INSERT языка SQL. Например:
mysql> INSERT INTO info_coffee SET name='Черная карта арабика';
Возникает вопрос, как можно воспользоваться такой командой (или любой другой командой SQL) в PHP скрипте. Для этого существует функция mysql_query().
Синтаксис mysql_query:
ресурс mysql_query (строка query [, ресурс link_identifier])
mysql_query() посылает SQL-запрос активной базе данных MySQL сервера, который определяется с помощью указателя link_identifier (это ссылка на соединение с сервером MySQL). Если параметр link_identifier опущен, используется последнее открытое соединение. Если открытые соединения отсутствуют, функция пытается соединиться с СУБД, аналогично функции mysql_connect() без параметров. Результат запроса буферизируется.
Insert.php
<?php
$name=$_REQUEST["name_c"];
$price=$_REQUEST["price_c"];
$firma=$_REQUEST["firma_c"];
$db=mysql_connect(localhost,'root','');
mysql_select_db("Coffee");
if ($but=insert_c) {$sql1="INSERT INTO name_coffee VALUES('','$name','$price','$firma')";
mysql_query($sql1);
}
print "Кофе $name $firma добавлено";
?>
poisk.php
$a=$_REQUEST["price_c"];
{print " кофе по цене < $a грн: <br>"; }
$conn=mysql_connect(localhost,'root','');
mysql_select_db("Coffee");
$sql="SELECT * FROM info_coffee where price=".$a;
$result=mysql_query($sql);
for ($i=1; $i<=mysql_num_rows($result);$i++)
{$row=mysql_fetch_object($result);
print "Кофе $row->name $row->firma стоит $row->price грн. <br>";
}
Предварительно была создана форма для ввода цены кофе, которое необходимо найти:
<form action=poisk.php method=post>
введите цену <input type=text name=price_c> <br>
<input type=submit name=ok value=search>
</form>
Примечание. БД и таблицы хранятся на сервере по следующему пути: Webserver\usr\local\mysql5\data\coffee
Задание к работе:
1 Ознакомиться с теоретическим материалом.
2 Создать БД согласно варианту (предметную область взять из табл. 2)
3 Разработать структуру таблиц
4 Создать скрипт на php для просмотра записей таблиц, поиска по критерию, добавления информации, удаления записей и изменения информации
5 Оформить отчет согласно требованиям.
Таблица 2 - Индивидуальное задание
1 Каталог напитков2 Номенклатура оборудования3 Каталог медицинских препаратов4 Каталог аудио дисков5 Каталог продуктов питания6 Каталог автомобилей7 Каталог бытовых приборов8 Каталог осветительных приборов9 Каталог оборудования на складе10 Каталог компьютерного оборудования: процессоры и материнские платы Отчет должен содержать:
1 Название и цель работы.
2 Ход работы с детальным описанием выполненных действий с рисунками, листингом кода.
3 Экранные формы браузера с загруженными страницами.
4 Выводы о проделанной работе.
Вопросы для подготовки к защите работы:
1 Взаимодействия PHP и СУБД MySql
2 Как происходит установка соединения с базой данных
3 Функциям отправки запросов и обработке ответов
4 Обработка ошибок при подключении к БД
Лабораторная работа №4
Разработка сайта с использованием MVC фреймворка
Цель работы: получить практические разработки модулей приложений с помощью Фреймворка CodeIgniter.
Теоретические сведения
MVC Фреймворк
Model-view-controller (Паттерн модель-представление-контроллер) используется очень давно. Еще в 1979 году его описал Тригве Реенскауг в своей работе "Разработка приложений на Smalltalk-80: как использовать Модель-представление-контроллер". С тех пор паттерн зарекомендовал себя как очень удачная архитектура программного обеспечения.
Пользователь, работая с интерфейсом, управляет контроллером, который перехватывает действия пользователя. Далее контроллер уведомляет модель о действиях пользователя, тем самым изменяя состояние модели. Контроллер также уведомляет представление. Представление, используя текущее состояние модели, строит пользовательский интерфейс.Основой паттерна является отделение модели данных приложения, его логики и представления данных друг от друга. Таким образом, следуя правилу "разделяй и властвуй", удается строить стройное программное обеспечение, в котором, во-первых, модель не зависит от представления и логики, а во-вторых, пользовательский интерфейс надежно отделен от управляющей логики.
На данный момент паттерн MVC реализован в том или ином виде для большинства языков программирования используемых для разработки web-приложений. Самое большое количество реализаций имеет PHP, но и для Java, Perl, Python, Ruby есть свои варианты. "M" или модель - часть MVC-системы, которая отвечает за запросы к базе данных (или другому внешнему источнику) и предоставление информации контроллеру. Можно было бы загружать необходимую модель в зависимости от запроса, но возможно немного стереть границы между моделью и контроллером, т.е. контроллер работает с БД непосредственно через библиотеку взаимодействия с БД, нежели чем через отдельную модель. Codeigniter CodeIgniter - открытый фреймворк написанный на PHP для разработки полноценных веб-систем и приложений. Разработан компанией EllisLab, а также Риком Эллисом (Rick Ellis) и Полом Бурдиком (Paul Burdick).
Фреймворк - это готовый каркас для приложений, которые будут строиться на его основе. В этот каркас включены наиболее часто используемые библиотеки. Можно при написании каждого нового приложения изобретать велосипед с распределением его основных модулей, структурой директорий, классами обработки основных компонентов и т.п., а можно воспользоваться готовым универсальным решением.
CodeIgniter является инструментарием для тех, кто строит веб-приложения на PHP. Его цель в том, чтобы позволить вам разрабатывать приложения быстрее, чем если бы вы писали код с нуля, предоставляя богатый набор библиотек для часто используемых задач, а также простой интерфейс и логическую структуру для доступа к этим библиотекам. CodeIgniter позволяет творчески сосредоточиться на ваших проектах, используя минимальный объема кода, необходимый для той или иной задачи.
CodeIgniter обладает рядом значительных плюсов перед другими веб-фреймворками, например: * используется модель MVC (Модель-Отображение-Контроллер), хорошо зарекомендовавшая себя при разработке приложений самой разной направленности;
* поддерживается множество баз данных (MySQL, PostgreSQL, MSSQL, SQLite, Oracle);
* отлично написанная документация с примерами позволит быстро освоить фреймворк;
* CodeIgniter очень быстр в работе. Его считают эталоном скорости генерации страниц.
Пример - разработка с помощью CodeIgniter простого приложения вывода строки приветствия
Создание контроллера welcome.php:
<?php
class Welcome extends Controller {
function Welcome()
{
parent::Controller();
$this->load->model('User_model', 'users'); // указание подключаемой модели
}
function index()
{
$this->load->view(welcome_message'); // указание файла отображения приветствия codeigniter
}
function say_hello($id=1) {
$data['name'] = $this->users->name($id);
$this->load->view('hello', $data); // указание файла отображения views и данных
}
}
Создание модели user_model.php:
<?php
class User_model extends Model {
function name($key) {
$names = $this->names();
return $names[$key];
}
function names() {
return array(1 => "Admin", 2 => "User"); // в зависимости от переданного параметра будет } вывод имени соответствующего пользователя }
?>
Создание view hello.php:
<html>
<head>
<title>Welcome to CodeIgniter</title> </head>
<body>
<h1><font color=red> Hello, <?=$name?></h1>
</body>
</html>
Запуск приложения:
Задание к работе:
1 Ознакомиться с теоретическим материалом.
2 Создать приложение согласно варианту (использовать элементы из таблицы 1 первого задания)
3 Разработать структуру приложения
4 Создать скрипт на php для ввода и выдачи результата, используя MVC 5 Оформить отчет согласно требованиям.
Отчет должен содержать:
1 Название и цель работы.
2 Ход работы с детальным описанием выполненных действий с рисунками, листингом кода.
3 Экранные формы браузера с загруженными страницами.
4 Выводы о проделанной работе.
Вопросы для подготовки к защите работы:
1 Особенности реализация взаимодействия модулей согласно концепции MVC
2 Структура фреймфорка
3 Особенности существующих фреймворков для php.
Лабораторная работа №5
Работа с таблицами БД с использованием MVC фреймворка
Цель работы: получить практические разработки модулей приложений с помощью фреймворка CodeIgniter для разработки каталога.
Теоретические сведения
Использование хелперов:
* Хелперы, как говорит их название, помогают в решении задач разработчика. Каждый файл с хелперами - это простая коллекция функций в той или иной категории.
* URL Хелперы - помогают создавать ссылки,
* Хелперы форм - помогают создать элементы форм
* Текстовые хелперы - выполняют различные функции по форматированию текста .....
* Если нужно загрузить более одного хелпера, можно перечислить их в одном массиве:
$this->load->helper( array('helper1', 'helper2', 'helper3') );
* Авто-загрузка хелперов - если необходим хелпер для всего приложения, можно указать CodeIgniter, чтобы он загружал его при инициализации приложения. В файле application/config/autoload.php добавить хелпер в массив автозагрузки:
$autoload['helper'] = array('url'); Пример:
Структура приложения:
* Controllers:
admin.php
* Models:
-blog_model.php
-user_model.php
-post_model.php
* Views:
Content, например View/post.php
<div>
<div style="color:blue"><?=$this->session->flashdata('info')?></div>
<table border="1">
<tr> <td> Id </td> <td> Id_user </td> <td> post_name </td> <td> post_data </td><td> post_delete</td> </tr>
<?php foreach($posts as $post):?> <tr>
<td><?=$post->id_post?></td>
<td><?=$post->first_name?></td>
<td><?=$post->contents?></td> <td><?=$post->created_at?></td>
<td><?=anchor("admin/delete_post/$post->id", "delete")?></td>
</tr>
<?php endforeach; ?>
</table>
</div>
View/Profiles.php
<div>
<div style="color:blue"><?=$this->session->flashdata('info')?></div>
<table border="1">
<tr><th>Id:</th><td><?=$profile->id?></td></tr>
<tr><th>First name:</th><td><?=$profile->first_name?></td></tr>
<tr><th>Last name:</th><td><?=$profile->last_name?></td></tr>
<tr><th>Nick:</th><td><?=anchor("admin/edit_profile", $profile->nick)?></td>
</tr>
<tr><th>E-mail:</th><td><?=$profile->email?></td></tr>
</table>
</div>
Controller/admin.php
<?php
class Admin extends Controller {
function Admin()
{ parent::Controller();
$this->load->model('Blog_model', 'blog');
$this->load->model('User_model', 'user');
$this->load->model('Post_model', 'post');
$this->load->helper(array('form', 'text', 'admin'));}
function index()
{ redirect("admin/settings"); }
function settings() {
$data['settings'] = $this->blog->current();
$this->_render('settings', $data); }
function profile() {
$data['profile'] = $this->user->current(); // Обращение к модели, вызов функции
$this->_render('profiles', $data); } // имя view
function post() {
$data['posts'] = $this->post->all();
$this->_render('posts', $data); }
function edit_profile() {
$this->form_validation->set_rules('profile[first_name]', 'First name', 'required');
$this->form_validation->set_rules('profile[last_name]', 'Last name', 'required');
$this->form_validation->set_rules('profile[nick]', 'Nick', 'required');
if ($this->form_validation->run() == FALSE) {
$this->session->set_flashdata('info', "Profile not saved!");
$data['profile'] = $this->user->current();
$this->_render('edit_profile', $data); }
else { $this->user->edit_profile($this->input->post('profile')); // Обращение к модели, вызов функции edit_profile. Передача данных по методу post
$this->session->set_flashdata('info', "Provile saved!");
redirect('admin/profile'); } }
Задание на работу:
Используя MVC фреймворк выполнить следующее:
1 Разработать модуль авторизации пользователей
2 Выполнить валидацию данных 3 Реализовать crud операции (create, read, update, delete) над основными сущностями предметной области Лабораторная работа №6
Прототипирование веб-сайта с использованием технологий "классического" PHP и шаблонизатора Smarty Цель работы: получить практические навыки развертывания и базовой настройки АМР-платформы, выполнить прототипирование фронт-энд и бэк-энд модулей веб-сайта с использованием методик классического php и шаблонизатора Smarty.
Теоретические сведения
Виртуальная платформа AMP = Apache + MySQL + PHP. АМР это не совсем платформа, скорее среда выполнения. Но под неё написано большинство WEB-приложений. Поэтому решено, что AMP - это платформа для WEB-приложений. На AMP работают CMS, различные движки блогов, Интернет магазинов, такие как Joomla, WordPress. Все WEB приложения работают в определённой среде, необязательно AMP, это может быть и среда Tomcat, GlassFish, JBoss при использовании Java.
Apache является кроссплатформенным ПО, поддерживая операционные системы GNU/Linux, BSD, Mac OS, Microsoft Windows, Novell NetWare, BeOS.
Веб-сервер Apache
Основными достоинствами Apache считаются надёжность и гибкость конфигурации. Он позволяет подключать внешние модули для предоставления данных, использовать СУБД для аутентификации пользователей, модифицировать сообщения об ошибках и т. д. Поддерживает IPv6.
Недостатком наиболее часто называется отсутствие удобного стандартного интерфейса для администратора. Веб-сервер Apache разрабатывается и поддерживается открытым сообществом разработчиков под эгидой Apache Software Foundation и включён во многие программные продукты, среди которых СУБД Oracle и IBM WebSphere.
С апреля 1996 и до настоящего времени является самым популярным HTTP-сервером в Интернете. Ядро Apache включает в себя основные функциональные возможности, такие как обработка конфигурационных файлов, протокол HTTP и система загрузки модулей. Ядро (в отличие от модулей) полностью разрабатывается Apache Software Foundation, без участия сторонних программистов. Теоретически, ядро apache может функционировать в чистом виде, без использования модулей. Однако, функциональность такого решения крайне ограничена.
Ядро Apache полностью написано на языке программирования C.
Система конфигурации Apache основана на текстовых конфигурационных файлах. Имеет три условных уровня конфигурации:
* Конфигурация сервера (httpd.conf).
* Конфигурация виртуального хоста (httpd.conf c версии 2.2 extra/httpd-vhosts.conf).
* Конфигурация уровня директории (.htaccess).
Имеет собственный язык конфигурационных файлов, основанный на блоках директив. Практически все параметры ядра могут быть изменены через конфигурационные файлы, вплоть до управления MPM. Большая часть модулей имеет собственные параметры.
Часть модулей использует в своей работе конфигурационные файлы операционной системы (например /etc/passwd и /etc/hosts). Помимо этого, параметры могут быть заданы через ключи командной строки.
Apache HTTP Server поддерживает модульность. Существует более 400 модулей, выполняющих различные функции. Часть из них разрабатывается командой Apache Software Foundation, но основное количество - отдельными open source-разработчиками. Модули могут быть как включены в состав сервера в момент компиляции, так и загружены динамически, через директивы конфигурационного файла.
В модулях реализуются такие вещи, как:
* Поддержка языков программирования.
* Добавление функционала.
* Исправление ошибок или модификация основных функций.
* Усиление безопасности.
Apache имеет встроенный механизм виртуальных хостов. Он позволяет полноценно обслуживать на одном IP адресе множество сайтов (доменных имен), отображая для каждого из них собственное содержимое. Для каждого виртуального хоста можно указать собственные настройки ядра и модулей, ограничить доступ ко всему сайту или отдельным файлам. Также, существуют модули, позволяющие учитывать и ограничивать ресурсы сервера (CPU, RAM, трафик) для каждого виртуального хоста.
Существует множество модулей, добавляющих к Apache поддержку различных языков программирования и систем разработки.К ним относятся:
* PHP (mod_php).
* Python (mod_python).
* Ruby (apache-ruby).
* Perl (mod_perl).
* ASP (apache-asp). Кроме того, Apache поддерживает механизмы CGI и FastCGI, что позволяет исполнять программы на практически всех языках программирования, в том числе C, C++, sh, Perl и Java.
Apache имеет различные механизмы обеспечения безопасности и разграничения доступа к данным. Основными являются:
* Ограничение доступа к определенным директориям или файлам.
* Механизм авторизации пользователей для доступа к директории по методу HTTP-Авторизации (mod_auth_basic) и digest-авторизации (mod_auth_digest).
* Ограничение доступа к опеределенным директориям или всему серверу, основанное на IP адресах пользователей.
* Запрет доступа к определенным типам файлов для всех или части пользователей, например запрет доступа к конфигурационным файлам и файлам баз данных.
* Существуют модули, реализующие авторизацию через СУБД Для реализации шифрования данных, передающихся между клиентом и сервером используется механизм SSL, реализованный через библиотеку OpenSSL.
Сервер БД MySQL
Сервер MySQL очень распространен и часто используется в Веб-технологиях. На этом сервере базируются большинство сайтов и решений в Интернете.
По настройке сервера MySQL можно посмотреть здесь: http://www.netbeans.org/kb/docs/ide/install-and-configure-mysql-server_ru.html
Для создания новой БД на сервере (http://localhost/denwer/) выбрать ссылку: phpMyAdmin - администрирование СУБД MySQL :
1 2
3
4 Для добавления данных нажать "Вставить":
Для просмотра всех записей нажать "Обзор".
Язык PHP
Язык PHP был разработан как инструмент для решения чисто практических задач. Его создатель, Расмус Лердорф, хотел знать, сколько человек читают его online-резюме, и написал для этого простенькую CGI-оболочку на языке Perl, т.е. это был набор Perl-скриптов, предназначенных исключительно для определенной цели - сбора статистики посещений.
CGI (Common Gateway Interface - общий интерфейс шлюзов) является стандартом, который предназначен для создания серверных приложений, работающих по протоколу HTTP. Такие приложения (их называют шлюзами или CGI-программами) запускаются сервером в режиме реального времени. Сервер передает запросы пользователя CGI-программе, которая их обрабатывает и возвращает результат своей работы на экран пользователя. Таким образом, посетитель получает динамическую информацию, которая может изменяться в результате влияния различных факторов. Сам шлюз (скрипт CGI) может быть написан на различных языках программирования - Cи/C++, Fortran, Perl, TCL, UNIX Shell, Visual Basic, Python и др.
Вскоре выяснилось, что оболочка обладает небольшой производительностью, и пришлось переписать ее заново, но уже на языке Си. После этого исходники были выложены на всеобщее обозрение для исправления ошибок и дополнения. Пользователи сервера, где располагался сайт с первой версией PHP, заинтересовались инструментом, появились желающие его использовать. Так что скоро PHP превратился в самостоятельный проект, и в начале 1995 года вышла первая известная версия продукта, называвшаяся Personal Home Page Tools (средства для персональной домашней страницы). Средства эти были более чем скромными: анализатор кода, понимающий всего лишь несколько специальных команд, и набор утилит, полезных для создания гостевой книги, счетчика посещений, чата и т.п.
PHP 3.0 была первой версией, напоминающей PHP, каким мы знаем его сегодня. Он очень сильно отличался от PHP/FI 2.0 и появился опять же как инструмент для решения конкретной прикладной задачи. Его создатели, Энди Гутманс (Andi Gutmans) и Зив Сураски (Zeev Suraski), в 1997 году переписали заново код PHP/FI, поскольку он показался им непригодным для разработки приложения электронной коммерции, над которым они работали. Для того чтобы получить помощь в реализации проекта от разработчиков PHP/FI, Гутманс и Сураски решили объединиться с ними и объявить PHP3 официальным преемником PHP/FI. После объединения разработка PHP/FI была полностью прекращена. Одной из сильных сторон PHP 3.0 была возможность расширения ядра. Именно свойство расширяемости PHP 3.0 привлекло внимание множества разработчиков, желающих добавить свой модуль расширения. Кроме того, PHP 3.0 предоставляла широкие возможности для взаимодействия с базами данных, различными протоколами и API. Немаловажным шагом к успеху оказалась разработка нового, намного более мощного и полного синтаксиса с поддержкой ООП. С момента появления PHP 3.0 изменилась не только функциональность и внутреннее устройство языка, но и его название. В аббревиатуре PHP больше не было упоминания о персональном использовании, PHP стало сокращением (рекурсивным акронимом) от PHP: Hypertext Preprocessor, что значит "PHP: препроцессор гипертекста". PHP 4.0, основанный на этом ядре и принесший с собой набор дополнительных функций, официально вышел в мае 2000 года, почти через два года после своего предшественника, PHP 3.0. Помимо улучшения производительности, PHP 4.0 имел еще несколько ключевых нововведений, таких как поддержка сессий, буферизация вывода, более безопасные способы обработки вводимой пользователем информации и несколько новых языковых конструкций. В настоящее время ведутся работы по улучшению Zend Engine и внедрению нововведений в PHP 5.0, первые бета-версии которого уже вышли в свет. Одно из существенных изменений произошло в объектной модели языка, ее основательно подлатали и добавили много новых возможностей. Сегодня PHP используется сотнями тысяч разработчиков. Несколько миллионов сайтов написаны на PHP
Возможности PHP
"PHP может все", - заявляют его создатели. В первую очередь PHP используется для создания скриптов, работающих на стороне сервера, для этого его, собственно, и придумали. PHP способен решать те же задачи, что и любые другие CGI-скрипты, в том числе обрабатывать данные html-форм, динамически генерировать html страницы и т.п. Но есть и другие области, где может использоваться PHP. Всего выделяют три основные области применения PHP. * Первая область, как уже говорилось, - это создание приложений (скриптов), которые исполняются на стороне сервера. PHP наиболее широко используется именно для создания такого рода скриптов. Для того чтобы работать таким образом, понадобится PHP-парсер (т.е. обработчик php-скриптов) и web-сервер для обработки скрипта, браузер для просмотра результатов работы скрипта, ну, и, конечно, какой-либо текстовый редактор для написания самого php-кода. Парсер PHP распространяется в виде CGI-программы или серверного модуля. Как установить его и web-сервер на свой компьютер, мы рассмотрим немного позднее. В этом курсе мы будем обсуждать, как правило, создание именно серверных приложений, как пример использования языка PHP. * Вторая область - это создание скриптов, выполняющихся в командной строке. То есть с помощью PHP можно создавать такие скрипты, которые будут исполняться, вне зависимости от web-сервера и браузера, на конкретной машине. Для такой работы потребуется лишь парсер PHP (в этом случае его называют интерпретатором командной строки (cli, command line interpreter)). Этот способ работы подходит, например, для скриптов, которые должны выполняться регулярно с помощью различных планировщиков задач или для решения задач простой обработки текста. * И последняя область - это создание GUI-приложений (графических интерфейсов), выполняющихся на стороне клиента. В принципе это не самый лучший способ использовать PHP, особенно для начинающих, но если вы уже досконально изучили PHP, то такие возможности языка могут оказаться весьма полезны. Для применения PHP в этой области потребуется специальный инструмент - PHP-GTK, который является расширением PHP. Итак, область применения PHP достаточно обширна и разнообразна. Тем не менее существует множество других языков программирования, способных решать похожие задачи. Почему стоит изучать PHP? Что это нам дает? Во-первых, PHP очень прост в изучении. Достаточно ознакомиться лишь с основными правилами синтаксиса и принципами его работы, и можно начинать писать собственные программы, причем браться за такие задачи, решение которых на другом языке требовало бы серьезной подготовки. Во-вторых, PHP поддерживается почти на всех известных платформах, почти во всех операционных системах и на самых разных серверах. Это тоже очень важно. Вряд ли кому-то захочется переходить, например, от работы под Windows к работе под Linux или от сервера IIS к серверу Apache только для того, чтобы изучить еще один язык программирования. В PHP сочетаются две самые популярные парадигмы программирования - объектная и процедурная. В PHP4 более полно поддерживается процедурное программирование, но есть возможность писать программы и в объектном стиле. Уже в первых пробных версиях PHP5 большинство недочетов в реализации объектно-ориентированной модели языка, существующих в PHP4, устранены. Таким образом, можно выбрать наиболее привычный стиль работы. Проверим, работает ли PHP в используемом пакете Denver. Для этого создадим тестовый файл (1.php) в директории пользователя (c:\Webserver\home\localhost\www) со следующим содержанием: <?php
echo"<h1>Hello!</h1>";
?>
Запустим этот файл через браузер, набрав http://localhost/1.php. Если что-то не так, то на экран будет выведен текст этого файла. Если все хорошо, то наш скрипт должен обработаться сервером и вывести большими буквами строку "Hello!". Рассмотрим пример. <html>
<head>
<title>Пример</title>
</head>
<body>
<?php echo "<p>Привет, я - скрипт PHP!</p>"; ?>
</body>
</html> Это простой HTML-файл, в который встроен с помощью специальных тегов код, написанный на языке PHP. PHP похож на Cи. Однако приведенная здесь программа сильно отличается от аналогичных по смыслу программ на языке Cи. Здесь не нужно писать кучу специальных команд для вывода HTML. Пишется непосредственно HTML-скрипт, в который можно встраивать PHP-код, осуществляющий какие-либо действия (например, выводящий текст на экран, как в нашем примере). Недостатком PHP по сравнению с Cи, несмотря на все усилия разработчиков, все еще является недостаточная быстрота выполнения сложных скриптов. PHP-скрипты - это программы, которые выполняются и обрабатываются сервером. Так что сравнивать его со скриптовыми языками типа JavaScript невозможно, потому что написанные на них скрипты выполняются на машине клиента. В чем отличие скриптов, выполняемых на сервере и на клиенте? Если скрипт обрабатывается сервером, клиенту посылаются только результаты работы скрипта. Например, если на сервере выполнялся скрипт, подобный приведенному выше, клиент получит сгенерированную HTML-страницу вида: <html>
<head>
<title>Пример</title>
</head>
<body>
<p>Привет, я - скрипт PHP!</p> </body>
</html> PHP-скрипты встраиваются в HTML-код. Возникает вопрос, каким образом? Есть несколько способов. Один из них приведен в самом первом примере - с помощью открывающего тега <?php и закрывающего тега ?>. Такого вида специальные теги позволяют переключаться между режимами HTML и PHP. Этот синтаксис наиболее предпочтителен, поскольку позволяет задействовать PHP в XML-совместимых программах (например, написанных на языке XHTML), но тем не менее можно использовать следующие альтернативные варианты (команда echo "Some text"; выводит на экран текст "Some text".): 1. <? echo "Это простейшая инструкция для обработки PHP"; ?>
2. <script language="php"> echo "Некоторые редакторы (FrontPage) предпочитают делать так";
</script>
3. <% echo "Можно использовать теги в стиле ASP "; %>
Первый из этих способов не всегда доступен. Чтобы им пользоваться, нужно включить короткие теги либо с помощью функции short_tags() для PHP 3, либо включив установку short_open_tag в конфигурационном файле PHP, либо скомпилировав PHP с параметром --enable-short-tags. Даже если это включено по умолчанию в php.ini-dist, использование коротких тегов не рекомендуется. Второй способ аналогичен вставке, например, JavaScript-кода и использует для этого соответствующий html тег. Поэтому использовать его можно всегда, но это делается редко из-за его громоздкости. Третий способ можно применить, только если теги в стиле ASP были включены, используя конфигурационную установку asp_tags.
Задание на работу:
4 Выполнить настройку АМР-платформы: установить пакет, состоящий из приложений - сервера Apache, сервера баз данных MySQL, интерпретатора PHP (возможна установка существующий пакетов Denver, XAMP, WAMP и т.д.)
5 Рассмотреть параметры основных файлов конфигурации веб-сервера Apache http.conf и интерпретатора php php.ini, выполнить настройку сервера Appach для работы web-приложений
6 На основе сформированного списка задач в лабораторной работе 1 выполнить следующее:
* реализовать crud операции (create, read, update, delete) над выбранной сущностью предметной области (моделью) в бэк-энд модуле приложении, используя возможности "классического" php; * реализовать две задачи из составленного списка задач во front-end части веб-приложения, используя возможности шаблонизатора Smarty. Лабораторная работа №7
Использование Ajax и JS библиотек
Цель работы: получить практические разработки приложений с использованием технологии Ajax и JS библиотек Теоретические сведения
AJAX означает "Asynchronous JavaScript and XML", т.е. Асинхронный JavaScript и XML. В действительности AJAX состоит из JavaScript, как и любое другое приложение, и соединения XMLHTTP с Web-сервером. Вот и все! Общая идея заключается в том, что можно извлекать с сервера данные просто по мере необходимости, не обновляя всю страницу.
Прежде всего AJAX почти всегда опирается на серверный язык, такой, как PHP или ASP. Когда пользователю необходимо получить новые данные, JavaScript запрашивает их, а сервер, вероятно, запросит базу данных и затем вернет данные. Эти данные можно вернуть в различной форме. Если они структурированы, то это будут обычно данные XML или JSON. Если это очень простые данные (такие, как получение описания какого-то объекта), то можно часто увидеть людей, которые просто записывают эти данные непосредственно в ответ AJAX.
Приложения AJAX могут выполняться только в Web-браузерах с поддержкой XML.
Поддержка AJAX браузерами
Приложения AJAX могут выполняться только в Web-браузерах с полной поддержкой XML, т.е. всеми основными современными браузерами. Предыдущий пример вызывает функцию с именем GetXmlHttpObject.
Эта функция предназначена для решения проблемы создания различных объектов XMLHTTP для различных браузеров. Функция имеет следующий код:
function GetXmlHttpObject(handler)
{ var objXMLHttp=null
if (window.XMLHttpRequest)
{
objXMLHttp=new XMLHttpRequest()
}
else if (window.ActiveXObject)
{
objXMLHttp=new ActiveXObject("Microsoft.XMLHTTP")
}
return objXMLHttp
}
. Страница HTML для примера AJAX
Эта страница HTML содержит простую форму HTML и ссылку на файл JavaScript.
<html>
<head>
<script src="clienthint.js"></script> </head>
<body>
<form> Имя:
<input type="text" id="txt1"
onkeyup="showHint(this.value)">
</form>
<p>Советуем: <span id="txtHint"></span></p> </body>
</html>
Код JavaScript приложения AJAX
Это код JavaScript, который находится в файле "clienthint.js":
var xmlHttp
function showHint(str)
{
if (str.length==0)
{ document.getElementById("txtHint").innerHTML=""
return
}
xmlHttp=GetXmlHttpObject()
if (xmlHttp==null)
{
alert ("Браузер не поддерживает запросы HTTP")
return
} var url="gethint.asp"
url=url+"?q="+str
url=url+"&sid="+Math.random()
xmlHttp.onreadystatechange=stateChanged xmlHttp.open("GET",url,true)
xmlHttp.send(null)
} function stateChanged() { if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
{ document.getElementById("txtHint").innerHTML=xmlHttp.responseText } } function GetXmlHttpObject()
{ var objXMLHttp=null
if (window.XMLHttpRequest)
{
objXMLHttp=new XMLHttpRequest()
}
else if (window.ActiveXObject)
{
objXMLHttp=new ActiveXObject("Microsoft.XMLHTTP")
}
return objXMLHttp
} Далее речь пойдет о серверной странице AJAX.
Серверные страницы AJAX для ASP и PHP
Сервера AJAX не существует. Страницы AJAX может обрабатывать любой сервер Интернет.
Пример AJAX на PHP
<?php
// Заполняем массив именами $a[]="Anna";
$a[]="Brittany";
$a[]="Cinderella";
$a[]="Diana";
$a[]="Eva";
$a[]="Fiona";
$a[]="Gunda";
$a[]="Hege";
$a[]="Inga";
$a[]="Johanna";
$a[]="Kitty";
$a[]="Linda";
$a[]="Nina";
$a[]="Ophelia";
$a[]="Petunia";
$a[]="Amanda";
$a[]="Raquel";
$a[]="Cindy";
$a[]="Doris";
$a[]="Eve";
$a[]="Evita";
$a[]="Sunniva";
$a[]="Tove";
$a[]="Unni";
$a[]="Violet";
$a[]="Liza";
$a[]="Elizabeth";
$a[]="Ellen";
$a[]="Wenche";
$a[]="Vicky";
//извлечение параметра q из URL
$q=$_GET["q"];
//поиск всех рекомендаций в массиве, если длина q>0
if (strlen($q) > 0)
{
$hint="";
for($i=0; $i<count($a); $i++)
{
if (strtolower($q)==strtolower(substr($a[$i],0,strlen($q))))
{
if ($hint=="")
{
$hint=$a[$i];
}
else
{
$hint=$hint." , ".$a[$i];
}
}
}
}
// Вывод "нет предложений", если рекомендаций не найдено // или вывод подходящих значений if ($hint == "")
{
$response="нет предложений";
}
else
{
$response=$hint;
}
//вывод ответа echo $response;
?>
Создание объекта XMLHttp
При создании запроса AJAX прежде всего необходимо создать объект XMLHTTP. Netscape/Firefox, Opera и другие браузеры имеют этот объект встроенным. Internet Explorer использует ActiveXObject. Поэтому мы создадим одну функцию для работы со всеми этими браузерами:
if(typeof(XMLHttpRequest)!='undefined'){
var getXMLHttpObj = function(){ return new XMLHttpRequest(); }
} else {
var getXMLHttpObj = function(){
var activeXObjects = ['Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0',
'Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP'];
for(var i=0; i<activeXObjects.length; i++){
try{
return new ActiveXObject(activeXObjects[i]);
}catch(err){}
}
}
}
Любой браузер, который поддерживает объект XMLHttpRequest, будет использовать этот встроенный объект. Internet Explorer 6 и более ранние версии будут использовать объект ActiveX XMLHttp компании Microsoft. Существует много различных версий этого объекта, поэтому мы попробуем их все, начиная с самого нового.
Теперь, когда мы имеем объект XMLHttp, можно разместить запрос на сервере:
var oXml = getXMLHttpObj();
oXml.open('GET', 'getData.php', true);
oXml.onreadystatechange = processingFunction;
oXml.send();
function processingFunction(){
if(oXml.readyState!=4) return; // запрос не выполнен // Результаты обрабатываются здесь. Подробнее дальше!
}
После создания объекта XMLHttp остается еще 4 дополнительных шага. Сначала определяются параметры соединения с помощью функции .open. Функция .open получает 3 аргумента: тип запроса, URL и флаг, который сообщает объекту, выполняться или нет асинхронно.
Первый аргумент, тип запроса, почти всегда будет GET или POST. Если извлекаются данные, то это будет обычно GET, а если отправляется форма с AJAX, то это часто будет POST.
Флаг асинхронности немного отличается почти от всего остального в JavaScript. Если этот флаг задан как false, то код продолжает выполняться, как и любой другой фрагмент кода, то есть он ожидает, пока объект XMLHttp завершит свою работу, прежде чем двигаться дальше. Однако, если этот флаг задан как true, то код продолжает делать то, что следует в коде после запроса. Когда состояние запроса изменяется, вызывается функция, которая определена в onreadystatechange.
В чем различие? Если флаг асинхронности задан как false, то браузер будет полностью заблокирован, пока обрабатывается запрос. Если запрошенные данные нужны в обязательном порядке для продолжения работы, то используйте это значение флага. Если флаг задан как true, то пользователь может продолжать использовать Web-страницу, но ничего не известно о том, когда вернется ответ на запрос. Может потребоваться 1/2 секунды или 1 минута. Все зависит от нагрузки на сервер и соединения конечного пользователя.
Когда все готово, посылается запрос. Затем мы ожидаем. Если запрос выполняется синхронно с функцией обработки, определенной с помощью onreadystatechange, то она будет вызываться несколько раз. На самом деле она вызывается всякий раз при изменении состояния запроса. Существуют различные состояния, такие, как отправка и загрузка данных, но нас интересует только завершение загрузки данных. Если readyState == 4, то запрос выполнен, поэтому в любом другом случае мы просто выходим из функции.
XML, JSON или текст
Существует три возможных варианта получения данных: XML, JSON или обычный текст. При извлечении данных из базы данных, скорее всего, будет использоваться XML или JSON. Ни один из этих вариантов не имеет явных преимуществ. XML - широко распространенный стандарт, и поэтому существует много приложений, которые работают с файлами XML. JSON является более новой идеей, но быстро становится популярным. Его обычно легче прочитать (для человека), и он требует немного меньшую полосу пропускания для пересылки.
Предположим, что создается приложение для управления контактами. Cервер может возвращать информацию о людях. Одни и те же данные можно выразить в форме XML или JSON:
XML:
<xml>
<contacts>
<person firstname="Joe" lastname="Smith" phone="555-1212" />
<person firstname="Sam" lastname="Stevens" phone="123-4567" />
</contacts>
</xml>
JSON:
{contacts:[
{"firstname":"Joe", "lastname":"Smith", "phone":"555-1212"},
{"firstname":"Sam", "lastname":"Stevens", "phone":"123-4567"}
]}
Можно видеть, что нотация XML выглядит очень похоже на HTML. По большей части это так и есть. HTML и XML оба являются основанными на тегах языками и могут даже анализироваться одинаковым образом. Нотация JSON выглядит очень похоже на простой JavaScript. JSON означает JavaScript Object Notation и поэтому действительно является обычным JavaScript.
Данные в любой нотации можно посылать с Web-сервера просто как обычный текст. Никакие пробелы, имеющиеся в этих примерах, не нужны, за исключением одиночных пробелов между именами атрибутов в тегах person (в версии XML).
Формат XML является совокупностью тегов, очень похожих на HTML. Можно иметь любое количество тегов, вложенных друг в друга, и каждый тег может иметь любое количество атрибутов: например, firstname, lastname и phone в примере выше. Однако имеется несколько вещей, за которыми необходимо следить.
* Каждый тег должен иметь закрывающий тег. Например, <contacts> закрывается с помощью расположенного ниже </contacts>. Теги person являются замкнутыми. /> в конце действует по сути как дополнительный закрывающий тег. Можно было так же легко написать один из них как <person ... ></person>.
* XML имеет ограниченный набор символов, которые можно использовать. В частности следующие символы являются недопустимыми в узлах и атрибутах и должны заменяться специальными комбинациями: &-->&amp;<-->&lt;>-->&gt;"-->&quot;'-->&#39;* Например, узел <group name="Bill & Paul" /> является недопустимым и должен быть заменен на <group name="Bill &amp; Paul" />.
* Приходящие с сервера данные должны посылаться с content-type, заданным как text/xml. Если извлекается файл с расширением .xml, то это должно происходить автоматически. Если данные извлекаются из сценария, необходимо задавать это вручную. Для PHP добавьте следующее:
<?php header('Content-type: text/xml'); ?>
Для ASP добавьте:
<% response.contentType = "text/xml" %>
* Для всех других языков добавьте эквивалентный заголовок content-type. Если этот заголовок не задан, свойство responseXML объекта XMLHttp будет пустым (это свойство будет описано далее).
JSON имеет аналогичный набор правил, и всю документацию по способам записи можно увидеть на json.org. Однако упрощенно можно сказать, что:
* объекты начинаются и заканчиваются с помощью символов { и } соответственно;
* массивы начинаются и заканчиваются с помощью символов [ и ] соответственно;
* все строки заключаются в двойные кавычки ";
* символы " в строке должны экранироваться: \".
Проще говоря, строка JSON должна представлять допустимый объект JavaScript.
Теперь посмотрим на то, как можно выполнить синтаксический разбор этих данных. В данный момент мы создадим просто сценарий, который сообщит, сколько имеется контактов, и выведет о них информацию. Начнем с версии XML, возвращаясь к предыдущему незаконченному фрагменту кода:
function processingFunction(){
if(oXml.readyState!=4) return; // запрос не выполнен // Результаты обрабатываются здесь. Подробнее дальше!
}
Когда скрипт попадает в тело функции, запрос XMLHttp будет выполнен. Объект XMLHttp имеет два метода для возврата данных: responseXML и responseText. Так как в данный момент мы работаем с файлом XML, то будем использовать responseXML:
function processingFunction(){
if(oXml.readyState!=4) return;
var xmlDoc = oXml.responseXML;
var contacts = xmlDoc.selectNodes('/xml/contacts/person');
alert('There are '+contacts.length+' contacts!');
for(var i=0; i<contacts.length; i++){
alert('Contact #'+(i+1)+':\n\n'+
'First Name: '+contacts[i].getAttribute('firstname')+'\n'+
'Last Name: '+contacts[i].getAttribute('lastname') +'\n'+
'Phone #: '+contacts[i].getAttribute('phone') +'\n');
} }
Здесь имеется 3 функции вывода (alert). Одна сообщает, что имеется два контакта, а еще две выводят контактную информацию для каждого человека.
Посмотрим на тот же сценарий, использующий текст JSON:
function processingFunction(){
if(oXml.readyState!=4) return;
var json = eval('('+oXml.responseText+')');
alert('There are '+json.contacts.length+' contacts!');
for(var i=0; i<json.contacts.length; i++){
alert('Contact #'+(i+1)+':\n\n'+
'First Name: '+json.contacts[i].firstname+'\n'+
'Last Name: '+json.contacts[i].lastname +'\n'+
'Phone #: '+json.contacts[i].phone +'\n');
}
}
Как можно видеть, строки JSON можно преобразовать в JavaScript, используя просто встроенную в JavaScript команду eval(). Однако это можно делать, только если вы полностью доверяете источнику данных. Если это не так (если данные поступают из не вполне известного источника данных), то необходимо пропустить их в целях безопасности через JSON Parser (Анализатор JSON).
Наконец можно выбрать получение данных в любом другом простом текстовом формате вместо XML или JSON. Однако в этом случае необходимо решить, как выполнить синтаксический анализ данных. Если имеется только один фрагмент данных, такой, как комментарий, то это может быть практичным решением.
Что использовать: XML или JSON? Здесь нет больших различий. XML имеет более широко распространенный формат и переносим почти на любую систему. Если создаваемый проект будет работать с внешними источниками, то, вероятно, лучше использовать XML. Однако JSON немного легче для понимания и в общем он быстрее для разработки кода, чем XML. Если эта технология применяется для персонального проекта или в начале нового проекта, которому не нужно взаимодействовать с другими приложениям, то JSON определенно заслуживает рассмотрения.
Пример со списком контактов
В действительности уже есть все, что нужно для создания приложений AJAX, но мы рассмотрим достаточно простой пример. Мы собираемся написать небольшую таблицу данных (data grid), которая извлекает данные из трех различных файлов JSON. Для простоты эти файлы уже были сгенерированы. На практике эти файлы будут скорее всего генерироваться оперативно с помощью серверного сценария.
Файл 1
{contacts:[
{"firstname":"Steve" ,"lastname":"Smith", "phone":"555-1212"}, {"firstname":"Joe" ,"lastname":"Stevens", "phone":"555-0193"}, {"firstname":"Sam" ,"lastname":"Smith", "phone":"555-5120"}, {"firstname":"Dave" ,"lastname":"Stevens", "phone":"555-0521"}, {"firstname":"Suzy" ,"lastname":"Smith", "phone":"555-9410"}, {"firstname":"Jessica" ,"lastname":"Stevens", "phone":"555-8521"}, {"firstname":"James" ,"lastname":"Smith", "phone":"555-4781"}, {"firstname":"Jacob" ,"lastname":"Stevens", "phone":"555-9281"}, {"firstname":"Alex" ,"lastname":"Smith", "phone":"555-7261"}, {"firstname":"Tam" ,"lastname":"Stevens", "phone":"555-1820"}
]}
Файл 2
{contacts:[
{"firstname":"Nancy" ,"lastname":"Smith", "phone":"555-9583"}, {"firstname":"Elane" ,"lastname":"Stevens", "phone":"555-7281"}, {"firstname":"Shawn" ,"lastname":"Smith", "phone":"555-5782"}, {"firstname":"Jessie" ,"lastname":"Stevens", "phone":"555-7312"}, {"firstname":"Matt" ,"lastname":"Smith", "phone":"555-4928"}, {"firstname":"Jason" ,"lastname":"Stevens", "phone":"555-3917"}, {"firstname":"Daniel" ,"lastname":"Smith", "phone":"555-8711"}, {"firstname":"Shannon" ,"lastname":"Stevens", "phone":"555-0912"}, {"firstname":"Diana" ,"lastname":"Smith", "phone":"555-6172"},
{"firstname":"Mark" ,"lastname":"Stevens", "phone":"555-8831"}
]}
Файл 3
{contacts:[
{"firstname":"Laura" ,"lastname":"Stevens", "phone":"555-3915"}, {"firstname":"Jeff" ,"lastname":"Smith", "phone":"555-8614"}, {"firstname":"Frank" ,"lastname":"Stevens", "phone":"555-0213"}, {"firstname":"Elizabeth" ,"lastname":"Smith", "phone":"555-7531"}, {"firstname":"Jim" ,"lastname":"Stevens", "phone":"555-3951"}
]}
Эти файлы будут обеспечивать все данные для нашего списка контактов на AJAX. Построение списка контактов является в действительности вполне простым: создается таблица TABLE для хранения всех контактов и функция для очищения и повторного заполнения этой таблицы. <table cellspacing="1" cellpadding="3" bgcolor="#000000" style="font-family:tahoma;font-size:10px;">
<tbody id="contactListTable">
<tr style="background-color:#CCF;">
<th>First Name</th>
<th>Last Name</th>
<th>Phone #</th>
</tr>
</tbody>
</table>
function loadContactListPage(n){
var oXML = getXMLHttpObj();
oXML.open('GET', '/img/10_json_file'+n+'.txt', true);
oXML.onreadystatechange = function(){ doneLoading(oXML); }
oXML.send('');
}
function doneLoading(oXML){
if(oXML.readyState!=4) return;
var json = eval('('+oXML.responseText+')');
var table = document.getElementById('contactListTable');
for(var i=table.childNodes.length-1; i>0; i--){
table.removeChild(table.childNodes[i]);
}
for(var i=0; i<json.contacts.length; i++){
var tr = document.createElement('TR');
var td1 = document.createElement('TD');
var td2 = document.createElement('TD');
var td3 = document.createElement('TD');
tr.style.backgroundColor = i%2?'#FFF':'#E6E6E6';
table.appendChild(tr);
tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);
td1.appendChild(document.createTextNode(json.contacts[i].firstname));
td2.appendChild(document.createTextNode(json.contacts[i].lastname));
td3.appendChild(document.createTextNode(json.contacts[i].phone));
}
}
Демонстрационный пример
First Name Last Name Phone #
Steve Smith 555-1212
Joe Stevens 555-0193
Sam Smith 555-5120
Dave Stevens 555-0521
Suzy Smith 555-9410
Jessica Stevens 555-8521
James Smith 555-4781
Jacob Stevens 555-9281
Alex Smith 555-7261
Tam Stevens 555-1820
Page 1 | Page 2 | Page 3 Как можно видеть из примера выше, это все достаточно просто. Большая часть кода нужна в действительности просто для создания новых строк в таблице.
AJAX может быть удивительно полезным инструментом. Его можно использовать для проверки форм перед их отправкой, для извлечения данных, как в этом примере, или для чего-то еще, что можно будет придумать. Однако в нормальной ситуации он не должен быть основным элементом Web-сайта. Обычно надо быть уверенным, что сайт будет доступен, даже если JavaScript будет отключен, но всегда существуют некоторые исключения для этого правила.
DOM (Document Object Model).
Обычно DOM добавляется как слой между XML-парсером и приложением, которому требуется информация из документа. То есть парсер берет данные из документа и передает их в DOM. Затем DOM используется приложениями более высокого уровня. Хотя DOM расшифровывается как "объектная модель документа", работает DOM преимущественно с интерфейсами, а не с объектами. Интерфейс - это соглашение, по которому поддерживаются определенные свойства и методы, применяемые к некоему объекту. На рис. 1 показано, как приведенный выше XML-документ представляется в DOM:
Рис. 1 Пример DOM (Document Object Model)
Каждый прямоугольник представляет собой объект, имена в прямоугольниках соответствуют интерфейсам, которые будут реализованы каждым объектом. Каждый объект может реализовывать несколько подходящих интерфейсов. Например, объект представляющий символьные данные "Hello,World!", реализует интерфейсы Text, CharacterData, Node. Преимущество модели DOM состоит в том, что она универсальна, т.е. может применяться для документов любого типа. Ее использование может существенно упростить обработку XML-документов. Но вернемся к технологии XML. Для чего она используется? В основном для хранения и передачи данных. В последнее время хранение данных в виде набора XML-файлов рассматривается даже как альтернатива реляционным базам данных. Но наиболее прогрессивные разработчики стремятся задействовать совместно XML и базы данных, пользуясь достоинствами обеих технологий. В частности, XML удобнее использовать для передачи данных, а базу данных - для их хранения и обработки. Например, главная компания и ее филиал в другом городе имеют два разных сайта поддержки, написанных на PHP. На сайте филиала нужно сообщать обо всех основных событиях, происходящих в главной компании, и наоборот. Поэтому обе организации ежедневно обмениваются новостями в универсальном формате XML, а эти файлы создаются и обрабатываются PHP-скриптами и отображаются на обоих сайтах.
Для работы с XML-документами в PHP существует два модуля, реализующие два разных стандарта обработки XML-данных: SAX (Simple API for XML) и DOM (Document Object Model).
Стандарт SAX (http://www.saxproject.org) не является стандартом W3C и описывает метод обработки XML-документов для получения из них данных. То есть этот метод обработки XML-документов позволит только прочитать данные из XML-документа, и не более того. Создавать и изменять XML-документы с его помощью невозможно. SAX основан на так называемом событийном программировании. Его особенность заключается в том, что вы предоставляете парсеру XML набор собственных функций, которые будут заниматься обработкой различных типов XML-данных (элементов (тегов), текста и т.п.), а парсер затем будет сам вызывать ваши функции в процессе обработки XML-документа, передавая им найденные данные. Функции будут вызываться в той же последовательности, в которой соответствующие данные располагаются в XML-документе. Другим стандартом для обработки XML-данных является DOM - стандарт W3C, спецификацию которого можно найти на сайте консорциума (http://www.w3c.org/DOM). В отличие от SAX, этот метод позволяет производить любые операции с XML-данными в достаточно удобной форме - представляя XML-документ как дерево объектов. Модуль, реализующий этот стандарт, называется DOM XML. Он не входит в основной набор модулей PHP, но может быть установлен как расширение. Взаимодействие PHP и XML посредством DOM XML
Что происходит, если взаимодействие PHP и XML осуществляется с помощью объектной модели стандарта DOM? Модуль DOM XML определяет в PHP несколько классов, таких как DomNode, DomDocument, DomElement, DomText и DomAttribute, большинство из которых идут из ядра стандарта DOM. Почти для всех классов (в частности, для перечисленных выше) класс DomNode является родительским, поэтому его свойства и методы наследуются всеми остальными классами. Если рассмотреть произвольный XML-документ, то классу DomDocument будет соответствовать сам этот документ, классу DomElement - каждый XML-тег, классу DomAttribute - атрибуты тегов, а классу DomText - содержание XML-элементов. В то же время классу DomNode будет соответствовать каждый из перечисленных элементов XML-документа. Рассмотрим коллекцию, содержащую описания персон. Если каждую из них мы описываем с помощью таких характеристик, как фамилия, имя, дата рождения и электронный адрес, то структура коллекции "Пользователь", где хранится информация обо всех известных нам персонах, может быть представлена следующим образом.
<?xml version="1.0"?>
<collection>
<person id="10">
<name>
<first>Nick</first>
<last>Petrov</last>
</name>
<birth>
<day>23</day>
<month>12</month>
<year>89</year>
</birth>
<email> nick@ngs.ru </email>
</person>
<person id="20">
<name>
<first>Bob</first>
<last>Ivanov</last>
</name>
<birth>
<day>03</day>
<month>05</month>
<year>90</year>
</birth>
<email> bob@ngs.ru </email>
</person>
</collection>
Пример 2. Коллекция "Пользователь" в виде XML-файла (persons.xml) Перевод данных XML-файла в объекты и классы PHP
Первое, что нужно сделать, если мы хотим работать с XML-данными в PHP при помощи расширения DOM XML, это перевести имеющиеся данные в объекты и классы DOM. Это можно сделать несколькими способами.
1. С помощью функции domxml_open_mem. Синтаксис: object domxml_open_mem (string str)
В качестве параметра эта функция принимает строку str, содержащую XML-документ. Результатом ее работы является объект класса, называемого DOMDocument. 2. С помощью функции domxml_open_file. Синтаксис: object domxml_open_file (string filename)
Эта функция обрабатывает XML-файл, имя которого задается параметром filename, и переводит его в объект класса DOMDocument. Доступ к файлу производится только на чтение. Такие функции, как domxml_open_mem() и domxml_open_file(), как правило, нужно вызывать перед вызовом любых других функций, связанных с расширением DOM.
Эти функции преобразуют XML-файл в дерево объектов. К таким объектам можно обращаться с помощью различных методов. В частности, для выделения корневого элемента используется метод DomDocument ->document_element().
Еще существует функция domxml_new_doc(string version), которая создает новый пустой XML-документ. Ее параметром является номер версии создаваемого документа. Но ее мы касаться не будем, а будем считать, что XML-файл уже создан.
<?
//считываем файл "persons.xml" в строку
$xmlstr = join('',file('persons.xml'));
// переводим строку с xml-файлом в дерево объектов. Если операция
// прошла неудачно, то выводим ошибку и прекращаем работу.
if(!$dom = domxml_open_mem($xmlstr)) {
echo "Ошибка при разборе документа\n";
exit;
}
// можно посмотреть, как выглядит этот объект
print_r($dom);
echo "<hr>";
// выделяем корневой элемент дерева объектов. В нашем случае это будет
// элемент <collection>
$root = $dom->document_element();
print_r($root);
echo "<hr>";
?>
Пример 3. Перевод XML-файла в дерево объектов PHP и выделение корневого элемента Каждому элементу XML-файла соответствует какой-то объект. Теперь нужно научиться перемещаться по дереву объектов и обращаться с этими объектами: получать и изменять их значения, находить их потомков и предков, удалять объекты. Задание на работу:
1. Выполнить работу с DOM. Реализовать поиск и манипулирование DOM-деревом
2. Реализовать эффекты с использованием jQuery UI (Draggable, Sorttable, According, Dialog, ...)
3. Выполнить клиентскую валидацию при регистрации
4. Использовать элементы GUI-JS (окна, tab, tool-ip, rating, progress-bar, деревья, календарь, ...)
5. Реализовать многоязычность приложения
Лабораторная работа №8
Разработка компонент для CMS Joomla.
Разработка простого компонента для пользовательской части
Цель работы: разработать для CMS Joomla компонент пользовательской части для просмотра информации из базы данных.
Краткие теоретические сведения:
Пример компонента helloworld
Все компоненты делятся на компоненты интерфейсной части и компоненты административной части. Компоненты интерфейсной части отображаются на веб-сайте, а компоненты административной части разрабатываются для административного раздела - в основном для управления компонентами интерфейсной части. С точки зрения посетителя сайта, можно узнать компонент по способу запроса страницы Joomla.
Так, например, URL - адрес http://localhost/Joomla150/index.php?option=com_contact вызывает компонент com_contact интерфейсной части.
Если просмотреть в базе данных, то можно увидеть множество компонентов в подкаталоге [Путь_к_Joomla]/components, и среди них - компонент com_contact.
В зависимости от сложности компонентов, в этом каталоге появляются дополнительные подкаталоги для модели, представления и контроллера.
Домашний каталог helloworld
Каждый компонент располагается в собственном каталоге. Joomla предлагает следующую последовательность обнаружения компонента.
1 Joomla интерпретирует сгенерированные значения в URL: /index.php?option=com_helloworld.
2 Выполняет поиск таблицы для компоненты com_helloworld.
3 Ищет каталог com_helloworld.
4 В этом каталоге ищет файл helloworld.php.
5 Интерпретирует этот файл.
Для правильной интерпретации необходимо несколько файлов.
- helloworld.php - точка входа в ваш компонент.
- controller.php - контроллер.
- views/helloworld/view.html.php - представление, передающее данные в шаблон.
- views/helloworld/tmpl/default.php - файл стандартного шаблона, который будет переписан корректным шаблоном или использован как есть.
- helloworld.xml -XML-файл, который объясняет содержимое пакета контроллеру, сообщает ему, куда инсталлировать его, и кто за него отвечает.
После создания и упаковки компонента его необходимо инсталлировать как пакет компонента com_hello.zip и установить пункт меню. Таким образом, вы немедленно размещаете все файлы в нужные каталоги и можете легко исследовать исходный код.
Точка входа(componenst/com_hello/hello.php)
Это первый файл, который будет вызван, когда вы указываете URL http://localhost/joomlal50/index.php?option=com_hello&view=hello или щелкаете на соответствующем пункте меню. Результат будет определенно ожидаемым. Вы увидите текст "Hello World" в окне контента.
Исходный код этого файла представлен ниже.
/components/com_hello/hello.php:
<?php
// ограниченный доступ
defined('_JEXEC') or die('Restricted access');
// импортирование базового контроллера
require__once (JPATH_COMPONENT.DS.'controller.php');
// создание собственного контроллера
$classname = 'HelloController'.$controller;
$controller = new $classname( );
// проверка наличия параметров запроса
$controller->execute( JRequest::getVar('task'));
// перенаправление внутри контроллера
$controller->redirect();
?>
Первая строка осуществляет контроль безопасности, проверяя, был ли файл вызван Joomla или же непосредственно. Непосредственно вызванный сценарий немедленно останавливается функцией die():
require_once {JPATH_COMPONENT.DS.'controller.php');
После этого импортируется первый контроллер. Абсолютный путь к текущему, компоненту (components/com_hello) выглядит как JPATH_COMPONENT, a DS представляет собой разделитель каталогов операционной системы. В Windows он отличается от Unix-подобных систем, т.е. это будет / или \. Joomla устанавливает это значение автоматически.
$classname = 'HelloController'.$controller;
$controller = new $classname();
Теперь можно создать экземпляр читающего контроллера, и тем самым получить контроллер, который затем использовать. Если нужен всего один контроллер, как это часто бывает в интерфейсной части, можно воспользоваться следующим оператором:
$controller=newHelloController();
Scontroller->execute( JRequest::getVar('task'));
Операторы для компонентов устанавливается в URL в следующей форме:
index.php?option=com_hello&task=task
(где task - одно из значений save, edit, new...).
Следующая строка используется для проверки, есть ли что-то для чтения:
$controller->redirect();
При этих условиях контроллер перенаправляет запрос на другой сайт, например, если что-то должно сохраниться.
Контроллер (/components/com_hello/controller.php)
Поскольку компонент действительно прост, перед контроллером теперь стоит задача отобразить что-нибудь. Нам не нужна модель данных, а достаточно одного метода display.
/components/com_hellо/controller.php:
<?php
jimport('joomla.application.component.controller');
class HelloController extends JController
{
function display()
{
parent::display();
}
}
?>
Вызов метода display() задает имя и компоновку представления. Наш компонент распознает только стандартную компоновку.
Представление (/components/cam_hello/views/hello/views.html.php)
Здесь представление уже имеется - представление по умолчанию. /components/com_hello/views/hello/views.html.php:
<?php
jimport( 'joomla.application.component.view');
class HelloViewHello extends JView
{
function display ($tpl = null)
{
$greeting = "Hello World!";
$this->assignRef( 'greeting1, $greeting);
parent::display ($tpl);
}
}
?>
Представление обычно содержит данные (из модели), подготавливает их и посылает шаблону:
$greeting = "Hello World!";
$this->assignRef( 'greeting', $greeting );
parent::display($tpl);
Из-за присваиваний переменных модель здесь избыточна. Переменная $greeting, однако, могла бы содержать результат запроса к базе данных. Переменная передается шаблону методом assignRef:
parent::display($tpl);
Это вызывает появление шаблона.
Шаблон (/components/com_hello/views/hello/tmpl/default.php)
Здесь применяется шаблон по умолчанию. Он всегда называется default.php и выглядит в своем простейшем виде, как показано в следующем листинге.
/components/com_hello/views/hello/tmpl/default.php:
defined('_JEXEC) or die('Restricted access'); ?>
<h1><?php echo $this->greeting; ?></h1>
Инсталляция
Все файлы теперь упакованы в ZIP-пакет и могут быть установлены инсталлятором Joomla. Файлы интерфейсной части из /components/com_hello сохраняются в каталоге site, а файлы административной области из /com_hello/administrator/components - в каталоге admin. Все файлы описываются дополнительной информацией в hello.xml.
hello.xml:
<?xml version="l.0" enooding="utf-8"?>
<!DOCTYPE install SYSTEM "http://dev.joomla.Org/xml/l.5/component-install.dtd">
<install type="component" version="l.5.0">
<name>Hello</name>
<creationDate>November</creationDate>
<author>Nobody</author>
<authorEmail>nobody@example.org</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<version>Component Version String</version>
<description>description of the component . . . </description>
<!- Site Main File Copy Section ->
<files folder="site">
<filename>index.html</filename>
<filename>hello.php</filename>
<filename>controller.php</filename>
<filename>views/index.html</filename>
<filename>views/hello/index.html</filename>
<filename>views/hello/view.html.php</filename>
<filename>views/hello/tmpl/index.html</filename>
<filename>views/hello/tmpl/default.php</filename>
</files>
<administration>
<!- Раздел меню администрирования ->
<menu>Hello World!</menu>
<!- Раздел копии главных файлов администрирования ->
<files folder="admin">
<!- Раздел копии главных файлов сайта ->
<filename>index.html</filename>
<filename>admin.hello.php</filename>
</files>
</administration>
</install>
При упаковке в ZIP-пакет необходимо сохранить структуру. Теперь можно позволить инсталлятору Joomla загрузить и инсталлировать пакет обычным образом.
Программирование для Joomla 1.5 легко, поддается расширению и предельно ясно. На первый взгляд все эти файлы казались несколько путающими, но результат прост. В каждом файле присутствует очень немного исходного кода, и потому получается гораздо лучший обзор. Именно на это и нацелена концепция MVC. И если нужно иметь специальный сложный шаблон, просто перепишите представление в вашем самодельном шаблоне. На рисунках 11.1, 11.2 показана установка созданного расширения.
Рисунок 11.1 - Установка модуля
Рисунок 11.2 - Сообщение об успешной установке
На рисунках 11.3 и 11.4 показано добавление ссылки на расширение в главное меню сайта.
Рисунок 11.3 - Ссылка на расширение в списке компонентов
Рисунок 11.4 - Добавление ссылки на компонент в главное меню сайта
На рисунке 11.5 показана работа созданного компонента на главной странице сайта.
Рисунок 11.5 - Отображение компонента на главной странице
Задание к работе:
Ознакомиться с теоретическим материалом.
Внести изменения в шаблон компонента CMS Joomla.
Подключить компонент через панель управления.
Включить компонент через "Менеджер модулей".
Изучить работу компонента на главной странице сайта.
Оформить отчет согласно требованиям.
Отчет должен содержать:
Название и цель работы.
Ход работы с детальным описанием выполненных действий с рисунками.
Экранные формы браузера с загруженными страницами.
Выводы о проделанной работе.
Вопросы для подготовки к защите работы:
1. Каким образом создаются модули и расширения в CMS Joomla?
2. Какая структура модулей и расширений используется в CMS Joomla?
3. Какой подход в программировании используется при создании модулей и расширений в CMS Joomla?
4. Чем отличается модуль от расширения в CMS Joomla?
Лабораторная работа №9
Разработка компонент для CMS Joomla.
Разработка компонента с использованием базы данных
Цель работы: разработать для CMS Joomla компонент пользовательской части для просмотра информации из базы данных.
Краткие теоретические сведения:
Создание модели
Модель (model) - часть компонента, которая предоставляет данные для Представления (view) по его запросу, посланному через Контроллер (controller). Такой метод часто освобождает от рутинной работы и от хаоса в коде, предоставляет возможность управлять данными удобным способом в дополнение к коду, который посылает запрос данных из Модели. В Joomla 1.5 Модель будет содержать классы функций: добавить, удалить и модернизировать информацию в таблицах базы данных. Также содержать методы восстановления списка таблиц базы данных. Основная структура доступа к данным должна быть кратко описана в модели. Если необходимо изменить обработку данных, Модель - единственная часть в которую вносятся изменения не затрагивая код Представления или Контроллера.
При переносе точки запроса данных в общем алгоритме компонента, вносятся изменение только в код Представления. Рассмотрим событие компонента "Hello", которое генерирует приветствие. Таким образом, в компоненте будет один запрос к модели getGreeting(), который возвратит строку "Hello, World!".
Образец кода для класса Модели: <?php
/**
* Hello Модель для "Hello" Компонета
* * @package Автор
* @package component/model/models/hello.php
* @link URL Автора
* @license Тип лицензии ( GNU/GPL )
*/
defined ('_JEXEC') or die();
jimport( 'joomla.application.component.model' );
/**
* Hello Model
*
* @package Автор
* @subpackage Components
*/
class HelloModelHello extends JModel
{
/**
* Gets the greeting
* @return string The greeting to be displayed to the user
*/
function getGreeting()
{
return 'Hello, World!';
}
}
Строка, которая начинается с jimport это функция используется для загрузки файлов Joomla 1.5. В данном случае подгружается структура, которая требуются для компонента. Этот запрос загрузит файл /libraries/joomla/application/component/model.php. Точки "." используются как директивные слеши, и последняя часть - имя загружаемого файла. С помощью этой функции все файлы загружаются из библиотеки (директория libraries). Этот файл содержит определение класса для JModel class, который является необходимым, так как наша модель является продолжением этого класса. Создав Модель, необходимо изменить Представление, добавить запрос к Модели для получения строки приветствия. Используем связь Модели (model) и Представления (view)
Структура Joomla 1.5 - организована таким способом, что контроллер автоматически загрузит модель, которая имеет то же название что и Представление и передаст доступ к своему классу. Так как Представление называется "Hello", модель "Hello" будет автоматически загружена и опубликована в Представлении. Поэтому можно легко объявить функцию класса модели, используя метод JView:: в строке JView::getModel(). В код файла view.html.php вносим изменения заменяя строку: $greeting = "Hello World!";
На код:
$model = $this->getModel();
$greeting = $model->getGreeting();
Так должен выглядеть полный код файла view.html.php:
<?php
/**
* Hello View for Hello World Component
* * @package Автор
* @subpackage Components
* @linkcomponents/views/hello/view.html.php
* @license GNU/GPL
*/
defined( '_JEXEC' ) or die( 'Restricted access' );
jimport( 'joomla.application.component.view');
/**
* HTML View class for the HelloWorld Component
*
* @package Joomla.Tutorials
* @subpackage Components
*/
class HelloViewHello extends JView
{
function display($tpl = null)
{
$model = $this->getModel();
$greeting = $model->getGreeting();
$this->assignRef( 'greeting',$greeting );
parent::display($tpl);
}
}
?>
Изменения в файле hello.xml
Для завершения работы над данной версией компонента, необходимо в секцию Site (Front End) добавить файлы Модели: <filename>models/hello.php</filename>
Код для нового файла hello.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE install SYSTEM "http://dev.joomla.org/xml/1.5/component-install.dtd">
<install type="component" version="1.5.0">
<name>Hello</name>
<creationDate>2007 02 22</creationDate>
<author>Имя Автора</author>
<authorEmail> author@mail.netЭтот адрес e-mail защищен от спам-ботов. Чтобы увидеть его, у Вас должен быть включен Java-Script
</authorEmail>
<authorUrl>www.autor.net</authorUrl> <copyright>Копирайт</copyright>
<license>Лицензия</license>
<version>Component Version String</version>
<description>Description of the component ...</description>
<!-- Site Main File Copy Section -->
<files folder="site">
<filename>index.html</filename>
<filename>hello.php</filename>
<filename>controller.php</filename>
<filename>views/index.html</filename>
<filename>views/hello/index.html</filename>
<filename>views/hello/view.html.php</filename>
<filename>views/hello/tmpl/index.html</filename>
<filename>views/hello/tmpl/default.php</filename>
<filename>models/index.html</filename>
<filename>models/hello.php</filename>
</files>
<administration>
<!-- Administration Menu Section -->
<menu>Hello World!</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the folder
to copy FROM in the package to install therefore files copied
in this section are copied from /admin/ in the package -->
<files folder="admin">
<!-- Site Main File Copy Section -->
<filename>index.html</filename>
<filename>admin.hello.php</filename>
</files> </administration>
</install>
Теперь создан простой MVC компонент. Каждый элемент очень прост в данный момент, но компонент уже обладает более большей гибкостью и возможностью. Получение данных из базы
Модель компонента в настоящее время имеет один метод: getGreeting(). Этот метод очень прост - все, что эта функция делает - возвращает приветствие. Для работы с базой данных, загрузим приветствие в таблицу базы данных.
При установке компонента необходимо создание таблицы с записью текстового поля с приветствием. Как создать SQL-файл и какие строки добавить в hello.xml, рассмотрим позже. Для начала заменим код в Модели для получения приветствия с таблицы базы данных.
В первую очередь нужно подключится к базе данных. В Joomla 1.5 все параметры для подключения уже есть и для того чтобы создать свое используем следующее: $db => JFactory::getDBO();
JFactory - статический класс, который используется, чтобы подключится к многим объектам системы. Подробней информацию об этом классе можно посмотреть в документации API. Для подключению к базе данных используется метод getDBO. Для получения приветствия необходимо сохранить запрос для получения объекта базы данных. Для этого вносим изменение для Модели в функции getGreeting(), находящейся в файле component/model/models/hello.php : function getGreeting()
{
$db = JFactory::getDBO();
$query = 'SELECT greeting FROM #__hello';
$db->setQuery( $query );
$greeting = $db->loadResult();
return $greeting;
}
$db->loadResult() метод выполнит запрос к базе данных, и вернет полученный объект. Создадим инсталляционный SQL-файл
Joomla 1.5 инсталлятор имеет встроенную поддержку выполнения SQL-запросов в процессе установки компонента. Эти запросы должны быть сохранены в стандартном install.sql файле. Для инсталляционного файла SQL используем три запроса: * Удаление таблицы на случай, если с таким именем уже существует. * Создание таблицы и текстового поля для хранение строки приветствия. * Загрузка строки приветствия в поле таблицы. Ниже приведены все три запроса для инсталляционного файла: DROP TABLE IF EXISTS `#__hello`;
CREATE TABLE `#__hello` (
`id` int(11) NOT NULL auto_increment,
`greeting` varchar(25) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT DEFAULT CHARSET=utf8;
INSERT INTO `#__hello` (`greeting`) VALUES ('Hello, World!'),
('Bonjour, Monde!'),
('Ciao, Mondo!');
Joomla сама заменит "#__ " на префикс таблицы текущей базы данных MySQL. в первом запросе уничтожается таблица #__hello, это необходимо для того, чтобы не было накладок при повторных установках одного и тоже компонента. По второму запросу создается два поля в таблице. Первое поле `ID` - которое является ключом, гарантирующим уникальность записи. Второе поле `greeting` - строка длиной 25 символов, в которой будет хранится приветствие. Сохраняем эти запросы в файле install.sql и переносим его в дистрибутив компонента по пути - com_hello/admin/install.sql. Создадим деинсталляционный uninstall.sql файл
При деинсталляции компонента необходимо удалять таблицы, которые были созданы во время установки, но при этом нужно всегда учитывать, то что пользователь может случайно удалить компонент. Для того чтобы он таким образом не удалил свои данные в таблицах базы данных, необходимо требовать подтверждение такого действия:
DROP TABLE IF EXISTS `#__hello`;
Сохраняем эти запросы в файле uninstall.sql и переносим его в дистрибутив компонента по пути - com_hello/admin/uninstall.sql. Заносим дополнение в инсталяционный файл hello.xml
Прежде чем указывать какие файлы использовать при установке и деинсталляции для запуска SQL-запросов нужно указать, куда копировать эти файлы. Оба файла должны находиться в корне папки административной части компонента. Далее указываем инсталлятору, какие файлы использовать для SQL-запроса при установке и деинсталляции компонента.
Новый код для инсталляционного XML файла:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE install SYSTEM "http://dev.joomla.org/xml/1.5/component-install.dtd">
<install type="component" version="1.5.0">
<name>Hello</name>
<!-- The following elements are optional and free of formatting conttraints -->
<creationDate>2007 02 22</creationDate>
<author>John Doe</author>
<authorEmail>john.doe@example.org</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<version>Component Version String</version>
<description>Description of the component ...</description>
<!-- Site Main File Copy Section -->
<files folder="site">
<filename>index.html</filename>
<filename>hello.php</filename>
<filename>controller.php</filename>
<filename>views/index.html</filename>
<filename>views/hello/index.html</filename>
<filename>views/hello/view.html.php</filename>
<filename>views/hello/tmpl/index.html</filename>
<filename>views/hello/tmpl/default.php</filename>
<filename>models/hello.php</filename>
</files>
<install>
<sql>
<file charset="utf8" driver="mysql">install.sql</file>
</sql>
</install>
<uninstall>
<sql>
<file charset="utf8" driver="mysql">uninstall.sql</file>
</sql>
</uninstall> <administration>
<!-- Administration Menu Section -->
<menu>Hello World!</menu>
<!-- Administration Main File Copy Section -->
<files folder="admin">
<!-- Site Main File Copy Section -->
<filename>index.html</filename>
<filename>admin.hello.php</filename>
<filename>install.sql</filename>
<filename>uninstall.sql</filename>
</files> </administration>
</install>
При инсталляции и деинсталляции у атрибута charset может быть два значения: первый - "utf8" и если версия MySql сервера не поддерживает кодировку utf8 указывается атрибут "non-utf8".
Атрибут driver пока может иметь только одно значение - "mysql". В дальнейшем планируется расширить возможности Joomla 1.5 для работы с разными базами данных.
Теперь компонент "Hello" может работать не только с MVC framework классами, но и с классами запросов JDatabase. На рисунках 12.1, 12.2 показана установка созданного расширения.
Рисунок 12.1 - Установка модуля
Рисунок 12.2 - Сообщение об успешной установке
На рисунках 12.3 и 12.4 показано добавление ссылки на расширение в главное меню сайта.
Рисунок 12.3 - Ссылка на расширение в списке компонентов
Рисунок 12.4 - Добавление ссылки на компонент в главное меню сайта
На рисунке 12.5 показана работа созданного компонента на главной странице сайта.
Рисунок 12.5 - Отображение компонента на главной странице
Задание к работе:
Ознакомиться с теоретическим материалом.
Внести изменения в шаблон компонента CMS Joomla - файл com_hello3.zip.
Подключить компонент через панель управления.
Изучить работу компонента на главной странице сайта.
Оформить отчет согласно требованиям.
Отчет должен содержать:
Название и цель работы.
Ход работы с детальным описанием выполненных действий с рисунками.
Экранные формы браузера с загруженными страницами.
Выводы о проделанной работе.
Вопросы для подготовки к защите работы:
Чем отличается структура компонента без Модели и с Моделью?
Каким образом Представление обращается к Модели?
Каким образом компонент обращается к базе данных?
Лабораторная работа №10
Разработка компонент для CMS Joomla.
Разработка компонента с административной частью
Цель работы: разработать для CMS Joomla компонент включающий пользовательскую и административную части для управления информацией из базы данных.
Краткие теоретические сведения:
Добавим к компоненту "Hello" в раздел Администратора интерфейс для работы с записями в таблице базы данных. Создание основной структуры
Основная среда панели администратора очень похожа на часть сайта. Основной точкой входа в администраторскую часть компонента является admin.hello.php. Этот файл идентичен файлу hello.php, который используется на сайте, кроме того, что имя загружаемого контроллера, изменено на HellosController. Контроллер по умолчанию также называется controller.php, и является идентичным контроллеру по умолчанию в части сайта, с тем отличием, что контроллер называется HellosController вместо HelloController. Эта разница означает, что контроллер JController по умолчанию будет загружать список наших приветствий. Код для файла admin.hello.php: <?php
/**
* @package Joomla.Tutorials
* @subpackage Components
* @link http://dev.joomla.org/
* @license GNU/GPL
*/
// прямой доступ отсутствует
defined( '_JEXEC' ) or die( 'Restricted access' );
// Добавляем основной контроллер
require_once( JPATH_COMPONENT.DS.'controller.php' );
// При необходимости добавляем специальный контроллер
if($controller = JRequest::getVar( 'controller' )) {
require_once( JPATH_COMPONENT.DS.'controllers'.DS.$controller.'.php' );
}
// Создаем контроллер
$classname = 'HellosController'.$controller;
$controller = new $classname( );
// Выполняем задачу Request
$controller->execute( JRequest::getVar( 'task' ) );
// Переадресация, если указано в контроллере
$controller->redirect();
?>
Представлением и моделью будут hellos view и the hellos model. Начнем с модели. Модель Hellos Модель Hellos будет очень простой. Единственным действием, нужным нам сейчас, является возможность получения списка приветствий из базы данных. Это действие будет выполняться в методе getData(). Класс JModel имеет встроенный защищенный метод _getList(). Этот метод может использоваться для упрощения задачи получения списка записей из базы данных. Необходимо выполнить запрос, и он возвратит список записей. Позже может возникнуть необходимость использовать запрос в другом методе. Таким образом, мы создадим приватный метод _buildQuery(), который возвратит запрос, передаваемый методу _getList(). Это облегчает изменение запроса, поскольку он вызывается из одного и того же места. Таким образом, в нашем классе нужны 2 метода: getData() и _buildQuery(). _buildQuery() просто возвращает запрос. Код метода _buildQuery():
/**
* Возвращает запрос @return string Строка запроса, используемая
* для получения строки из базы данных */
function _buildQuery()
{
$query = ' SELECT * '.' FROM #__hello ';
return $query;
}
getData() получает запрос и извлекает записи из базы данных. Может случиться, что нам потребуется дважды получить этот список при одной загрузке страницы. Будет расточительством получать этот список дважды. Таким образом, метод должен сохранять полученные данные в защищенном свойстве (переменной), чтобы на последующий запрос он мог просто возвращать полученные ранее данные. Это свойство будет называться _data. Код метода getData(): /**
* Получение данных @return array
* Массив объектов, содержащий данные из базы
*/
function getData()
{
// Загрузка данных, если они еще не были загружены
if (empty( $this->_data ))
{
$query = $this->_buildQuery();
$this->_data = $this->_getList( $query );
}
return $this->_data;
}
Полностью модель выглядит так:
<?php
/**
* Модель Hellos для компонента Hello World
* * @package Joomla.Tutorials
* @subpackage Components
* @link http://dev.joomla.org/
* @license GNU/GPL
*/
// Проверьте, включен ли этот файл в Joomla!
defined('_JEXEC') or die();
jimport( 'joomla.application.component.model' );
/**
* Hello Model
*
* @package Joomla.Tutorials
* @subpackage Components
*/
class HellosModelHellos extends JModel
{
/**
* Hellos data array
*
* @var array
*/
var $_data;
/**
* Возвращает запрос
* @return string запрос, используемый для извлечения строк из базы данных
*/
function _buildQuery()
{
$query = ' SELECT * '.' FROM #__hello ';
return $query;
}
/**
* Получение данных * @return array Массив объектов, содержащий данные из базы
*/
function getData()
{
// Загружаем данные, если они еще не загружены
if (empty( $this->_data ))
{
$query = $this->_buildQuery();
$this->_data = $this->_getList( $query );
}
return $this->_data;
}
}
Файл сохранен как models/hellos.php. Представление Hellos
Теперь, когда у нас есть модель для получения данных, нужно отобразить полученные данные. Это представление будет похожим на отображение с раздела сайта. Поскольку наша модель была автоматически описана в сайте, она принадлежит администратору. Методы, использующие get в модели, доступны с помощью метода get() класса JView. Представление имеет три уровня: один получает данные из модели, другой вставляет данные в шаблон, и третий с помощью метода display() для отображения. Код представления:
<?php
/**
* Hellos View for Hello World Component
* * @package Joomla.Tutorials
* @subpackage Components
* @link http://dev.joomla.org/
* @license GNU/GPL
*/
defined('_JEXEC') or die();
jimport( 'joomla.application.component.view' );
/**
* Hellos View
*
* @package Joomla.Tutorials
* @subpackage Components
*/
class HellosViewHellos extends JView
{
/**
* Hellos view display method
* @return void
**/
function display($tpl = null)
{
JToolBarHelper::title( JText::_( 'Hello Manager' ), 'generic.png' );
JToolBarHelper::deleteList();
JToolBarHelper::editListX();
JToolBarHelper::addNewX();
// Get data from the model
$items = > $this->get( 'Data');
$this->assignRef('items', $items);
parent::display($tpl);
}
}
Этот файл сохранен как views/hellos/view.html.php. Шаблон Hellos
Шаблон будет получать данные из представления и формировать вывод. Отобразим этот вывод в простой таблице. Поскольку таблица очень проста, в административной части нам понадобится минимальное количество дополнительной логики для выполнения циклов с данными. Шаблон: <?php defined('_JEXEC') or die('Restricted access'); ?>
<form action="index.php" method="post" name="adminForm">
<div id="editcell">
<table class="adminlist">
<thead>
<tr>
<th width="5">
<?php echo JText::_( 'ID' ); ?>
</th>
<th>
<?php echo JText::_( 'Greeting' ); ?>
</th>
</tr> </thead>
<?php
$k = 0;
for ($i=0, $n=count( $this->items ); $i < $n; $i++)
{
$row = >$this->items[$i];
?>
<tr class="<?php echo "row$k"; ?>">
<td>
<?php echo $row->id; ?>
</td>
<td>
<?php echo $row->greeting; ?>
</td>
</tr>
<?php
$k = 1 - $k;
}
?>
</table>
</div>
<input type="hidden" name="option" value="com_hello" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="boxchecked" value="0" />
<input type="hidden" name="controller" value="hello" />
</form>
Этот шаблон сохранен как views/hellos/tmpl/default.php. Вывод заключен в форму. Сейчас это не является необходимым, но скоро понадобится. Мы рассмотрели основную часть первого представления, добавив пять файлов в администраторский раздел нашего компонента:
admin.hello.php
controller.php
models/hellos.php
views/hellos/view.html.php
views/hellos/tmpl/default.php
Файлы необходимо добавить в XML-файл инсталляции и посмотреть, что получится.
Добавление функциональности
Пока наш административный раздел не очень полезен. Он не делает ничего, кроме отображений содержимого базы данных. Для добавления полезных функций необходимо добавить несколько кнопок и ссылок. Панель инструментов
В административной части отображается панель инструментов. Нашему компоненту она также необходима. Joomla облегчает ее создание. Добавим кнопки "Удалить записи", "Изменить записи", и "Создать новые записи". Также добавим заголовок, который будет отображаться на нашей панели инструментов. Это можно сделать, добавив немного кода в представление. Чтобы добавить кнопки, используем статические методы из класса JToolBarHelper. Код выглядит так: JToolBarHelper::title( JText::_( 'Hello Manager' ), 'generic.png' );
JToolBarHelper::deleteList();
JToolBarHelper::editListX();
JToolBarHelper::addNewX();
Эти четыре метода создают соответствующие кнопки. Метод deleteList() может принимать три параметра: первый параметр является строкой, спрашивающей пользователя о подтверждении удаления. Второй параметр является задачей, которая отправляется вместе с запросом (по умолчанию "remove"), а третий - текст, отображаемый под кнопкой. Методы editListX() и addNewX() могут получать два дополнительных параметра. Первый - задача (по умолчанию - соответственно, edit и add), второй - текст, отображаемый под кнопкой. Для вывода информации используется метод JText::_ как в прошлом шаблоне. Это функция, значительно облегчающая перевод компонента. Метод JText::_ ищет текстовую строку в языковом файле компонента и возвращает переведенную строку. Если перевод не найден, функция возвращает строку, переданную ей. Если компонент нужно перевести на другой язык, все, что нужно сделать - создать языковый файл, включающий строки и их перевод на требуемый язык. Флажки и ссылки
Теперь у нас есть кнопки. Две из этих кнопок управляют существующими записями. Пользователь определяет с какими записями ему необходимо работать. Для этого нужно добавить флажки в таблицу, чтобы пользователь мог выбрать необходимые записи. Это реализовано в шаблоне. Для добавления флажков необходимо добавить в таблицу дополнительный столбец. Добавим столбец между двумя имеющимися. В заголовке столбца добавим флажок, который можно использовать для выбора или сброса всех флажков: <th width="20">
<input type="checkbox" name="toggle" value="" onclick="checkAll(<?php echo count( $this->items ); ?>);" />
</th>
Функция Javascript checkAll встроена в основной пакет Joomla.
Теперь необходимо добавить флажки в каждую строку. У класса JHTML есть метод JHTML::_(), который создаст для нас флажки. Добавим следующие строки в наш цикл: $checked = JHTML::_('grid.id', $i, $row->id );
После строки
$row = >$this->items[$i];
Затем добавим ячейку между двумя имеющимися:
<td>
<?php echo $checked; ?>
</td>
Необходимость выбирать флажок, перемещаться вверх страницы и нажимать кнопку слишком обременительна. Мы добавим ссылку, позволяющую перейти непосредственно к форме редактирования. Следующие строки добавим после вызова метода JHTML::_() для создания ссылки HTML:
$link = JRoute::_( 'index.php?option=com_hello>controller=hello>task=edit>cid[]='. $row->id );
Добавляем ссылку в ячейку, отображая текст:
<td>
<a href="<?php echo $link; ?>"><?php echo $row->greeting; ?></a>
</td>
Обратите внимание, что ссылка указывает на контроллер hello. Этот контроллер обработает данные наших приветствий В предыдущем шаблоне были четыре скрытых поля внизу формы. Первое поле носило имя option. Вторым полем является поле task. Оно получает данные в случае нажатия одной из кнопок на панели инструментов. В случае удаления этого поля будет получена ошибка Javascript и кнопки не будут работать. Третье поле - boxchecked. Оно хранит количество отмеченных флажков. Кнопки редактирования и удаления проверяют условие превышения этой величиной нуля, в противном случае не позволяя отправление данных формы. Четвертое поле - это поле контроллера, используемое для определения того, что данные, отправленные из этой формы, будут обработаны контроллером hello. Полный код файла default.php: <?php /**
* Default admin hello view for Hello World Component
* * @package Joomla.Tutorials
* @subpackage Components
* @link http://dev.joomla.org/component/option,com_jd-wiki/Itemid,31/id,tutorials:modules/
* @license GNU/GPL
*/
defined('_JEXEC') or die('Restricted access');
?>
<form action="index.php" method="post" name="adminForm">
<div id="editcell">
<table class="adminlist">
<thead>
<tr>
<th width="5">
<?php echo JText::_( 'ID' ); ?>
</th>
<th width="20"> <!-- checkbox to check all items -->
<input type="checkbox" name="toggle" value="" onclick="checkAll( <?php echo count($this->items); ?> );" /> </th>
<th>
<?php echo JText::_( 'Greeting' ); ?>
</th>
</tr> </thead>
<?php
$k = 0;
for ($i=0, $n=count( $this->items ); $i < $n; $i++)
{
$row => $this->items[$i];
$checked = JHTML::_('grid.id', $i, $row->id ); $link = JRoute::_( 'index.php?option=com_hello>controller=hello>task=edit>cid[]='. $row->id );
?>
<tr class="<?php echo "row$k"; ?>">
<td>
<?php echo $row->id; ?>
</td>
<td>
<?php echo $checked; ?> </td>
<td>
<a href="<?php echo $link; ?>"><?php echo $row->greeting; ?></a>
</td>
</tr>
<?php
$k = 1 - $k; }
?>
</table>
</div>
<input type="hidden" name="option" value="com_hello" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="boxchecked" value="0" />
<input type="hidden" name="controller" value="hello" />
</form>
Теперь код Представления hellos завершен. Можно загрузить компонент, чтобы увидеть результаты.
Расширение возможностей административной части
После того как представление Hellos завершено, необходимо изменить представление и модель Hello. Настоящая работа выполняется именно здесь. Контроллер Hello
Единственной работой контроллера по умолчанию является отображение представлений. Необходимо иметь возможность выполнять задачи, запускаемые из представления Hellos: добавлять, изменять и удалять.
Фактически, добавление и изменение являются одним и тем же заданием: они оба отображают пользователю форму, позволяющую редактировать приветствие. Единственная разница в том, что при создании отображается пустая форма, а при изменении - форма с данными. Поскольку они являются похожими, можно выполнять задачу добавления с помощью обработчика задачи изменения. Это указывается в нашем конструкторе: /**
* constructor (registers additional tasks to methods)
* @return void
*/
function __construct()
{
parent::__construct();
// Регистрация дополнительных задач $this->registerTask('add','edit');
}
Первый параметр JController::registerTask является задачей, второй - метод ее выполнения.
Начнем с обработки задачи изменения. В этом случае работа контроллера проста. Все, что ему нужно - указать представление и макет для загрузки (в нашем случае представление hello и макет формы). Мы также укажем Joomla отключить главное меню во время изменения приветствия. Это предотвращает оставление открытых несохраненных записей. Наш обработчик задачи изменения выглядит следующим образом: /**
* display the edit form
* @return void
*/
function edit()
{
JRequest::setVar( 'view', 'hello' );
JRequest::setVar( 'layout', 'form' );
JRequest::setVar('hidemainmenu', 1);
parent::display();
}
Представление Hello
Представление Hello отображает форму, позволяющую пользователю редактировать приветствие. Метод display должен выполнять несколько простых операций: * получить данные из модели;
* создать панель инструментов;
* поместить данные в шаблон;
* вызвать метод display() для отображения шаблона.
Это немного сложнее, так как одно представление выполняет как редактирование, так и добавление. Наша панель инструментов должна сообщать пользователю о выполняемой в данный момент операции - добавление это или редактирование, то есть нужно определить выполняемую задачу. Когда мы получаем запись для отображения из модели, мы можем использовать эти данные для определения текущей задачи. Если задачей является редактирование, значит, поле id записи было изменено. Если это новая задача, значит, его значение не будет установлено. Эта деталь может помочь определить, создается ли новая запись, или редактируется существующая. Также добавим на панель инструментов две кнопки: "save" и "cancel". Функциональность будет практически одинаковой, но в зависимости от текущей задачи отображаться будут разные кнопки. В случае новой записи будет отображаться кнопка "cancel", а в случае изменения существующей - кнопка "close". Метод display будет выглядеть так: /**
* display method of Hello view
* @return void
**/
function display($tpl = null)
{
//получаем приветствие
$hello => $this->get('Data');
$isNew = ($hello->id < 1);
$text = $isNew ? JText::_( 'New' ) : JText::_( 'Edit' );
JToolBarHelper::title( JText::_( 'Hello' ).': <small><small>[ ' . $text.' ]</small></small>' );
JToolBarHelper::save();
if ($isNew) {
JToolBarHelper::cancel();
} else {
// для существующих записей кнопка переименовывается на `close`
JToolBarHelper::cancel( 'cancel', 'Close' );
}
$this->assignRef('hello', $hello);
parent::display($tpl);
}
Модель Hello
Для нашего представления необходимы данные. Это значит, что нужно создать соответствующую модель. У нашей модели будут два свойства: _id и _data. _id будет хранить идентификатор приветствия, data - данные. Начнем с конструктора, который получает id из запроса: /**
* Constructor that retrieves the ID from the request
*
* @access public
* @return void
*/
function __construct()
{
parent::__construct();
$array = JRequest::getVar('cid', 0, '', 'array');
$this->setId((int)$array[0]);
}
Метод JRequest::getVar() используется для получения данных из запроса. Первым параметром является имя переменной формы. Второй параметр - значение по умолчанию для присвоения в случае, если значение не найдено. Третий параметр - это имя хэша для получения значения из get, post, и т.д., и последнее значение - тип данных, который следует установить для значения. Конструктор получит первое значение из массива cid и присвоит его id. Метод setId() может использоваться для установки id. Изменение id, на которое указывает наша модель, означает, что points указывает на неправильные данные. Следовательно, устанавливая значение id, мы очищаем свойство data: /**
* Method to set the hello identifier
*
* @access public
* @param int Hello identifier
* @return void
*/
function setId($id)
{
// Устанавливаем id и удаляем данные
$this->_id = $id;
$this->_data = null;
}
Теперь нужен метод для получения data: getData().
getData проверит, установлено ли значение свойства _data. Если да, он просто возвратит его. В противном случае будут получены данные из базы данных. /**
* Method to get a hello
* @return object with data
*/
function &getData()
{
// Загружаем данные
if (empty( $this->_data )) {
$query = ' SELECT * FROM #__hello '.
' WHERE id = '.$this->_id;
$this->_db->setQuery( $query );
$this->_data = $this->_db->loadObject();
}
if (!$this->_data) {
$this->_data = new stdClass();
$this->_data->id = 0;
$this->_data->greeting = null;
}
return $this->_data;
}
Форма
Осталось - создать форму для данных. Поскольку мы определили макет как формы, форма будет размещена в файле каталога tmpl представления hello под именем form.php: <?php defined('_JEXEC') or die('Доступ ограничен!'); ?>
<form action="index.php" method="post" name="adminForm" id="adminForm">
<div class="col100">
<fieldset class="adminform">
<legend><?php echo JText::_( 'Details' ); ?></legend>
<table class="admintable">
<tr>
<td width="100" align="right" class="key">
<label for="greeting">
<?php echo JText::_( 'Greeting' ); ?>:
</label>
</td>
<td>
<input class="text_area" type="text" name="greeting" id="greeting" size="32" maxlength="250" value="<?php echo $this->hello->greeting;?>" />
</td>
</tr>
</table>
</fieldset>
</div>
<div class="clr"></div>
<input type="hidden" name="option" value="com_hello" />
<input type="hidden" name="id" value="<?php echo $this->hello->id; ?>" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="controller" value="hello" />
</form>
Обратите внимание: в дополнение к полю ввода присутствует скрытое поле для id. Пользователь не должен изменять id, поэтому мы просто незаметно помещаем его в форму. Реализация функций
Наш контроллер выполняет только две задачи: создание и изменение. Однако у нас есть кнопки также для сохранения, удаления записей, и отмены. Нужно написать соответствующий код для выполнения этих задач. Сохранение записи
Следующим шагом необходимо реализовать сохранение записи. Это потребует использование выбора для обработки различных ситуаций, например, различия между созданием новой записи (запрос INSERT), и обновлением существующей записи (запрос UPDATE). Существует несколько нюансов, связанных с получением данных из формы и помещения их в запрос. Фреймворк Joomla облегчает выполнение многих задач. Класс JTable упрощает управление записями в базе данных без необходимости заботится о написании SQL-кода, лежащего в основе этих операций. Он также облегчает перенос данных из HTML-форм в базу данных. Создание класса Table
Класс JTable является абстрактным классом, от которого можно получить производные классы для работы с конкретными таблицами. Для его использования нужно просто создать класс, расширяющий класс JTable, добавить поля вашей базы данных как свойства, и переназначить конструктор для указания имени таблицы и первичного ключа. Вот как выглядит наш класс JTable:
<?php
/**
* Hello World table class
* * @package Joomla.Tutorials
* @subpackage Components
* @link http://dev.joomla.org/
* @license GNU/GPL
*/
// Прямой доступ отсутствует
defined('_JEXEC') or die('Доступ ограничен!');
/**
* Hello Table class
*
* @package Joomla.Tutorials
* @subpackage Components
*/
class TableHello extends JTable
{
var $id = null;
var $greeting = null;
/**
* Constructor
*
* @param object Database connector object
*/
function TableHello(> $db) {
parent::__construct('#__hello', 'id', $db);
}
}
?>
Мы определили два поля: идентификатор и приветствие. Затем был определен конструктор, вызывающий конструктор родительского класса и передающий ему имя таблицы (#__hello), имя поля, являющегося первичным ключом (id), и объект дескриптора базы данных.
Этот файл следует назвать hello.php и поместить в каталог tables в администраторском разделе нашего компонента. Реализация функций в модели
Теперь можно добавить метод в модель для сохранения записи. Назовем этот метод store. Метод store() будет выполнять три вещи: помещать данные из формы в объект TableHello, проверять корректность сформированной записи и сохранять запись в базе данных. Метод будет выглядеть так: /**
* Method to store a record
*
* @access public
* @return boolean True on success
*/
function store()
{
$row => $this->getTable();
$data = JRequest::get( 'post' );
// Переносим данные из полей формы в таблицу hello
if (!$row->bind($data)) {
$this->setError($this->_db->getErrorMsg());
return false;
}
// Проверяем, корректна ли запись
if (!$row->check()) {
$this->setError($this->_db->getErrorMsg());
return false;
}
// Сохраняем таблицу в базу данных
if (!$row->store()) {
$this->setError($this->_db->getErrorMsg());
return false;
}
return true;
}
Этот метод добавляется в модель hello. Метод получает один параметр, являющийся ассоциативным массивом данных, которые мы сохраняем в базу данных. Эти данные могут быть легко получены из запроса, как будет показано далее. Первая строка получает ссылку на объект JTable. Если таблица названа правильно, можно не указывать это имя - класс JModel знает, где его искать. Ранее мы назвали наш класс таблицы TableHello и поместили его в файл hello.php в каталоге tables, класс JModel создаст объект автоматически.
Вторая строка получает данные из формы. Класс JRequest делает эту операцию очень легкой. В данном случае мы получаем все переменные, переданные с помощью метода POST. Они возвращаются в виде ассоциативного массива. Остальное просто - мы получаем, проверяем и сохраняем. Метод bind() копирует значения из массива в соответствующие свойства объекта таблицы. В данном случае он копирует значения идентификатора и приветствия в объект TableHello. Метод check() выполняет проверку данных. В классе JTable() этот метод просто возвращает true. Пока он не представляет какого-либо значения, но в будущем он позволит проверять данные с помощью класса TableHello. Этот метод может быть переназначен в классе TableHello методом, выполняющим необходимые проверки. Метод store() будет помещать данные из объекта в базу данных. Если id равно нулю, будет создана новая запись (INSERT), в противном случае он обновит существующую запись (UPDATE). Добавление задачи в контроллер
Теперь все готово для добавления задачи в контроллер. Поскольку задача называется save, мы должны назвать метод "save". /**
* save a record (and redirect to main page)
* @return void
*/
function save()
{
$model = $this->getModel('hello');
if ($model->store()) {
$msg = JText::_( 'Приветствие сохранено!' );
} else {
$msg = JText::_( 'Ошибка сохранения приветствия' );
}
// Проверяем, возможно ли изменение таблицы....
$link = 'index.php?option=com_hello';
$this->setRedirect($link, $msg);
}
Необходимо вызвать метод store() модели. Затем следует использовать метод setRedirect() для перенаправления к списку приветствий. Также мы задаем сообщение, которое будет отображено вверху страницы. Удаление записи
Реализация функции в модели
В модели мы получаем список ID для удаления и вызываем класс JTable для их удаления: /**
* Method to delete record(s)
*
* @access public
* @return boolean True on success
*/
function delete()
{
$cids = JRequest::getVar( 'cid', array(0), 'post', 'array' );
$row => $this->getTable();
foreach($cids as $cid) {
if (!$row->delete( $cid )) {
$this->setError( $row->getErrorMsg() );
return false;
}
} return true;
}
Вызываем метод JRequest::getVar() для получения данных из запроса, затем вызываем метод delete() для удаления каждой строки. Сохраняя ошибки в модели, мы обеспечиваем возможность получить их позже, если потребуется. Выполнение задачи удаления в контроллере
Это очень похоже на метод save(), выполняющий сохранение: /**
* remove record(s)
* @return void
*/
function remove()
{
$model = $this->getModel('hello');
if(!$model->delete()) {
$msg = JText::_( 'Error: One or More Greetings Could not be Deleted' );
} else {
$msg = JText::_( 'Приветствие удалено' );
}
$this->setRedirect( 'index.php?option=com_hello', $msg );
}
Отмена операции редактирования
Все, что нужно для прерывания операции редактирования - перенаправление на главное представление: /**
* cancel editing a record
* @return void
*/
function cancel()
{
$msg = JText::_( 'Операция прервана' );
$this->setRedirect( 'index.php?option=com_hello', $msg );
}
Теперь у нас есть возможность редактировать элементы, отображаемые в представлении. При создании компонента мы продемонстрировали взаимодействие между моделями, представлениями и контроллерами. Также мы рассмотрели, как класс JTable можно расширить для предоставления простого доступа к таблицам в базе данных. Также можно увидеть использование класса JToolBarHelper для создание панелей кнопок в компоненте для предоставления стандартного вида для различных компонентов. На рисунках 13.1, 13.2 показана установка созданного расширения.
Рисунок 13.1 - Установка модуля
Рисунок 13.2 - Сообщение об успешной установке
На рисунках 13.3 - 13.7 показано работа с компонентом в административной части.
Рисунок 13.3 - Ссылка на расширение в списке компонентов
Рисунок 13.4 - Просмотр записей в административной части
Рисунок 13.5 - Просмотр первой записи
Рисунок 13.6 - Просмотр второй записи
Рисунок 13.7 - Просмотр третьей записи
На рисунке 13.8 показано добавление ссылки на расширение в главное меню сайта.
Рисунок 13.8 - Добавление ссылки на компонент в главное меню сайта
На рисунке 13.9 показана работа созданного компонента на главной странице сайта.
Рисунок 13.9 - Отображение компонента на главной странице
Задание к работе:
Ознакомиться с теоретическим материалом.
Внести изменения в шаблон компонента CMS Joomla - файл com_hello4.zip.
Подключить компонент через панель управления.
Изучить работу компонента на главной странице сайта.
Оформить отчет согласно требованиям.
Отчет должен содержать:
Название и цель работы.
Ход работы с детальным описанием выполненных действий с рисунками.
Экранные формы браузера с загруженными страницами.
Выводы о проделанной работе.
Вопросы для подготовки к защите работы:
Каким образом создаются и используются несколько Контроллеров?
Какая структура компонента при использовании нескольких Контроллеров?
В каких случаях необходимо использовать несколько Контроллеров?
Каким образом автоматизируется обработка данных из базы?
Каким образом компонент получает доступ к панели инструментов?
Лабораторная работа №11
Разработка приложения с помощью технологии ASP.NET
Цель работы: изучение среды разработки Web-приложений Visual Studio 2005 и элементов диалога. Cоздание динамических страниц. Рассмотрение структуры проекта.
Теоретические сведения
Microsoft .NET Framework - это платформа для создания, развертывания и запуска web-сервисов и приложений. Она предоставляет высокопроизводительную, основанную на стандартах многоязыковую среду, которая позволяет интегрировать существующие приложения с приложениями и сервисами следующего поколения, а также решать задачи развертывания и использования интернет-приложений. .NET Framework состоит из трех основных частей - общеязыковой среды выполнения (common language runtime), иерархического множества унифицированных библиотек классов и компонентной версии ASP, называемой ASP .NET.
ASP .NET - это часть технологии .NET, используемая для написания мощных клиент-серверных интернет-приложений. Она позволяет создавать динамические страницы HTML. ASP .NET возникла в результате объединения более старой технологии ASP (активные серверные страницы) и .NET Framework. Она содержит множество готовых элементов управления, применяя которые, можно быстро создавать интерактивные web-сайты. Вы также можете использовать сервисы, предоставляемые другими сайтами, прозрачно для пользователей вашего сайта. В общем, возможности ASP .NET ограничены только вашим воображением
В 2000 году на конференции разработчиков в качестве части новой технологии .NET Microsoft представила ASP+. С выходом .NET Framework 1.0 она стала называться ASP .NET.
ASP .NET - это не продолжение ASP. Это концептуально новая технология Microsoft, созданная в рамках идеологии .NET. В ASP .NET заложено все для того, чтобы сделать весь цикл разработки web-приложения более быстрым, а поддержку - более простой. ASP .NET основана на объектно-ориентированной технологии, но сохранила модель разработки asp: вы создаете программу и помещаете ее в директорию, выделенную сервером, и она будет работать. В ASP .NET появилось много новых функций, а существовавшие ранее в asp значительно усовершенствованы.
В ASP .NET используются компилируемые языки. Во время компиляции проверяется синтаксическая корректность исходного текста. Скомпилированный в промежуточный язык код выполняется быстрее, и он будет таким же независимо от языка, который мы используем. Компилируемые языки поддерживают строгую типизацию.
Компиляция происходит на сервере в момент первого обращения пользователя к странице. Если программист изменил текст страницы, программа перекомпилируется автоматически. При написании кода можно использовать набор компонентов, поставляемых с .NET.
Платформа .NET Framework предоставляет приложениям среду выполнения, сама непосредственно взаимодействуя с операционной системой. Выше лежит интерфейс ASP .NET-приложений, на котором в свою очередь базируются web-формы (ASP .NET-страницы) и web-сервисы. Интерфейс .NET Framework позволяет стандартизировать обращение к системным вызовам и предоставляет среду для более быстрой и удобной разработки. CLR обеспечивает единый набор сервисов для всех языков.
ASP .NET использует технологию доступа к данным ADO .NET, которая обеспечивает единый интерфейс для доступа к базам данных SQL Server и файлам XML. Кроме того, усиленная модель безопасности позволяет обеспечивать защиту клиента и сервера от несанкционированного доступа.
В 2004 году появилась версия ASP .NET 2.0 (бета-версия, окончательный выход - конец 2005 - начало 2006 гг.). Как утверждается, эта версия позволяет сократить объем кодирования на 70%. Новые возможности версии 2.0 - использование шаблонов дизайна страниц (Master Page), упрощенная локализация web-приложений, более 50 новых серверных элементов управления. Цели, которые преследовали разработчики новой версии, - повысить скорость разработки сайтов, масштабируемость, легкость поддержки и администрирования сайтов, скорость работы сервера. Появилась панель оснастки MMC (консоль управления Microsoft), предоставляющая графический интерфейс для управления настройками ASP .NET. Изменять настройки проекта теперь можно и через web-интерфейс. ASP .NET 2.0 поддерживает работу на 64-битных процессорах. Сервис персонализации (personalization) предоставляет готовое решение для хранения персональных данных, непосредственно характеризующих пользователя сайта, - так называемого профиля пользователя (Profile).
Шаблоны дизайна, темы и скины позволяют отлаживать дизайн всего сайта отдельно от его функциональности, темы включают графику и каскадные таблицы стилей.
Предыдущие версии Visual Studio для проектов ASP .NET требовали наличия на машине разработчика сервера IIS. Теперь сервер встроен в среду разработки.
ASP .NET 2.0 и Visual Studio 2005 предоставляют инструменты для легкого построения локализируемых сайтов, которые определяют предпочитаемый язык пользователя и посылают ему страницы на его языке.
Возможность прекомпиляции позволяет обнаружить ошибки до загрузки страниц на сервер. Можно не хранить исходные страницы aspx на сервере, тем самым защищая свою интеллектуальную собственность.
В ASP .NET 2.0 встроена технология автоматического обновления кэширования баз данных. Данные, полученные из базы, хранятся на сервере, и он не обращается к базе для обработки повторного запроса. При изменении базы данных кэш обновляет свое содержимое.
ASP .NET - это технология, а не язык, и позволяет программировать на разных языках - С#, Visual Basic, J#. "В платформе .NET все языки равны, но некоторые - равнее" (Дж. Оруэлл). Вот таким языком и является С#, потому что он был специально создан для этой платформы. Программирование C# позволяет в полной мере использовать концепции, методы и паттерны объектно-ориентированной разработки. Язык Visual Basic 8.0 наделен почти теми же возможностями. Чтобы научиться ASP .NET, вам нужно знать основы HTML, а знание asp не обязательно. Оно может даже помешать, так как придется менять образ мышления. Также для понимания желательно знать CSS и JavaScript.
Первый проект
В начале решите, в какой директории будете создавать страницы. Все файлы, находящиеся в одной директории, считаются единым проектом. Запустите выбранную вами среду разработки. Выберите пункт меню File-New-Website. Появится диалоговое окно. Назначьте в нем имя проекта и выберите язык программирования С#.
По умолчанию проект создается в файловой системе. По желанию его можно создать на HTTP или FTP-сервере. Из файловой системы проект всегда можно скопировать на сервер нажатием одной кнопки в заголовке Solution Explorer.
В проекте будет создана страница default.aspx. Выберите ее, и появится окно редактирования с закладками Design и Source. Не меняя ничего, щелкните на кнопке со стрелкой, чтобы просмотреть страницу в браузере. Появится окно, в котором спрашивается, нужно ли добавить в файл web.config возможность отладки. Нажмите "OK". На панели задач должен появиться значок web-сервера. Откроется браузер, показывающий страницу по адресу http://localhost:номер_порта/Website1/default.aspx. "Localhost" обозначает сервер, работающий на вашем компьютере. Встроенный сервер Cassini сам назначает себе номер порта - для каждого проекта он разный. Сервер IIS обычно работает через порт 80 (или 8080, если тот занят), и для него номер порта указывать не нужно. При этом ваша страница будет скомпилирована.
Пока что страница в браузере пустая.
Но исходный код этой страницы не пустой. Программа сгенерировала код для вас.
<%@ Page Language="C#" AutoEventWireup="true"; CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"; "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
</html>
Разберем эту страницу:
<%@ Page Language="C#" %>. Тег <% всегда предназначается для интерпретации ASP-кода. Директива Page всегда присутствует на странице aspx. Ее атрибут Language - это указание, что в скриптах данной страницы будет использоваться C#, а могли бы VB, C++ или J#. CodeFile - имя файла с отделенным кодом (code-behind). Inherits - класс, определенный в том файле, от которого наследуется класс страницы.
Одновременно будет создан и файл Default.aspx.cs.
Это технология разделения кода, о которой мы уже говорили. Сама форма находится в файле Default.aspx, а в файле Default.aspx.cs находится класс страницы на языке C#. Таким образом, дизайн страницы может быть изменен не затрагивая кода страницы, что позволяет разделить ответственность за внешний вид и работу страницы между дизайнером и программистом.
<form runat="server">
Этот тег дает указание компилятору обрабатывать элементы управления страницы. Обратите внимание на то, что данный тег имеет свойство runat, для которого установлено значение "server" (других значений не бывает). При использовании этого свойства элемент управления обрабатывается компилятором, а не передается браузеру "как есть".
Вставьте в Default.aspx между тегами <form> и </form> тег, задающий элемент управления.
<asp:Label id="Time" runat="server"
Text="Текущее время: "
/>
Серверный элемент управления Label является средством размещения на странице текста, который может содержать теги HTML. Изменяя значения свойств этого элемента управления в коде, вы можете динамически изменять текст на странице. В asp:Label компилятору сообщается, с каким объектом ведется работа (в рассматриваемом случае - с элементом управления Label).
В файле Default.aspx.cs должен содержаться такой текст:
using System;
......
public partial class _Default : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e)
{
}
}
Ключевое слово partial появилось в C# 2.0, и позволяет разбить текст определения класса между разными файлами.
System.Web.UI.Page - класс, базовый для всех страниц ASP .NET.
Если вы работаете с WebMatrix, вставьте его самостоятельно между тегами <script> и </script> файла default.aspx.
Вставьте в эту функцию строчку
Time.Text+=DateTime.Now.ToString();
Возможно, вы уже знакомы с классом System.DateTime библиотеки классов FCL - составной части .NET Framework. Здесь мы используем этот класс, как в любой программе на C#. Следовательно, любой класс .NET доступен и в локальных, и в распределенных приложениях.
Полученное значение присваивается свойству Text объекта time. Это элемент управления типа Label (метка), который мы вставили. Время на часах клиента и сервера может не совпадать, если они находятся в разных точках земного шара.
Page_Load похож на обычный обработчик события формы. Как можно легко догадаться, эта функция вызывается каждый раз, когда загружается форма.
Задание на работу
1 Изучить оболочку Visual Studio
2 Рассмотреть палитру элементов управления и визуальных компонент
3 Выполнить учебный проект
4 Согласно вариантам выполнить индивидуальное задание:
Разработать приложение, содержащее две формы с использованием указанных элементов и обрабатывающее полученные данные с выдачей результатов. Добавить вывод клиенту указанных переменных окружения (Request["REMOTE_ADDR"];). ВариантЭлемент диалогаЭлемент диалогаПеременная окруженияПеременная окружения1LabelCheckBoxAUTH_TYPECONTENT_LENGTH2ListBoxRadioButtonCONTENT_TYPEGATEWAY_INTERFACE3PasswordSelectREMOTE_ADDRREMOTE_HOST4HiddenRadioButtonREMOTE_USERREQUEST_METHOD5TextBoxHyperLinkSCRIPT_NAMESERVER_NAME6LinkButonSelectSERVER_PORTSERVER_PROTOCOL7CheckBoxListListBoxSERVER_SOFTWAREHTTP_USER_AGENT8DropDowListLinkButtonREMOTE_HOSTAUTH_TYPE9CalendarTextBoxREQUEST_METHODCONTENT_TYPE10BulletedListLabelCONTENT_LENGTHSERVER_PORT11LinkButtonTextBoxSERVER_PROTOCOLSCRIPT_NAME12HiddenSelectHTTP_USER_AGENTREMOTE_USER13CheckBoxListBoxSERVER_NAMESERVER_PORT14PasswordLiteralGATEWAY_INTERFACEREMOTE_ADDR15ImageButtonTextBoxREMOTE_HOSTHTTP_USER_AGENT
Примечание:
Преобразование строки в число: int result = int.Parse(TextBox1.Text) * 2;
Работа с сессией: protected void LinkButton1_Click(object sender, EventArgs e)
{
Session["myvariable"] = "value1"; // запись значения в сессию
Response.Redirect("~/my2.aspx"); // переадресация на страницу my2.aspx
}
my2.aspx
if (Session["myvariable"] != null)
{ Label1.Text = (string)(Session["myvariable"]); }
Лабораторная работа №12
Авторизация. Поддержка сеанса пользователя
Цель работы: изучение возможностей технологии ASP.NET при разработке безлопастных приложений. Теоретические сведения
Важная часть многих web-приложений - возможность контролировать доступ к ресурсам. Безопасность проекта вращается вокруг двух концепций - аутентификации и авторизации. Аутентификация - процесс определения личности пользователя. Авторизация - процесс определения прав пользователя на доступ к определенным ресурсам, на просмотр некоторых разделов, на возможность редактирования информации и так далее.
Для авторизации пользователь вводит пользовательское имя, под которым зарегистрирован(а), и пароль. После этого приложение определяет возможность доступа к ресурсам, а также может видоизменять как внешний вид с помощью тем, так и содержание генерируемых страниц. К примеру, в форуме записи могут показываться в виде дерева или линейно.
В ASP .NET 2.0 аутентификацией управляют с помощью службы Membership, которая позволяет определить различные виды членства на сайте. Информацию о членах можно хранить в различных местах - в базах данных, текстовых файлах или даже в учетных записях Windows. Конфигурировать членство можно индивидуально для каждого пользователя или на основе ролей с помощью сервиса Role Manager. Роли облегчают конфигурирование, так как можно создавать роли и потом добавлять пользователей к готовым ролям. Любому пользователю может принадлежать любое количество ролей.
По умолчанию службы используют провайдера AspNetSqlProvider. В таком случае ASP .NET автоматически создает базу данных ASPNETDB.MDF в директории проекта App_Data, когда запускается команда ASP.NET Configuration - или программно, или с помощью элементов управления группы Login задействуются службы Membership или Role Manager. Служба Membership также обеспечена провайдером, работающим с Active Directory. Создать пользователей и назначить им роли можно во встроенном приложении ASP .NET Configuration. Информация о пользователях хранится в таблицах aspnet_Users, aspnet_UsersInroles, aspnet_Membership. Пароли хранятся в зашифрованном с помощью хэш-функции виде. Даже администратор не может его подсмотреть. Пароль, который вводится в момент аутентификации, тоже хэшируется и сравнивается со значением в базе. Хранение в незашифрованном виде - это угроза безопасности.
Любой пользователь может зарегистрироваться, но при этом не получит роли и у него не будет новых прав, пока администратор не назначит ему роли.
В этом приложении можно также создавать правила доступа.
Настройки конфигурации служб Membership и Role Manager, конечно же, записываются в файл Web.config:
<roleManager enabled="true" />
Таким образом включается служба Role Manager.
Элемент authentication mode определяет способ аутентификации. Если это Forms, то свои имя и пароль пользователь вводит в форме. В локальной сети (интранет) можно аутентифицировать пользователей по их учетной записи, тогда его значение ставится как Windows.
С помощью элемента authentication запускается служба Membership:
<authentication mode="Forms">
<forms loginUrl ="Login.aspx"/>
</authentication>
При значении Passport пользователи авторизуются с помощью паспорта от Microsoft.
При аутентификации с помощью форм пользователи получают доступ к страницам в зависимости от данных, введенных на форме. До входа на сайт пользователь считается анонимным и используется анонимная аутентификация. Всего у элемента forms 8 возможных атрибутов:
nameОпределяет имя файла- cookie, который посылается пользователям после аутентификации. По умолчанию он называется .ASPXAUTHloginUrl:URL страницы, с которой можно войти в систему. По умолчанию это Login.aspxprotection:Уровень защиты файла- cookie на пользовательской машине. Возможные значения - All, None, Encryption, и Validationtimeout:Время, по истечении которого cookie устаревает. Значение по умолчанию - 30 минутpath:Путь к файлам cookierequireSSL:Нужно ли шифровать данные по протоколу SSLslidingExpiration:Если True, то cookie устаревает через период времени timeout после последнего запроса. Иначе - через период времени timeout после созданияcookieless:Место хранения идентификатора пользователя. Значение по умолчанию useDeviceProfile По умолчанию всем пользователям доступны все страницы приложения. Если нужно ограничить доступ пользователей к какой-нибудь странице, в Web.config вводится запись:
<location path="Admin.aspx">
<system.web>
<authorization>
<allow roles="Admin" />
<deny users="*" />
</authorization>
</system.web>
</location>
Значение "?" обозначает анонимного пользователя, а "*" - всех пользователей:
<allow users="?" />
В элементах allow и deny пользователи и роли могут быть заданы перечислением:
<allow users="Alex, Dave" />
Элемент location определяет часть сайта, доступ к которой нужно ограничить. В данном случае это одна страница Admin.aspx. Первая часть авторизации разрешает доступ к ней пользователям в роли администратора Admin. Вторая запрещает доступ всем остальным пользователям.
Если элемент system.web находится в корневом узле файла, то вложенный в него узел authorization определяет настройки доступа ко всему сайту.
Когда неавторизованный пользователь пытается получить доступ к странице, открывается форма, определенная в атрибуте forms loginUrl. Если он введет имя и пароль пользователя, который имеет доступ к странице, то она откроется, иначе опять ему или ей будет показана форма логина.
Часто бывает нужно сконфигурировать с точки зрения безопасности систему навигации. Это значит, что меню не должно показывать те страницы, для просмотра которых пользователь не авторизован:
<siteMap defaultProvider="AspXmlSiteMapProvider" enabled="true">
<providers>
<clear/>
<add name="AspXmlSiteMapProvider" type="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
siteMapFile="web.sitemap" securityTrimmingEnabled="true"/>
</providers>
</siteMap>
Здесь атрибут securityTrimmingEnabled, установленный в true, заставляет провайдера карты сайта фильтровать узлы в зависимости от роли пользователя. Это значит, что в элементах навигации будут видны только доступные страницы.
Член User страницы позволяет получить доступ ко всей информации, касающейся текущего пользователя.
Метод IsInRole определяет, принадлежит ли пользователь к роли:
if (User.IsInRole("Admin"))
Page.Title = "Hello, Administrator!";
Свойство Identity дает информацию об аутентификации пользователя:
if (User.Identity.IsAuthenticated)
//выполнить код, если пользователь легален
User.Identity.AuthenticationType показывает способ авторизации, установленный в Web.config.
Можно ограничить доступ не только к страницам, но и к частям страниц.
Элементы управления группы Login
Мы уже создавали формы регистрации. Это было только упражнение, так как элементы управления этой группы могут брать на себя регистрацию и авторизацию пользователей, восстановления пароля и другие функции, взаимодействуя при этом с системой Membership и Roles. Группа Login находится в панели инструментов.
Элемент управления LoginName позволяет показать имя пользователя:
Заходите еще, <asp:LoginName ID="FCLoginName" Runat="server" />
Отображаемый текст можно форматировать с помощью FormatString:
<asp:LoginName ID="HelloLoginName" Runat="server" FormatString="Hello, {0}" />.</p>
LoginStatus - это умный элемент управления. Если пользователь не аутентифицирован, отображается гиперссылка Login на страницу входа на сайт. Если пользователь авторизован, это ImageButton с командой Logout. Если ее нажать, то пользователь выходит из системы. Текст ссылок можно менять в свойствах LoginText и LogoutText или использовать изображения:
<asp:LoginStatus ID="LoginStatus1" runat="server" LoginText="Вход" LogoutText="Выход" />
<asp:LoginStatus ID="LoginStatus2" runat="server" LogoutAction="Redirect" LogoutPageUrl="~/Default.aspx" LoginImageUrl="~/Images/arrow_next.gif" LogoutImageUrl="Images/arrow_prev.gif" />
Нажатие на ссылку Logout в этом случае перенаправит пользователя на страницу Default.aspx.
Элемент управления LoginView состоит из двух шаблонов: AnonymousTemplate и LoggedInTemplate. Который из них используется для отображения, зависит от того, просматривает ли страницу анонимный пользователь или авторизованный.
СreateUserWizard позволяет создавать пользователей, используя службу Membership. Естественно, в нем происходит валидация введенных данных. Например, длина пароля должна быть не меньше 7 знаков и в нем должен присутствовать хотя бы один символ - не буква и не цифра. Обязательно заполнение контрольного вопроса и ответа, по которым можно будет восстановить пароль, если он забыт, или изменить пароль
Персонализация
Многие сайты собирают информацию о пользователях, чтобы подстроить показ информации под их личные вкусы. Часто для этого используют файлы-cookie, объекты приложения и сессии.
В ASP .NET 2.0 появились новые удобные способы хранить пользовательскую информацию. Это функция персонализации. Механизм персонализации позволяет установить прямую связь между пользователем и всеми данными, относящимися к нему. При этом его настройки хранятся не в файлах-cookie на компьютере пользователя, которые он может стереть, а на сервере. Их можно поместить в любое хранилище данных.
Модель персонализации проста и расширяема.
В файле web.config содержится информация о том, какие данные о пользователе необходимо хранить. Она записывается в секции <configuration><system.web> перед секцией authentication:
<profile>
<properties>
<add name="FirstName" />
<add name="LastName" />
<add name="LastVisited" />
<add name="Age" />
<add name="Member" />
</properties>
</profile>
Профиль персонализации может хранить данные об авторизированном пользователе, но может обслуживать и анонимного пользователя. По умолчанию анонимная персонализация выключена. Чтобы ее включить, нужно в файле web.config создать запись
<anonymousIdentification enabled="true" />
(также в секции <system.web>).
Когда анонимная персонализация включена, ASP .NET хранит уникальный идентификатор для каждого анонимного пользователя. Он посылается вместе с любым запросом. Идентификатор хранится в файле-cookie пользователя, а дополнительные данные, которые удалось собрать о его предпочтениях, - на сервере. По умолчанию имя файла-cookie - .ASPXANONYMOUS. Его можно поменять с помощью атрибута cookieName элемента anonymousIdentification:
<anonymousIdentification enabled="true" cookieName=".intuit"/>
Время хранения файла-cookie в минутах определяется атрибутом cookieTimeout.
По умолчанию оно равно 100 000 минутам (69,4 дня).
От использования cookie можно отказаться, например, написав
cookieless="UseUri"
В таком случае идентификатор передается через строку URL:
cookieless="AutoDetect"
В этом случае определяются настройки пользователя. Если возможность хранить cookie выключена, используется строка URL.
Анонимный идентификатор по своей сути представляет собой GUID (32-байтное число, алгоритм генерации которого гарантирует глобальную уникальность). Свойство AnonymousId объекта Request страницы позволяет получить к нему доступ.
Для того чтобы определить, какие данные можно хранить для анонимного пользователя, в элемент add name определяют атрибут allowAnonymous:
<add name="LastVisited" allowAnonymous="true"/>
Пример использование компонентов Login , UserWizard
для авторизации пользователей (Toolbox - Login)
"LoginStatus": Cвойства (EnableViewState - True). "Login": Свойство (CreateUser Text - Create new)
Для Log In :
public partial class _Default : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Login1_LoggedIn(object sender, EventArgs e)
{
bool is_admin = Roles.IsUserInRole(Login1.UserName, "admin");
if (is_admin) Response.Redirect("~/admin/admin.aspx");
else Response.Redirect("~/user/user.aspx");
}
}
На форме Regist/ login.aspx использование компонента "UserWizard": Свойство ContinueDestinitionPageUrl и FinishDestinitionPageUrl : ~/Default.aspx
Для события CreatedUser выбрать CreateUserWizard1
protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
{
Roles.AddUserToRole(CreateUserWizard1.UserName, "user");
}
Настройка доступа и пользователей: ASP.NET Configuratio:
Назначить пользователям роли (Manager users).
Установить права на каталоги:
Настройка файла Web.config :
Web.config
<connectionStrings/>
<system.web>
<roleManager enabled="true" />
<compilation debug="true">
</compilation>
<authentication mode="Forms">
<forms defaultUrl="default.aspx" loginUrl="~/register/login.aspx"></forms>
</authentication>
Использование Cookie и Session:
Default.aspx
using System.Web.SessionState;
protected void Button1_Click(object sender, EventArgs e)
{
TextBox1.Text = Session.SessionID;
if ((Response.Cookies["myCookie"] == null) ||
(Response.Cookies["myCookie"].Value == null))
{
HttpCookie objCookie = new HttpCookie("myCookie", TextBox2.Text);
//objCookie.Values.Add("value_cookie", "11");
objCookie.Expires = DateTime.Today;
Response.Cookies.Add(objCookie);
}
Label1.Text = Response.Cookies["myCookie"].Value;
}
protected void LinkButton1_Click(object sender, EventArgs e)
{Session["myvariable"] = "value1";
Response.Redirect("~/user/user.aspx");
}
В др. модуле считать сессию:
if (Session["myvariable"] != null)
// { Label1.Text = (string)((ArrayList)Session["myvariable"])[0]; }
{ Label1.Text = (string)(Session["myvariable"]); }
else { Label1.Text = " null"; }
Задание на работу
1 Рассмотреть возможности технологии ASP.NET для разработки защищенного приложения
2 Выполнить учебный проект (см. пример использования)
3 На основе лабораторной работы 3 разработать структуру приложения для разных групп пользователей (например, admin и user), выделив отдельные папки для каждой роли пользователей. 4 Реализовать работу с БД пользователей для выполнения основных операций добавления, удаления и редактирование в режиме администратора. Использовать все элементы управления из ToolBox раздела "Login"
Лабораторная работа №13
Работа с БД в ASP.NET
Цель работы: изучение среды разработки Visual Studio 2005 и элементов управления для работы с БД. Изучение классов и объектов ADO .NET Теоретические сведения
Для хранения данных чаще всего используются СУБД (системы управления базами данных). В ASP .NET 2.0 работа с данными происходит через ADO .NET 2.0 - часть .NET, разработанная специально для доступа к базам данных или XML-файлам.
Веб-проект в Visual Studio 2005 содержит предопределенную папку App_Data. В ней могут храниться файлы с данными, которые используются в приложении. Это могут быть файлы .mdf (MS SQL), .mdb (Microsoft Access), .xml и другие.
Классы ADO .NET объединены в несколько пространств имен.
System.Data - это ядро ADO .NET. Оно содержит классы, необходимые для связи посредством любых провайдеров данных. Эти классы представляют таблицы, строки, столбцы, DataSet (множество взаимосвязанных таблиц). Там определены интерфейсы (в смысле языка C#) соединений с базами данных, команд, адаптеров данных.
System.Data.Common - базовые классы для всех провайдеров данных - DbConnection, DbCommand, DbDataAdapter.
В System.Data.OleDb находятся классы, позволяющие работать с источниками данных OleDb, в том числе с MS SQL версии 6.0 и ниже. Там находятся такие классы, как OleDbConnection, OleDbDataAdapter и OleDbCommand.
System.Data.Odbc содержит классы, которые работают с источниками данных ODBC посредством провайдера .NET ODBC. Классы имеют аналогичные имена с префиксом Odbc.
System.Data.SqlClient. Здесь определен провайдер данных для СУБД SQL Server версии 7.0 и выше. Содержатся классы SqlConnection, SqlTransaction, SqlCommand и другие.
В System.Data.SqlTypes находятся классы, представляющие типы данных СУБД SQL Server.
Схема типичной программы в ADO .NET следующая:
1 Вначале создается соединение с базой данных - класс Connection, который обеспечивается необходимой информацией - строкой соединения.
2 Создается объект Command и задается команда, которую необходимо выполнить в данной СУБД. Эта команда может быть запросом SQL или исполняемой процедурой. Нужно задать параметры этой команды, если они имеются.
3 Если команда не возвращает данных, она просто выполняется с помощью одного из методов Execute. Например, это может быть удаление или обновление данных таблицы.
4 Если команда возвращает выборку данных, их необходимо куда-то поместить. Решите, нужно ли вам получить данные для последующего использования без связи с базой данных или же нужно просто быстро выполнить команду. В первом случае нужно создать класс DataAdapter и с его помощью сохранить данные в DataSet или в DataTable. Во втором случае создается класс DataReader, который требует сохранять соединение на все время работы, хранит выборку только для чтения и позволяет двигаться только вперед. Зато чтение с помощью DataReader выполняется в несколько раз быстрее, чем в DataAdapter.
5 Задать полученный DataSet или DataReader как источник данных элемента управления или вывести их на страницу другим способом.
Задание на работу
1 Рассмотреть возможности элементов управления для работы с БД.
2 Выполнить учебный проект (см. файл "пример работы с БД.doc")
3 Согласно вариантам реализовать работу с объектами предметной области с помощью БД (Документация - см. в файле "asp-net.pdf"). Представить ER-диаграмму (степень связи между сущностями 1:n).
4 Выполнить основные CRUD-операции: добавление, удаление, редактирование, поиск элементов. Перечень объектов для реализации в БД
Вариант Название сущностей1Группы - Студенты2Проект- Списки дел3Вопросы - Ответы4Папки - Файлы5Страна - Туры 6Каталог - Продукты 7Роли - Пользователи 8Пользователи - сообщения 9Прайс-лист - Продукты 10Команда - Игрок
Лабораторная работа №14
Оформление дизайна страниц в ASP.NET
Цель работы: изучение возможностей технологии ASP.NET при оформлении страниц. Теоретические сведения
Шаблоны дизайна - это визуальное наследование страниц, впервые появившееся в ASP .NET 2.0. Вы можете создавать основу для любого количества страниц приложения. Шаблоны позволяют легче создавать и поддерживать приложения. Visual Studio 2005 включает поддержку создания и редактирования шаблонов страниц.
Для простого пользователя отличие одного сайта от другого - в разнообразном дизайне страниц. Большинство web-сайтов сегодня имеют узнаваемый дизайн, который достигается использованием одних и тех же элементов в тех же самых местах в разных страницах сайта. Поэтому дизайн страниц является едва ли менее важным, чем общая функциональность.
Основы Master Pages
С помощью шаблонов страниц вы определяете некоторое общее содержание и помещаете его в страницу с расширением .master. Естественно, таких страниц в приложении может быть несколько. Этот шаблон могут использовать любое количество дочерних страниц, которые, как и обычные страницы, имеют расширение aspx.
В страницу шаблона также включают общие заголовки и нижние колонтитулы.
Это единственный тип страниц, где возможно разместить специальные элементы управления ContentPlaceHolder. Они определяют место, в которое дочерние страницы данного мастера могут помещать свое собственное содержание. Когда ASP .NET получает запрос отобразить дочернюю страницу, она сливает ее код с кодом главной страницы, в результате генерируется HTML, в котором не видно никаких "швов".
Когда дочерняя страница редактируется в среде разработки, на вкладке Design видна полная страница вместе с элементами из шаблона, но они показаны серым цветом. Их редактировать нельзя. Можно редактировать то, что находится в элементах Content.
В диалоге Add New Item выберите тип страницы Master Page. Как и обычные страницы, их можно создавать с отделенным кодом или кодом, встроенным в страницу. Это никак не влияет на модель разделения кода дочерних страниц. Кроме того, главная и дочерняя страницы могут разрабатываться на разных языках.
Первое отличие этой страницы от обычной в том, что она начинается с директивы Master, а не Page. Класс мастер-страницы определен в файле MasterPage.master.cs:
public partial class MasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
Класс шаблона - наследник System.Web.UI.MasterPage, который в свою очередь наследует от System.Web.UI.UserControl.
В ней могут находиться любые элементы управления и HTML-код. В ней могут обрабатываться и события страницы. Два элемента ContentPlaceHolder обозначают места, куда вставляется содержание страницы-наследницы.
<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="MainSchool.aspx.cs" Inherits="MainSchool" Title="Untitled Page" %>
Атрибут MasterPage директивы Page определяет шаблон дизайна, или эталонную страницу данной страницы.
Возможно настроить приложение так, чтобы все страницы наследовали одну страницу шаблона дизайна. В конфигурационном файле в секцию System.web нужно вставить элемент:
<pages masterPageFile="~/ MasterPage.master " />
Но и в этом случае назначение главной страницы в директиве Page имеет приоритет над назначением на уровне приложения. Установка web.config действует на тех страницах, в которых masterPageFile не указан, но определены элементы управления Content. Эта установка не действует на обычные aspx-страницы.
В странице содержания можно переназначить ее главную страницу программно. Для этого нужно присвоить нужное значение свойству Page.MasterPageFile. Шаблон поменяется независимо от того, какой шаблон был назначен в директиве @Page. Но если попробуете проделать это в функциях Page_Load или Page_Init, получите ошибку времени выполнения.
Это свойство можно изменить только во время обработки события Page_PreInit. Событие Page_PreInit - самая ранняя фаза жизненного цикла страницы, к которой можно получить доступ. Во время события Init главная и дочерняя страница уже сливаются в одну, поэтому поздно менять шаблон. По этой причине событие Page_PreInit - единственное, в обработчике которого можно работать с главной страницей отдельно от страницы содержания:
protected void Page_PreInit(object sender, EventArgs e)
{
Page.MasterPageFile = "~/MyMasterPage.master";
}
Для того чтобы из страницы содержания обратиться к элементам управления главной страницы, можно воспользоваться функцией FindControl. Непосредственно обратиться к ним нельзя, так как это защищенные члены.
Label mpLabel = (Label) Master.FindControl("masterPageLabel");
if(mpLabel != null)
{
//Set content page title to master page control
Title.Text = mpLabel.Text
}
Страницы шаблона могут иметь методы и свойства. Чтобы можно было обращаться к ним, нужно использовать директиву @MasterType. При этом становится доступен класс страницы шаблона дизайна через строго типизированную ссылку. Атрибут TypeName задает имя типа, а VirtualPath - путь относительно корневого каталога web-приложения к файлу шаблона:
<%@ page language="C#" masterpagefile="~/Site3.master" %>
<%@ mastertype virtualpath="~/Site3.master" %>
Свойства могут быть определены в классе главной страницы:
public String FooterText {
get { return Footer.Text; }
set { Footer.Text = value; }
}
Таким образом, страница разрешает доступ извне к свойствам своих элементов.
Страница содержания меняет это свойство, а элемент управления AdRotator находит с помощью FindControl:
void Page_Load()
{
Master.FooterText = "This is a custom footer";
AdRotator ad = (AdRotator)Master.FindControl("MyAdRotator");
if (ad != null)
{
ad.BorderColor = System.Drawing.Color.Purple;
ad.BorderWidth = 10;
}
}
Темы и skin (шкурки)
В интерфейсе почтовой службы Rambler дизайн страниц меняется в зависимости от времени года. Пользователь может сам выбрать себе вариант дизайна. Подобной функциональности в ASP .NET можно добиться с помощью тем.
Темы похожи на CSS тем, что тоже позволяют определять внешний вид страниц. Но темы могут сделать гораздо больше них. Таблицы стилей определяются для тегов HTML, а скины, которые входят в тему, - для элементов управления. Скины применяются на стороне сервера, поэтому могут использоваться для установки специфичных свойств серверных контролов. Например, для элемента управления Calendar таким свойством является DayNameFormat. CSS никак не позволяет оперировать такими свойствами.
Темы можно применять к страницам, к сайту или отдельным элементам управления.
Файлы тем находятся в папке с зарезервированным названием App_Themes. Эту папку можно создать, если в контекстном меню проекта выбрать "Add ASP .NET Folder". В папке App_Themes можно создавать темы, например, для разных времен года. У каждой темы будет свой каталог, в котором будут находиться относящиеся к ней файлы. На многих сайтах пользователь может выбрать тему. Вложение тем друг в друга не допускается.
Каждая тема обычно состоит из одного или нескольких файлов скинов с расширением ".skin", а также других, необходимых для задания внешнего вида сайта файлов, таких как файлы каскадных таблиц стилей, картинок, XSL-преобразований и так далее, которые также могут быть упорядочены в поддиректориях корневой директории темы. Файлы скинов и таблиц стилей обычно расположены в корне темы, а картинки - в поддиректории Images.
Темы можно применить к странице с помощью атрибута Theme директивы Page. Тему можно поменять программно. Поэтому можно дать возможность пользователю выбрать тему. Тему можно установить до или во время события PreInit:
protected void Page_PreInit(object sender, EventArgs e)
{
Page.Theme = "Black";
}
Тему можно применить ко всем страницам приложения, если в файле web.config вставить эту директиву:
<configuration>
<system.web>
<pages theme=" Black " />
</system.web>
</configuration>
Если тема установлена в странице, она имеет преимущество перед глобальной темой. Темы страницы переопределяют свойства элементов управления. Если нужно, чтобы темы не применялись к элементу, нужно установить его свойство EnableTheming в False.
Если нужно отменить применение темы к группе элементов, можно поместить их в Panel и установить его свойство EnableTheming в False.
Свойство EnableTheming можно менять и на уровне страницы:
<%@ Page Language="C#" AutoEventWireup="true" EnableTheming="False"%>
Атрибут StylesheetTheme работает так же, как и Theme. Но если тема установлена с помощью этого атрибута, то свойства управления элемента имеют преимущество перед темой страницы.
В файлах тем с расширением .skin хранятся варианты внешнего вида элементов управления. Перевод термина skin на русский язык не устоялся. Можно называть его "шкурка" или "оболочка".
Скин - это шаблон элемента управления с определением набора визуальных свойств, которые будут использоваться для генерации элементов управления данной темы. Скины могут работать вместе с картинками и таблицами стилей. Один ".skin"-файл может хранить множество разных элементов управления. Например, в проекте "Starter Kit" определены две темы - Black и White. В файле Default.skin обеих тем хранятся скины элементов ImageButton, Image, GridView.
Можно создать столько файлов шкурок, сколько необходимо. Для удобства и ясности можно создать файлы скинов для каждого элемента, например, Label.skin, GridView.skin.
Создайте в папке App_Themes тему Summer. Добавьте в тему скин Calendar.skin.
Описание стиля элемента управления похоже на описание на странице, с тем отличием, что атрибут ControlId не указывается. Однако необходимо указать атрибут runat="server":
<asp:Calendar runat="server" BackColor="Honeydew" BorderColor="Teal" BorderWidth="1px" CellPadding="1" DayNameFormat="Shortest" Font-Names="Verdana" Font-Size="8pt" ForeColor="DarkSlateGray" Height="200px" Width="220px"> <SelectedDayStyle BackColor="#009999" Font-Bold="True" ForeColor="#CCFF99" /> <SelectorStyle BackColor="#99CCCC" ForeColor="#336666" /> <WeekendDayStyle BackColor="#C0FFC0" /> <OtherMonthDayStyle ForeColor="#999999" /> <TodayDayStyle BackColor="#99CCCC" ForeColor="White" /> <NextPrevStyle Font-Size="8pt" ForeColor="#CCCCFF" /> <DayHeaderStyle BackColor="#80FF80" ForeColor="#336666" Height="1px" /> <TitleStyle BackColor="Green" BorderColor="#3366CC" BorderWidth="1px" Font-Bold="True" Font-Size="10pt" ForeColor="White" Height="25px" /> </asp:Calendar>
Теперь на всех страницах, где установлена тема Summer, календарь будет выглядеть так:
У описания шкурки может быть описан атрибут SkinId. Скин с установленным атрибутом SkinID называется именованным скином. Этот атрибут при описании каждого типа элемента управления должен быть уникальным. Скин применяется к тем элементам, у которых значение свойства SkinId совпадает со SkinId описания:
<asp:Label Runat="server" SkinId="June" ForeColor="#Teal" Font-Names="Verdana"
Font-Size="X-Small" />
При этом, если у элемента не определен SkinId, применяется скин, в котором SkinId тоже отсутствует (скин по умолчанию). Этот скин для каждого класса может быть описан только один раз.
Задание на работу
1 Рассмотреть возможности технологии ASP.NET для оформления приложения
2 Выполнить учебный проект (см. файл "к заданию 5.ppt")
3 На основе предыдущего задания разработать дизайн оформления сайта приложения. Использовать возможности MasterPage, Theme и skin.
СПИСОК РЕКОМЕНДОВАННОЙ ЛИТЕРАТУРЫ
1 Kennard, James. Mastering Joomla! 1.5 Extension and Framework Development. - BIRMINGHAM: Published by Packt Publishing Ltd., 2007 - ISBN : 1847192823
2 LeBlanc, Joseph. Learning Joomla! 1.5 Extension Development. - BIRMINGHAM: Published by Packt Publishing Ltd., 2007 - ISBN-10: 1847196209
3 Колисниченко, Д.Н. Joomla 1.5. Руководство пользователя / Д.Н. Колисниченко. - М. : Диалект, 2009. - 210 с. - ISBN 978-5-8459-1509-2
4 Граф, Хаген. Создание web-сайтов с помощью Joomla 1.5!. - Хаген Граф . - М. : Изд. Дом Вильямс, 2008. - 294 с. - ISBN 978-5-8459-1506-1
5 Томсон, Лаура. Разработка Web-приложений на PHP и MySQL : пер. с англ. / Лаура Томсон, Люк Веллинг. - М. : Диасофт, 2002. - 672 с. - ISBN 978-5-8459-0862-9
6 Ратшиллер, Т. PHP4: Разработка web-приложений. Библиотека программиста. - Т. Ратшиллер, Т. Геркен. - СПб.: Питер, 2001. - 384с.:ил. - ISBN 5-318-00007-Х Навчальне видання
WEB-ПРОГРАМУВАННЯ
МЕТОДИЧНІ ВКАЗІВКИ
до лабораторних робіт та самостійної роботи
для студентів очної форми навчання
спеціальності 6.050101
"Інформаційні технології проектування"
(Російською мовою)
УкладачіАлтухов Олександр Валерійович
Таран Светлана Викторівна
Редактор
Комп'ютерна версткаО. П. Ордіна
168/2007. Підп. до друку . Формат 60 х 84/16.
Папір офсетний. Ум. друк. арк. . Обл.-вид. арк. .
Тираж 50 прим. Зам. №
Видавець і виготівник
"Донбаська державна машинобудівна академія"
84313, м. Краматорськ, вул. Шкадінова, 72.
Свідоцтво про внесення суб'єкта видавничої справи до Державного реєстру
серія ДК №1633 від 24.12.03.
1
Документ
Категория
Без категории
Просмотров
1 415
Размер файла
4 298 Кб
Теги
web, lab, programmirovania, rab
1/--страниц
Пожаловаться на содержимое документа