ВУЗ: Не указан

Категория: Реферат

Дисциплина: Не указана

Добавлен: 07.11.2023

Просмотров: 164

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

СОДЕРЖАНИЕ

Введение

1. Аналитическая часть

1.1.2 Роль веб-сайта в работе медицинской клиники

1.2 Обоснование выбора средств создания веб-сайта

1.3 Обзор систем управления базами данных

2.Технологическая часть

2.1 Постановка задачи

2.1.1 Актуальность

2.1.2 Назначение веб-сайта

2.1.3 Характеристики оборудования

2.2 Реализация проекта

2.3 Средства для разработки и проектирование сайта

2.3.1 Анализ средств для разработки и создания Web-сайта

2.3.2 Фреймворки, используемые при разработке Web-сайтов: сравнительный анализ

2.3.4 Разработка веб-сайта в CMS WordPress

3. Тестирование веб-сайта и руководство пользователя

3.1. Тестирование веб-сайта

3.2. Руководство пользователя

Заключение

Список использованной литературы

Приложение

Archive config file not found in dup-installer folder. '; return $error; } }$is_https = $this->isHttps(); if($is_https) { $current_url = 'https://'; } else { $current_url = 'http://'; } if(($_SERVER['SERVER_PORT'] == 80) && ($is_https)) { // Fixing what appears to be a bad server setting $server_port = 443; } else { $server_port = $_SERVER['SERVER_PORT']; } // for ngrok url and Local by Flywheel Live URL if (isset($_SERVER['HTTP_X_ORIGINAL_HOST'])) { $host = $_SERVER['HTTP_X_ORIGINAL_HOST']; } else { $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'];//WAS SERVER_NAME and caused problems on some boxes } $current_url .= $host; if(strpos($current_url,':') === false) {$current_url = $current_url.':'.$server_port;}$current_url .= $_SERVER['REQUEST_URI']; $uri_start = dirname($current_url);$encoded_archive_path = urlencode($archive_filepath); if ($error === null) {$error = $this->postExtractProcessing();if($error == null) {$bootloader_name = basename(__FILE__);$this->mainInstallerURL = $uri_start.'/'.self::INSTALLER_DIR_NAME.'/main.installer.php';$this->fixInstallerPerms($this->mainInstallerURL); $this->archive = $archive_filepath; $this->bootloader = $bootloader_name;if (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) {$this->mainInstallerURL .= '?'.$_SERVER['QUERY_STRING'];}self::log("DONE: No detected errors so redirecting to the main installer. Main Installer URI = {$this->mainInstallerURL}");}} return $error; } public function postExtractProcessing() { $dproInstallerDir = dirname(__FILE__) . '/dup-installer'; $libDir = $dproInstallerDir . '/lib'; $fileopsDir = $libDir . '/fileops';if(!file_exists($dproInstallerDir)) {return 'Can\'t extract installer directory. See this FAQ item for details on how to resolve.';} $sourceFilepath = "{$fileopsDir}/fileops.ppp"; $destFilepath = "{$fileopsDir}/fileops.php"; if(file_exists($sourceFilepath) && (!file_exists($destFilepath))) { if(@rename($sourceFilepath, $destFilepath) === false) { return "Error renaming {$sourceFilepath}"; } } }/*** Indicates if site is running https or not** @return bool Returns true if https, false if not*/ public function isHttps() { $retVal = true;if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {$_SERVER ['HTTPS'] = 'on';} if (isset($_SERVER['HTTPS'])) { $retVal = ($_SERVER['HTTPS'] !== 'off'); } else { $retVal = ($_SERVER['SERVER_PORT'] == 443);} return $retVal; }/*** Fetches current URL via php** @param bool $queryString If true the query string will also be returned.* @param int $getParentDirLevel if 0 get current script name or parent folder, if 1 parent folder if 2 parent of parent folder ... ** @returns The current page url*/public static function getCurrentUrl($queryString = true, $requestUri = false, $getParentDirLevel = 0){// *** HOSTif (isset($_SERVER['HTTP_X_ORIGINAL_HOST'])) {$host = $_SERVER['HTTP_X_ORIGINAL_HOST'];} else {$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']; //WAS SERVER_NAME and caused problems on some boxes}// *** PROTOCOLif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {$_SERVER ['HTTPS'] = 'on';}if (isset($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] === 'https') {$_SERVER ['HTTPS'] = 'on';}if (isset($_SERVER['HTTP_CF_VISITOR'])) {$visitor = json_decode($_SERVER['HTTP_CF_VISITOR']);if ($visitor->scheme == 'https') {$_SERVER ['HTTPS'] = 'on';}}$protocol = 'http'.((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) === 'on') ? 's' : '');if ($requestUri) {$serverUrlSelf = preg_replace('/\?.*$/', '', $_SERVER['REQUEST_URI']);} else {// *** SCRIPT NAME$serverUrlSelf = $_SERVER['SCRIPT_NAME'];for ($i = 0; $i < $getParentDirLevel; $i++) {$serverUrlSelf = preg_match('/^[\\\\\/]?$/', dirname($serverUrlSelf)) ? '' : dirname($serverUrlSelf);}}// *** QUERY STRING $query = ($queryString && isset($_SERVER['QUERY_STRING']) && strlen($_SERVER['QUERY_STRING']) > 0 ) ? '?'.$_SERVER['QUERY_STRING'] : '';return $protocol.'://'.$host.$serverUrlSelf.$query;} /*** Attempts to set the 'dup-installer' directory permissions** @return null*/ private function fixInstallerPerms() { $file_perms = 'u+rw'; $dir_perms = 'u+rwx'; $installer_dir_path = $this->installerContentsPath; $this->setPerms($installer_dir_path, $dir_perms, false); $this->setPerms($installer_dir_path, $file_perms, true); } /*** Set the permissions of a given directory and optionally all files** @param string $directory The full path to the directory where perms will be set* @param string $perms The given permission sets to use such as '0755' or 'u+rw' * @param string $do_files Also set the permissions of all the files in the directory** @return null*/ private function setPerms($directory, $perms, $do_files) { if (!$do_files) { // If setting a directory hiearchy be sure to include the base directory $this->setPermsOnItem($directory, $perms); } $item_names = array_diff(scandir($directory), array('.', '..')); foreach ($item_names as $item_name) { $path = "$directory/$item_name"; if (($do_files && is_file($path)) || (!$do_files && !is_file($path))) { $this->setPermsOnItem($path, $perms); } } } /*** Set the permissions of a single directory or file** @param string $path The full path to the directory or file where perms will be set* @param string $perms The given permission sets to use such as '0755' or 'u+rw'** @return bool Returns true if the permission was properly set*/ private function setPermsOnItem($path, $perms) { if (($result = self::chmod($path, $perms)) === false) {self::log("ERROR: Couldn't set permissions of $path");} else {self::log("Set permissions of $path");}return $result; }/*** Compare two strings and return html text which represts diff** @param string $oldString* @param string $newString** @return string Returns html text*/private function compareStrings($oldString, $newString) { $ret = ''; for($i=0; isset($oldString[$i]) || isset($newString[$i]); $i++) { if(!isset($oldString[$i])) { $ret .= '' . $newString[$i] . ''; continue; } for($char=0; isset($oldString[$i][$char]) || isset($newString[$i][$char]); $char++) {if(!isset($oldString[$i][$char])) { $ret .= '' . substr($newString[$i], $char) . ''; break; } elseif(!isset($newString[$i][$char])) { break; }if(ord($oldString[$i][$char]) != ord($newString[$i][$char])) $ret .= '' . $newString[$i][$char] . ''; else $ret .= $newString[$i][$char]; } } return $ret; }/*** Logs a string to the dup-installer-bootlog__[HASH].txt file** @param string $s The string to log to the log file** @return boog|int // This function returns the number of bytes that were written to the file, or FALSE on failure. */ public static function log($s, $deleteOld = false) {static $logfile = null;if (is_null($logfile)) {$logfile = self::getBootLogFilePath();}if ($deleteOld && file_exists($logfile)) {@unlink($logfile);}$timestamp = date('M j H:i:s'); return @file_put_contents($logfile, '['.$timestamp.'] '.self::postprocessLog($s)."\n", FILE_APPEND); }/*** get boot log file name the dup-installer-bootlog__[HASH].txt file** @return string */public static function getBootLogFilePath() {return dirname(__FILE__).'/dup-installer-bootlog__'.self::SECONDARY_PACKAGE_HASH.'.txt';}protected static function postprocessLog($str) {return str_replace(array(self::getArchiveFileHash(),self::PACKAGE_HASH, self::SECONDARY_PACKAGE_HASH), '[HASH]' , $str);}public static function getArchiveFileHash(){static $fileHash = null;if (is_null($fileHash)) {$fileHash = preg_replace('/^.+_([a-z0-9]+)_[0-9]{14}_archive\.(?:daf|zip)$/', '$1', self::ARCHIVE_FILENAME);}return $fileHash;}/*** Extracts only the 'dup-installer' files using ZipArchive** @param string $archive_filepath The path to the archive file.** @return bool Returns true if the data was properly extracted*/ private function extractInstallerZipArchive($archive_filepath, $checkSubFolder = false) { $success = true; $zipArchive = new ZipArchive(); $subFolderArchiveList = array(); if (($zipOpenRes = $zipArchive->open($archive_filepath)) === true) {self::log("Successfully opened archive file."); $destination = dirname(__FILE__); $folder_prefix = self::INSTALLER_DIR_NAME.'/'; self::log("Extracting all files from archive within ".self::INSTALLER_DIR_NAME); $this->installer_files_found = 0; for ($i = 0; $i < $zipArchive->numFiles; $i++) { $stat = $zipArchive->statIndex($i); if ($checkSubFolder == false) { $filenameCheck = $stat['name']; $filename = $stat['name'];$tmpSubFolder = null; } else {$safePath = rtrim(self::setSafePath($stat['name']) , '/'); $tmpArray = explode('/' , $safePath);if (count($tmpArray) < 2) { continue; } $tmpSubFolder = $tmpArray[0]; array_shift($tmpArray); $filenameCheck = implode('/' , $tmpArray); $filename = $stat['name']; } if ($this->startsWith($filenameCheck , $folder_prefix)) { $this->installer_files_found++; if (!empty($tmpSubFolder) && !in_array($tmpSubFolder , $subFolderArchiveList)) { $subFolderArchiveList[] = $tmpSubFolder; } if ($zipArchive->extractTo($destination, $filename) === true) { self::log("Success: {$filename} >>> {$destination}"); } else { self::log("[ERROR] Error extracting {$filename} from archive archive file"); $success = false; break; } } } if ($checkSubFolder && count($subFolderArchiveList) !== 1) { self::log("Error: Multiple dup subfolder archive"); $success = false; } else { if ($checkSubFolder) { $this->moveUpfromSubFolder(dirname(__FILE__).'/'.$subFolderArchiveList[0] , true); } $lib_directory = dirname(__FILE__).'/'.self::INSTALLER_DIR_NAME.'/lib'; $snaplib_directory = $lib_directory.'/snaplib'; // If snaplib files aren't present attempt to extract and copy those if(!file_exists($snaplib_directory)) { $folder_prefix = 'snaplib/'; $destination = $lib_directory; for ($i = 0; $i < $zipArchive->numFiles; $i++) { $stat = $zipArchive->statIndex($i); $filename = $stat['name']; if ($this->startsWith($filename, $folder_prefix)) { $this->installer_files_found++; if ($zipArchive->extractTo($destination, $filename) === true) { self::log("Success: {$filename} >>> {$destination}"); } else { self::log("[ERROR] Error extracting {$filename} from archive archive file"); $success = false; break; } } } } } if ($zipArchive->close() === true) { self::log("Successfully closed archive file"); } else { self::log("[ERROR] Problem closing archive file"); $success = false; }if ($success != false && $this->installer_files_found < 10) { if ($checkSubFolder) { self::log("[ERROR] Couldn't find the installer directory in the archive!"); $success = false; } else { self::log("[ERROR] Couldn't find the installer directory in archive root! Check subfolder"); $this->extractInstallerZipArchive($archive_filepath, true); } } } else { self::log("[ERROR] Couldn't open archive archive file with ZipArchive CODE[".$zipOpenRes."]"); $success = false; } return $success; }/*** return true if current SO is windows* * @staticvar bool $isWindows* @return bool*/public static function isWindows(){static $isWindows = null;if (is_null($isWindows)) {$isWindows = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');}return $isWindows;}/*** return current SO path path len* @staticvar int $maxPath* @return int*/public static function maxPathLen(){static $maxPath = null;if (is_null($maxPath)) {if (defined('PHP_MAXPATHLEN')) {$maxPath = PHP_MAXPATHLEN;} else {// for PHP < 5.3.0$maxPath = self::isWindows() ? 260 : 4096;}}return $maxPath;}/*** this function make a chmod only if the are different from perms input and if chmod function is enabled** this function handles the variable MODE in a way similar to the chmod of lunux* So the MODE variable can be* 1) an octal number (0755)* 2) a string that defines an octal number ("644")* 3) a string with the following format [ugoa]*([-+=]([rwx]*)+** examples* u+rw add read and write at the user* u+rw,uo-wx add read and write ad the user and remove wx at groupd and other* a=rw is equal at 666* u=rwx,go-rwx is equal at 700** @param string $file* @param int|string $mode* @return boolean*/public static function chmod($file, $mode){if (!file_exists($file)) {return false;}$octalMode = 0;if (is_int($mode)) {$octalMode = $mode;} else if (is_string($mode)) {$mode = trim($mode);if (preg_match('/([0-7]{1,3})/', $mode)) {$octalMode = intval(('0'.$mode), 8);} else if (preg_match_all('/(a|[ugo]{1,3})([-=+])([rwx]{1,3})/', $mode, $gMatch, PREG_SET_ORDER)) {if (!function_exists('fileperms')) {return false;}// start by file permission$octalMode = (fileperms($file) & 0777);foreach ($gMatch as $matches) {// [ugo] or a = ugo$group = $matches[1];if ($group === 'a') {$group = 'ugo';}// can be + - =$action = $matches[2];// [rwx]$gPerms = $matches[3];// reset octal group perms$octalGroupMode = 0;// Init sub perms$subPerm = 0;$subPerm += strpos($gPerms, 'x') !== false ? 1 : 0; // mask 001$subPerm += strpos($gPerms, 'w') !== false ? 2 : 0; // mask 010$subPerm += strpos($gPerms, 'r') !== false ? 4 : 0; // mask 100$ugoLen = strlen($group);if ($action === '=') {// generate octal group permsissions and ugo mask invert$ugoMaskInvert = 0777;for ($i = 0; $i < $ugoLen; $i++) {switch ($group[$i]) {case 'u':$octalGroupMode = $octalGroupMode | $subPerm << 6; // mask xxx000000$ugoMaskInvert = $ugoMaskInvert & 077;break;case 'g':$octalGroupMode = $octalGroupMode | $subPerm << 3; // mask 000xxx000$ugoMaskInvert = $ugoMaskInvert & 0707;break;case 'o':$octalGroupMode = $octalGroupMode | $subPerm; // mask 000000xxx$ugoMaskInvert = $ugoMaskInvert & 0770;break;}}// apply = action$octalMode = $octalMode & ($ugoMaskInvert | $octalGroupMode);} else {// generate octal group permsissionsfor ($i = 0; $i < $ugoLen; $i++) {switch ($group[$i]) {case 'u':$octalGroupMode = $octalGroupMode | $subPerm << 6; // mask xxx000000break;case 'g':$octalGroupMode = $octalGroupMode | $subPerm << 3; // mask 000xxx000break;case 'o':$octalGroupMode = $octalGroupMode | $subPerm; // mask 000000xxxbreak;}}// apply + or - actionswitch ($action) {case '+':$octalMode = $octalMode | $octalGroupMode;break;case '-':$octalMode = $octalMode &



Для использования PHP необходимы смежные серверные компоненты, а именно:

  • web-сервер;

  • сервер баз данных - это серверный компонент, который позволит работать с базами данных, управляемых из PHP.

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

JavaScript — это скриптовый язык программирования. Часто используется как встраиваемый язык для программного доступа к объектам приложения. Он наиболее широко используется в браузерах в качестве языка сценариев для создания интерактивных веб-страниц.

Для написания приложений вы можете использовать NotePad++, бесплатный текстовый редактор с открытым исходным кодом для Windows с подсветкой синтаксиса для большого количества языков программирования и разметки. Базовый функционал программы может быть расширен плагинами и сторонними модулями, такими как компиляторы и препроцессоры [23].

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

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

Для css и xml вы можете использовать HTML-Kit — редактор HTML, XHTML и XML с подключаемыми модулями, который предоставляет рекомендации по CSS и многое другое.

2.3.2 Фреймворки, используемые при разработке Web-сайтов: сравнительный анализ


Фреймворк — это программный фреймворк, который реализует базовую архитектуру проекта. Самыми известными современными php-фреймворками являются Zend Framework, Yii, CodeIgniter, Symfony и многие другие.

Фреймворки предоставляют разработчикам очень мощный инструмент для разработки более гибких и менее подверженных ошибкам приложений за меньшее время. Фреймворки часто помогают ускорить процесс разработки, предоставляя необходимую функциональность. К ним относятся управление пользователями/разрешениями, доступ к данным, кэширование и многое другое. Фреймворки помогают сосредоточиться на более важных деталях дизайна и с легкостью управлять проектами.Zend Framework (ZF) - является объектно-ориентированным фреймворком с открытым исходным кодом, использует PHP5 и выпущен под лицензией New BSD License.

Zend Framework был задуман в начале 2005 года, когда много новых фреймворков набирали популярность в сообществе web-разработчиков. О ZF впервые было объявлено на первой Zend конференции в октябре 2005 года.

Функции Zend Framework включают в себя:

  • большое количество модулей и библиотек;

  • разрабатывается разработчиками ядра PHP;

  • поддержка unit-тестов;

  • достаточно низкая скорость работы с библиотеками;

  • встроенный JS фреймворк DOJO и библиотеки для него.

Symfony – web-фреймворк написанный на PHP, использует платформу модель-представление-контроллер (MVC). Был выпущен под лицензией MIT. Symfony является свободным программным обеспечением.

Symfony не следует путать с Symfony CMS, Open Source XML/XSLT системой управления контентом. Symfony ускоряет создание и поддержку web-приложений. В настоящее время совместима с ORM Propel и Doctrine. Следует отметить, что на типичном хостинге, где ускоритель PHP отсутствует, Symfony может использовать собственный движок кэширования для ускорения выполнения кода.

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

Достоинства:

  • простой в освоении;

  • достаточно высокая скорость работы ядра.

Yii — высокопроизводительный фреймворк, и для организации из 10+ человек имеет смысл его изучать, а с одним Yii сложно справиться. Этот фреймворк позволяет создавать очень эффективные системы.

Yii — лучший выбор между Zend Framework и Codeingiter. Он хорошо документирован

, и вы всегда можете вникнуть в код, чтобы понять, что и как работает.

Фреймворк строго написан на PHP5 и строго следует концепции ООП, поэтому его легко понять, если у вас есть базовое понимание принципов ООП.

Yii более сложен (более функционален) и лучше структурирован, чем CodeIgniter.

Он меньше и более производительный, чем фреймворк Zend. Для написания приложений требуется гораздо меньше кода, в то время как у Yii масса функций.

CodeIgniter - это PHP фреймворк, который использует платформу MVC, имеет классы для доступа к данным, классы для работы с почтой, FTP и XML-RPC.

У CodeIgniter имеется исчерпывающая документация для начала работы [24].На рисунке 3 изображён интефейс CodeIgniter.


Рисунок 3- Интерфейс CodeIgniter
Таблица 2 Характерные особенности фреймворков




Zend Framework 1

Code Igniter 2

Symfony 2

Описание

Академически грамотный код. Очень гибок. Требует хорошего знания PHP и ООП.

Почти микрофреймворк. Очень лёгкий для изучения. Отличная документация. Гибок. Легко использовать сторонний код.

Активно использует командную строку. Мощный ORM, хорошая система view, генераторы кода.

Необходимый уровень знаний

PHP5, ООП, шаблоны проектирования.

PHP, Основы ООП

PHP5, ООП, ORM, консоль.

Платформа

PHP 5

PHP 4/5

PHP 5

Сложность установки и настройки

Высокая

Низкая

Высокая

Поддерживаемые БД

MySQL, Oracle, PostgreSQL, MS SQL, SQLite

MySQL, Oracle, PostgreSQL, MS SQL, SQLite

MySQL, Oracle, PostgreSQL, MS SQL, SQLite

Русскоязычное сообщество

Да

Документация, форум, блоги

Нет

Лицензия

New BSD

BSD

MIT


2.3.3 Проектирование веб-сайта

Заказчиком является поликлиника, расположенная в городе Абиджан находящаяся по адресу 4 Bd de l'Indenié, Abidjan, Кот-д'Ивуар, поликлинику посещают жители города и ближайших населенных пунктов города Абиджан.

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

Структура сайта представлена на рисунке 2.



Рисунок 2- Структура сайта

  1. Первая страница.

Главная страница — это лицо сайта, где обычно приводится краткая информация о направлениях деятельности поликлиники, предоставляемых услуг.

Основное назначение главной страницы web-сайта - рассказать пользователям о поликлинике, ее преимуществах. Разработанный сайт оказывает медицинские услуги. Это и отражено на главной странице путём размещения на ней прямых ссылок на главную информацию о поликлинике и её услугах.

  1. О поликлинике.

В этом разделе приводится краткая информация о поликлинике.

  1. Услуги.

В этом разделе описаны медицинские услуги, которые предоставляет поликлиника

  1. Отзывы.

Раздел содержит отзывы посетителей поликлинике совместно с оцениванием её по 5 бальной шкале

  1. Книга записей

Раздел «Книга записей» — раздел в котором показано свободное время для записей у специалистов поликлиники.

  1. Вход в систему

Раздел «Вход в систему» позволяет пользователю зарегистрироваться на веб-сайте или войти под своим логином и паролем, если он уже зарегистрирован на веб-сайте.

  1. После регистрации или входа на сайт пользователь может записаться на приём к специалисту, посмотреть активные записи, посмотреть предыдущие записи или сменить пароль своей учётной записи.

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


За управлением базами данных отвечает специальный плагин KiviCare.

KiviCare — плагин для клиники и управления пациентами. Он разработан для врачей и клиник, чтобы обрабатывать несколько назначений врачей и встреч в клинике. Это позволяет делать, управлять и отслеживать запись пациентов на прием к врачам. Сохраняя конфиденциальность на переднем плане, каждый визит к врачу может быть конфиденциальным для других. Администратор создаёт учётную запись для врача и присылает на его почту пароль, который врач может поменять перейдя по ссылке полученной по электронной почте. На рисунке 3 показана панель администратора при создании учётной записи врача.



Рисунок 3- Панель администратора

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



Рисунок 4- Структура главной страницы

На рисунке 5 и 6 изображены база данных пациентов и врачей , которые можно экспортировать в csv и excel.



Рисунок 5- База данных пациентов



Рисунок 6- База данных врачей