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



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





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]Кол-во просмотров: 24940

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

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

2018-09-15 12:51:01
Justin
Вам нужен кредит для вашего бизнеса или личных целей? Мы оказываем финансовую помощь компаниям и частным лицам с удобной для кармана процентной ставкой в размере 3% годовых. Наши условия дешевы и понятны.

Свяжитесь с нами сегодня и будет финансироваться в течение 2-4 рабочих дней. E-mail: unique2aal@gmail.com

2018-08-24 07:09:26
RebaCarrasco
Все компоненты в креме действуют по принципу синергии – повышают эффективность друг друга. Уникальное действие крема Bioretin объясняется огромным количеством питательных веществ в составе. При регулярном применении вам удастся добиться следующих результатов: запустить внутреннее обновление клеток; усилить подкожное кровообращение; улучшить подкожный обмен веществ; нормализовать восстановительные процессы; сделать лицо более свежим и подтянутым; восстановить водный баланс; избавиться от шелушения; уменьшить отечность и сухость кожи; избавиться от многочисленных морщинок. <a href=http://otzyvy-vrachej.com/protivogribkovyy-krem-mitsinorm-otzyvy-pokupateley-kupit-sredstvo-v-aptekah.php>противогрибковый крем мицинорм</a> Оставьте заявку, менеджер с Вами свяжется и проконсультирует по любым вопросам. Xtrazеx для потeнции: улучшает вcе aспекты сексуaльнoй жизни. Усилить мужскую силу и раскрыть весь сексуальный потенциал помогут шипучие таблетки Xtrazex для потенции. Благодаря нетоксичности препарата его можно применять в любом возрасте, не опасаясь побочных эффектов. Разрешен совместный прием с алкоголем и другими медикаментами. Уже многие мужчины благодаря средству теперь занимаются сексом в 2-3 раза чаще, испытывают мощные оргазмы и полностью свободны в своих сексуальных фантазиях. Это уникальное средство, которое поддерживает потенцию даже при стрессах и нервных перегрузках.

2018-04-17 01:20:46
kawanboni.com
沒有醫生的處方
cialis 5 mg para diabeticos
<a href="http://cialisvipsale.com/#">viagra vs cialis</a>
can you purchase viagra online
<a href=http://viagrayosale.com/#>Viagra 20 mg</a>

2018-01-21 20:12:52
WalterPem
АЛКОВЕРИН АКТИВИРУЕТ РЕЖИМ АЛКОГОЛЬНОГО ОТТОРЖЕНИЯ
С ALCOVIRIN выпить ПРОСТО НЕ УДАСТСЯ!

Это первый биогенный растительный комплекс, способствующий выработке непереносимости алкоголя при совместном приеме капель и спиртных напитков, вызывая тошноту и его полное отторжение организмом!

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

Официальный сайт: http://alcovirin.bxox.info

2018-01-21 12:09:40
CraigVet
Приобрести можно на веб-сайте http://tedsjkpb.bestseller-super.ru

Рады предложить вам удивительное средство для снижения веса сироп Мангустина. С его помощью реально избавиться от 15 кг за 14 дней.

Дерево мангостан произрастает на Шри-Ланке. Плоды растения обладают удивительными особенностями, которые были положены в основу препарата Мангустина. В баночке содержится более 25 плодов этого замечательного растения. Плоды с растения мангостан помогают сжечь чрезмерную жировую ткань. И отлично влияют на организм в комплексе. Технология производства средства, и уникальная упаковка позволяют сберечь все полезные свойства мангостина.

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


2017-12-23 18:55:03
MiLaskinaunwig
Какую выбрать шлейку для собаки? Открытый вопрос

Наверняка <a href=https://www.murzoo.ru/>купить щенка</a> у Вас уже получилось и Вы начали ухаживать за ним. Для комфортного ношения шлейка должна быть правильно подобрана по размерам собаки, <a href=https://www.murzoo.ru/component/djclassifieds/?view=items&cid=0&se=1&option=com_djclassifieds&view=items&Itemid=&search=шлейка&se_regs=0&se_cats=&se_price_f=&se_price_t=>купить шлейку</a> можно какую угодно, но нужно внимательно подойти к этому вопросу для обеспечения комфорта вашему питомцу. Существуют размерные таблицы, выкройки, облегчающие выбор. Чтобы воспользоваться таблицей, вы должны снять со своей собачки несколько мерок:
Главная мерка: от костей холки до основания хвоста измеряется длина спины.
Обхват груди: измеряется в самом широком месте сразу за локтями. К результату добавляется для мелких пород 1 см, для крупных — 2 см.
Обхват шеи в том месте, где должен быть ошейник.
Мерки для определения размеров ездовой шлейки снимаются иначе из-за конструктивных особенностей амуниции. Ездовая шлейка требует таких измерений собак:
расстояние между началом грудной кости и холкой;
длина грудины;
расстояние от окончания грудной кости до основания хвоста.
Правильно подобранная по размеру шлейка не болтается на корпусе собаки, но и не давит нигде. Под ремни должна входить ваша ладонь. Правильный замер позволит <a href=https://www.murzoo.ru/tovary-dlya-zhivotnykh,165>купить шлейку</a> не выходя из дома, что с экономит вам время.

Ну и в заключении хотелось бы пригласить Вас в нашу группу ВКОНТАКТЕ: <a href=https://vk.com/murzooru>Купить щенка / купить котёнка - murzoo.ru</a>

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.

Ваше имя: *
Текст записи: *
Имя:

Пароль:



Регистрация

Какие книги вам больше нравятся?
Приключения
7% (12)
Фантастика и фэнтези
30% (50)
Детективы
5% (8)
Ужасы
0% (0)
Юмористические
1% (2)
Учебники и энциклопедии
12% (20)
Спец. литературу
22% (37)
Я не умею читать :(
17% (28)
Другие
5% (9)

Проголосовало: 166
Встречаются как то НАШ Российский хакер и ихний БИЛ ГЕЙТС!
ГЕЙТС: Слушай у тебя случайно Wind(Ы)2000 нет, а то Рождество на Носу, а подарить друзьям нечего? Все деньги жена забирает!
ХАКЕР: Есть! Что за вопросы! А ТЕБЕ КАКУЮ, Русскую или Английскую?
Рейтинг: 9/10 (1)
Посмотреть все анекдоты