вторник, 13 октября 2009 г.

Как я прикручивал php мануал (часть 2)

Прошу прощения за продолжительный перерыв, но к сожалению затянула рутина и работа, просто физически не было времени продолжать писать здесь.
Итак сегодня я хочу продолжить свой рассказ о том как я прикручивал мануал на данный ресурс.
В прошлой статье я jgbcfk, как возможно преобразовать html мануал под свои нужды. Надеюсь, что вы разобрались, что к чему. Ну что ж продолжим.
Мне требовалось интегрировать страницу в тело вордпресса. Они уже были подготовлены для этого, но полностью страница html мне была не нужна. Надо было выдернуть лишь часть ее внутри тэгов body. Вот тут-то мне и понадобились регулярки. Нет можно было конечно не осваиваться с регулярками, а взять мою любимую функцию explode и с ее помощью все сделать, но это было бы нудно, и, некрасиво. Согласитесь гораздо приятнее, когда весь код выглядит «элегантно». Вот примерно такая функция работает у меня при запросах к мануалу php:


<?php

function HTML2WPDo()

{

    
preg_match('@([0-9A-Za-z_\.\s]+)@i',$_POST['search'],$search);

    
$search $search[1];

    
preg_match('@([\d\w_\.\s\-]+)@i',urldecode($_SERVER['QUERY_STRING']),$page);

    
$page $page[1];

    
//print $page;

    
$dir get_option('dir4html');

    
$abs_dir $_SERVER['DOCUMENT_ROOT'].'/'.$dir;

    if(
$search)

    {

        
$search str_replace('_','-',$search);

        
$content_file 'function.'.$search.'.html';

        if(
file_exists($abs_dir.$content_file))

        {

            
$man_func file_get_contents($abs_dir.$content_file);

        }

        else 
$content 'Произошла ошибка. Функция с подобным именем не найдена!';

    }

    else 

    {

        if(!
$page$page 'index';

        if(
file_exists($abs_dir.$page.'.html'))$man_func file_get_contents($abs_dir.$page.'.html');

    }

    
$count preg_match("|<body([^>]*)>(.*?)<\/body\s*>|si",$man_func,$func_body);

    if(
$count

    {

        
$content $func_body[2];

        
$func_body '';

    }

    return 
$content;    

}

?>

Что же она может? Данный алгоритм может как искать по имени функции, так и просто отдавать требуемые страницы. Хочу заметить что сделано все достаточно примитивно, ибо мне не нужны были какие-то изыски, единственное на данный момент что я хочу доработать это чтобы для каждой страницы в мануале генерился свой title и meta-description, но пока к сожаленеию не дошли руки. Ну это все на будущее, а теперь рассмотрим то что есть.
Первая строка:


<?php

preg_match
('@([0-9A-Za-z_\.\s]+)@i',$_POST['search'],$search);

?>

Здесь в строке поиска (элемент массива POST с ключом search) мы смотрим чтобы значение соответствовало шаблону(только цифры, латинские символы, точка, пробел, нижнее подчеркивание). Результат в виде массива помещается в переменную $search. Если выражение будет соответствовать то первый элемент массива как раз и будет содержать его.
Дальше подобную же проверку проходит элемент глобального массива $_SERVER['QUERY_STRING'] (для запросов к различным страницам мануала используется именно этот элемент).
После чего нам требуется получить дирректорию в которой лежит мануал. Так как все написано под вордпресс то я воспользовался функцией WP которая получает сохраненные в админке данные(дирректорию в данном случае).


<?php

$dir 
get_option('dir4html');

$abs_dir $_SERVER['DOCUMENT_ROOT'].'/'.$dir;

?>

Далее если переменная $search не пустая-проверяем существует ли файл с такой функцией (все файлы мануала имеют удобное для нас имя. function.имя функции.html), если такой файл существует-читаем его в строку.
В ином случае:
если не задана $page выдаем индекс;
иначе ищем файл с таким названием и если существует читаем в строку.
Ну, а дальше самое «сладкое»:


<?php

$count 
preg_match("|<body([^>]*)>(.*?)<\/body\s*>|si",$man_func,$func_body);

?>

регулярное выражение. Так как у боди могут быть параметры используем ([^>]*)
т.е любой символ, но не «>» и данные символы могут повторяться 0 или более раз (благодаря «*»).
(.*?) – это означает любой символ любое количество раз. Ну и ищем все это в переменной $man_func и пишем в $func_body. Таким образом $func_body[2] будет содержать именно то, что нам надо. (почему читайте в предыдущей статье цикла) Ну и собственно возвращаем результат обработки:


<?php

return $content;

?>

Все готово. Функция простая как топор. :) Пишите свои комментарии, пожелания, указывайте на замеченные недостатки. Всегда буду рад обсудить.