创建时间 2011年6月1日 上午
什么是finder,作用是什么?
就我理解,finder是后台desktop定义好的在页面显示表格数据的方法(函数)。
一、在finder方法里,调用了3个类,分别是:
view.php这个类,是finder列表显示在页面的必须类,finder 标题 ,finder头部 finder 底部,定义筛选器,
六月二号下午 1:30
以我自己的现有的项目mynotebook为例,细细去探索
首先在我的app后台自定义控制器notebook.php,定义一个index方法,调用finder方法,传两个参数,具体如下:【参数1】:是自定义的model,“mynotebook_mdl_notebook”
【参数2】:有两种,一种是内置的一些操作方法(删除,导入,导出,标签 ...等等);一种是自定义的操作方法(增加操作...等等);还有一些(刷新,列表配置,高级筛选,搜索...等等)
了解了参数,我们一起跟踪到finder方法,自定义控制器本身没有finder方法,只能去他的父类desktop_controller中找,咦!找到了function finder($object_name,$params=array()){}。finder方法开始对$_GET获取过来的参数‘action’进行判断,因为没有传“action”参数,所以都是空值。在判断中调用了location_to()这个方法(这个方法中,先实例化了“base_component_request”这个类,再去调用了is_ajax()这个方法,判断是不是调用了ajax系统,结果返回的是true),在这个方法里判断is_ajax()方法返回的结果true,所以没有执行其他操作,直接返回给finder一个空值。
由于没有传参数“action”所以这里实例化一个默认类“desktop_finder_builder_view”。
$finder = kernel::single('desktop_finder_builder_'.$_GET['action'],$this);
接下来对finder第二个参数进行处理(循环将这个数组里的值赋给view类中定义好的变量)
foreach($params as $k=>$v){ $finder->$k = $v; }
接着是根据获取的第一个参数来截取app的名称 并传给$finder这对象,作为一个属性。
最后吧第一个参数再次作为参数传个$finder对象的work($object_name)方法
到此在finder方法的工作就告一段落,我们跟着去work方法
再一步步的跟踪下我们找到了 “class desktop_finder_builder_view” 类,查找没有work方法,只能去父类去找。找到方法了 function work($full_object_name){}。
$this->url = 'index.php?';$query = http_build_query($_GET);$this->url = $this->url.$query
$service_list = array(); foreach(kernel::servicelist('desktop_finder.'.$this->object_name) as $name=>$object){ $service_list[$name] = $object; } foreach(kernel::servicelist('desktop_finder.'.$this->object_name.'.'.$this->finder_aliasname) as $name=>$object){ $service_list[$name] = $object; } foreach($service_list as $name=>$object){ $tmpobj = $object; foreach(get_class_methods($tmpobj) as $method){ switch(substr($method,0,7)){ case 'column_': $this->addon_columns[] = array(&$tmpobj,$method); break; case 'detail_': if(!$this->alertpage_finder)//如果是弹出页finder,则去详细查看按钮 $this->detail_pages[$method] = array(&$tmpobj,$method); break; } } $this->service_object[] = &$tmpobj; if(method_exists($tmpobj,'row_style')){ $this->row_style_func[] = &$tmpobj; } unset($tmpobj); $i++; }以上代码主要找到的是mynotebook/lib/finder/notebook.php这个类中的所有对象属性。根据属性获取方法判断方法的前缀看他属于那种列显示。
得到了finder列表的增加项,接下来去处理这些增加项:首先查找有没有这个model注册的service。代码如下:
/** * 对额外添加的column和detail的修改 */ $obj_addon_cols = kernel::servicelist('desktop_finder_column_modifier.'.$this->object_name.'.'.$this->finder_aliasname); if ($obj_addon_cols) { foreach ($obj_addon_cols as $obj) { $obj->columns_modifier($this->addon_columns); } } $obj_addon_detail_cols = kernel::servicelist('desktop_finder_detail_modifier.'.$this->object_name.'.'.$this->finder_aliasname); if ($obj_addon_detail_cols) { foreach ($obj_addon_detail_cols as $obj) { $obj->detail_columns_modifier($this->detail_pages); } } /** end **/如果有注册的service,那就去调用这个service注册的类中的方法“columns_modifier”或者“detail_columns_modifier”,并且把相应的列属性以参数形式传给这个方法,去执行相应的操作。如下例调用的是“detail_columns_modifier“方法;
public function detail_columns_modifier(&$detail_pages){ $objuser = kernel::single('desktop_user'); if($objuser->is_super()) return ; $perss = $objuser->group(); $t1 = array(); if(is_array($perss) && !empty($perss)){ foreach ($perss as $v){ $t = explode('-', $v); $t1[] = $t[count($t)-1]; } } $action = array_keys($detail_pages); foreach ($action as $v){ if(!in_array($v, (array)$t1)){ unset($detail_pages[$v]); } continue; } }所有的service都处理好了,接下来获取数据表里的信息,包括表里设定的每个字段还有在model中设置的has_tag标签列,得到这些之后 跟着去 view.php类得main方法。
public $use_buildin_new_dialog = false; public $use_buildin_set_tag = false; public $use_buildin_recycle = true; public $use_buildin_export = false; public $use_buildin_import = false; public $use_buildin_filter = false; public $use_buildin_setcol = true; public $use_buildin_refresh = true; public $use_buildin_selectrow =true; public $use_buildin_tagedit =true; public $allow_detail_popup =false; public $max_actions =7; public $filter = array(); public $delete_confirm_tip = ''; public $base_query_string = '';
如果方法存在,获取定义好的标签,主要是筛选器finder项
if(method_exists($this->controller,'_views')){ $views = $this->controller->_views(); foreach((array)$views as $k=>$view){ //强制转换成数组循环读出 if(!isset($view['finder'])){ //判断是否设置 finder值 $views_temp[$k] = $view; }elseif(isset($view['finder'])){ if(is_array($view['finder'])){ if(in_array($this->finder_aliasname,$view['finder'])){ $views_temp[$k] = $view; } }elseif($this->finder_aliasname==$view['finder']){ $views_temp[$k] = $view; } } } }以上代码就是对 _views()方法定义的标签的处理,最后把键值赋给$views_temp数组。
$_filter = array( 'model'=>$this->object_name, 'app' =>$_GET['app'], 'ctl' =>$_GET['ctl'], 'act' =>$_GET['act'], 'user_id' => $this->controller->user->user_id, );以自定义的筛选器$_finder为条件在desktop 的 finder表中查询,是否存在这个筛选器$row
foreach($rows as $row){ $_url_array = array('app'=>$_filter['app'],'act'=>$_filter['act'],'ctl'=>$_filter['ctl'],'view'=>$view); //一个url数组 $view++; if( $extends && is_array($extends) ) { foreach( $extends as $_key => $_val ) { if( array_key_exists($_key,$_url_array) ) continue; $_url_array[$_key] = $_val; } } $url = $o->gen_url( $_url_array ); //调用desktop/lib/router.php这个类中的方法,获取路径 unset( $_url_array ); parse_str($row['filter_query'],$filter); // 解析字符串”$row['filter_query']“, $views_temp[] = array( 'label'=>$row['filter_name'], 'optional'=>'', 'filter'=>$filter, 'filter_id'=>$row['filter_id'], 'addon'=>'_FILTER_POINT_', 'custom'=>true, 'href'=>$url, ); }以上代码最后返回 数组形式的标签值,返回给main()方法,如果返回的数组不为空,并且标签被设置为显示,就执行以下代码:
if(count($this->get_views()) && $this->use_view_tab){ $_view = $this->get_views(); $this->tab_view_count = 0; foreach((array)$_view as $view){ if($view['addon']) $this->tab_view_count += $view['addon']; } $view_filter = (array)$_view[$_GET['view']]['filter']; }最后将tag的筛选条件赋给$view_filter;
接下来判断是否有一个finder参数,并且将获取到的值赋给$get_filter;
if($_GET['filter']){ $get_filter = (array)$_GET['filter']; if(!is_array($_GET['filter'])){ if(isset($_GET['filter']) && $_GET['filter']=(array)unserialize(urldecode($_GET['filter']))){ $get_filter = (array)$_GET['filter']; } } }最后将$get_filter、$view_filter、$this->base_filter、$_POST四个数组放在$this->params变量中。
接下来通过调用父类中的方法:getColumns()、getOrderBy()、$this->getPageLimit()$this->getColumns(); //获取 返回被调用的表的字段名
$this->getOrderBy(); //获取对数据的排序方式
$this->pagelimit = $this->getPageLimit(); //获取分页参数接着实例化一个对象:$render = $this->render = new base_render(app::get('desktop'));render这个类的路径是:base/lib/render调用对象属性$pagedata 项页面传值;
下面有个循环语句
if($this->top_extra_view){ $render->pagedata['top_extra'] = ""; foreach($this->top_extra_view as $app=>$view){ $_render = new base_render(app::get($app)); //再次实例化render对象 $_render->pagedata = $render->pagedata; //调用属性$pagedata $render->pagedata['top_extra'].= $_render->fetch($view); } }
下面调用本身的方法 createView() 显示finder列表的方法 再次方法里首先会获取所有的字段名作为finder列表的表头接着或获取所有的数据显示在定义好的表格中,(在获取数据的时候 回去dbeav这个app中model->controller)第二步中又会查找以前已经处理并定义好的属性变量,例如1、自定义列的显示内容和样式 (查看列的方式 和路径都是在这里处理的),还有在这里定义好的列(选择项列:复选框等);最后通过对象$render的fetch方法显示在页面,并且返回到main方法
回到main方法接着向后看 他会调用自身的一个方法_pager(),用以在列表最后显示页码;接着定义了一个$output变量,用以想页面作输出。在这里调用了自身的很多方法最主要的是$_actions方法,这里就是所谓的内置方法(删除、导入、导出、标签等等)最后完全的显示在页面 即返回了$output。到这里所有的数据都显示出来啦,view这个对象也就调用结束了 。
view.php 中的createView()的方法中,需要查询所有的数据显示在finder列表中,这段代码在:
foreach((array)$this->service_object as $k=>$object){ //$this->service_object 这个是在work方法中 渠道的server 对象 if($object->addon_cols){ $object->col_prefix = '_'.$k.'_'; foreach(explode(',',$object->addon_cols) as $col){ $sql[] = $col.' as '.$object->col_prefix.$col; } } } $sql = (array)$sql;//这里取到了所有字段名称 if(!isset($colArray[$this->dbschema['idColumn']])) array_unshift($sql,$this->dbschema['idColumn']); if($this->params===-1){ $list = array(); }else{ $this->object->filter_use_like = true; $count_method = $this->object_method['count']; $item_count = $this->object->$count_method($this->params); //在这里第一次调用 model ,他会调用到 model中重写的 _finder的方法——————2 $total_pages = ceil($item_count/$this->pagelimit); if($page <0 || ($page >1 && $page > $total_pages)){ $page = 1; } $getlist_method = $this->object_method['getlist']; $order = $this->orderBy?$this->orderBy.' '.$this->orderType:''; $list = $this->object->$getlist_method(implode(',',$sql),$this->params,($page-1)*$this->pagelimit,$this->pagelimit,$order); //在这里调用了model getlist方法 ——————3 $body = &$this->item_list_body($page, $list, $colArray, $key_modifier, $object_modifier, $type_modifier); $count = count($list); $total_pages = ceil($item_count/max($count,$this->pagelimit)); $this->pager_info = array( 'current'=> $page, 'list'=>$count, 'count'=>$item_count, 'total'=> $total_pages?$total_pages:1, ); $this->object->filter_use_like = false; }从标记2这里开始了对model的调用,在这里可以调用到model中我们自己重写的finder方法,我们可以试着重写,示例如下:
注:此处重写finder方法的命名是_finder()。
function _finder($filter,$tableAlias=null,$baseWhere=null){ //$filter此参数是控制器里调用finder方法传入的第二个参数。也可以说是搜索条件 if($filter['subject']){ $row=$this->getList('notebook_id',array('subject|has'=>$filter)); foreach($row as $k=>$v){ $filter['id']=$v['notebook_id']; } } unset($filter['subject']); return $filter; }
代码中有个3的标记,这里调用了mynotebook_mdl_notebook中的getList方法,如果没有找到这个方法,就去dbeav_model中找,现在去看看
function getList($cols='*', $filter=array(), $offset=0, $limit=-1, $orderType=null){ if(!$cols){ $cols = $this->defaultCols; } if(!empty($this->appendCols)){ $cols.=','.$this->appendCols; } if($this->use_meta){ $meta_info = $this->prepare_select($cols); } $orderType = $orderType?$orderType:$this->defaultOrder; $sql = 'SELECT '.$cols.' FROM `'.$this->table_name(true).'` WHERE '.$this->_filter($filter); if($orderType)$sql.=' ORDER BY '.(is_array($orderType)?implode($orderType,' '):$orderType); $data = $this->db->selectLimit($sql,$limit,$offset); $this->tidy_data($data, $cols); if($this->use_meta && count($meta_info['metacols']) && $data){ foreach($meta_info['metacols'] as $col){ $obj_meta = new dbeav_meta($this->table_name(true),$col,$meta_info['has_pk']); $obj_meta->select($data); } } return $data; }
basekernel.php
boot()single()对类进行实例化,autoload()request()对base/lib目录下的request类的实例化。"request.php get_path_info() 获取服务器的当前环境"service()servicelist()strip_magic_quotes() 对获取的get或post值进行处理register_autoload() 这个方法返回false,就会引入autoload.php这个自动加载类“self::$router = app::get($app)->router();(调用app对象的router函数,实例化router类) self::$router->dispatch($path);(调用router对象的dispatch函数,最后实例化控制器类,调用控制器对象中的函数)”;
app.php
controller()实例化控制器类model()实例化model类get()实例化app这个类render() 实例化base/lib 目录下的 rander类router() 实例化base/lib 目录下的 router类
router.php
dispatch() 调用控制器对象的函数
self::$__router->dispatch($path); 由此进入控制器
dbeav
lib/filder.php 处理 sql语句的where条件
创建时间 2011年6月1日 下午
1、通过引用传递参数例子:重视 & 符号 ,它表明了这个是引用传参(意思是,参数不是指向变量值,而是指向变量存储在内存里的位置)
function doublevalue(&$var){ $var=$var*2; } $variable=5; doublevalue($variable); print "\$variable is : $variable"; 输出的结果是:$variable is :102、通过引用赋值:使用&的引用也能给变量赋值,使内存持有的变量值可被多个变量访问。例子:$y现在直接引用$x,所以对$y的改变也会影响$x.(事实上,他们等于是同一个变量),$y也可以被移除(unset($y)),但不影响$x.
$x=10;$y=&$x;$y++;print $x;print $y; 输出结果:11 113、结合引用与赋值的运算符(=&)也能完成引用其他变量。例子:$x=10;$y =& $x; $z = &$x;$x=100; 输出结果“x = 100,y = 100,z = 100”;
: count()函数计算数组中的单元数目或对象中的属性个数;
count() 对没有初始化的变量返回 0,但对于空的数组也会返回 0。 用 isset() 来测试变量是否已经初始化。count() 的递归例子;count()函数有一个可选参数(COUNT_RECURSIVE 或 1),这个参数将递归地对数组计数,默认为0。
<?php $food = array('fruits' => array('orange', 'banana', 'apple'), 'veggie' => array('carrot', 'collard','pea')); // recursive count echo count($food, COUNT_RECURSIVE); // output 8 // normal count echo count($food); // output 2 ?>: array_count_values() 统计数组中所有的值出现的次数,返回一个数组,该数组用 原 数组中的值作为键名,该值在 原 数组中出现的次数作为值。例子:
<?php $array = array(1, "hello", 1, "world", "hello"); print_r(array_count_values ($array)); ?> 以上例程会输出: Array ( [1] => 2 [hello] => 2 [world] => 1 ): array_unique — 移除数组中重复的值,返回没有重复值的新数组
注意键名保留不变。array_unique() 先将值作为字符串排序,然后对每个值只保留第一个遇到的键名,接着忽略所有后面的键名。这并不意味着在未排序的 array 中同一个值的第一个出现的键名会被保留。
strict是可选参数,用于字符串与needle比较是强制检查类型。
array_search():语法——mixed array_seach(mixed needle,array haystack,boolean); 它与in_array()的运作方式相同,只是与needel相对应的键也会被返回。找到了返回的是键值(也有true);没有找到返回的是false
警告:此函数可能返回布尔值 FALSE,但也可能返回等同于 FALSE 的非布尔值,例如 0 或 ""(空串)。应使用 === 运算符 来测试此函数的返回值。
array array_keys(array $input [, mixed $search_value [, bool $strict ]]);返回数组中所有的键名。返回 input 数组中的数字或者字符串的键名。如果指定了可选参数 search_value,则只返回该值的键名。否则 input 数组中的所有键名都会被返回。自 PHP 5 起,可以用 strict 参数来进行全等比较(===)。
array array_values ( array $input ):返回数组中所有的值;返回 input 数组中所有的值并给其建立数字索引。
● sort(array &$array [, int $sort_flags ] ) 和 rsort(array &$array [, int $sort_flags ] ),这两个函数都基于元素值来排列数组。
sort() 排序整数数组(升) <?php $fruits = array("lemon", "orange", "banana", "apple"); sort($fruits); foreach ($fruits as $key => $val) { echo "fruits[".$key."] = " . $val . "\n"; } ?> 以上例程会输出: fruits[0] = apple fruits[1] = banana fruits[2] = lemon fruits[3] = orange ____________________________ rsort()(降) <?php $fruits = array("lemon", "orange", "banana", "apple"); rsort($fruits); foreach ($fruits as $key => $val) { echo "$key = $val\n"; } ?> 以上例程会输出: 0 = orange 1 = lemon 2 = banana 3 = apple
● 关联数组的排序 asort() 和 arsort() 排序后维护键与值的关联● 对键排序 ksort() 和 krsort() 这两个函数排序依据是数组的键● 用户自定义排序方式○ usort(array subject,string compare_function)
<?php function cmp($a, $b) { if ($a == $b) { return 0; } return ($a < $b) ? -1 : 1; } $a = array(3, 2, 5, 6, 1); usort($a, "cmp"); foreach ($a as $key => $value) { echo "$key: $value\n"; } ?> 以上例程会输出: 0: 1 1: 2 2: 3 3: 5 4: 6○ uasort(array subject,string compare_function)
<?php $fruits = array('Orange9','Orange11','Orange10','Orange6','Orange15'); uasort ( $fruits , function ($a, $b) { return strnatcmp($a,$b); // or other function/code } ); print_r($fruits); ?> returns Array ( [3] => Orange6 [0] => Orange9 [2] => Orange10 [1] => Orange11 [4] => Orange15 )○ uksort(array subject,string compare_function)
<?php function cmp($a, $b) { if ($a == $b) { return 0; } return ($a > $b) ? -1 : 1; } $a = array(4 => "four", 3 => "three", 20 => "twenty", 10 => "ten"); uksort($a, "cmp"); foreach ($a as $key => $value) { echo "$key: $value\n"; } ?> 以上例程会输出: 20: twenty 10: ten 4: four 3: three
警告:此函数可能返回布尔值 FALSE,但也可能返回等同于 FALSE 的非布尔值,例如 0 或 ""(空串)。应使用 === 运算符 来测试此函数的返回值。● strrpos():计算指定字符串在目标字符串中最后一次出现的位置;语法:int strrpos ( string $haystack , string $needle [, int $offset = 0 ] );
● 函数ereg():语法————boolean ereg(string pattern,string subject,array);若在subject 字符串里找到了正则表达式的模式,函数ereg()便返回true。● 函数:ereg_replace();语法————string ereg_replace(string pattern,string replacement,string source);本函数在 string 中扫描与 pattern 匹配的部分,并将其替换为 replacement。返回替换后的字符串。(如果没有可供替换的匹配项则会返回原字符串。)
<?php list($user, $pass, $uid, $gid, $extra) = split (":", $passwd_line, 5); ?>
int gmmktime(int hour,int minute,int second,int month,int day,int year,int);—————它的参数标示GMT日期和时间计算;``以上的函数都能正确的处理超出范围的参数值。
绝对值函数 abs();向上取整函数 ceil();向下取整函数 floor();舍入函数 round();随机数函数 rand();
类定义了如何将数据与函数绑定在一起 ——————成员变量与函数均在类中取得自身的意义;
问题聚集
类
类中: 属性和方法又可以使用public, protected, private三个不同的关键字来将属性和方法的作用范围做进一步的区分,带有private关键字的属性和方法,只有所在的类中的方法才能调用;带有protected关键字的属性和方法,除了自己以外,自己的父类和子类中的方法也可以调用;带有public关键字的属性和方法,则可以从实例化以后的对象中进行调用。
static关键字是有别于public, protected, private的另一类型关键字(因此可以和public, protected, private叠加起来使用):
<?php class TEST { public static function name() { echo 'value'; } } ?>带有static关键字的方法,可以在不对类进行实例化的情况下直接通过“::”符号调用,和public, protected, private的搭配,也可以让调用区分权限,但是一般都是和public搭档,前面提到的常量关键字const,应该就是public static类型的,因此只能通过self::NAME,TEST::NAME这样的形式调用常量,后面的construct,destruct等方法,都是属于static.
没有被实例化的时候,静态(static)的属性和方法可以被直接调用,调用方法是 类名::属性名或方法名
static关键字用来修饰属性和方法,称为静态属性和静态方法,static关键字声明一个方法和属性是和类相关的,而不是类的某个特定实例相关,所以这类属性和方法也称为“类属性”和“类方法”。调用通过类名两个冒号来调用(类名::类属性/方法)。
<?php class TEST { public static function name() { echo 'value'; } } //方法1:使用new关键字 $test = new TEST; $test->name(); //方法2:使用“::”符号 TEST::name(); ?>(1):使用new关键字成为实例化,上面的$test就是一个通过TEST类实例化而产生的对象,$test->name()称为调用$test对象的name方法。(2):使用new关键字使用类的时候,可以使用$this来指代类本身。(3):使用“::”符号的前提是方法必须是带有static关键字的,使用new关键字时,被调用的方法,必须带有public关键字(一个方法如果不带public, protected, private中的任何一个关键字,则默认为public)(4):同一个类可以通过new关键字被实例成多个不同的对象,但是彼此之间的是隔离的;“::”符号在使用的时候,方法在多次使用之间,是共享的:
<?php class TEST1 { public $name = 0; public function name() { $this->name = $this->name + 1; } } $test1 = new TEST1; $test2 = new TEST1; $test1->name(); //$name1 == 1 $test2->name(); //$name1 == 1 /*--------------------------------------------*/ class TEST2 { public static $name = 0; public static function name() { TEST2::$name = TEST2::$name + 1; } } TEST2::name(); // $name == 1 TEST2::name(); // $name == 2 ?>
<?php class test{ public $public; private $private; protected $protected; static $instance; static $good = 'tankzhang '; public $tank = 'zhangying '; public function __construct(){ $this->public = 'public '; $this->private = 'private '; $this->protected = 'protected '; } public function tank(){ //私有方法不能继承,换成public,protected if (!isset(self::$instance[get_class()])) { $c = get_class(); self::$instance = new $c; } return self::$instance; } public function pub_function() { echo "you request public function "; echo $this->public; } protected function pro_function(){ echo "you request protected function "; echo $this->protected; } private function pri_function(){ echo "you request private function "; echo $this->private; } static function sta_function(){ echo "you request static function "; } } class test1 extends test{ static $love = "tank "; private $aaaaaaa = "ying "; public function __construct(){ parent::tank(); parent::__construct(); } public function tank(){ echo $this->public; echo $this->protected; echo $this->aaaaaaa; $this->pro_function(); } public function test1_function(){ echo self::$love; echo self::$good; echo parent::$good; echo parent::$tank; //Fatal error: Access to undeclared static property: test::$tank echo self::$tank; //Fatal error: Access to undeclared static property: test::$tank } static function extends_function(){ parent::sta_function(); self::pro_function(); echo "you request extends_private function "; } } error_reporting(E_ALL); $test = new test1(); $test->tank(); //子类和父类有相同名字的属性和方法,实例化子类时,会调用子类中的方法。 test1::test1_function(); test1::extends_function(); //执行一部分后,报Fatal error: Using $this when not in object context in D:\xampp\htdocs\mytest\www4.php on line 32 ?> 1,当我们调用$test->tank();这个方法时,tank里面的$this是一个对像,这个对像可以调用本类,父类中的方法和属性, 2,test1::test1_function();当我们用静态的方法去调用非静态方法时,会显示警告的,Non-static method test::test1_function() should not be called statically可以看出不,self可以调用本类,父类中的静态属性,parent可以调用父类中的静态属性,二者调用非静态属性会报错。代码中有注释 3,test1::extends_function();这一步会报错,报在非对像中使用$this。为什么会这样呢,test1::extends_function();只是调用了class中的一个方法,并没有实例化,所以根本不存在什么对像,当父类中用到$this时,就会报错
<?php abstract class TEST1 // 抽象 { abstract public function name1(); public function name2() { } } class TEST2 extends TEST1 implements TEST3 // 继承 { public function name1() { } } interface TEST3 // 接口 { public function name2(); } ?> (1)带有abstract关键字的类是抽象类,带有abstract关键字的方法是抽象方法,抽象类中的抽象方法,必须在子类中被覆写。 (2)带有interface关键字的类,就是接口,接口不允许实现任何的方法,接口中所有的方法,都必须在子类中被覆写。 (3)带有 classA extends classB 或者 classA implements classB 字样的就是继承,extends表示继承另一个类,implements表示继承另一个接口,一次只能extends一个类,但是可以implements多个接口。 (4)抽象类,接口,以及最终继承并实现的方法,都必须是public的。extends 和 implements 的区别!extends 是继承某个类继承之后可以使用父类的方法也可以重写父类的方法;implements 是实现多个接口接口的方法一般为空的必须重写才能使用;
调用父类的构造函数通过“parent::__construct()”。
重新定义函数:父类定义过的函数可以在子类中重新定义,创建子类对象,子类函数会替代父类的同名函数。访问父类函数使用parent::'类名',但是 parent:: 方式只能访问上一层的父类,要访问任意的祖先类,需要要用类名来引用 即“类名::函数名“
用final声明的函数(方法)不可以被子类重新定义。
抛出与捕获异常:异常模式(exception model),可以使用throw与try...catch语句来抛出(throw)与捕获(catch)对象。
$total=100; $n=5; $result; try{ if($n==0) throw new Exception("canlt set n to zero."); $result=$total/$n; }catch(Exeption $x){ print "there was an error:{$x->getMessage()}"; }
sql与mysql
$connection = mysql_connect("localhost","username","password"); //打开数据库连接————连接服务器 mysql_select_db("数据库名",$connection); //选择数据库 $result = mysql_query("select * from wine",$connection); //在本次连接中查询 //把查询结果获取的模式转换为数组,村与数组$row中 while($row = mysql_fetch_array($result,MYSQL_NUM)){ //输出$row的每个元素,也就是输出各个字段的值 foreach($row as $attribute) print "{$attribute}"; print "\n"; }php与javascript的验证
检查字符串是否为字母:ereg("^[[:alpha:]]+$",$string);检查字符串是否为大写或小写:大:ereg("^[:upper:]]+$",$string);]+$",$string)url的验证:
$url = parse_url("http://www.webdatabasebook.com/test.php?status=F#message"); foreach($url as $k=>$v){ echo "{$k} => {$v]\n"; } 输出结果: 'scheme'=>'http', 'host'=>'www.webdatabasebook.com', 'path'=>'/test.php', 'query'=>'status=F', 'fragment'=>message,
检查数字:is_numeris ()检查的数字格式包括:整数,浮点,十六进制数字,负数。此函数可能会因为”字符串首尾的空格,回车符,逗号,负号后的空格“返回false,此处可以用trim()去除空格。
再跟代码的时候碰到的一些函数extract————int extract ( array $var_array [, int $extract_type [, string $prefix ]] ):本函数用来将变量从数组中导入到当前的符号表中。接受结合数组 var_array 作为参数并将键名当作变量名,值作为变量的值。对每个键/值对都会在当前的符号表中建立变量,并受到 extract_type 和 prefix 参数的影响。
extract() 检查每个键名看是否可以作为一个合法的变量名,同时也检查和符号表中已有的变量名的冲突。对待非法/数字和冲突的键名的方法将根据 extract_type 参数决定。可以是以下值之一:
EXTR_OVERWRITE 如果有冲突,覆盖已有的变量。 EXTR_SKIP 如果有冲突,不覆盖已有的变量。 EXTR_PREFIX_SAME 如果有冲突,在变量名前加上前缀 prefix。 EXTR_PREFIX_ALL 给所有变量名加上前缀 prefix。自 PHP 4.0.5 起这也包括了对数字索引的处理。 EXTR_PREFIX_INVALID 仅在非法/数字的变量名前加上前缀 prefix。本标记是 PHP 4.0.5 新加的。 EXTR_IF_EXISTS 仅在当前符号表中已有同名变量时,覆盖它们的值。其它的都不处理。可以用在已经定义了一组合法的变量,然后要从一个数组例如 $_REQUEST 中提取值覆盖这些变量的场合。本标记是 PHP 4.2.0 新加的。 EXTR_PREFIX_IF_EXISTS 仅在当前符号表中已有同名变量时,建立附加了前缀的变量名,其它的都不处理。本标记是 PHP 4.2.0 新加的。 EXTR_REFS 将变量作为引用提取。这有力地表明了导入的变量仍然引用了 var_array 参数的值。可以单独使用这个标志或者在 extract_type 中用 OR 与其它任何标志结合使用。本标记是 PHP 4.3.0 新加的。 如果没有指定 extract_type,则被假定为 EXTR_OVERWRITE。 注意 prefix 仅在 extract_type 的值是 EXTR_PREFIX_SAME,EXTR_PREFIX_ALL,EXTR_PREFIX_INVALID 或 EXTR_PREFIX_IF_EXISTS 时需要。如果附加了前缀后的结果不是合法的变量名,将不会导入到符号表中。前缀和数组键名之间会自动加上一个下划线。 extract() 返回成功导入到符号表中的变量数目。 例子: <?php /* 假定 $var_array 是 wddx_deserialize 返回的数组*/ $size = "large"; $var_array = array("color" => "blue", "size" => "medium", "shape" => "sphere"); extract($var_array, EXTR_PREFIX_SAME, "wddx"); echo "$color, $size, $shape, $wddx_size\n"; ?> 输出结果:blue, large, sphere, medium
ltrim ———— string ltrim ( string $str [, string $charlist ] ):去除字符串的开始空白符或者指定字符;
FILE :被称为PHP魔术常量 ,返回当前执行PHP脚本的完整路径和文件名,包含一个绝对路径;
get_magic_quotes_gpc()———— 取的环境变量“magic_quotes_gpc”的值;
strpos ————int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] ):查找字符串首次出现的位置,第三个参数是可选的,参数可以用来指定从 haystack 中的哪一个字符开始查找。返回的数字位置是相对于 haystack 的起始位置而言的。
substr ————string substr ( string $string , int $start [, int $length ] ):返回字符串 string 由 start 和 length 参数指定的子字符串。
date_default_timezone_set ————bool date_default_timezone_set ( string $timezone_identifier ):设定用于所有日期时间函数的默认时区。
dirname ——————string dirname ( string $path ): 给出一个包含有指向一个文件的全路径的字符串,本函数返回去掉文件名后的目录名。
realpath ——————string realpath ( string $path ):返回的路径中没有符号连接,'/./' 或 '/../' 成分。
stripcslashes ——————string stripcslashes ( string $str ):反引用一个使用 addcslashes() 转义的字符串;返回反转义后的字符串
addcslashes ——————string addcslashes ( string $str , string $charlist ):以 C 语言风格使用反斜线转义字符串中的字符;返回字符串,该字符串在属于参数 charlist 列表中的字符前都加上了反斜线。如果 charlist 中包含有 \n,\r 等字符,将以 C 语言风格转换,而其它非字母数字且 ASCII 码低于 32 以及高于 126 的字符均转换成使用八进制表示。
call_user_func_array()——————mixed call_user_func_array ( callback function, array param_arr ):call_user_func函数类似于一种特别的调用函数的方法
function a($b, $c) { echo $b; echo $c; } call_user_func_array('a', array("111", "222")); //显示 111 222 ?>get_class_methods ————————array get_class_methods ( mixed $class_name ): 返回由类的方法名组成的数组
DIRECTORY_SEPARATOR——————php的内置变量DIRECTORY_SEPARATOR是一个显示系统分隔符的命令。
mysql_fetch_array() 中可选的第二个参数 result_type 是一个常量,可以接受以下值:MYSQL_ASSOC,MYSQL_NUM 和 MYSQL_BOTH.如果用了 MYSQL_BOTH,将得到一个同时包含关联和数字索引的数组。用 MYSQL_ASSOC 只得到关联索引(如同 mysql_fetch_assoc() 那样),用 MYSQL_NUM 只得到数字索引(如同 mysql_fetch_row() 那样).
魔术方法
会话
session管理简介
用session来管理Web浏览器与服务器的交互,应用程序才能追踪购物车存储的物品、处理用户账号的状态、检查用户是否登录、在线交易是否结束等。在web数据库应用程序中都占有重要地位。session有两部分组成:session变量与session标示符(session_id)。session变量记录与用户交互有关的状态信息。存储在web服务器或数据库服务器上,以session_id指定其位置。session_id通常以cookie的形式传递,cookie是指一小段存储与浏览器端的文本,把会随着请求送出,与数据随着get或post方法送出的方式相似。web上管理session有三个重点:1、必须存储信息或状态。2、每次http请求都需要带有标示符,以使服务器能以正确的session变量来处理请求。3、session需要逾期时间
php的session管理
管理session的三项要点————1、识别session;2、存储session变量;3、清理旧的session
开启session————函数 sessiong_start()用于创建新的session,即开启session。
使用session变量——————函数 sessiong_start()也可用于查找已存在的session,
删除session变量——————unsert($_SESSION["count"]);
结束session session_destroy();
安全
对字符串加密:1、md5()可以处理的字符串长度不限,返回值都是固定的32个字符,内容则随着字符按串的不同而变化,如aardvark7和aardvark8这两个字符串就会产生很大的差异。2、crypt()只使用密码的前8个字符与salt来计算加密字符串,如aardvark7和aardvark8这两个字符串会形成相同的加密字符串。只要以不同的salt加密,就会产生不同的字符串。
变量调节器用于变量,自定义函数和字符串.可以使用&apos|&apos符号和调节器名称应用调节器.变量调节器由赋予的参数值决定其行为.参数由&apos:&apos符号分开.如果你用变量调节器调节数组变量,结果是数组的每个值都被调节.如果你想要调节器调节整个数组,你必须在调节器名字前加上@符号.例如: {$articleTitle|@count} ( 这将会在输出 $articleTitle 数组里的数目) capitalize 将变量里的所有单词首字大写. 参数值boolean型决定带数字的词是否首字大写。默认不大写 count_characters 计算变量值里的字符数.参数值boolean型决定是否计算空格数。默认不计算空格 cat 将cat里的参数值连接到给定的变量后面.默认为空。 count_paragraphs 计算变量里的段落数量 count_sentences 计算变量里句子的数量 count_words 计算变量里的词数 date_format 日期格式 第一个参数控制日期格式. 如果传给date_format的数据是空的,将使用第二个参数作为默认时间 %a -星期几的简写 %A -星期几的全写 %b -月份的简写 %B -月份的全写 %c -日期时间06/12/05 11:15:10 %C -世纪时间 %d -一个月的第几号(从 01 到 31) %D -同 %m/%d/%y %e -一个月的第几号,号为单数则前面加一空格 (从 1 到 31) %g -世纪 %G -世纪 [0000,9999] %h -同%b %H - 24小时形式的小时(从00到23) %I - 12小时形式的小时(从01到 12) %j -一年中的第几天(从 001 到 366) %k - 24小时形式的小时,单数字前面加空格. (从 0 到 23) %l - 12小时形式的小时,单数字前面加空格.(range 1 to 12) %m -月份 (range 01 to 12) %M -分 %n -换行符 %p -显示早上还是下午`am&apos或 `pm&apos %r - a.m.或 p.m.形式的时间 %R - 24小时形式的时间 %S -秒 %t - tab符号 %T -同%H:%M:%S %u -用 [1,7],表示星期几 %U -计算是该年的第几个星期,从该年的第一个星期天开始计算 %V -计算是该年的第几个星期, 从 01 到 53, 第一个星期必须至少有4天在这一年, 星期天作为这个星期的第一天 %w -用数字的形式表示是星期的第几天, 星期天 为 0 %W -用数字的形式是该年的第几个星期,从该年的第一个星期一开始计算 %x -显示日期:月/日/年 %X -显示时间:小时:分钟:秒 %y -不包括世纪的年份 %Y -包括世纪的年份 %Z -时区 %% -输出% 其中有些有时不能正常输出。 default 默认 为空变量设置一个默认值. 当变量为空或者未分配的时候,将由给定的默认值替代输出. escape 转码 参数值为html,htmlall,url,quotes,hex,hexentity,javascript。默认是html转码 indent 缩进 在每行缩进字符串,第一个参数指定缩进多少个字符,默认是4个字符.第二个参数,指定缩进用什么字符代替。 lower 小写 This is used to lowercase a variable. 将变量字符串小写 nl2br 换行符替换成 regex_replace 正则替换 寻找和替换正则表达式.必须有两个参数,参数1是替换正则表达式. 参数2使用什么文本字串来替换 replace 替换 简单的搜索和替换字符串必须有两个参数,参数1是将被替换的字符串. 参数2是用来替换的文本 spacify spacify是在字符串的每个字符之间插入空格或者其他的字符串. 参数表示将在两个字符之间插入的字符串,默认为一个空格。 string_format字符串格式化 是一种格式化浮点数的方法.例如十进制数.使用sprintf语法格式化。参数是必须的,规定使用的格式化方式。%d表示显示整数,%.2f表示截取两个浮点数。 strip去除(多余空格) 替换所有重复的空格,换行和tab为单个或者指定的字符串. 如果有参数则是指定的字符串。 strip_tags去除所有html标签 truncate截取 参数1,规定截取的字符数.默认是80个. 第二个参数指定在截取的那段字符串后加上什么字符.默认为... 第三个参数决定是否精确截取,默认情况下为false,则smarty不会分割单词。 upper将变量改为大写 wordwrap行宽约束 第一个参数指定段落的宽度(也就是多少个字符一行,超过这个字符数换行).默认80. 第二个参数指定在约束点使用什么字符(默认是换行符\n). 第三个参数决定是否精确截取字符,默认情况下是不精确截取,就是截取时不能分开单词。
assign assign用来在执行模板时分配变量值.var,value是必须的参数.var为要分配值的变量名,value为分配的值. counter counter用来输出一个计数. 可以用多个计数,但是名字必须各不相同.name表示计数器名,默认为default.start表示计数的初始值,默认为1.skip计数的间隔,默认为1.direction表示计数方向,up或down,默认为up.print表示是否打印该值,默认为true.assign定义模板变量,计数器的输出将被分配到assign定义的变量中. cycle Cycle用来循环显示一组数值.name表示cycle名,values("值1","值2",...)表示循环显示的一组数值.print表示是否显示.advance决定是否显示下一个数值. delimiter决定value的分隔符,默认为逗号. assign定义模板变量,cycle的输出将被分配到assign定义的变量中. debug debug可以显示所有分配了值的变量,但是不显示模板内容,output属性决定显示的格式html或javascript,默认是html. eval eval用来在变量里插入变量。var是插入的变量名,assign把输出分配给一个变量。 fetch 用来取得文件内容,并输出文件内容,可以取得本地文件,http文件和ftp文件,file是取得文件的路径, assign把输出分配给一个变量。 html_checkboxes html_checkbox用来用给定的数据创建checkbox。name表示checkbox的名称,values表示checkbox的值,output表示checkbox的显示,selected表示被选选项的值,options表示一组checkbox的值和显示,separator表示分割每个checkbox的符号,labels表示给输出添加标签,默认为true。 html_image html_image用来为一个图片创建html标签,如果height和width不分配值将会自动生成。file是图片的路径,height,width,alt同html标签,basedir是图片相对路径开始的目录的路径,默认为服务器根目录。href定义图片的链接。 html_options 输出下拉列表,参数有name,values,output,selected,options。 html_radios 输出单选框,参数同复选框。 html_select_date prefix定义各个下拉列表名字的前缀,默认为Date_。time决定使用的时间,默认是当前时间。start_year决定下拉列表开始的年份,可以用年份表示,也可以用与当前年份的相对年数来表示。默认是当前年份。end_year决定下拉列表结束的年份,可以用年份表示,也可以用与当前年份的相对年数来表示。默认是当前年份。display_days决定是否显示日期。display_months决定是否显示月份。display_years决定是否显示年份。month_format决定显示月份的格式,默认为%B。day_format决定显示日期的格式,默认为%02d。day_value_format决定日期值的格式,默认为%d。month_value_format决定月份值的格式,默认为%m。year_as_text决定是否将年份按文本格式输出。reverse_years决定是否反向输出各年份。field_array用来取得一组变量,可以用name[Day],name[Month],name[Year]的方式从form取得获得的值。day_size,month_size,year_size添加大小标签。all_extra,day_extra,month_extra,year_extra添加额外的属性到select或input标签。field_order决定年月日下拉列表的顺序,默认为MDY。field_separator不同下拉列表之间的分隔符,默认是\n。year_empty,month_empty,day_empty是在各下拉列表第一栏显示的内容。 html_select_time prefix定义各个下拉列表名字的前缀,默认为Time_。time决定使用的时间,默认是当前时间。display_hours决定是否显示小时。display_minutes决定是否显示分钟。display_seconds决定是否显示秒数。display_meridian 决定是否显示上午或下午,即显示am/pm。use_24_hours 决定是否24小时制。minute_interval 决定分钟之间的间隔。second_interval 决定秒数之间的间隔。field_array用来取得一组变量,可以用name[Hour],name[Minute],name[Second]的方式从form取得获得的值。all_extra,hour_extra,minute_extra,second_extra ,meridian_extra添加额外的属性到select或input标签。 html_table loop定义用于循环的一组数据。cols决定列的数目,rows决定行的数目,如果其中一个为空,另一个有值,则根据元素个数和有值的属性来计算另一个的值,两者的默认值为3。inner决定元素的列举方向cols则列跟着列排列,rows则行跟着行排列,默认为cols。table_attr,tr_attr,td_attr分别为table,tr,td增加标签,如果tr_attr,td_attr是数组,将会循环增加标签。trailpad用来填充最后一行没有值的单元格,默认是 。hdir决定每行元素的排列方向,从左到右right或从右到左left,默认为right。vdir决定每列的排列方向,从上到下down或从下到上up,默认为down。 math 进行数字运算操作。equation和var是必须的。equation定义运算式,可以使用的运算符有+, -, /, *, abs, ceil, cos, exp, floor, log, log10, max, min, pi, pow, rand, round, sin, sqrt, srans and tan。var给运算变量赋值。format确定结果的格式。assign将输出赋给一个参数。 mailto 使用mailto函数能使网络蜘蛛很难获取你的email地址,但是能在网页上正常显示,因为他把email地址进行了加密处理。address是必须的,定义email地址。text是显示在页面上的文本内容,默认是email地址。encode是加密email地址的方式,可以是none,hex或javascript,默认是none。如果要把邮件发给其他的邮箱,可以用cc抄送,email地址之间用,分割。bcc则为密件抄送。subject是邮件主题。newsgroups是发表内容的新闻组,新闻组之间用,隔开。extra添加附加标签。followupto意思不知。 textformat textformat用来格式化文本,他会去掉空格和特殊字符,和规定行宽和缩进。style规定当前的格式,indent规定缩进的位数。indent_first规定第一行的缩进。indent_char用来缩进的字符,默认是一个空格。wrap规定行宽,即一行的字符数,默认是80。wrap_char规定每行的分隔符,默认是\n。wrap_cut决定是否分割单词。assign将输出分配给变量。
内建函数不能擅自修改。 capture capture函数的作用是收集模板输出的数据到一个变量里,而不是把它们输出到页面.例如任何在 {capture name="foo"}和{/capture}之间的数据都被收到了由函数的名称属性指定的变量{$foo}里,或者{$smarty.capture.foo}里。如果函数没有名字属性,将使用"default".每个{capture}都必须对应{/capture},也不能嵌套使用capture函数。 config_load 引用配置文件 file是必须的,说明要包含进来的配置文件名称,section说明要加载的部分的名称,scope被处理的变量的作用域.必须是local,parent或者global. local的意思是变量将在本模板里被加载. parent的意思是变量将在本模板和上级模板被加载. global的意思是变量将应用到所有的模板.默认为local。变量是否在上级模板可视,默认为no。如果scope属性已经有了,这个值将被忽略. foreach,foreachelse foreach循环是选择性的section循环.用于遍历关联数组.foreach的语法比section简单的多,但是作为一个折中它只能用于简单数组. foreach必须的参数是from和item. from变量表示需要循环的数组的名称,item表示当前元素的变量名,key表示当前关键字的变量名,name表示访问foreach属性的foreach循环名。循环可以互相嵌套,被嵌套的循环之间的名字必须是独立的.foreachelse 在from变量没有值的时候被执行 include 用来引用其他的模板。 file属性是必须的用来表示所引用模板的名字,assign表示include文件将要分配的输出的变量。你可以自行用属性名="属性值"的方式定义任意个局部变量。 include_php 用来在模板中引入php脚本。file是必须的用来表示php脚本的路径,once确定如果在模板中引用了php脚本多次,是否只装载一次。默认为true。 insert 用来包含php脚本中的函数,name是必须的,表示所插入的脚本的名称,注意如果名称是name,则包含的函数则是insert_name(),所以所有要插入的函数要有前缀insert_ 。如果用了assign属性,则insert的输出将会分配给模板变量而不会显示。script表示要引用的脚本路径。这个程序产生的内容将不会被缓存,在每次调用该页时重新执行,适用于广告,投票,查询结果等互动的地方。 if,elseif,else if语句和和条件同php差不多,但每个词之间必须用空格分割开。也有一些新的条件语句,列举如下:eq相等,ne、neq不相等,gt大于,lt小于,gte、ge大于等于,lte、le 小于等于,not非,mod求模。is [not] div by是否能被某数整除,is [not]even是否为偶数,$a is [not] even by $b即($a / $b) % 2 == 0,is [not] odd是否为奇,$a is not odd by $b即($a / $b) % 2 != 0 php php标记可以让模板中能直接使用php语言。 section,sectionelse section用来循环显示数组的数据,name和loop是必须的参数。name表示嵌套名. section 可以嵌套使用,但是名字必须各不相同。loop表示循环的次数. sectionelse在loop参数为空的输出。start用来规定循环开始的指针,如果值为负则从数组尾部计算开始的指针,默认为0.step表示循环的步数,为负则反向循环,默认为1.max设定循环的最大步数.show决定是否显示section. section也有自己的变量处理section属性,用{$smarty.section.sectionname.varname} 来显示. index index用来显示当前循环的指针,从0开始. index_prev 用来显示前一次循环的指针,从-1开始 index_next 用来显示后一次循环的指针. iteration 显示当前循环的次数,从1开始. first 如果当前循环为第一个循环,则值为true. last 如果当前循环为最后一个循环,则值为true. rownum 同iteration. loop 显示最后一次循环的指针,可以用在section中间的任何地方,也可以用在section之后. show show决定是否显示section. total 显示总共循环的次数,可以用在section中间的任何地方,也可以用在section之后. strip 去掉多余的空格
插件文件必须命名如下: type . name .php Where type is one of these plugin types: 其中type是如下插件中的一种: function modifier block compiler prefilter postfilter outputfilter resource insert name为仅包含字母、数字和下划线的合法标志符。 插件内的函数应遵循如下命名约定: smarty_ type _ name () type和name的意义如前。
如果某个插件依赖其它插件内的某些功能(例如某些插件功能捆绑于Smarty内),那么可以通过如下方法装载必须的插件:
require_once $smarty->_get_plugin_filepath('function', 'html_options');
1、使用insert函数使模板的一部分不被缓存 index.tpl: <div>{insert name="get_current_time"}</div> index.php function insert_get_current_time(){ return date("Y-m-d H:m:s"); } $smarty=new smarty(); $smarty->caching = true; if(!$smarty->is_cached()){ ....... } $smarty->display('index.tpl'); 注解: 定义一个函数,函数名格式为:inser_name(array $params, object &$smarty), 函数参数可选的,如果在模板的insert方法中需要加入其他属性,就会作为数组传递给用户定义的函数。 如:{insert name='get_current_time' local='zh'} 在get_current_time函数中我们就可以通过$params['local']来获得属性值。 如果在get_current_time函数中需要用到当前smarty对象的方法或属性,就可以通过第二个参数获得。 这时你会发现index.tpl已被缓存,但当前时间却随每次刷新在不断变化。 2、使用register_function阻止插件从缓存中输出 index.tpl: <div>{current_time}{/div} index.php: function smarty_function_current_time($params, &$smarty){ return date("Y-m-d H:m:s"); } $smarty=new smarty(); $smarty->caching = true; $smarty->register_function('current_time','smarty_function_current_time',false); if(!$smarty->is_cached()){ ....... } $smarty->display('index.tpl'); 注解: 定义一个函数,函数名格式为:smarty_type_name($params, &$smarty) type为function name为用户自定义标签名称,在这里是{current_time} 两个参数是必须的,即使在函数中没有使用也要写上。两个参数的功能同上。 3、使用register_block使整篇页面中的某一块不被缓存 index.tpl: <div align='center'> Page created: {"0"|date_format:"%D %H:%M:%S"} {dynamic} Now is: {"0"|date_format:"%D %H:%M:%S"} ... do other stuff ... {/dynamic} </div> index.php: function smarty_block_dynamic($param, $content, &$smarty) { return $content; } $smarty = new Smarty; $smarty->caching = true; $smarty->register_block('dynamic', 'smarty_block_dynamic', false); if(!$smarty->is_cached()){ ....... } $smarty->display('index.tpl'); 注解: 定义一个函数,函数名格式为:smarty_type_name($params, &$smarty) type为block name为用户自定义标签名称,在这里是{dynamic} 两个参数是必须的,即使在函数中没有使用也要写上。两个参数的功能同上。
Modifiers修正器 ————————mixed smarty_modifier_ name (mixed $value, mixed):修正器插件的第一个参数是不可缺少的,修正器必须有返回值。
Block Functions块函数——————————void smarty_block_ name (array $params, mixed $content, object &$smarty)
Functions(函数):每一个smarty标签输出一个变量或者调用某种函数.在定界符内 函数(用'{'包住)和其属性(用界符包住)将被处理和输出.例如: {funcname attr1="val" attr2="val"}.
函数语法 {config_load file="colors.conf"} {include file="header.tpl"} {if $highlight_name} Welcome, <font color="{#fontColor#}">{$name}!</font> {else} Welcome, {$name}! {/if} {include file="footer.tpl"}