Практическая работа №2. Разработка веб-приложения с динамически подключаемыми модулями

Опубликовано пользователем Бессонов Л.В. 04.02.2010г.

Цель работы

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

Теоретические материалы

  1. Понятие обратного вызова
  2. Пример написания системы подключающей плагины

Варианты индивидуальных заданий

Во всех заданиях подразумевается что файлы плагинов имеют имена, удовлетворяющие маске "*.plugin.php".

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

Вариант 1

Приложение «Автозамена» прочитывает из файла 'input.txt' текст. Плагины содержат функции (одна функция в каждом плагине) '<имя модуля>_autochange($text)', получающие в аргументе текст и осуществляющие некоторую текстовую замену.

Сделайте плагины замены:

  1. «о» на «а»;
  2. «е» на «и»;
  3. «ё» на «е».

Вариант 2

Приложение «Аналитик» прочитывает из файла 'input.txt' текст. Плагины содержат функции (две функция в каждом плагине):

  1. '<имя модуля>_info()' — возвращает название анализируемого показателя;
  2. '<имя модуля>_analysis($text)' — возвращает число-значение анализируемого показателя.

Сделайте плагины анализа:

  1. Количество гласных букв в тексте;
  2. Количество согласных букв в тексте;
  3. Количество цифр в тексте.

Пример выполнения задания

Задача

Приложение «Линейная алгебра» должно вычислять нормы двумерных векторов (каждый элемент вектора — число). Правила вычисления нормы заведомо неизвестны.

Приложение находит и подключает файлы по маске *.plugin.php

Каждый файл плагина содержит две функции:

  1. <имя плагина>_info() — возвращает строку с названием соответствующей нормы
  2. <имя плагина>_norm($v=array()) — вычисляет норму вектора, переданного в аргументе

Приложение должно вычислять все «известные» ему варианты норм, выводя пары (Название нормы, Значение нормы).

Ход решения

Напишем саму систему, подключающую плагины. Алгоритм действия системы:

  1. Прочитать все элементы каталога
  2. Выделить среди них файлы, имя которых заканчивается на '.plugin.php'
  3. Подключить эти файлы
  4. Вызвать функции из плагинов для расчёта заданного вектора

Файл algebra.php

  1. <?php
  2. $dir = opendir("./" );
  3. $plugins = array();
  4. while($any_file = readdir($dir)){
  5. if (is_file($any_file)){
  6. if(strpos($any_file, '.plugin.php')!==FALSE){
  7. include("./".$any_file);
  8. $plugins[]=substr($any_file,0,strpos($any_file, '.plugin.php'));
  9. }
  10. }
  11. }
  12. closedir($dir);
  13.  
  14. $vector = array(3, 4);
  15. print "<p>Вычисляем норму вектора</p><p>";
  16. print_r($vector);
  17. print "</p>";
  18. foreach ($plugins as $p){
  19. $info_func = $p.'_info';
  20. $calc_func = $p.'_norm';
  21. if (!function_exists($info_func) || !function_exists($calc_func)){
  22. print "<p>Плагин $p содержит ошибку</p>";
  23. }else{
  24. print "<p>";
  25. print call_user_func($info_func)." равна ";
  26. print call_user_func($calc_func, $vector);
  27. print "</p>";
  28. }
  29. }
  30. ?>

Построчный разбор:

  1. Открылась инструкция php
  2. Открыли текущую папку и сохранили указатель на неё в переменную $dir
  3. Проинициализировали массив, в который будем складывать имена найденных плагинов
  4. Начали цикл обхода всех элементов внутри каталога
  5. Если рассматриваемый элемент является файлом, то
  6. Если он к тому же ещё в имени имеет частицу '.plugin.php', то
  7. Подключить этот файл
  8. В массив имён плагинов добавить элемент, в который положить имя файла (из имени файла берётся всё, кроме '.plugin.php')
  9. Закрыли ветвление
  10. Закрыли ветвление
  11. Закрыли цикл
  12. Закрыли текущую папку
  13.  
  14. Создали переменную $vector, инициализировали её как массив из двух элементов: 3 и 4
  15. Вывели текст
  16. Вывели содержимое переменной (print_r — функция вывода структур данных)
  17. Вывели текст
  18. Открыли цикл по всем элементам массива имён плагинов, на каждом шаге цикла элемент перекладывается в переменную $p
  19. В переменной определили имя информационной функции
  20. В переменной определили имя рассчётной функции
  21. Если хоть одна из этих функций не существует, то
  22. Сообщаем об ошибке
  23. В противном случае
  24. Выводим текст
  25. Выводим результат выполнения информационной функции
  26. Выводим результат выполнения рассчётной функции с переданным ей в аргументе нашим вектором
  27. Выводим текст
  28. Закрыли ветвление
  29. Закрыли цикл по элементам массива имён плагинов
  30. Закрыли php-инструкцию

Напишем плагины для этой системы

Файл lp.plugin.php

  1. <?php
  2.  
  3. function lp_info(){
  4. return "Евклидова норма";
  5. }
  6.  
  7. function lp_norm($v=array()){
  8. $norm = 0;
  9. foreach ($v as $element){
  10. $norm+=$element*$element;
  11. }
  12. return sqrt($norm);
  13. }
  14. ?>

Файл max.plugin.php

  1. <?php
  2.  
  3. function max_info(){
  4. return "Чебышевская норма";
  5. }
  6.  
  7. function max_norm($v=array()){
  8. if (count($v)==0){
  9. return 0;
  10. }
  11. $max = $v[0];
  12. foreach ($v as $element){
  13. if ($element > $max){
  14. $max = $element;
  15. }
  16. }
  17. return $max;
  18. }
  19.  
  20. ?>

Результатом вывода при запуске программы algebra.php будет:

  1.  
  2. Вычисляем норму вектора
  3. [0] => 3
  4. [1] => 4
  5. )
  6. Евклидова норма равна 5
  7. Чебышевская норма равна 4

Баннер SGU.RU