SPL(PHP標準庫)-----------------------個人筆記

來源:互聯網
上載者:User

標籤:php   spl

<?php     ****************************************PHP進階程式員必修課*******************************************************

//SPL:PHP標準庫,Standand  PHP  Library   解決常見問題的一組介面與類的集合



/*

問題:數學建模/資料結構,解決資料如何儲存的問題

      元素便利,資料如何查看的問題

      常用方法的統一調用(通用方法,自訂遍曆)

      類定義的自動裝載

*/


/*

SPL的基本架構

資料結構     基礎介面    基礎函數

迭代器       異常        其它

*/



/*SPL的常用資料結構

雙向鏈表    堆棧    隊列     堆     降序堆   升序堆    優先順序隊列    定長數組    對象容器

*/






//雙向鏈表

微博使用者A    <--關注-->    微博使用者B    <--關注-->     微博使用者C       //如果是單向的,則為單向鏈表

註:最先添加到列表當中的節點:Bottom/head

    最後添加到列表當中的節點:Top,也稱為尾部

    鏈表指標:是當前關注的節點的標識,可以指向任意節點

    當前節點:鏈表指標指向的節點

節點的組成:節點名稱key/offset        節點資料value


SqlDoublyLinkedList類

操作:

當前節點操作:rewind(第一個節點),current(當前節點),next(下一個節點),prev(前一個節點)

增加節點操作:push,array_unshift

刪除節點操作:pop,shift 

定位操作:     bottom,top 

特定節點操作:offsetExists,offsetGet,offsetSet,offsetUnset


雙向鏈表在SPL中的實現:PHP -f   SqlDoublyLinkedList.php可以在cmd中測試


$obj=new  SqlDoublyLinkedList();

$obj->push(1);         //將1推入鏈表,也就是添加到頂部top

$obj->push(2);

$obj->push(3);

$obj->unshift(10);     //反向將10推入鏈表,也就是10將索引值0佔據,也就是添加到底部botton

$obj->rewind();        //調用rewind後,才會有指標,也就是才有current(當前指標的節點值),將指標指向bottom

$obj->next();          //指標向後移動一次

$obj->prev();          //指標向前移動一次

echo "current:".$obj->current();    //擷取當前節點的值

if($obj->current){                  //判斷是否移動完畢

    echo "current node valid\n";

}else{

echo "current  node  invalid\n";

}

if($obj->valid()){               //可以直接用內建函數判斷是不是指標移動完畢(判斷節點是否有效)

echo "valid  list \n";

}

$obj->pop();                     //刪除離top最近的節點

$obj->shift();                   //刪除bottom所在位置的節點


雙向鏈表總結:兩頭皆可操作








//堆棧               算是雙向鏈表的衍生

         3號圓盤         |

         5號圓盤         |

         7號圓盤         |


SqlStack類繼承自SqlDoublyLinkedList類

操作:

     push:壓入堆棧(存入)

     pop: 退出堆棧(取出)

代碼實現:

$Stack = new SqlStack();

$stack->push(‘a‘);      //加入a,b,c

$stack->push(‘b‘);

$stack->push(‘c‘);


print_r($stack);

echo $stack->bottom;   

echo $stack->top;

echo $stack->offsetSet(0,‘C‘);       //堆棧的offset=0是top所在的位置,offset=1是靠近top所在的節點,而在雙向鏈表中相反!!!

                                     //將offset=0的索引值對應的value設為C

$stack->rewind();

$stack->current();                   //rewind()之後,堆棧指向top位置,雙向鏈表指向底部bottom

$stack->next();                      //會指向靠近bottom的方向

//遍曆堆棧

$stck->rewind();

while($stck->valid()){

echo $stack->key()."=>".$stack->current()."\n";

$stack->next();

}

//刪除堆棧資料

$popobj = $stack->pop();     

echo "被刪除的元素".$popobj;


堆棧總結:只能從top操作,很多函數如next,prev指向的方向與雙向鏈表相反











//隊列:排隊打飯一樣,先到先打,與堆棧恰恰相反

SqlQueue類也繼承自SqlDoublyLinkedList類

enqueue:進入隊列

dequeue:退出隊列


代碼實現:

$obj = new  SqlQueue();

$obj->enqueue(‘a‘);      //將abc加入到隊列

$obj->enqueue(‘b‘);

$obj->enqueue(‘c‘);

echo "bottom: ".$obj->bottom."\n";   

echo "top: ".$obj->top."\n";   

$obj->offsetSet(0,‘A‘);         //隊列裡面0為bottom

$obj->rewind();                 //隊列裡面指向bottom

遍曆隊列

while($obj->valid()){

    echo %$obj->key()."=>".$obj->current()."\n";

    $obj->next();

}

//刪除

$delobj=>$obj->dequeue();   


隊列小結:一切以先來先出為原則。






/***************************************************************************************************************************

資料結構大總結:

雙向鏈表,堆棧,隊列的關係:

堆棧:先進後出

隊列:先進先出

雙向鏈表:兩頭都可以進出

****************************************************************************************************************************/









//******************************************SPL的常用迭代器************************************************************

迭代器概念:通過某種統一的方式遍曆鏈表或者數組的元素的過程叫做迭代遍曆,而這種統一的便利工具我們叫做迭代器。

PHP中的迭代器是通過Iterator介面定義的


常用的迭代器一:ArrayIterator-------------------------------------------------------------------------(用於遍曆數組)

    1: freach與while語句通過ArrayIterator遍曆數組

    2:seek跳過某些元素

    3:ArrayIterator()進行排序

代碼實現:

$fruits = array(

     "apple"=>‘apple  value‘,

     "orange"=>‘orange  value‘,

     "grape"=>‘grape  value‘,

     "plum"=>‘plum  value‘,

);

//一般遍曆

foreach($fruits  as  $key=>$value){

echo $key.":".$value."\n";

}

//使用ArrayIterator迭代器遍曆數組(相當於普通迴圈的詳細化)

$obj = new  ArrayObject($fruits);

$it = $obj->getIterator();

foreach($it  as  $key=>$value){

echo echo $key.":".$value."\n";

}

//使用while之前需要調用rewind()

$it->rewind();

while($it->valid()){

echo $it->key().":".$it->value()."\n";

$it->next();

}



//跳過某些元素進行列印

$it->rewind();

if($it->valid()){

$it->seek(1);              //跳過position=1的元素

while($it->valid()){

echo $it->key().":".$it->current()."\n";

$it->next;

}

}


//排序列印

$it->ksort();     //按照key字母排序

foreach($it  as  $key=>$value){

echo $key.":".$value."\n";

}

//使用value排序

$it->asort();

foreach($it  as  $key=>$value){

echo $key.":".$value."\n";

}









常用的迭代器二:AppendIterator----------------------------------------------------------------------(按照順序迭代訪問幾個不同的迭代器)

代碼實現:

$array_a = new  ArrayIterator(array(‘a‘,‘b‘,‘c‘));

$array_b = new  ArrayIterator(array(‘d‘,‘e‘,‘f‘));

$it = new   AppendIterator();

$it->append($array_a);

$it->append($array_b);

foreach($it  as  $key=>$value){

     echo $value."\n";

}

/*a

  b

  c

  d

  e

  f*/











常用的迭代器三:MultipleIterator----------------------------------------------------------------------(將多個Iterator裡面的資料群組合成為一個整體來訪問)

代碼實現:

$idIter = new ArrayIterator(array(‘01‘,‘02‘,‘03‘));

$nameIter = new ArrayIterator(array(‘張三‘,‘李四‘,‘王五‘));

$ageIter = new ArrayIterator(array(‘21‘,‘23‘,‘25‘));

$mit = new  MultipleIterator(MultipleIterator::MIT_KEY_ASSOC);

$mit->attachIterator($idIter,"ID");

$mit->attachIterator($nameIter,"NAME");

$mit->attachIterator($ageIter,"AGE");

foreach($mit  as  $value){

print_r($value);

}


/*

array(

[ID]=>01,

[NAME]=>張三,

[AGE]=>22

)

array(

[ID]=>02,

[NAME]=>李四,

[AGE]=>23

)

array(

[ID]=>03,

[NAME]=>王五,

[AGE]=>25

)

*/








常用的迭代器四:FilesystemIterator----------------------------------------------------------------------(遍曆檔案系統)

代碼實現:

date_default_timezone_get(‘PRC‘);

$it = new  FilesystemIterator(‘.‘);    //.表示目前的目錄

foreach ($it  as  $finfo){

printf("%s\t%s%8s\t%s\n",

  date("Y-m-d  H:i:s",$finfo->getMTime())."\n",     //列印出當前檔案夾下的所有檔案的格式化時間

  $finfo->isDir()?<DIR>":"",                         //判斷是否是目錄

  number_format($finfo->getSize()),                   //將檔案大小格式化,每3位加逗號

  $finfo->getFileName()

  );

}



















//******************************************SPL的基礎介面************************************************************

      1:理解Countable/OuterIterator/RecursiveIterator/SeekableIterator等4個介面的概念

      2:熟練掌握Countable介面的使用

Countable:繼承該介面的類可以直接調用count得到元素的個數

OuterIterator:如果想對迭代器進行一定的處理之後再返回,可以使用這個介面

RecursiveIterator:可以對多層結構的迭代器進行迭代,比如遍曆一棵樹

SeekableIterator:通過seek方法定位到集合裡面的某一個特定元素


******************************************Countable介面*****************************************************

count(array(‘name‘=>‘Peter‘,‘id‘=>‘2‘))

date_default_timezone_get(‘PRC‘)

$array=array (

     array(‘name‘=>‘Jonathon‘,‘id‘=>‘2‘),

     array(‘name‘=>‘SEM‘,‘id‘=>‘2‘),

     array(‘name‘=>‘Tom‘,‘id‘=>‘2‘)

  )

echo count($array);        //3  自數組個數

echo count($array[1]);     //2   第二個子數位元素個數



class  CountMe   implements Countable {

    protected   $_myCount=3;

    public function  count(){

        return   $this->_myCount;

    }

}

$obj = new  CountMe();

echo count($obj);        //不加implements  Countable時顯示1,加後顯示為3!!!!!!!!!!


******************************************OuterIterator介面*****************************************************

如果想對迭代器進行一定的處理之後再返回,可以用這個介面

IteratorIterator類時OuterIterator類的實現,擴充的時候可以直接繼承IteratorIterator

代碼實現:

date_default_timezone_get(‘PRC‘);

$array=[‘Value1‘,‘Vlaue2‘,‘Vlaue3‘,‘Vlaue4‘];

$outerObj = new OuterImpl(new Arrayi($array);

forach($outerObj  as  $key=>$value){

  echo "++".$key."-".$vale."\n";            //$key會顯示成Pre_0,$value會顯示成Value1_tail

}


class  OuterImpl  extends   IteratorIterator{

  public  function current(){                               //value

    return  parent::current().‘_tail‘;

  }

  public  function  key(){                             //key

    return  "Pre_".parent::key(); 

  }

}





******************************************RecursiveIterator介面*****************************************************

見doc的一張圖,粗講。


******************************************SeekableIterator介面*****************************************************

見doc的一張圖,粗講。















//******************************************SPL函數的使用************************************************************

1:

Autoload:為了初始化PHP中的類對象,需要通過一定的方法尋找類的定義。通常情況下,類會定義在一個單獨的檔案中。

         Aotuload就是PHP找到這些類檔案的方法。

class   Test{

     public  function __construct(){

        echo  "Loading   Class  libs/Test.php\n";

     }

}

<?php

spl_autoload_extensions(‘.class.php,.php‘);                      //會自動載入Test.class.php,也可以設定為.php,兩者也可俱在

set_include_path(get_include_path().PATH_SEPARATOR."libs/");     //將類的位置這隻在libs/下   

                                                                 //設定autoload尋找定義的類檔案的目錄,多個目錄用_PATH_SEPARATOR進行分割。

spl_autoload_register();                                         //PHP使用Autoload機制尋找類定義

new   Test();  

?>




2:

__autoload裝載類

function  __autoload($class_name){

     echo "__autoload  class :".$class_name."\n";

     require_once("libs/".$class_name.‘.php‘);

}

//也可以自訂一個類似__autoload方法

function  classLoader($class_name){

     echo "classLoader  class :".$class_name."\n";

     require_once("libs/".$class_name.‘.php‘);

}

spl_autoload_register(‘classLoader‘);          //這樣也就將__autoload方法重新命名了,將__autoload方法頂替了

new  Test();


註:還可以將require_once替換成set_include_path頂替,代碼實現如下:

function  classLoader($class_name){

     echo "classLoader  class :".$class_name."\n";

     set_include_path("libs/");

     spl_autoload($class_name);         //當我們不用require或者require_once載入類檔案的時候,而是想通過系統尋找include_path來裝載類時,必須顯式調用spl_autoload函數,參數是類的名稱來重啟類檔案的自動尋找

}

spl_autoload_register(‘classLoader‘);          

new  Test();


*************************************

總結:類載入的基本流程,參見doc文檔一圖。

*************************************














//******************************************SPL的檔案處理類庫************************************************************

兩個類庫

實現代碼:

date_default_timezone_get("PRC");

$file = new  SqlFileInfo("tmp.txt");

echo "File  is  created   at".date("Y-m-d  H:i:s",$file->getCTime())."\n";     //查看檔案的資訊

echo "File  is  modified   at".date("Y-m-d  H:i:s",$file->getMTime())."\n";

//讀取裡面的內容

$fileObj = $file->openFile("r");             //以讀的方式開啟一個檔案

while($fileObj->valid()){

  echo $fileObj->fgets();          //fget擷取檔案裡面的一行資料

}

$openObj = null;                   //用於關閉開啟的檔案

$file  null;                       


這裡檔案的讀入方式是物件導向的,比fopen之類的函數要簡潔,提倡使用!








****************************************************************************************************************

課程總結:略

****************************************************************************************************************





?>



本文出自 “枷羅部落格” 部落格,請務必保留此出處http://sun231013.blog.51cto.com/8558055/1576803

SPL(PHP標準庫)-----------------------個人筆記

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.