begin61

finder

创建时间 2011年6月1日 上午

什么是finder,作用是什么?

就我理解,finder是后台desktop定义好的在页面显示表格数据的方法(函数)

  • 起初在app中调用finder方法,并传两个参数,接下来就去后台执行。现在从 desktop_controller 类中的finder方法起,去一步步执行。

    一、在finder方法里,调用了3个类,分别是:

    • base/kernel.php:kernel.php类中的single方法主要是实例化一个类(在这里实例化的是 view 这个类)
    • base/lib/static/app.php:app.php类中get方法 返回 app的名称
    • desktop/lib/finder/builder/view.php:view.php类父类中 work方法,里面会设一些公用的对象属性如下-》 ☉ $this->url; ☉ $this->object_name; ☉ $this->service_object[]
      1. $this->url:当前app的finder调用路径
      2. $this->object_name:当前app传给finder方法的model类
      3. $this->service_object[]:存储的是app/lib/finder/对finder列表的扩展项

  • 从这个方法 我们进入到 view.php 自身的 main 方法,这个方法里调用的类有:
    1. 父类prototype.php的get_views()方法 获取筛选器
    2. 父类prototype.php的getColumns()方法 获取列信息
    3. 父类prototype.php的getOrderBy()方法 获取数据的排序方式
    4. 父类prototype.php的getPageLimit()方法 获取分页信息
    5. base/lib/render类 的$this->pagedata 属性和fetch()的方法
    6. 自身的createView()方法
    7. 自身的_pager() 方法
    8. 调用到的app的控制器里的sidePanel()方法,这里调用的是desktop/lib/controller.php 里的方法

      view.php这个类,是finder列表显示在页面的必须类,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){}。

    1. 我们首先看到了在处理一个url,他根据$_GET获取的参数(ctl,act)在拼接了一个$_GET['_finder']['finder_id'],最后把这个数组转化成一个url地址

      $this->url = 'index.php?';$query = http_build_query($_GET);$this->url = $this->url.$query

      1. 把获取到的参数赋值给$this->object_name,作为一个变量
      2. 对参数进行截取,得到app名 和 model的类名;
      3. 查找service注册的“desktop_finder_变量($this->object_name)”,即根据表名注册的finder 列表的增加项。
           $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这个类中的所有对象属性。根据属性获取方法判断方法的前缀看他属于那种列显示。
        1. “column_”:增加的操作列,如编辑,删除 ...等等;
        2. “detail_”:增加的详情查看列,有新弹出finder页面查看 和 本页面查看所以在自定义finder/xxx.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方法。

今天主要是研究 对象$finder中的main方法,具体如下

    • view 类中首先设定了一些公用的变量,他们代表着finder()方法的第二个参数的那些内定操作,其实就是定义在这里,他们初始值都设好了,根据finder()方法的参数来改变了它的值。
          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 = '';
      
    • main 方法中首先设定了一些对象属性,初始值为空;
    • $this->short_object_name:获取到的类名,这里也可以说是表名
    • 接下来有一个判断,判段里调用了一个方法get_view():
      1. 判断$this->use_view_tab 他是否被设为 true;
      2. 通过截取获取到了app_id(app名mynotebook)和 model(表名notebook);
      3. 判断截取到的app是否与被调用的app一致;不一致返回空数组;
      4. 判断此控制器中是否有_veiws()这个方法(这个方法是,一个标签的定义方法,此方法定义的标签显示在表格的顶部),如图

        如果方法存在,获取定义好的标签,主要是筛选器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数组。
      5. 自定义筛选器
        	$_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
      6. 调用_get_args()方法
      7. 调用了desktop/lib/router.php这个类
      8. 统计定义的标签的个数
      9. 循环筛选器
        	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条件


PHP&MySql Web 数据库应用指南

创建时间 2011年6月1日 下午

  • 检查变量的类型的函数:is_int();is_float;is_bool();is_string();is_array();is_object();他们的返回值是bool类型的。
  • 恒等运算符”===“和费恒等运算符”!==“:他们会检查两个变量的值和类型是否相等。
  • 变量的测试,设定与解除:isset()会测试变量是否被设定为non-null;empty()是测试时变量值是否等于false;unset()用于解除变量;
  • 传送变量给函数:默认是以值的形式被传给函数。

    1、通过引用传递参数例子:重视 & 符号 ,它表明了这个是引用传参(意思是,参数不是指向变量值,而是指向变量存储在内存里的位置)

    	function doublevalue(&$var){
    		$var=$var*2;
    	}
    	$variable=5;
    	doublevalue($variable);
    	print "\$variable is : $variable";
    	输出的结果是:$variable is :10
    
    2、通过引用赋值:使用&的引用也能给变量赋值,使内存持有的变量值可被多个变量访问。例子:$y现在直接引用$x,所以对$y的改变也会影响$x.(事实上,他们等于是同一个变量),$y也可以被移除(unset($y)),但不影响$x.
    	$x=10;$y=&$x;$y++;print $x;print $y;
    	输出结果:11    11
    
    3、结合引用与赋值的运算符(=&)也能完成引用其他变量。例子:$x=10;$y =& $x; $z = &$x;$x=100; 输出结果“x = 100,y = 100,z = 100”;
  • include 和 require
    1. include和require都能读取外部的include文件,不同之处在于它们读不到指定文件时的反应。
    2. include会提出警告;require却会因为重大错误终止程序的运行。
    3. include_once 和 require_once 确保文件内容只被引入一次。

PHP的高级数据控制功能

  • 数组与数组函数库
    • 创建数组 $array=array(); 数组输出 print_r();
    • 关联数组 $array=array('first'=>1,'sencond'=>2,'third'=>3);
    • 移除数组元素 或整个数组 用函数unset();
    • 数组用foreach循环读取每个值
    • 基本数组的函数
      1. 计算数组元素的数量:

        : 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 中同一个值的第一个出现的键名会被保留。
        
  1. array_map() 将回调函数作用到给定数组的单元上 ;语法:array array_map ( callback callback, array arr1 , )返回一个数组,该数组包含了 arr1 中的所有单元经过 callback 作用过之后的单元。callback 接受的参数数目应该和传递给 array_map() 函数的数组数目一致。
    1. 创建数组的函数(array_file()用给定的值填充数组;range()建立一个包含指定范围单元的数组)
      1. array array_file(integer start,integer count,mixed value):返回的新数组元素的数量由count指定,索引键由start指定的数字开始,元素值都是value。
      2. array range(mixed low,mixed high ,inter):由低至高依次创建数组元素值,参数step可决定新数组中的元素如何递增。
  2. 字符串与数组的互换(explode() ; implode() ; join())
    1. array explode(string separator,string subject ,integer)
    2. string implode(string glue,array pieces)
    3. string join(string glue,array pieces)
  3. 数组中的最大最小值
    1. 查找数组中的值(in_array() 和 array_search())in_array():语法——boolean in_array(mixed needle,array haystack,boolean);

strict是可选参数,用于字符串与needle比较是强制检查类型。

array_search():语法——mixed array_seach(mixed needle,array haystack,boolean); 它与in_array()的运作方式相同,只是与needel相对应的键也会被返回。找到了返回的是键值(也有true);没有找到返回的是false

	    警告:此函数可能返回布尔值 FALSE,但也可能返回等同于 FALSE 的非布尔值,例如 0 或 ""(空串)。应使用 === 运算符 来测试此函数的返回值。
  1. 元素的键与值boolean array_key_exists(mixed key,array source);检查给定的键名或索引是否存在于数组中,在给定的 key 存在于数组中时返回 TRUE。key 可以是任何能作为数组索引的值。array_key_exists() 也可用于对象。

array array_keys(array $input [, mixed $search_value [, bool $strict ]]);返回数组中所有的键名。返回 input 数组中的数字或者字符串的键名。如果指定了可选参数 search_value,则只返回该值的键名。否则 input 数组中的所有键名都会被返回。自 PHP 5 起,可以用 strict 参数来进行全等比较(===)。

array array_values ( array $input ):返回数组中所有的值;返回 input 数组中所有的值并给其建立数字索引。

  1. 连接多个数组 array_merge()
  2. 重新排列数组 array_reverse()
  3. 数组排序

    ● 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
    • 字符串与字符串函数库
      1. 字符串的长度 strlen()
      2. 字符串格式化输出 sprintf() 和 printf();
      3. 字符串填充● str_pad()函数是增加空格的简单方法;string str_pad(string input,int length ,string]]),可选参数padding 可悲提供一代特空格字符
      4. 查找子字符串的位置● strpos():查找字符串首次出现的位置;语法:nt strpos ( string $haystack , mixed $needle [, int $offset = 0 ] );
        	     警告:此函数可能返回布尔值 FALSE,但也可能返回等同于 FALSE 的非布尔值,例如 0 或 ""(空串)。应使用 === 运算符 来测试此函数的返回值。
        
        
        ● strrpos():计算指定字符串在目标字符串中最后一次出现的位置;语法:int strrpos ( string $haystack , string $needle [, int $offset = 0 ] );
      5. 从字符串中抽取找到的部分● string strstr ( string $haystack , mixed $needle [, bool $before_needle = false ] ):返回 haystack 字符串从 needle 第一次出现的位置开始到 haystack 结尾的字符串。● string stristr ( string $haystack , mixed $needle [, bool $before_needle = false ] ):(strstr() 函数的忽略大小写版本)返回 haystack 字符串从 needle 第一次出现的位置开始到 haystack 结尾的字符串。
      6. 转换字符和子字符串 (strtr:该函数返回 str 的一个副本,并将在 from 中指定的字符转换为 to 中相应的字符。如果 from 与 to 长度不相等,那么多余的字符部分将被忽略。 )● strtr — 转换指定字符string strtr ( string $str , string $from , string $to )● strtr — 转换指定字符string strtr ( string $str , array $replace_pairs )● mixed str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] ):该函数返回一个字符串或者数组。该字符串或数组是将 subject 中全部的 search 都被 replace 替换之后的结果。
  • 正则表达式
    1. 语法

      ● 函数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。返回替换后的字符串。(如果没有可供替换的匹配项则会返回原字符串。)

  1. 将一个字符串拆分成数组● split — 用正则表达式将字符串分割到数组中,本函数返回一个字符串数组,每个单元为 string 经区分大小写的正则表达式 pattern 作为边界分割出的子串。如果设定了 limit,则返回的数组最多包含 limit 个单元,而其中最后一个单元包含了 string 中剩余的所有部分。如果出错,则 split() 返回 FALSE。
    	    <?php
    		list($user, $pass, $uid, $gid, $extra) =
    	  	 split (":", $passwd_line, 5);
    	    ?>
    
    • 日期与时间函数库
      1. 生成时间戳
  • 当前时间 integer time()
    • mktime() 和 gmmktime() 这两个函数均可按照提供的参数创建时间戳``int mktime(int hour,int minute,int second,int month,int day,int year,int);——————它的参数表示本地时间;

int gmmktime(int hour,int minute,int second,int month,int day,int year,int);—————它的参数标示GMT日期和时间计算;``以上的函数都能正确的处理超出范围的参数值。

    1. 字符串到时间按戳integer strtotime(string time); 例 相对时间的转换 strtotime("+1 day")————明天;strtotime("-2 weeks")————两周前;strtotime("-2 hours 2 seconds")————两个小时又两分钟后;
      1. 亚秒级的时间——————string microtime();它的常见用法是为随机数生成器生成种子;返回以微妙计和以妙计的时间戳,微妙在前,以秒计的整数在后
    • 整数与浮点数的函数库

      绝对值函数 abs();向上取整函数 ceil();向下取整函数 floor();舍入函数 round();随机数函数 rand();

    • array_unshift()语法:int array_unshift ( array &$array , mixed $var [, mixed $... ] ) ——————在数组开头插入一个或多个单元
    • PHP5的面向对象编程
    1. 类和对象:面相对像的编程最基本的思想是将数据与函数组合之成为对象的便利容器;创建对象 就是new一个类,最后通过运算符"->"调用这个对象中的函数或属性(语法 $object(对象名)->属性或方法),调用自身的方法或属性通过$this来调用。

类定义了如何将数据与函数绑定在一起 ——————成员变量与函数均在类中取得自身的意义;

问题聚集

类中: 属性和方法又可以使用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.

    • 没有实例化的时候,public、static、private、protected这四个状态的类变量那个能被调用?

      没有被实例化的时候,静态(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
	?>
  • this 和 self parent 他们的区别是什么?this是指向当前对象的指针(姑且用C里面的指针来看吧),self是指向当前类的指针,parent是指向父类的指针。
        <?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时,就会报错
    
  • 构造函数和析构函数在什么时候调用?构造函数在建立一个对象实例时被执行,他有参数和默认值;析构函数在对象被销毁的时候调用。
  • extends interface
    	<?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加密,就会产生不同的字符串。

smarty 手册

变量调节器

变量调节器用于变量,自定义函数和字符串.可以使用&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).
第三个参数决定是否精确截取字符,默认情况下是不精确截取,就是截取时不能分开单词。

smarty常规函数

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将输出分配给变量。

smarty内建函数

内建函数不能擅自修改。
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
去掉多余的空格

以插件扩展Smarty

  • 插件的命名
    插件文件必须命名如下:
    
        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"}