Вторая техника задействует динамические URL. При работе с динамическими URL
решение будет несколько иным. Теперь уже не нужно ничего делать с mod_rewrite, но все-таки требуется какой-то способ чтения и удаления идентификаторов партнеров из динамических URL, а затем перенаправления на нужную версию URL. В приведенном ниже упражнении вы создадите простую партнерскую страницу с именем afftest.php. При загрузке этого сценария с параметром affid в строке запроса вначале сохраняется значение идентификатора, затем удаляется параметр affid и выполняется перенаправление 301 на новый URL.
При удалении параметров из строки запроса необходима осторожность, чтобы не
изменить существующие параметры. Поэтому для выполнения этой задачи будет создано несколько специальных функций.
Перенаправление динамических партнерских URL
1. Создайте в папке seophp\include новый файл с именем url_utils.inc.php и
введите в него следующий код:
<?php
// преобразование строки запроса в ассоциативный массив
function parse_query_string ($query_string)
{
// разбиение строки запроса на отдельные пары имя-значение
$items - explode('&1, $query_string);
// инициализация возвращаемого массива
$qs_array - array () ;
// заполнение массива
foreach($iterns as $i)
{
// разбиение пары имя-значение и сохранение ее элементов в $qs_array
$pair = explode (' = ', $i) ;
$qs_array[urldecode ($pair[0])] = urldecode($pair[1]);
}
// возврат массива
return $qs_array;
}
// удаление параметра из строки запроса
function remove_query_param($url, $param)
{
// извлечение строги запроса из $url
$tokens = explode('?', $url);
$url_path = $tokens[0];
$query_string = $ to kens [1] ,-
// преобразование строки запроса в ассоциативный массив
$qs_array = parse_query_string($query_string) ;
// удаление элемента $param из массива
unset($qs_array[$param]); ,
// создание новой с трохи запроса объединением остальных параметров
$new_query_string = ' ' ;
if ($qs_array)
{
foreach ($qs_array as $name => $value)
$new_query_string . = ($new_query_string = 1 ' ? '? ' : 'S')
. urlencode($name) . '=' . urlencode($value);
}
}
// возврат URL, не содержащего $param
return $url_path . $new_query_string;
)
?>
2. В папке seophp создайте новый сценарий с именем aff test.php и введите в
него следующий код:
<?php
// включение библиотеки программ работы с URL
require_once 'include/url_utils.inc.php';
// загрузка конфигурационного сценария
require_once 'include/config.inc.php';
// начало сеанса PHP
session_start();
// перенаправление партнерских ссылок
if (isset($_REQUEST['aff_id']))
{
// сохранение идентификатора партнера
$_SESSION[•aff_id'] = $_REQUEST[•aff_id'];
// получение URL без идентификатора партнера
$clean_url = SITE_DOMAIM . remove_query_param($_SERVER[ 'REQUEST_URI' ], 'aff_id') ;
// перенаправление 301 на новый URL
header('HTTP/1.1 301 Moved Permanently') ;
header('Location: ' . $clean_url);
}
// вывод информации о партнере
echo ' Вы попали сюда через партнера: 1 ;
if (!isset($_SESSION['aff_id']))
{
echo '(нет партнера)';
}
else
{
echo $ SESSION['aff id']
}
?>
3. Загрузите страницу http://seophp.example.com/aff_test.php — вы должны
получить результаты, приведенные на рис. 5.3. (Если не получается, попробуйте
закрыть и снова открыть приложение браузера, т.к. оно может помнить последнее
состояние — Примеч. пер.)
4. Загрузите адрес http://seophp.example.com/aff_test.php?a=l&aff_id=
34&b=2— должно произойти перенаправление на адрес http://localhost/seophp/aff_test.php?a=l&b=2 с сохранением идентификатора партнера
(рис. 5.4).
Здесь появилось довольно много нового кода, но он вполне понятен. Подмена URL не применяется, поэтому на этот раз все делается с помощью чистого РНР-кода.
Сценарий af f_test. php начинает свою работу с загрузки файлов url_utils.inc.php
и config.inc.php и запуска сеанса PHP:
<?php
// включение программ работы с URL
require_once 'include/url_utils.inc.php';
// загрузка конфигурационного сценария
require_once 'include/config.inc.php';
// начало сеанса PHP
session_start();
Затем проверяется наличие параметра af f_id в строке запроса. Если он присутствует, его значение сохраняется в сеансе пользователя, и выполняется перенаправление на версию URL, не содержащую affid .
Здесь очень удобна функция remove_query_j?aram () из библиотеки программ работы с URL, т.к. она правильно сохраняет все существующие параметры:
// перенаправление партнерских ссылок
if (isset($_REQUEST['aff_id']))
{
// сохранение идентификатора партнера
$_SESSION['aff_id'] = $_REQUEST[*aff_id'];
// получение URL без идентификатора партнера
$clean_url = SITE_DOMAIN . remove_query_param($_SERVER['REQOEST_URI'], 'aff_id');
// перенаправление 301 на новый URL
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $clean_url);
}
И в конце работы сценария осуществляется проверка, имеет ли значение параметр сеанса с именем af f_id. Если имеет, то пользователь попал на данную страницу по партнерской ссылке, и это надо учитывать при работе при работе с данным пользователем.
Для упрощения упражнения здесь лишь выводится идентификатор партнера
или сообщение (нет партнера), если страница была загружена сразу без параметра aff_id.
// вывод информации о партнере
echo 'Вы попали сюда через партнера: 1;
if (!isset($_SESSION['aff_id']>)
{
echo '(нет партнера)';
}
else
{
echo $_SESSION['aff_id'];
}
?>
Полезно также рассмотреть, что происходит внутри функции remove_query_
param () из файла urlutils.inc.php. Удаление одного параметра из строки запроса
выполняется с помощью преобразования существующей строки запроса в ассоциативный массив, а затем объединения его элементов снова в строку запроса, но без параметра aff_id.
Чтобы сделать код понятнее, в нем выделена специальная функция для преобразования строки запроса в ассоциативный массив. Эта функция называется parse _querystring(); она принимает в качестве параметра строку запроса (вроде a=l&af f_id=34&b=2) и возвращает ассоциативный массив с этими элементами:
'а' => '1'
'aff_id' => '34'
'b' => '2'
Функция начинает свою работу с вызова explode () для разбиения строки запроса
по символам &:
// преобразование строки запроса в ассоциативный массив
function parse_query_string($query_string)
{
// разбиение строки запроса на отдельные пары имя-значение
$items = explode('&', $query_string);
Если строка запроса содержит a=l&af f_id=34&b=2, то массив items будет содержать
эти три элемента:
$items[0] => 'а=1'
$items[l] => 'aff_id=34'
$items[2] => 'b=2'
Затем выполняется разбор всех этих элементов с помощью цикла foreach, в котором
каждый элемент разбивается с помощью функции explode () по символу =.
Полученные данные заносятся в ассоциативный массив $qs_array, который и возвращается
функцией. Для сохранения каждого параметра строки запроса используется
функция u r l d e c o d e О , т.к. в нем могут быть закодированы специальные символы:
// инициализация возвращаемого массива
$qs_array = array();
// заполнение массива
foreach($items as $i)
{
// разбиение пары имя-значение и сохранение ее элементов в $qs_array
$pair = explode('=', $i);
$qs_array[urldecode($pair[0])] = urldecode($pair[1]);
II возврат массива
return $qs_array;
}
Мы рассмотрели функцию p a r s e _ q u e r y _ s t r i n g () потому, что она используется
в функции remove_query_param(), которая нас, собственно, и интересует — как вы
помните, она вызывается из af f _ t e s t .php для удаления из строки запроса параметра aff_id.
Функция remove_query_param () принимает два параметра: URL и параметр,
который нужно удалить из этого URL. Передаваемый URL имеет вид /aff_test.
php?a=lsb=2. Поскольку для дальнейшей обработки нужна строка запроса, функция remove_query_param() вначале разбивает параметр $ url на части $url_path и $query_string:
// удаление параметра из строки запроса
function remove_query_param($url, $param)
{
// извлечение строки запроса из $url
$tokens = explode('?', $url);
$url_path = $tokens[0];
$query_string = $tokens[l];
После этого вызывается функция parse_query_string () для преобразования строки запроса в ассоциативный массив:
// преобразование строки запроса в ассоциативный массив
$qs_array = parse_query_string($query_string);
Как было сказано выше, ассоциативный массив будет содержать данные вроде:
'а' => 1 '
'aff_id' => '34'
'b' => '2'
Ассоциативные массивы удобны тем, что с ними легко работать. Теперь, при наличии в ассоциативном массиве разобранной по элементам строки запроса, достаточно удалить ненужный параметр с помощью вызова u n s e t ( ) . В данном случае значением
$param является ' a f f _ i d ' :
// удаление элемента $param из массива
unset($qs_array[$param]);
Теперь у нас есть ассоциативный массив с содержащимися в нем элементами, из
которых нужно составить новую строку запроса. Так что эти элементы снова объединяются
в строку, форматированную в виде строки запроса. Учтите, что так надо делать,
только если ассоциативный массив не пуст, и для сборки строки запроса применяется
тернарная операция:
// создание новой строки запроса объединением остальных параметров
$new_query_string = ' ' ;
if ($qs_array)
{
foreach ($qs_array as $name => $ value)
{
$new_query_string .= ($new_query_string = =' ' ? ' ? ' : '&')
. urlencode($name) . '=' . urlencode($value);
}
}
Что это за тернарная операция? Если вы не знакомы с ней, то вот краткое пояснение.
Тернарная операция имеет вид (условие ? зяачеяиеА : значенивВ). Есйм условие верно, то операция возвращает значенная, иначе она возвращает значение Б.
В нашем случае выполняется проверка, пуста ли переменная $new_query_string. Если пуста, то сначала к ней добавляется символ — ограничитель первого параметра строки запроса. Для всех остальных параметров применяется символ &.
После того как новая строка запроса скомпонована, она снова заносится в путь
URL-адреса, из которого она была вначале выбрана (в данном случае /afftest.php)
и возвращается функцией:
// возврат URL, не содержащего $param
return $url_path . $new_query_string;
}
Мы надеемся, что это было интересное упражнение по обработке строк. Для любителей регулярных выражений сообщаем, что они также могут с успехом выбрать параметр aff_id из строки запроса. Это делается следующим образом:
function remove_query_param($url, $param)
{
// удаление $param
$new_url = preg_replace("#aff_id=?(.*?(S|$))?#", ", $url) ;
// удаление завершающего ? или &, если он есть
if (substr($new_url, -1) = '?' || substr{$new_url, -1) = '5')
{
$new_url = substr($new_url, 0, strlen($new_url) - 1) ;
}
// возврат нового URL
return $new url;
}
Разбор этого регулярного выражения оставляем вам в качестве домашнего задания.
Пример № 2
Tagged: