Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Функция замены переменных в строке 
:(
    Опции темы
kanaris
Дата 13.3.2008, 13:58 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 16.2.2008

Репутация: -1
Всего: -1



Есть след. задача. Из базы данных извлекается строка вида 'файл скачан $count раз' (это к примеру). Есть ли в пхп встроенная функция, которая заменит вхождение $count в строке на реальное значение этой переменной?

Должно получиться что-то типа

Код

$count=666;
$s='файл скачан $count раз'; // допустим, это извлекли из БД

$result=some_func($s); // функция, которая заменяет переменные

echo $result; // выведет "файл скачан 666 раз"


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

Это сообщение отредактировал(а) kanaris - 13.3.2008, 14:07
PM MAIL   Вверх
vasac
Дата 13.3.2008, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1060
Регистрация: 4.5.2006

Репутация: 8
Всего: 36



А функции работы с регулярными выражениями не встроенные?

str_replace может быть поможет? Или нужна именно функция, которая заменяет "count" на $count? smile
PM WWW   Вверх
kanaris
Дата 13.3.2008, 14:14 (ссылка)    | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 16.2.2008

Репутация: -1
Всего: -1




Нужна именно функция, которая заменяет вообще переменные в строке, будь то $count, $count[sdfsdf], $count[123], $count->variable, подобно, как заменяются переменные в строках с двойными кавычками:

Код

$var=123;

echo "Переменная: $var"; // Переменная: 123


Вот только строка, в которой производится замена, извлекается из БД, и должна парситься такой функцией
PM MAIL   Вверх
flashaa
Дата 13.3.2008, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 796
Регистрация: 7.3.2006

Репутация: 19
Всего: 25



Не нашел такой ф-ции.
Либо работа со строками либо eval:
Код

function getStr($str) {
    eval('$s = '. $str);
    return $s;
}

Хотя с ф-цией это я не прав.. Область видимости.

Это сообщение отредактировал(а) flashaa - 13.3.2008, 14:32
PM MAIL   Вверх
kanaris
Дата 13.3.2008, 15:20 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 16.2.2008

Репутация: -1
Всего: -1




Код

function getStr($str) {
    eval('$s = "'. $str.'"'); // тут поправил чуть
    return $s;
}


вот человек предложил функцию. вроде бы офигенно. но на самом деле полная фигня.
1) область видимости (нужно глобализировать кучу переменных, ужас)
2) если в существующей строке уже были кавычки, то строка не обработается eval()'ом.
3) если совершенствовать эту конструкцию, то получится полная фигня, которая пашет в 10 раз медленнее той, что у меня уже существует, и баговее во стока же раз

Я сам искал в документации по пхп, вроде ничего подобного и нету. или может быть плохо искал.

Это сообщение отредактировал(а) kanaris - 13.3.2008, 15:22
PM MAIL   Вверх
Canarat
Дата 13.3.2008, 15:25 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 212
Регистрация: 11.3.2008
Где: Каспий

Репутация: 5
Всего: 5



kanaris, вообще мне кажется что этот подход яйца выеденного не стоит. Для чего тогда sprintf, printf и вообще технология placeholder'ов? А функция, которую написал flashaa, будет работать в таком виде:
Код

<?php
function getStr($str) {
    eval('
extract($GLOBALS);
$s = "'. $str.'";');
    return $s;
}
$count=123;
echo getStr('check$count'); //выводит "check123"
?>


Добавлено через 11 минут и 30 секунд
Любые подобные операции есть изврат над самой сутью работы со строками в РНР smile И потому ни скоростью, ни удобством, ни очевидностью они отличаться не будут.
PM MAIL   Вверх
kanaris
Дата 13.3.2008, 16:11 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 16.2.2008

Репутация: -1
Всего: -1



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

Чтобы не вводить никого в заблуждение, привожу полный пример скрипта, который парсит страницу (пока со старым вариантом). Если все-таки такая функция существует, парситься будет значительно быстрее и шаблоны будут намного понятнее программеру.

Код

<?php

/**
 * @author kanaris
 * @copyright 2008
 */
 
/*
%ELEMENT(id)%    - Элемент, парсится локально.
%SVAL(id)%        - Статическое значение. Берется из БД по id, парсится глобально.
%DVAL(id)%        - Динамическое значение, берется из массива по ключу id, парсится глобально.
%TEXT(id)%        - Фраза, берется из БД по id, парсится глобально.
*/

$templates=array(
    'razm_page_normal' => '<html><head>%ELEMENT(redirect)%</head><body>%ELEMENT(menu)%%ELEMENT(path)%%ELEMENT(content)%</body></html>',
    'other_redirect' => '<meta http-equiv="prefresh" content="%ELEMENT(timeout)%; URL=%ELEMENT(url)%">',
    'nav_hmenu_sel' => '<span class="sel">%ELEMENT(text)%</span>',
    'nav_hmenu_unsel' => '<span class="unsel"><a href="%ELEMENT(url)%">%ELEMENT(text)%</a></span>'
);

define('ENTRY_VAL',0);
define('ENTRY_TEMPLATE',1);
define('ENTRY_DEFINE',2);
define('ENTRY_JOIN',3);
define('ENTRY_ARRAY',4);
// define('ENTRY_',);

$req_templates=array();

class entry{
    var $type,    /* Типы элементов дерева:
            0    Элемент без шаблонов, просто значение.
            1    Элемент, базирующийся на статическом шаблоне с вхождением(ями).
            2    Элемент, базирующийся на динамическом шаблоне с вхождением(ями).
            3    Статические элементы, расположенные по порядку (простой массив)
            4    Динамические элементы, расположенные по порядку (массив из обьектов)
            */
        $template,    // Идентификатор шаблона, применяемого к элементу
        $body;        // единичное значение или массив из элементов

    function __construct($type,$template,$values){
        global $req_templates;
        $this->type=$type;
        $this->template=$template;
        $this->body=$values;
        if ($type==1){
            array_push($req_templates,$template);
        }
    }//__construct
    
    function add($value,$index){
        switch($this->type){
            case 1||2:
                $this->body[$index]=$value;
                break;
            case 3||4:
                array_push($this->body,$value);
                break;
            default:
                $this->body=$value;
        }
//        $this->body.=
    }//add

    function parse(){
        global $templates;
        switch($this->type){
            case 1:
                $t=$templates[$this->template];
                preg_match_all("|%ELEMENT\(([a-z]+)\)%|U",$t,$ev,PREG_SET_ORDER);
                if(sizeof($ev)>0){
                    foreach($ev as $repl){
                        $t=str_replace($repl[0],$this->body[$repl[1]]->parse(),$t);
                    }
                }
                $ret=$t;
                break;
            case 2:
                $t=$this->template;
                preg_match_all("|%ELEMENT\(([a-z]+)\)%|U",$t,$ev,PREG_SET_ORDER);
                if(sizeof($ev)>0){
                    foreach($ev as $repl){
                        $t=str_replace($repl[0],$this->body[$repl[1]]->parse(),$t);
                    }
                }
                $ret=$t;
                break;
            case 3:
                foreach($this->body as $val){
                    $ret.=$val;
                }
                break;
            case 4:
                foreach($this->body as $val){
                    $ret.=$val->parse();
                }
                break;
            default:
                $ret=$this->body;
        }
        return($ret);
    }//parse
}//class entry

$document=new entry(ENTRY_TEMPLATE,'razm_page_normal',
    array(
        'redirect' => new entry(ENTRY_TEMPLATE,'other_redirect',array(
            'timeout' => new entry(ENTRY_VAL,'',100),
            'url' => new entry(ENTRY_VAL,'','http://dev.hackersoft.ru/403/')
        )),
        'menu' => new entry(ENTRY_ARRAY,'',array(
            0 => new entry(ENTRY_TEMPLATE,'nav_hmenu_sel',array(
                'text' => new entry(ENTRY_VAL,'','Главная')
            )),
            1 => new entry(ENTRY_TEMPLATE,'nav_hmenu_unsel',array(
                'text' => new entry(ENTRY_VAL,'','Контакты'),
                'url' => new entry(ENTRY_VAL,'','feedback.php')
            )),
            2 => new entry(ENTRY_TEMPLATE,'nav_hmenu_unsel',array(
                'text' => new entry(ENTRY_VAL,'','FAQ'),
                'url' => new entry(ENTRY_VAL,'','faq.php')
            ))
        )),
        'path' => new entry(ENTRY_VAL,'','Path'),
        'content' => new entry(ENTRY_VAL,'','Content'),
    )
);

$_mtime=microtime();
$_mtime=explode(" ",$_mtime);
$_mtime=$_mtime[1]+$_mtime[0];
$_tstart=$_mtime;

echo $document->parse();

$_mtime=microtime();
$_mtime=explode(" ",$_mtime);
$_mtime=$_mtime[1]+$_mtime[0];
$_tend=$_mtime;
$_totaltime=($_tend-$_tstart);
settype($_totaltime,"string");
echo '<!-- Шаблон парсился '.$_totaltime.' секунд -->';


//echo '<pre>'.print_r($parse,true).'</pre>';

$req_templates=array_unique($req_templates);
echo '<pre>'.print_r($document,true).'</pre>';

echo '<hr/>'.$document->body[menu]->body[1]->body[url]->body;

?>


Этот скрипт парсит страницу, и выводит это:

Код

<html>
<head>
<meta http-equiv="prefresh" content="100; URL=http://dev.hackersoft.ru/403/">
</head>
<body>
<span class="sel">Главная</span>
<span class="unsel"><a href="feedback.php">Контакты</a></span>
<span class="unsel"><a href="faq.php">FAQ</a></span>
PathContent
</body>
</html>
<!-- Шаблон парсился 0.000469923019409 секунд -->


Здесь пока в роли такой функции выступают эти строки:

Код

$t=$templates[$this->template];
preg_match_all("|%ELEMENT\(([a-z]+)\)%|U",$t,$ev,PREG_SET_ORDER);
if(sizeof($ev)>0){
    foreach($ev as $repl){
        $t=str_replace($repl[0],$this->body[$repl[1]]->parse(),$t);
    }
}


кстати, как сама идея шаблонизатора?
PM MAIL   Вверх
Canarat
Дата 13.3.2008, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 212
Регистрация: 11.3.2008
Где: Каспий

Репутация: 5
Всего: 5



kanaris, 
Цитата

кстати, как сама идея шаблонизатора? 

Ничего сверх стандартной концепции шаблонизаторов
Цитата

а если в строке будут кавычки? ничего не получится

И str_replace отключен? smile Вообще, можно заставить её работать при любых условиях, даже самых катастрофических. И оптимизировать до бесконечности, но эта задача сама по себе стоит неправильно. Шаблонизаторы это стандартная методика в таких случаях, и пренебрегать ей ради сомнительного облегчения кода - не думаю. Можно правда облегчить сам шаблонизатор, или вообще перейти на sprintf, для такой задачи.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0746 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.