» Главная
eXcode.ru » Статьи » PHP » Трюки
» Новости
» Опросы
» Файлы
» Журнал



Пользователей: 0
Гостей: 6





TDD: Рефакторинг приложения




Рефакторинг приложения

Отделяем бизнес логику от презентационной

Пожалуй, это самый важный первый шаг, который стоит сделать. Для этого несколько модифицируем index.php, выделив из него разметку в отдельный файл /templates/feedback.html.

index.php

<?php
ob_start();
 
include_once('db.php');
 
$conn = mysql_connect($db_host, $db_user, $db_password);
 
if($conn === FALSE){
    die('db connect error: ' . mysql_error());
}
 
if(!mysql_select_db($db_name, $conn)){
    die('can not use db: ' . mysql_error());
}
 
if(isset($_POST['submit'])) {
    $name = mysql_escape_string($_POST['name']);
    $email = mysql_escape_string($_POST['email']);
    $message = mysql_escape_string($_POST['message']);
    $time = time();
 
    $sql = "INSERT INTO feedback (name, email, message, time) VALUES ('$name', '$email', '$message', '$time')";
 
    $result = mysql_query($sql, $conn);
    if(!$result){
        die('invalid query: ' . mysql_error());
    }
}
 
$limit = 3;
$offset = isset($_GET['offset']) ? $_GET['offset'] : 0;
 
$sql = "SELECT * FROM feedback ORDER BY time DESC LIMIT " . ($offset * $limit) . ", {$limit}";
$fetch_result = mysql_query($sql, $conn);
if(!$fetch_result){
    die('invalid query: ' . mysql_error());
}
 
$sql = "SELECT COUNT(*) as counter FROM feedback";
$count_result = mysql_query($sql, $conn);
if(!$count_result){
    die('invalid query: ' . mysql_error());
}
$row = mysql_fetch_assoc($count_result);
$total = (int)$row['counter'];
 
include_once('templates/feedback.html');
 
ob_end_flush();
?>

templates/feedback.html

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<link rel=stylesheet type='text/css' href='styles/main.css'>
<script language="JavaScript" type="text/javascript" src="js/form.js"></script>
</head>
<body>
<table width="100%" style="height:100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="10%" style="background-color:#7F1A22">
</td>
<td width="90%" style="padding:5px 10px 5px 10px" valign="top">
<h1>Обратная связь</h1>
<p>
  Если у вас есть пожелания или вопросы к сотрудникам нашей компании,<br>
  пожалуйста, заполните поля формы.<br>
</p>
<form action="index.php" method="post" onsubmit="return submit_form(this);">
<table>
  <tr>
    <td align="right">
      Ваше имя:
    </td>
    <td>
      <input name="name" value="" type="text">
    </td>
 </tr>
  <tr>
    <td align="right">
      Email:
    </td>
    <td>
      <input name="email" value="" type="text">
    </td>
 </tr>
    <tr>
     <td align="right">
       Текст вопроса:
     </td>
     <td>
       <textarea name="message" cols="50" rows="4"></textarea>
     </td>
    </tr>
    <tr>
    <td>
    </td>
    <td>
        <input value="Отправить" name="submit" type="submit">
    </td>
    </tr>
</table>
</form>
<?php if($offset > 0) :?><b><a href="?offset=<?=($offset-1)?>">&lt;</a></b><?php endif; ?>
<?php if($total > 0) :?><?=($offset*$limit)+1?> - <?=(($offset+1)*$limit > $total)? $total : ($offset+1)*$limit ?><?php endif; ?>
<?php if(($offset+1)*$limit < $total) :?><b><a href="?offset=<?=($offset+1)?>">&gt;</a></b><?php endif; ?>
<?php
while ($row = mysql_fetch_assoc($fetch_result)) {
?>
<hr/>
<b>Автор:</b> <a href="mailto:<?=htmlspecialchars($row['email']);?>"><?=htmlspecialchars($row['name']);?></a><br/>
<b>Сообщение:</b> <?=htmlspecialchars($row['message']);?><br/>
<b>Время:</b> <?=strftime("%m/%d/%y %H:%M:%S", $row['time'])?><br/>
<?php } ?>
</td>
</tr>
</table>
</body>
</html>

До идела еще далеко, но читается уже намного лучше. Удостоверившись в том, что все функциональные тесты срабатывают, продолжаем дальше.

Используем WACT

WACT предоставляет мощные средства для отделения презентационной и бизнес логики. Помимо гибкой шаблонной системы в WACT присутствуют также инструменты для абстрагирования работы с БД. Т.к. эти инструменты очень гибко интегрируюся с шаблонной системой, имеет смысл остановить на них выбор.

WACT требует наличие config.ini файла, в котором описываются глобальные конфигурационные настройки приложения. Перенесем данные из db.php в config.ini.

[templates]
forcecompile = TRUE

[database]
driver = mysql
mysql.database = "feedback"
mysql.user = "root"
mysql.password = "test"
mysql.host = "localhost" 

Создадим также файл tests/config.ini, в котором мы будем хранить настройки для тестов.

[templates]
forcecompile = TRUE

[database]
driver = mysql
mysql.database = "feedback-web-tests"
mysql.user = "root"
mysql.password = "test"
mysql.host = "localhost" 

Заставим WACT также пользоваться этим конфигурационным файлом при вызове из тестов. Для этого добавим следующую строку в /tests/setup.php:

<?php
define('WACT_CONFIG_DIRECTORY', dirname(__FILE__) . '/'); 
?>

Нам необходимо заменять config.ini на /tests/config.ini на время выполнения тестов, как мы это делали с db.php, для этого несколько изменим фикстуру:

<?php
class AcceptanceTestOfFeedbackProject extends WebTestCase {
    function setUp() {
        DBC :: execute('DELETE FROM feedback');
        $this->_switchToWebTestingConfig();
    }
 
    function tearDown() {
        $this->_switchToProductionConfig();
    } 
 
    function _switchToWebTestingConfig() {
        $project_dir = dirname(__FILE__) . '/../';
        $tests_dir = dirname(__FILE__) . '/';
 
        if(!file_exists($project_dir . 'config.ini~')) {
            rename($project_dir . 'config.ini', $project_dir . 'config.ini~');
        }
        copy($tests_dir . 'config.ini', $project_dir . 'config.ini');
    }
 
    function _switchToProductionConfig() {
        $project_dir = dirname(__FILE__) . '/../';
        if(file_exists($project_dir . 'config.ini~')) {
            unlink($project_dir . 'config.ini');
            rename($project_dir . 'config.ini~', $project_dir . 'config.ini');
        }
    } 
    [...]
?>

Имеет смысл также пользоваться в тесте средствами WACT для работы с БД. Как можно видеть, вызов DBC :: execute('DELETE FROM feedback') - пришел на смену жесткой привязке к mysql_ функциям.

Все готово к тому, чтобы полностью отделить бизнес логику от презентационной. Начинаем с index.php:

<?php
ob_start();
 
require_once(dirname(__FILE__) . '/external/wact/framework/common.inc.php');
require_once(WACT_ROOT . '/db/db.inc.php');
require_once(WACT_ROOT . '/template/template.inc.php');
 
function &getList(&$pager) {
    return DBC::NewPagedRecordSet('SELECT * FROM feedback ORDER BY time DESC', $pager);
}
 
function insertFeedback($arr) {
    $dataspace = new DataSpace();
    $dataspace->import($arr);
    $record =& DBC::NewRecord($dataspace);
    return $record->insert('feedback', array('name', 'email', 'message', 'time'));
}
 
if(isset($_POST['submit'])) {
    insertFeedback(array('name' => $_POST['name'],
                 'email' => $_POST['email'],
                 'message' => $_POST['message'],
                 'time' => time()));
}
 
$page = new Template('/feedback.html');
$pager =& $page->getChild('pager');
 
$feedback =& $page->findChild('feedback');
$feedback->registerDataSet(getList($pager));
 
$page->display();
 
ob_end_flush();
?>

WACT ищет по-умолчанию шаблоны в директории /templates/source, модифицируем и перенесем feedback.html.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<link rel=stylesheet type='text/css' href='styles/main.css'>
<script language="JavaScript" type="text/javascript" src="js/form.js"></script>
</head>
<body>
<table width="100%" style="height:100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="10%" style="background-color:#7F1A22">
</td>
<td width="90%" style="padding:5px 10px 5px 10px" valign="top">
<h1>Обратная связь</h1>
<p>
  Если у вас есть пожелания или вопросы к сотрудникам нашей компании,<br>
  пожалуйста, заполните поля формы.<br>
</p>
<form action="index.php" method="post" onsubmit="return submit_form(this);">
<table>
  <tr>
    <td align="right">
      Ваше имя:
    </td>
    <td>
      <input name="name" value="" type="text">
    </td>
 </tr>
  <tr>
    <td align="right">
      Email:
    </td>
    <td>
      <input name="email" value="" type="text">
    </td>
 </tr>
    <tr>
     <td align="right">
       Текст вопроса:
     </td>
     <td>
       <textarea name="message" cols="50" rows="4"></textarea>
     </td>
    </tr>
    <tr>
    <td>
    </td>
    <td>
        <input value="Отправить" name="submit" type="submit">
    </td>
    </tr>
</table>
</form>
<list:LIST id="feedback">
<page:navigator id="pager" items="3">
Страница: {$PageNumber} из {$TotalPages}
    <page:first>&lt;&lt;</page:first> <page:prev>&lt;</page:prev>
    <page:list>
        <page:number>
        <page:elipses>...</page:elipses>
        <page:separator> </page:separator>
    </page:list>
    <page:next>&gt;</page:next> <page:last>&gt;&gt;</page:last>
</page:navigator>
<list:ITEM>
<hr>
<b>Автор:</b> <a href="mailto:{$email}">{$name}</a><br>
<b>Сообщение:</b> {$message}<br>
<b>Время:</b> {$time|date:"H:i:s m/d/Y"}<br>
</list:ITEM>
</list:LIST>
</td>
</tr>
</table>
</body>
</html>

WACT предоставляет набор компонентов, позволяющих заметно облегчить жизнь верстальщика. При помощи <list:LIST> компонента организуется итерация по сообщениям в шаблоне. <page:navigator> компонент берет полностью на себя всю рутину по организации и выводу пейджера. При этом содержимое index.php и feedback.html заметно упростилось и приобрело более логический вид.

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

Далее - Шаг третий - внедряем паттерн ActiveRecord.

К началу статьи





Добавил: PIXELДата публикации: 2008-03-05 08:58:31
Рейтинг статьи:4.00 [Голосов 1]Кол-во просмотров: 22470

Комментарии читателей

Всего комментариев: 71

2017-11-16 21:38:54
JosephGlima
Здравствуйте, скорее http://vulkan-cazino24.com .

Все хиты Вулкана в двух турнирах – присоединяйтесь! Давайте вспомним все самые приятные события уходящего 2017 года




Гарантии, акции, победа ждут тебя


Ниже сайт:
http://vulkan-cazino24.com
<a href=vulkan-cazino24.com> Игровые автоматы бесплатно </a>

2017-09-12 08:49:04
Robertbix
гостиная Роза
http://1stbest.info/

----------

2017-08-08 02:27:40
LarryHeilt
Приобрести сироп Mangoosteen можно на веб-сайте http://mangjoo77.mangoosteen.com

Хотим предложить нашим клиентам инновационное средство для снижения веса Mangoosteen. При помощи него реально сбросить около 10 килограмм за недели.

Дерево мангкут растет на Филиппинах. Плоды этого растения обладают замечательными свойствами, которые были взяты за основу сиропа Mangoosteen. В банке имеется более 25 плодов данного замечательного растения. Плоды растения мангостан помогают сжечь излишнею липидную ткань. А также положительно влияют на человека в целом. Технология изготовления средства, и специальная упаковка позволяют сохранить все удивительные свойства гарцинии.

Основным действующим веществом сиропа Mangoosteen являются плоды с дерева гарциния, в которых имеется огромное число полезных микроэлементов. Благодаря компоненту ксантону, которое в огромных дозах содержатся во фрукте, сильно притормаживаются процессы окисления в теле. Окись дифениленкетона признается одним из самых мощных антиоксидантов. В плоде дерева гарциния к тому же имеются разные витамины и микроэлементы. Приобрести сироп Mangoosteen возможно на веб-сайте http://mangjoo77.mangoosteen.com.


2017-08-01 09:46:11
LarryHeilt
Хотим предложить вам потрясающее средство для снижения веса Mangoosteen. С ним реально сбросить около 15 кг за 14 дней.

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

Главным компонентом сиропа Mangoosteen являются фрукты с растения гарциния, в которых содержится огромное количество питательных веществ. Благодаря компоненту ксантону, которое в больших количествах содержатся в плоде, сильно притормаживаются окислительные процессы в организме. Окись дифениленкетона признана одним из наиболее сильных антиоксидантов. В плодах дерева гарциния также есть разные группы витаминов и элементы. Купить сироп Mangoosteen можно на веб-сайте http://mangjoo77.mangoosteen.com.


2017-06-30 06:22:36
Мебель каталог
Гостиная комната (зал) занимает едва ли не главное место в доме: здесь собирается вся семья, проходят дни рождения, встречи с друзьями. И от того, как она оборудована, зависит удобство хозяев дома. Здесь важно все: освещение, напольное покрытие, мебель, шторы. Все элементы должны гармонировать между собой и создавать единый стиль помещения.
Неотъемлемый атрибут гостиной - диван. Он может быть любых размеров, главное правило - чтобы на нем комфортно могли разместиться члены семьи. В комплекте с диваном очень часто идут кресла, их хорошо для удобства дополнить журнальным столиком. Если позволяет площадь комнаты, диван и кресла можно разместить посередине, возле стены мебель обычно размещают при недостатке пространства.
Маленькую гостиную оборудуют комодом или небольшими шкафами, но гостиная со стенкой - очень распространенный вариант. Стенки состоят из множества сочетающихся полок, тумбочек, шкафчиков; отличаются функциональностью, эргономичной компоновкой. Приобретая стенку, можно забыть о проблеме размещения большого количества вещей. На рынке мебели представлено множество моделей стенок для гостиной, способных удовлетворить разные вкусы и предпочтения.


http://pronews24.ru/


<a href=http://lnkgo.com/5tl8>Click Here</a>

2017-06-23 12:36:09
Jasonteert
Вкуснейший экзотический плод - мангустин, стал настоящим открытием в диетологии!
Он содержит РЕКОРДНОЕ количество полезных веществ, стимулирующих активное жиросжигание и снижающих вес!
Сироп мангустина растопит до 10 кг жира за 2 недели!
Спаситесь от ожирения и сократите риск инфаркта, диабета и гипертонии на 89%.
Перейти на сайт: http://mangjoo77.mangoosteen.com/

2017-06-16 12:58:51
Kennsolo
Amoxicillin And Methadone <a href=http://viacheap.com>viagra</a> Priligy Venta En Venezuela Acheter Viagra MontrСЂВ al <a href=http://priligy.ccrpdc.com/buy-priligy-usa.php>Buy Priligy Usa</a> Alquilo Kamagra Buy Now Fedex Real Progesterone C.O.D. Without Rx <a href=http://vardenafil-20mg.buylevi.com>Vardenafil 20mg</a> 1767 Buy Clonidine Overnight Viagra 100 Mg Doctissimo <a href=http://cial40mg.com/cialis-40mg.php>Cialis 40mg</a> Amoxicillin And Breast Lumps Progesterone Hormone Replacement Order Cod Accepted <a href=http://order-kamagra-tablets.kamagpills.com>Order Kamagra Tablets</a> Viagra Wirkung Nicht Cialis Acheter Pas Cher <a href=http://dapoxetine-priligy-price.priliorder.com>Dapoxetine Priligy Price</a> Preisliste Fur Levitra Cheap Cialis Pills <a href=http://buy-real-viagra-online.via100mg.com>Buy Real Viagra Online</a> Valor De Propecia

2017-06-10 19:59:34
Raymondfap
п»їNurture your talent: The life story of Muhammad Assaf

This is the life story of Mohammad Assaf born to Palestinian parents in Libya, Assaf moved with them to the Khan Yunis Refugee Camp in Gaza when he was four years old. He began singing aged five and, by his teens, regularly worked at weddings and local festivities. Assaf&rsquo;s parents recognised his talent, and played him their cassettes of the great Arab singers.
The film Arab Idol was released in 2015 depicting the life of Mohammad Assaf. The film is centered around his special relationship with his sister who was suffering from chronic kidney failure, and his childhood friends who started a band playing music for weddings. His sister sadly passes away, and Mohammed stops singing. Later on, he decides to leave Gaza and try his chances for the Arab idol competition. The auditions were being held in neighboring city Cairo.
Because of the Israeli blockade and Hamas&rsquo;s authoritarian rule, travel to Egypt was not an easy deal. After purchasing a forged visa, and avoiding Hamas&rsquo;s police he reaches Cairo.
According to a Financial times interview, the true story goes like this:
The hotel where auditions were under way had locked its doors. No more contestants welcome.
Refusing to quit, Assaf climbed the hotel&rsquo;s wall and found his way to the auditions. He was too late to get an entrant&rsquo;s pass for the competition, so he sat in the corridor and sang. Another contestant heard him and said, &ldquo;I know I won&rsquo;t reach the final, but you will&rdquo;, and gave Assaf his contest number. He indeed sang his way to the finals, and the story of the golden-voiced refugee who risked all to sing on TV won hearts across the Arab world.
Nowadays, Mohammad Assaf lives in Dubai. He tours the world performing a mix of Arabic classical music and traditional folk music and pop.
The life story of Mohammad Assaf reminds us that we may be born with a great talent, but life circumstances do not always allow us to bring this gift to the world. We must persevere. Through his striving and luck, Mohammad was able to lift the spirit of millions of people in Gaza and around the world.
He says(1): &ldquo;I do feel, however, that I have a responsibility towards my people to carry their voices, their dreams, their hopes to the world so they can be heard.&rdquo;
Nurture your talent, persevere, never give up.
References:
(1)


http://hceap.info/hotel/cheap-hotels-manhattan-new-york-midtown.php

2017-06-10 18:45:45
LorenReunc
Tinedol – эффективное средство от грибка стопы, неприятного запаха и зуда.
Перейти на сайт: http://tinedol.1stbest.info/

2017-06-10 17:15:02
Jasonteert
Вкуснейший экзотический плод - мангустин, стал настоящим открытием в диетологии!
Он содержит РЕКОРДНОЕ количество полезных веществ, стимулирующих активное жиросжигание и снижающих вес!
Сироп мангустина растопит до 10 кг жира за 2 недели!
Спаситесь от ожирения и сократите риск инфаркта, диабета и гипертонии на 89%.
Перейти на сайт: http://mangjoo77.mangoosteen.com/
Ваше имя: *
Текст записи: *
Имя:

Пароль:



Регистрация

Каким браузером вы пользуйтесь?
MS Internet Explorer
22% (66)
Mozilla
3% (8)
Mozilla Firefox
26% (77)
Opera
43% (130)
Konqueror
1% (3)
Netscape
0% (0)
Lynx
0% (0)
Galeon
0% (0)
Другим
5% (15)

Проголосовало: 299
Чтобы запустить человека на Луну, потребовалось вычислительная мощность всего трех С64 процессоров, а для того, чтоб запустить Windows, нужен 486 процессор. Что-то здесь не так...
Рейтинг: 6.7/10 (3)
Посмотреть все анекдоты