За последние 24 часа нас посетил 17331 программист и 1216 роботов. Сейчас ищут 1459 программистов ...

Есть идеи по оптимизации кода?

Тема в разделе "Прочие вопросы по PHP", создана пользователем alien, 8 ноя 2008.

  1. alien

    alien Активный пользователь

    С нами с:
    23 фев 2006
    Сообщения:
    18
    Симпатии:
    0
    Есть следующий код. Есть ли идеи по оптимизации.
    PHP:
    1. $data=<<<HEREDOC
    2. [foreach {f_arr}]
    3. {f_val:name}<br />
    4. <b>{f_val:value}</b>
    5. <br /><br />
    6. [/foreach]
    7. HEREDOC;
    8.  
    9.  
    10.  
    11.             $vars['foreach']['arr'][]=array('name'=>'my1','value'=>'jon');
    12.             $vars['foreach']['arr'][]=array('name'=>'my2','value'=>'smit');
    13.             $vars['foreach']['arr'][]=array('name'=>'my3','value'=>'anjil');
    14.             $vars['foreach']['arr'][]=array('name'=>'my4','value'=>'demon');
    15.             $vars['foreach']['arr'][]=array('name'=>'my5','value'=>'tokar');
    16.  
    17.     preg_match_all('/\[foreach {f_(.+?)}](.+?)\[\/foreach\]/is', $data, $parr);
    18.         if(isset($parr))
    19.         {
    20.             $tmpd='';
    21.             foreach ($parr[0] as $k => $v) {
    22.                 foreach ($vars['foreach'][$parr[1][$k]] as $tmp)
    23.                 {
    24.                     //print_r($tmp);
    25.                     $work=$parr[2][$k];
    26.                     preg_match_all('/{f_(\S+?):(\S+?)}/i', $data, $farr);
    27.                     $num_var=count($farr[2]);
    28.                     for($i=0;$i<$num_var;$i++)  $work=str_replace("{f_{$farr[1][0]}:{$farr[2][$i]}}",$tmp[$farr[2][$i]],$work);
    29.                     $tmpd.=$work;
    30.                 }
    31.             $data = str_replace($v, $tmpd,$data );
    32.             }
    33.         }
    34. echo $data;
    35.  
    у меня только одна идея.
    заменить тут str_replace
    PHP:
    1. for($i=0;$i<$num_var;$i++)  $work=str_replace("{f_{$farr[1][0]}:{$farr[2][$i]}}",$tmp[$farr[2][$i]],$work);
    на preg_replace но чето немогу некак составить регулярку. Да и надо ли?
    Еще думаю можно избавиться от временных переменных. но тоже не-могу придумать нечего.
     
  2. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    есть, использвоать натив пхп
     
  3. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    хотя можно так =))
    PHP:
    1. <?
    2.  $data=<<<HEREDOC
    3.  [foreach item=var key=key value=val]
    4.  <b>{key}</b> <br>
    5.    [foreach item=val key=k value=v]
    6.       {k}=>{v}<br>
    7.    [/foreach]
    8.  <br /><br />
    9.  [/foreach]
    10. HEREDOC;
    11. function getattr($str) {
    12.    preg_match_all("#([^\[\]\s]+)=([^\[\]\s]+)#i",$str,$res);
    13.    $attr=array();
    14.    for($i=0,$c=count($res[1]);$i<$c;$i++) {
    15.        $attr[$res[1][$i]]=$res[2][$i];
    16.    }
    17.    return $attr;
    18. }
    19. $vars=array("var"=>array("key1"=>array("key1"=>"val1","key2"=>"val2"),"key2"=>array("key1"=>"val1","key2"=>"val2")));
    20.  $compile='';
    21.  $compile=str_replace("{","<?=\$vars['",$data);
    22.  $compile=str_replace("}","'];?".">",$compile);
    23.  $compile=str_replace("[/foreach]","<?}?>",$compile);
    24.  preg_match_all("#\[foreach(.+?)\]#is",$compile,$res);
    25.  $who=array();
    26.  $replace=array();
    27.  for($i=0,$c=count($res[0]);$i<$c;$i++) {
    28.      $who[]=$res[0][$i];
    29.      $attr=getattr($res[0][$i]);
    30.      $replace[]="<?foreach(\$vars['{$attr['item']}'] as \$vars['{$attr['key']}']=>\$vars['{$attr['value']}']){?>";
    31.  }
    32.  $compile=str_replace($who,$replace,$compile);
    33.  eval("?".">".$compile."<?");
    34.  ?>
     
  4. obsrv

    obsrv Активный пользователь

    С нами с:
    2 окт 2008
    Сообщения:
    238
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    Объясните неразумному (немодному :) ), это чО:
    Код (Text):
    1.  
    2. $data=<<<HEREDOC
    3.    [foreach item=var key=key value=val]
    4.    <b>{key}</b> <br>
    5.     [foreach item=val key=k value=v]
    6.         {k}=>{v}<br>
    7.     [/foreach]
    8.    <br /><br />
    9.    [/foreach]
    10.   HEREDOC;
    у меня даже не "компайлится"
     
  5. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    obsrv,
    1. Всё работает
    2. Синтаксис я немного переделал =))
     
  6. obsrv

    obsrv Активный пользователь

    С нами с:
    2 окт 2008
    Сообщения:
    238
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    Mr.M.I.T.
    дошло, пробела в закрывающем HEREDOC не должно быть)) очуметь. Спасибо.

    [off]если в шапке была идея сделать парсер темплейтов с циклами, то идея по организации работы мне ваще не нравится.[/off]
     
  7. alien

    alien Активный пользователь

    С нами с:
    23 фев 2006
    Сообщения:
    18
    Симпатии:
    0
    Чем конкретно?
     
  8. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    наверно тем что вы пытаетесь имитировать циклы и а не компилировать свои шаблоны в натив пхп представление
    Зы. Ещё раз, шаблонизаторы это зло, используйте натив пхп, ну или по крайней мере пиши синтаксис шаблонов как можно ближе к пхпшному
    например
    Код (Text):
    1. {foreach($arr as $key=>$val)}
    2.    {$key}=>{$val}<br>
    3.    {$val=htmlspecialchars($val)}
    4.    {$val}
    5. {/foreach}
    как то так
     
  9. alien

    alien Активный пользователь

    С нами с:
    23 фев 2006
    Сообщения:
    18
    Симпатии:
    0
    А eval для обработки темплейтах это нормально(и по скорости работает быстрее чем то-что я писал?). Если да то сделать именно на натив не проблема.
     
  10. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    что быстрее парсер пхп или парсер tpl на пхп?
    а если ещё и кешировать скомпилированные шаблоны ....
     
  11. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    фтопку!
     
  12. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    include 0о?
     
  13. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    А почему бы и нет? И пускай он внутри фнкции обрабатывается, которая будет возвращать готовый HTML.
     
  14. Увы. Инклюд происходит в глобальную область видимости. Wait for namespaces.
     
  15. obsrv

    obsrv Активный пользователь

    С нами с:
    2 окт 2008
    Сообщения:
    238
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    alien
    К сожалению, не могу точно описать.
    Так как еще НЕ думал о написании такого парсера, да думаю и не буду.
    Но если прямо на ходу то примерно вижу так (далее поток сознания, сорри если чего не понятно).
    Будут интерфейсы (с методами вывода), будут классы ( по типам , например класс описывающий foreach или array). Класс foreach имеющий аттрибуты (которые тоже классы).
    Будет дерево из таких классов в результате парсов (может переработка в xml).
    Потом будет обратная сборка с подставлением значений (с пробегом - может по дереву) с использованием методов реализованных интерфейса.

    А тут я вижу решение в лоб. Не масштабируемое, неудобное и тд. Но допускаю, что абсолютно раочее.

    Сорри, если чО :)
     
  16. alien

    alien Активный пользователь

    С нами с:
    23 фев 2006
    Сообщения:
    18
    Симпатии:
    0
    Смотрю тут кажый придерживаться своего мнения.
    Псевдо код плохо. eval плохо. Что-же тогда хорошо?
     
  17. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Smarty 3.
     
  18. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    [vs]
    потому что там инклюд? :)
     
  19. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    вот оно!
    PHP:
    1. <?
    2. class tpl {
    3.    public static $tpldir,$cachedir,$cachetime;
    4.    private $data,$vars,$whoreplace,$replacer,$result;
    5.    function __construct() {
    6.        if (!self::$tpldir)
    7.           $this->error("Ошибка: Не указана папка с шаблонами");
    8.        if (!self::$cachedir)
    9.           $this->error("Ошибка: Не указана папка для кеширования шаблонов");
    10.    }
    11.    function error($msg) {
    12.        trigger_error($msg,E_USER_ERROR);
    13.    }
    14.    function set($name=0,$value=0) {
    15.        if (is_array($name) && !empty($name)) {
    16.            foreach($name as $key=>$val) {
    17.                $this->vars[$key]=$val;
    18.            }
    19.        } else if (!empty($name) && (!empty($value) || $value==0 || $value==false)){
    20.             $this->vars[$name]=$value;
    21.        }
    22.    }
    23.    function loadStr($str) {
    24.        $this->data=$str;
    25.        $this->compiler();
    26.        return $this->result;
    27.    }
    28.    function load($tpl) {
    29.     if(!$this->is_cached($tpl)) {
    30.        $fp=file_get_contents(self::$tpldir.'/'.$tpl);
    31.        if ($fp) {
    32.            $fp=get_magic_quotes_gpc()?stripslashes($fp):$fp;
    33.            $this->data=$fp;
    34.            $this->compiler();
    35.            $this->savecache($tpl);
    36.        }else {
    37.            $this->error("Ошибка: Шаблон $tpl не найден");
    38.        }
    39.      }else {
    40.         $this->compilecache($tpl);
    41.      }
    42.       return $this->result;
    43.    }
    44.    private function compilecache($tpl) {
    45.       @ob_start();
    46.          include self::$cachedir."/".md5($tpl).".tpl.php";
    47.          $this->result=ob_get_contents();
    48.       ob_clean();
    49.    }
    50.    private function is_cached($tpl) {
    51.       $dir=self::$cachedir."/".md5($tpl).".tpl.php";
    52.       if(file_exists($dir)) {
    53.           if (filemtime($dir)+self::$cachetime>=time()) {
    54.               return true;
    55.           }else {
    56.               unlink($dir);
    57.           }
    58.       }
    59.       return false;
    60.    }
    61.    private function compiler() {
    62.        $sys=$this->parseSys();
    63.        for($i=0,$c=count($sys);$i<$c;$i++) {
    64.            $this->whoreplace[]="{".$sys[$i]."}";
    65.            switch($this->TypeStr($sys[$i])) {
    66.                case"func":
    67.                   $this->parseFunc($sys[$i]);
    68.                break;
    69.                case"var":
    70.                   $this->parseVar($sys[$i]);
    71.                break;
    72.                case"closed":
    73.                   $this->parseClosed();
    74.                break;
    75.                case"else":
    76.                  $this->parseElse();
    77.                break;
    78.                case false:
    79.                  $this->error("Неизвестный параметр {{$sys[$i]}}");
    80.                break;
    81.                default:
    82.                   $this->parseSpec($sys[$i]);
    83.            }
    84.        }
    85.       $this->data=str_replace($this->whoreplace,$this->replacer,$this->data);
    86.       @ob_start();
    87.          eval("?".">".$this->data."<?");
    88.          $this->result=ob_get_contents();
    89.       ob_clean();
    90.    }
    91.    
    92.    private function savecache($tpl) {
    93.        $dir=self::$cachedir."/".md5($tpl).".tpl.php";
    94.         file_put_contents($dir,$this->data);
    95.         return true;
    96.    }
    97.    private function getPrinFunc() {
    98.        return array(
    99.                  "print_r",
    100.                  "print",
    101.                  "echo",
    102.                  "var_dump",
    103.                  "var_export",
    104.                  "eval", // пцц =))
    105.                  "include",
    106.                    );
    107.    }
    108.    private function parseFunc($f) {
    109.        preg_match("#(?<!\/)([\w]+)[\s]*\((.+)\)#iU",$f,$fn);
    110.        $bz=preg_match('#\$([\w]+)\=#i',$f);
    111.        $f=preg_replace('#(?<!\:\:)\$([\w]+)#i',"\$this->vars['\\1']",$f); // блин, смайлик, убрать его
    112.        if ($bz || in_array(strtolower($fn[1]),$this->getPrinFunc()))
    113.           $this->replacer[]="<?$f;?>";
    114.        else
    115.          $this->replacer[]="<? echo $f;?>";
    116.  
    117.    }
    118.    private function parseVar($v) {
    119.       $cmd=preg_match('#\$([\w]+)(.*?)(\=|\+|\-)#i',$v);
    120.       $v=preg_replace('#\$([\w]+)#i',"\$this->vars['\\1']",$v);
    121.       if(!$cmd)
    122.          $this->replacer[]="<? echo $v;?>";
    123.       else
    124.          $this->replacer[]="<?$v;?>";
    125.    }
    126.  
    127.    private function getUnMatch() {
    128.        return array("else");
    129.    }
    130.    private function parseSpec($str) {
    131.        $str=preg_replace('#\$([\w]+)#i',"\$this->vars['\\1']",$str);
    132.        $this->replacer[]="<?$str{?>";
    133.    }
    134.    private function parseClosed() {
    135.        $this->replacer[]="<?}?>";
    136.    }
    137.    private function parseElse() {
    138.        $this->replacer[]="<?}else{?>";
    139.    }
    140.    private function TypeStr($str) {
    141.        if (in_array($str,$this->getUnMatch()))
    142.           return $str;
    143.  
    144.        if (preg_match("#(?<!\/)([\w]+)[\s]*\((.+)\)#iU",$str,$par)) {
    145.            if(!in_array($par[1],$this->getClosed()))
    146.                return 'func';
    147.            else
    148.                return $par[1];
    149.        }
    150.        
    151.        if (preg_match("#(?<=\/)([\w]+)#i",$str,$par))
    152.           return 'closed';
    153.          
    154.        if (preg_match('#\$[\w]+#i',$str))
    155.           return 'var';
    156.          
    157.        return false;
    158.    }
    159.    private function getClosed() {
    160.        return array(
    161.                  "foreach",
    162.                  "if",
    163.                  "for",
    164.                    );
    165.    }
    166.    private function parseSys() {
    167.        preg_match_all("#{(.+?)}#is",$this->data,$res);
    168.        return $res[1];
    169.    }
    170. }
    171.  
    172. tpl::$tpldir='tpl';      // Папка с шаблонами
    173. tpl::$cachedir="ctpl"; // Папка с откомпилированными шаблонами
    174. tpl::$cachetime=60;  // Время обновления кеша
    175. $tpl=new tpl();
    176. $tpl->set(array("arr"=>array("key1","key2",'key3')));  
    177. print $tpl->load('tpl.tpl');
    178. ?>
    листинг шаблона tpl.tpl
    HTML:
    1. {if($arr)}
    2.  {$z=0}
    3.  {$array=array("123","12312","123123")}
    4.  {for($i=0;$i<count($arr);$i++)}
    5.   {$z++}
    6.   {$arr[$i]}
    7.   {if ($z!==count($arr))}<hr>{/if}
    8.    <br>
    9.  {/for}
    10.  {foreach ($array as $key=>$val)}
    11.    {$array[$key]="prefix_".$val}
    12.  {/foreach}
    13.  {print_r($array)}
    14. {else}
    15.    =)))))
    16. {/if}
    17.  
    18. // А теперь отожом!
    19.  
    20. {include("db.class.php")}
    21. {db::$cnf=array("db_pass"=>'','db_host'=>'localhost','db_pref'=>'test','db_name'=>'test','db_user'=>'root')}
    22. {$db=new db()}
    23. {$row=$db->super_query("SELECT * FROM ".$db->pref."_test")}
    24. {for($i=0,$c=count($row);$i<$c;$i++)}
    25.  {print_r($row)}<br>
    26. {/for}
    нафиг нам пхп? =))
    Зы. Тестил только основные возможности
     
  20. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    на выходе
    PHP:
    1. <?if($this->vars['arr']){?>
    2.  <?$this->vars['z']=0;?>
    3.  <?$this->vars['array']=array("123","12312","123123");?>
    4.  <?for($this->vars['i']=0;$this->vars['i']<count($this->vars['arr']);$this->vars['i']++){?>
    5.    <?$this->vars['z']++;?>
    6.    <? echo $this->vars['arr'][$this->vars['i']];?>
    7.    <?if ($this->vars['z']!==count($this->vars['arr'])){?><hr><?}?>
    8.    <br>
    9.  <?}?>
    10.  <?foreach ($this->vars['array'] as $this->vars['key']=>$this->vars['val']){?>
    11.    <?$this->vars['array'][$this->vars['key']]="prefix_".$this->vars['val'];?>
    12.  <?}?>
    13.  <?print_r($this->vars['array']);?>
    14. <?}else{?>
    15.    =)))))
    16. <?}?>
    17. <?include("db.class.php");?>
    18. <?db::$cnf=array("db_pass"=>'','db_host'=>'localhost','db_pref'=>'test','db_name'=>'test','db_user'=>'root');?>
    19. <?$this->vars['db']=new db();?>
    20. <?$this->vars['row']=$this->vars['db']->super_query("SELECT * FROM ".$this->vars['db']->pref."_test");?>
    21. <?for($this->vars['i']=0,$this->vars['c']=count($this->vars['row']);$this->vars['i']<$this->vars['c'];$this->vars['i']++){?>
    22.   <?print_r($this->vars['row']);?><br>
    23. <?}?>
     
  21. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Классный шаблонизатор, +100 :)
     
  22. alien

    alien Активный пользователь

    С нами с:
    23 фев 2006
    Сообщения:
    18
    Симпатии:
    0
    Блин МЕГА. Супер. Слушай ты не против если твой шаблонизатор заюзаю.
    Просто очуметь. то-что нужно. Это лучше всего что я видел. Смарти мне не нравиться(вообще, не просите объяснять просто не нравиться)
    Еще протестирую на скорость работы. Если будет неплохая то буду юзать спс.
     
  23. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    alien
    да мне не жалко =))
    делать нечего вот и написал,
    только я его почти не тестил, если что говори, буду исправлять =)
     
  24. alien

    alien Активный пользователь

    С нами с:
    23 фев 2006
    Сообщения:
    18
    Симпатии:
    0
    Ок. Буду тестить. еще
    print $tpl->load('tpl.tpl');
    думаю сразу выводить не самое лучшая идея.
    Что нибудь придумаю по этому поводу.