ITCS - Реальное программирование. Часть 2 - ПРОГРАММИРОВАНИЕ
Сегодня: Четверг, 08.12.2016, 01:12 (МСК)| Здравствуйте, Гость| Мой профиль | Регистрация | Вход | RSS

Популярно об ИИ.
Третий сезон

Спецэффекты в Cinema4D

Роботы и экзоскелеты

ТВ-тюнеры. Как выбирать?

Adobe Audition 3. Лучшая в 2010-м
Главная » ПРОГРАММИРОВАНИЕ

Реальное программирование. Часть 2

12.05.2013
В этом обзоре: сбор статистики просмотров с использованием memcashed, ротатор баннеров на высоконагруженных ресурсах, установка TinyMCE.


Сбор статистики просмотров с использованием memcashed


Рассмотрим типовую ситуацию для высоконагруженных ресурсов: нам нужно организовать сбор статистики просмотров каждой страницы (например, с товарами). Обращение к БД напрямую в данном случае не является оправданным. Поэтому нам нужно реализовать следующее: помещать данные о просмотрах в memcashed, после чего они периодически сбрасываются в БД специальным скриптом через cron. 

Сам скрипт счетчика просмотров должен только вызываться, но его исполнение самой загружаемой страницей контролироваться не должно («запустил и забыл»).

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

Вариантов реализации можно предусмотреть сразу несколько, например, реализовав работу метода в отдельном потоке за счет вызова сценария с использованием функции exec(). Также, вероятно, можно и особым образом настроить crontab, формируя очередь исполнения скриптов, и наверняка есть и другие варианты решений, все нужно пробовать. 

Я остановлюсь на решении с сокетами, потому как оно является, наверное, наиболее кроссплатформенным, не требует сторонних библиотек.

Решение разделим на три php-файла, два приведены ниже — index.php с классом, который в рамках своего конструктора вызывает файл сценария views_counter.php, а третий connect.php — это стандартное подключение к БД (его мы приводить не будем). 

Основной файл index.php:

 
class product_views{

//конструктор
function product_views($url, $params = array())
{
    $parts = parse_url($url);
 
    if (!$fp = fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80))
    {
        return false;
    }
 
    $data = http_build_query($params, '', '&');
 
    fwrite($fp, "POST " . (!empty($parts['path']) ? $parts['path'] : '/') . " HTTP/1.1\r\n");
    fwrite($fp, "Host: " . $parts['host'] . "\r\n");
    fwrite($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
    fwrite($fp, "Content-Length: " . strlen($data) . "\r\n");
    fwrite($fp, "Connection: Close\r\n\r\n");
    fwrite($fp, $data);
    fclose($fp);
 
    return true;
}
}

//получаем ID продукта
$id = $_GET['productID'];

//создаем экземпляр класса product_views
$pageCount = new product_views('http://имя_сайта.ru/phpfns/views_counter.php', array('$productID'=>$id));

?>

Данные в файле сценария мы получаем через $_POST['productID']. В данном случае мы не будем предусматривать возможности добавления префиксов или суффиксов для ключей записей продуктов. Хотя в реальной ситуации они должны быть предусмотрены для удобной идентификации конкретных параметров. 

Второй файл views_counter.php может выглядеть так:


//получаем id продукта
$productID = $_GET['productID'];

$memcache_obj = new Memcache;

//коннектимся с сервером Memcached
$memcache_obj->connect('memcache_host', 11211);


//стандартный вариант, но с исключением
//коллизий на всякий случай
while(true) {
$get_result = $memcache_obj->get($productID);
if($get_result)
{
if($memcache_obj->increment($productID)) break;
else 
{
//подключаемся к БД
include('includes/connect.php');
//обращаемся к БД
$query="SELECT views FROM products_table WHERE productID='".$productID."';";
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
$row['views']++;
if($memcache_obj->add($productID, $row['views'])) break;
}
usleep(rand(10, 1000));
}
//Закрываем соединение с сервером Memcached
$memcache_obj->close();

?>

Также тут стоит отметить, что в данном файле вы можете заметить бесконечный цикл, выход из которого конкретно не описан. Тут дело в том, что предусмотрен тот факт, что время выполнения PHP-скриптов ограничивается со стороны PHP (по умолчанию оно составляет 30 секунд, см. настройки php.ini). Если скрипт не успевает выполниться, он сбрасывается. При более аккуртном программировании рекомендуется самостоятельно продумать выход из бесконечного цикла. 


Ротатор баннеров


Также типовая задача. Допустим, у нас есть около 1000 баннеров, для каждого из которых указана своя частота показов. Сайт с высокой посещаемостью. Наилучшим решением будет являться помещение в cron PHP-скрипта, который рассчитывает ID показываемого баннера и записывает его в кэш или буфер memcashed. 

Теперь перейдем к написанию непосредственно PHP-скрипта, а именно, как наиболее оптимально обратиться к MySQL. Наиболее быстрым вариантом будет что-то типа такого:

//выполняем запрос по определенному полю bannerID, указав точное число для него, 
//сгенерированное с помощью RAND(). 
$get_banner = mysql_query("SELECT bannerID, banner_img, banner_url  FROM banners_table WHERE bannerID >= 
(SELECT FLOOR( MAX(bannerID) * RAND()) FROM banners_table) AND day_views<rate AND enabled=1 ORDER BY bannerID LIMIT 1");
$banner = mysql_fetch_assoc($get_banner);
//echo "<a href='".$banner['banner_url']."'><img src='".$banner['banner_img']."'></a>";

В случае отсутствия выбранного случайным образом bannerID, либо если баннер «выработал показы» (day_views>rate), либо отключен(enabled=0), выбирается ближайший больший bannerID.  Именно поэтому используется «>=». 

Для реализации инкрементного увеличения счетчика показов баннеров можно в теле загружаемой страницы, после того как мы получили там bannerID (в зависимости от того, как вы все организовали), вписать строку:

$update_banner = mysql_query("UPDATE banners_table SET day_views = day_views+1 WHERE bannerID = '".$banner['bannerID']."' ");
    
Хотя  «вешать» update в страницы на ресурсе с высокой посещаемостью крайне не рекомендуется, поэтому используйте вариант со счетчиками и memcashed, который был описан выше. 


Установка и настройка TinyMCE. Правильная стыковка со Smarty




Среди визуальных онлайн текстовых редакторов WYSIWYG (What You See Is What You Get) наиболее популярным является TinyMCE. Он имеет фактически все необходимое для работы с текстом и функционально подобен работе с Microsoft Word с дополнениями, необходимыми для специфической работе с вебом: переходом от визуального текстового представления к HTML-редактору, очисткой лишнего кода, вставкой текста из Word (позволяет избавиться от лишних символов форматирования), добавления смайликов и т.п. Единственное, что разработчиками дается платно  — это менеджеры загрузок для изображений и файлов (два отдельных модуля-плагина).  Но есть и бесплатная альтернатива. 

Итак, сама установка, если вы используете нативный PHP без всяких «шаблонных примочек» типа Smarty, проблем с установкой быть не должно.
Сначала вы скачиваете последнюю версию TinyMCE. Тут можно выбрать одну из двух вариантов версий — обычная и с использованием jQuery. Распаковывайте архив в папку вашего сайта (в моем примере он будет в папке js, расположенной в корне сайта).
Параллельно с этим скачиваете архив с русификацией. Распаковываем его в папку /js/tinymce/jscripts/tiny_mce. То есть, там, где есть каталоги lang, plugins и т.п. 

Теперь в нужном php или html файле добавляем: 

<script type="text/javascript" src="/js/tinymce/jscripts/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript">
tinyMCE.init({
        // режим
        mode : "textareas",
        theme : "advanced", // тема, есть простая -simple
language:"ru", // язык
        plugins :  // подключаем плагины, это подкаталоги в каталоге plugins
"spellchecker,pagebreak,style,layer,table,save,
advhr,advimage,advlink,emotions,iespell,inlinepopups,
insertdatetime,preview,media,searchreplace,print,contextmenu,
paste,directionality,fullscreen,noneditable,visualchars,
nonbreaking,xhtmlxtras,template",
 
        // теперь перечисляем какие кнопки вывести на панель 
        theme_advanced_buttons1 : "save,newdocument,|,bold,italic,
underline,strikethrough,|,justifyleft,justifycenter,
justifyright,justifyfull,|,styleselect,formatselect,
fontselect,fontsizeselect",
        theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,
replace,|,bullist,numlist,|,outdent,indent,
blockquote,|,undo,redo,|,link,unlink,anchor,
image,cleanup,help,code,|,insertdate,inserttime,
preview,|,forecolor,backcolor",
        theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,
sub,sup,|,charmap,emotions,iespell,media,advhr,|,
print,|,ltr,rtl,|,fullscreen",
        theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,
spellchecker,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,
nonbreaking,template,blockquote,pagebreak,|,insertfile,insertimage",
        theme_advanced_toolbar_location : "top",
        theme_advanced_toolbar_align : "left",
        theme_advanced_statusbar_location : "bottom",
        theme_advanced_resizing : true,
 
        // скин
        skin : "o2k7",
        skin_variant : "silver",
 
        //  Указываем CSS сайта
        content_css : "css/example.css",
//  в файле можно привести и другие параметры
 
});
</script>

И в данном случае все элементы textarea поменяются на визуальные редакторы TinyMCE. Все достаточно просто. Конфигурацию кнопок и плагинов можно изменять по своему усмотрению. К тому же мы сейчас рассмотрели более сложный вариант, с темой «advanced». Есть и еще одна — «simple», в которой дается минимальный набор, и для подключения достаточно вписать просто:
 
<script type="text/javascript" src="/js/tinymce/jscripts/tiny_mce/tiny_mce.js"></script>
 <script type="text/javascript">
    tinyMCE.init({
        mode:"textareas",
        theme:"simple",
        language:"ru"
    });
</script>

Также стоит указать на один важный момент. В описанном выше случае все поля textarea заменяются редакторами TinyMCE, но иногда этого не требуется — достаточно обычных текстовых полей. Как это реализовать? На самом деле очень просто. В настройках TinyMCE добавляем одну строку:

tinyMCE.init({
        ...
        editor_deselector : "mceNoEditor"
});

И теперь в textarea можно указать переключатель как класс…

<textarea name="short_description" class="mceNoEditor">
        TinyMCE не загружается
</textarea>

Вариант с менеджерами загрузки файлов и изображений можно решить и бесплатным образом. Для этого можно воспользоваться плагином Image Manager Андрея Антонова, который скачивается здесь. Скачивается также в виде архива, который потом нужно распаковать в каталог plugins в папке tiny_mce. Таким образом, там появится новая директория images.

В ней мы заходим в …/tiny_mce/plugins/images/connector/php/, где открываем два файла: config.php и yoursessioncheck.php. В config.php указываем директории для сохранения изображений и файлов. Чтобы все работало успешно, установите права доступа на эти папки как CHMOD 777. В файле yoursessioncheck.php отключен комментариями блок кода проверки сессии. Если вам не требуется соблюдать безопасность ввода данных, то можно оставить все как есть, т.е. закомментированным, это может быть актуально в некоторых случаях для фронт-энда. Но, например, в моем случае, чаще всего визуальный редактор и вставка файлов и изображений реализуется в рамках админ-панели, то есть, бэк-энда, поэтому проверка делается. В общем, это на ваше усмотрение. 

Для подключения Image Manager к TinyMCE нужно вставить слово «images» в список plugins нашего кода (для theme:advanced), а также в кнопки theme_advanced_buttons1. 

Альтернативой Image Manager может послужить Tiny Browser, с версии 1.4.2 он стал платным ($6), так что вы можете попробовать поискать его более ранние версии, хотя Image Manager удовлетворяет всем необходимым потребностям. 

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

Что касается особенностей подключения TinyMCE на сайт, где вы используете Smarty, то наиболее часто задается вопрос по ошибке «Fatal error: Smarty: [in ./templates/… имя файла]: syntax error: unrecognized tag…». Это, в принципе, даже не ошибка конкретно TinyMCE, а вообще, JS-кода, вставляемого в шаблоны. Дело в том, что в Smarty по умолчанию и в большинстве случаев (хотя это можно изменить) все теги шаблонов располагаются между специальными символьными разделителями — фигурными скобками. Как мы знаем, фигурные скобки используются и в JS. Поэтому при вставке JS-кода нужно несколько изменить конструкцию, а именно, открывающие и закрывающие фигурные скобки JS-кода заменить соответственно на {literal}{{/literal} и {literal}}{/literal}. Всё.

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

Кристофер

 



Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Ассоциация боевых роботов
Рекомендуем...
Новости

Разделы

Опросы

Какой язык программирования вы считаете наиболее актуальным сегодня?
Всего ответов: 308

Друзья

3D-кино






Найти на сайте:








Об авторе       Контакты      Вопрос-ответ        Хостинг от uCoz