CSDN博客

img maojunhua

个人摸索的一些技巧,大家一起来写自己的心得啊

发表于2004/6/25 22:08:00  609人阅读

这里总结了一些个人心得,可能大家平时早就在用了。写出来,目的是抛砖引玉,互相学习,希望大家将自己的心得能够总结成文,集合成一大贴。文中提到的说法皆为自称,如有不当,欢迎批评指正。


1。模拟动态创建和继承,多态,可以用来实现接口统一,而提供不同的底层实现,如提供一个文档类给上层,此文档可以具体实现到数据库或者具体实现到文本I/O。也可以下面讲到的2结合,由对象隐藏的信息进行创建。
   php的继承大家都很熟悉了,派生类继承基类的函数,当调用的函数派生类里不存在时,将转而调用基类的函数,也可以使用basename::func()跳过派生类函数而直接调用基类函数。

 对于多态(与真正的多态是有差距的,这里其实是类似多态的一种特性)的模拟要麻烦一些,因为不像C++,php是弱类型,不能通过强制将基类指针指向派生来实现,当是可以简介模拟,先在基类定义一函数x(),派生类中不再重新定义这个函数,在这个函数中调用另外一个需要实现多态的函数y(),于是形成了以下特点。

 如果基类中有定义y(),派生类中也有y(),将优先调用基类中的y();
 如果基类中不定义y(),而是将基类作为抽象类,不同的派生类定义不同的y(),于是在不同的派生类实例中调用x(),会实现类似多态的效果。
 
 多态特性一个用处就是:所有派生类都需要一系列的通用的操作(函数间的互相调用),于是我们自然将这写操作定义到基类实现,但是其中一个环节z()却需要到各个派生类才能具体实现,于是我们在基类不定义z(),而改在派生类中定义。

   值得一提的还有动态创建特性,在new对象或者调用函数的时候,除了可以直接在源代码中写出类名和函数名外,可以采用变量替代类名和函数名的方法。
 如:
 $class_name="Class1";
 new $class_name;//等于new Class1;
 对于函数调用我们在3中会提到。
<?
/////////////////////////////////////////////////////////////
//////////模拟动态创建和继承,多态,作者:mao_junhua//////////////
/////////////////////////////////////////////////////////////
//以下为定义部分
class base
{
     function Show()
    {
     $this->ShowSelf();
    }
    function ShowSelf()
    {
     echo "I'm Base"."<br>";
    }
}
class type1 extends base
{

    function ShowSelf()
    {
        echo "I'm Type 1<br>";
    }
}
class type2 extends base
{
    function ShowSelf()
    {
     echo "I'm Type 2<br>";
    }
}
class type3 extends base
{

}
class type4 extends base
{
    function ShowSelf()
    {
     echo "I'm Type 4, But I'll call base: ";
        base::ShowSelf();
    }
}
$param_arr="1234332131413412344132412";

////////////////////////////
//动态创建模拟示例
for($i=0;$param_arr[$i];$i++)
{
 $tmp="type".$param_arr[$i];
 $instance[]=new $tmp;
}

//////////////////////////
//继承,多态模拟示例
for($i=0;$param_arr[$i];$i++)
{
 $instance[$i]->Show();
}
?>


2。方便快捷的对对象加入自定义隐藏信息
   php加入数据成员不需要声明,使用就是定义,此特性有好有坏,且不讨论,在此我们可以灵活利用它,实现方便快捷地实现隐藏地加入自定义信息进创建的实例中或者隐藏地做一些自定义操作。


<?php
//////////////////////////////////////////////////////////
////////////简便加入隐藏信息作者:mao_junhua//////////////////
//////////////////////////////////////////////////////////

class Info
{
    var $type;
    var $name;
    function ShowInfo()
    {
        echo 'My type is: '.$this->type.', My name is: '.$this->name.'<br>';
    }
}
class Obj
{
    var $objs;
 function ShowAllObjInfo()
 {
     for($i=0;$this->objs[$i];$i++)
     {
           $tmp=$this->objs[$i];
           global $$tmp;
        echo  $$tmp->info->ShowInfo();
     }
 }
}
$OBJ=new Obj;
function NewObj($type)
{
    $out=new $type;
    $info=new Info;
    $info->type=$type;
    $out->info=$info;
    return $out;
}
function MyNew($type,$name)
{
    global $$name,$OBJ;
    $$name=NewObj($type);
    $$name->info->name=$name;
    $OBJ->objs[]=$name;
}

/////////////////////////////////////////////////////////////

class derive1
{

}

class derive2
{
}
///////////////////////////////
MyNew("Derive1","Inst1");
MyNew("Derive1","Inst2");
MyNew("Derive2","Inst3");
$Inst1->info->ShowInfo();
$OBJ->ShowAllObjInfo();
?>


3。php变量不分类型,且之间可以直接方便转换,php数组为变长的,这个特性类似于容器。
   不知道是否是设置问题,我的php5在参数传递的时候仍然是传值拷贝(按理说php5所有参数传递默认是传引用),需要加&说明是传引用。
 此例中用到的特性还有1中提到的采用变量表示函数名或者类名,实现了类似函数指针的特性,与容器特性结合可以用来实现回调函数和泛型算法。

<?php
////////////////////////////////////////////////////////////
////////////////引用,回调和泛型,作者:mao_junhua///////////////
////////////////////////////////////////////////////////////
//函数定义部分
function MySort(&$in,$SortProc="DefaultProc")
{
    for($i=0;$in[$i];$i++)
    {
        for($j=0;$in[$j];$j++)
        {
            if( $SortProc($in[$i],$in[$j]) )
            {
                $tmp=$in[$j];
                $in[$j]=$in[$i];
                $in[$i]=$tmp;
            }
        }
    }
}
function DefaultProc($param1,$param2)
{
    return false;
}

//////////////////////////////////////////////////////////
//测试部分1,对数字大小排序
$arr[0]=1;
$arr[1]=2;
$arr[2]=3;
$arr[3]=4;
$arr[4]=5;
MySort($arr,"SortProc");
function SortProc($param1,$param2)
{
    return ($param1>$param2);
}
for($i=0;$arr[$i];$i++)
{
    echo $arr[$i]."<br>";
}

//测试部分2,对数组长度排序
$arr[0]="a";
$arr[1]="ab";
$arr[2]="abc";
$arr[3]="abcd";
$arr[4]="abcde";
MySort($arr,"SortLength");
function SortLength($param1,$param2)
{
    return (strlen($param1)>strlen($param2));
}
for($i=0;$arr[$i];$i++)
{
    echo $arr[$i]."<br>";
}
?>
回调用在数据库查询模块上的例子:
<?
class HDatabase extends HObject
{
 var $dbh;
 var $table_name;
 var $db_name;
 function HDatabase()
 {
  $this->db_name=$GLOBALS['mysql_db_name'];
  $this->table_name=$GLOBALS['mysql_table_name'];
  $this->dbh = mysql_pconnect($GLOBALS['mysql_hostname'],$GLOBALS['mysql_username'],$GLOBALS['mysql_password']);
 }

 function Query($query,$call_back_function="DefProc",$param="")//采用回调函数,第三个参数定义回调函数名,为全局函数,原形见下面的example,第四个为传递的参数,也可以使用引用传入
 {
  $result = mysql_db_query($this->db_name,$query,$this->dbh);
  switch($result)
  {
   case false:
   {
    $call_back_function(false,$param);
    return false;
   }
   case 1:
   {
    $call_back_function($result,$param);
    return true;
   }
   default:
   {
    $flag=false;
    while($row = mysql_fetch_array($result))
    {
     $call_back_function($row,$param);
     $flag=true;
    }
    mysql_free_result($result);
    return $flag;
   }
  }
 }
}

function DefProc($row,$param) //默认处理函数
{

}
/////////////////////////////////
function DbProc($row,$param)
{
   echo "This is from database:".$row['field_name']."<br>";
 echo $param;
}
$connect=new HDatabase;
$connect->Query("Select * from table_name","DbProc","This is an appended parameter");
?>
无限级目录与目录之间的复制代码
windows:
exec("xcopy32/s src_dir di_dir",$str,$var);
linux:
exec("cp -r ........
如果需要复杂交互操作可以使用管道
popen();
或者更加强大的
proc_open();//php4.3.0
4.调试时对于逻辑错误,可以采用2中方法,将错误处理对象隐藏的加入调试对象内部,可以将错误信息分布到各个对象内部,这样可以明显表示错误的宿主。因为全局对象$OBJ记录了所以实例的名字,又可以全局访问各个对象的错误信息。
<?
//错误处理供调试,可以将错误分布到各个对象内部,但是又提供全局访问能力
$err_code[1]="error 1";
$err_code[2]="error 2";
$err_code[3]="error 3";
$err_code[4]="error 4";
$err_code[5]="error 5";

class Info
{
    var $type;
    var $name;
 var $error;

 function AddError($code)
 {
  $this->error[]=$code;
 }

 function ShowMyError()
 {  
  global $err_code;
  for($i=0;$this->error[$i];$i++)
   echo $err_code[$this->error[$i]]."<br>";
 }
}
class Obj
{
    var $objs;
 function ShowAllError()
 {
     for($i=0;$this->objs[$i];$i++)
     {
           $tmp=$this->objs[$i];
           global $$tmp;
        echo  $$tmp->info->ShowMyError();
     }
 }
}
$OBJ=new Obj;
function NewObj($type)
{
    $out=new $type;
    $info=new Info;
    $info->type=$type;
    $out->info=$info;
    return $out;
}
function MyNew($type,$name)
{
    global $$name,$OBJ;
    $$name=NewObj($type);
    $$name->info->name=$name;
    $OBJ->objs[]=$name;
}

class derive1
{
    function do1()
 {
  $i=1;
  if($i==1)
   $this->info->AddError(1);
  else
   $this->info->AddError(2);
 }
}

class derive2
{
 function do2()
 {

  $i=2;
  if($i==1)
   $this->info->AddError(1);
  else
   $this->info->AddError(2);

 }
}
///////////////////////////////
MyNew("Derive1","Inst1");
MyNew("Derive1","Inst2");
MyNew("Derive2","Inst3");
$Inst1->do1();
$Inst3->do2();
echo "The following lines list error in Inst1:<br>";
$Inst1->info->ShowMyError();
echo "The following lists all error:<br>";
$OBJ->ShowAllError();
?>
5。MCV

0 0

相关博文

我的热门文章

img
取 消
img