Попытка ответить №2 "Речь не о физическом размере кода или его скорости, а о рациональности использования 2-х и более функций вместо использования одной при условии одинакового функционала"
dark-demon Vladson Что рациональней? strcmp vs strncmp, либо strcmp с дополнительным параметром? Ответ: разницы нет. Одному больше нравится одно, другому другое. Вопрос совершенно не принципиальный.
strncmp это более новая функция по этому их стало две (чтоб не вызвать неудобств) в свою очередь если функция задумана сразу со всеми параметрами то она должна быть одна (как например сделано в случае с mysql_fetch_array)
она возвращает либо ассоциативный массив, либо индексный, либо комбинировнный. где может быть полезен последний вариант - моей фантазии не хватает. для второго существовала mysql_fetch_row(), а вот для первого приходилость юзать неудобную конструкцию mysql_fetch_array($res,MYSQL_ASSOC), поэтому в четвёртом пыхе появилась функция mysql_fetch_assoc()
Есть такая CMF/CMS phpXCore - созданная мной и моей командой. Вот несколько фич: MVC контроллер Поддержка PHP4 и PHP5 Диспетчер URL c применением регулярных выражений (для генерации ЧПУ) Поддержка и интеграция PEAR пакетов (http://pear.php.net) Использование Smarty (http://smarty.php.net) Простая AJAX интеграция (http://xajaxproject.org) JavaScript framework (http://script.aculo.us) Описывать что есть в системе - это долго, можно заглянуть в вики: дока по компонентам системы дока по CMF Если система как таковая Вас не заинтересовала, то я думаю всегда интересно поковыряться в чужой архитектуре и классах...
Посмотрел на названия компонентов и задумался. Есть такие Х-технологии, которые активно продвигает W3C, не боитесь, что названия могут пересечся?
+1. Только почему контроллер? А MySQL 3.23 она не держит? Лень написать свой шаблонизатор заточеный под двиг?
засекаем время выполнения скрипта: fscript_time.php PHP: <? function script_time ($start_time) { $stime = explode(" ",$start_time); $stime = $stime[1] + $stime[0]; $etime = microtime(); $etime = explode(" ",$etime); $etime = $etime[1] + $etime[0]; $totaltime = ($etime - $stime); printf ("<p>Страница сгенерирована за %f секунд !</p>", $totaltime); } ?> index.php PHP: <? // засекаем время начала выполнения скрипта, должно быть в файле заголовков html, напр. header.php $start_time = microtime(); ?> <p>а тут будет сайт :-)</p> <? // самые последние строки во всех скриптах, должно быть в файле заголовков html, напр. footer.php include "fscrpt_time.php"; script_time($start_time); ?>
PHP: <?php function execTime() { static $start = 0; if (!$start) { $start = microtime(true); } else { printf('%.8f', microtime(true) - $start); } } execTime(); // Some code... execTime(); ?>
целиком подобные классы не использую, но изложу какие к ним требования: 1) основное - возможность переноса с платформы на платформу. 2) уже реализованный необходимый функционал (перепрыжки по разным базам, стандартная обработка ошибок,подсчет кол-ва запросов, етс ) 3) унификация интерфейса. что приходилось использовать по частям: function setdb($dbname='',$connect='') { function startUpdate() { function endUpdate() { function LastUpdated() { $out = $this->updateFlag; return $out; } function addlog($table, $params,$keyname,$key) { function countquery($ask='',$func='other') { static $queries; static $sum; if (!(isset($queries))) { $queries=array(); $sum=0; } if ($ask!='') return $sum; if (!(isset($queries[$func]))) { $queries[$func]=1; } else {$queries[$func]++; } $sum++; } Попадались такие вещи, при запросе limit=1,100 уже неплохо нагружает систему лишним перебором массива. Произвольный доступ нужен не ко всем записям и полям, его обычно стоит использовать после общей обработки, а не до. Если нужен до, то стоит пытаться решить это средствами бд. Дополнительно удобная функция для унификации использования справочников. PHP: function xsqlcashe($sql,$id) { $q=xquery($sql); $out=array(); while($row=mysql_fetch_assoc($q)) { $out2=array(); foreach ($row as $key=>$value) { $out2[$key]=$value; } $out[$row[$id]]=$out2; } return $out; } использование: PHP: function GetUsersFio($id) { static $cashe; if (!isset($cashe)) { $sql="select us_fio,us_id from "._USERS_TBL; $cashe=xsqlcashe($sql,'us_id'); } if (isset($cashe[$id])) { return $cashe[$id]['us_fio']; } else { return false;} }
У меня явно другие требования к ним... (Моё главное требование это полное отсутствие абстракции, но увы похоже я одинок в этом)
неа. В рбк один из ведущих программистов тоже против абстракции. Мое же мнение - абстракция полезна при написании блогов и гостевух. в серьезных проектах - это зло.
Давай там это обсудим там http://php.ru/forum/viewtopic.php?t=6170 (хотя там этот класс ещё страшнее)
примитивный шаблонизатор: PHP: class tmpl { var $params=array(); var $tdir; var $template; function tmpl($template="simple_table",$templatedir="./tmpldir/common/") { $this->$tdir=$templatedir; $this->$template; require_once("IT.php"); } function setp($pname,$value) { $this->params[$pname]=$value; } function p($name) { return $this->params[$name]; } function get() { $tpl = new HTML_Template_IT($this->tdir); $tpl->loadTemplatefile($this->template, true, true); $tpl->setvariable("BLANK",''); foreach ($this->params as $key=>$value) { $tpl->setvariable($key,$value); } return $tpl->get(); } } Применение: PHP: require_once('includes/t.inc.php'); class xlist extends tmpl { var... function xlist($uid,$reftable,$postid,$list_field,$single_field='',$keyname='',$key='') { // , - для мультисправочника $this->tmpl(); //$this->table=$table; $this->uid=$uid; $this->reftable=$reftable; $this->list_field=$list_field; $this->refkeyname=$keyname; $this->refkey=$key; $this->postid=$postid; } //............................................................................. function getPlainXList($title,$list,$refname,$refid,$single='') { if ($refname!='') $this->refname=$refname; if ($refid!='') $this->refid=$refid; $this->setp('LISTFULLOPT',$this->getFullXListOptions()); $this->setp('POSTID',$this->postid); $this->setp('UID',$this->uid); $this->setp('LISTVALUE',$list); $this->setp('TITLE',$title); $this->setp('LISTNAME',$this->list_field); $this->setp('LISTOPT',$this->getXListOptions($list)); return $this->get(); } //............................................................................. } // end class наследуемый класс уже никак не зависит от применяемого шаблонизатора, будь это пир, смарти или str_replace, пока любители смарти не успели перенести в него всю логику; Еще бы в вариант с str_replace'ом добавить регулярку для распознавания строк цикла <!-- BEGIN rowname --> ... <!-- END rowname --> и пир уже не нужен.
Меня никто никогда не переубедит, что PHP луший активный шаблонизатор. Написал класс шаблонизатора с PHP подобным языком: PHP: <?php /** * (C) 2007 Fedotov Sergey <sergey89@gmail.com> */ /** * Работа с шаблонами */ class Parser { static private $_plugins = array( 'metaCharset', 'tag', 'contentType', 'curDate', 'curTime', 'curDatetime', 'rfcDate' ); static private $_vars = array(); static private $_vars_group = array(); static private $_vars_global = array(); static private $_dir = './'; // Установить директорию с шаблонами static public function setDir($name) { if ((substr($name, -1) == '/') || (substr($name, -1) == '\\')) { $name = substr($name, 0, -1); } self::$_dir = $name; return true; } // Установить значение переменной static public function setVar($name, $value) { self::$_vars[$name] = $value; return true; } // Установить значение глобальной переменной static public function setGlobalVar($name, $value) { self::$_vars_global[$name] = $value; return true; } // Получить HTML код готового шаблона static public function getHtml($fname) { global $_config; if (file_exists(self::$_dir . DS . $fname)) { if (isset(self::$_vars_global)) { foreach (self::$_vars_global as $name => $value) { $$name = $value; } } foreach (self::$_vars as $name => $value) { $$name = $value; } self::$_vars = array(); $tpl_file = self::$_dir . DS . $fname; $cache_file = CACHE_DIR . DS . 'templates' . DS . md5($tpl_file) . '.php'; if ($_config['tpl']['cache']) { if (!file_exists($cache_file) || (filemtime($cache_file) < filemtime($tpl_file))) { $tpl = self::prepare($tpl_file); file_put_contents($cache_file, $tpl); } } ob_start(); include $cache_file; return ob_get_clean(); } else { return false; } } // парсер щаблонов public static function prepare($fname) { $tpl = file_get_contents($fname); // плагины foreach (self::$_plugins as $name) { $tpl = preg_replace('#<\?(.*)_' . $name . '\((.*)\)(.*)\?>#Usi', '<?$1self::_' . $name . '($2)$3?>', $tpl); } // директивы $tpl = preg_replace('#<\?use\s+(\$[a-zA-Z_][a-zA-Z0-9_]*)\s*\?>#Usi', '<?global $1?>', $tpl); $tpl = preg_replace('#<\?set\s+\'([a-zA-Z_][a-zA-Z0-9_]*)\'\s*,\s*(.*)\s*\?>#Usi', '<?self::setVar(\'$1\', $2)?>', $tpl); $tpl = preg_replace('#<\?get\s+\'(.*)\'\s*\?>#Usi', '<?=self::getHtml(\'$1\')?>', $tpl); $tpl = preg_replace('#<\?type\s+\'(.*)\'\s*\?>#Usi', '<?header(\'Content-type: $1\')?>', $tpl); // альтернатива {, } и } else { $tpl = preg_replace('#<\?\s*else\s*\?>#Usi', '<?} else {?>', $tpl); $tpl = preg_replace('#<\?(.*)\s*:\s*\?>#Usi', '<?$1 {?>', $tpl); $tpl = preg_replace('#<\?\s*end\s*\?>#Usi', '<?}?>', $tpl); // подготавливаем к short_open_tags off $tpl = preg_replace('#<\?\s*\?>#Usi', '', $tpl); $tpl = preg_replace('#<\?([^=].*)\?>#Usi', '<?php $1?>', $tpl); $tpl = preg_replace('#<\?=\s*(.*)\?>#Usi', '<?php print $1?>', $tpl); return $tpl; } private static function _metaCharset($charset) { return '<meta http-equiv="Content-Type" content="text/html; charset=' . $charset . '" />' . "\n"; } private static function _tag($tag) { return '<?' . $tag . '?>' . "\n"; } private static function _curDate($format = 'd-m-Y') { return date($format); } private static function _curTime($format = 'H:i:s') { return date($format); } private static function _curDatetime($format = 'd-m-Y H:i:s') { return date($format); } private static function _rfcDate($timestamp = TIME) { return date('r', $timestamp); } } ?> Стоит заметить, что класс выступает в роли пространства имён. Пример создания RSS ленты. Шаблон: Код (Text): <?use $_encoding?> <?type 'text/xml'?> <?=_tag('xml version="1.0" encoding="' . $_encoding . '"')?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" > <channel> <title><?=$title?></title> <link>http://<?=$_SERVER['HTTP_HOST']?></link> <description><?=$desc?></description> <generator><?=$gen?></generator> <language><?=$lang?></language> <?foreach($items as $item):?><item> <title><?=$item['title']?></title> <link><?=$item['link']?></link> <pubDate><?=_rfcDate($item['date'])?></pubDate> <description><![CDATA[<?=$item['desc']?>]]></description> <content><![CDATA[<?=$item['msg']?>]]></content> </item> <?end?> </channel> </rss> Обработчик: PHP: <?php $_encoding = 'UTF-8'; Parser::setVar('title', 'Test RSS Feed'); Parser::setVar('desc', 'RSS Feed generated by PHPS Parser 1.0'); Parser::setVar('gen', 'PHPS Parser 1.0'); Parser::setVar('lang', 'RU'); $items = array(); // Test data for ($i = 0; $i < 3; $i++) { $items[] = array( 'title' => 'Title #' . $i, 'link' => 'http://localhost/news/' . $i . '/', 'date' => time() + $i * 10, 'desc' => 'Description #' . $i, 'msg' => 'Message #' . $i, ); } Parser::setVar('items', $items); Parser::setDir(dirname(__FILE__)); print Parser::getHtml('index.tpl'); ?>
Ещё более примитивный PHP: <?php Class Template { var $variables; function assign($array) { $this->variables = array_merge($this->variables, $array); } function parse($name) { extract($this->variables); include $name; } } ?> Пример использования PHP: <?php include "template.php"; $template = new Template(); // теперь мы можем добавлять любые значения $template->assign(array( 'title'=>'Test' )); // в любых количествах $template->assign(array( 'content'=>'Сontent', 'content2'=>'Content 2' )); // И выводить их на экран. $template->parse('test_tpl.php'); ?> PHP: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title><?=$title?></title> </head> <body> <p><?=$content?></p> <p><?=$content2?></p> </body> </html> А вот такой-же только лучше http://www.massassi.com/php/articles/template_engines/