【面試那些事兒一】 PHP基礎

/** 
 * 第6題:如何實現中文字符串截取無亂碼的方法(mb_*系列函數),首先:需要開啓 extension=php_mbstring.dll 擴展 ,結果:"你" 
 */  
  
echo mb_substr("你好",0,1,"gb2312")."<br/>"; 
/** 
 * 第7題:用PHP寫出顯示客戶端和服務器端IP的代碼 
 */  
  
echo $_SERVER['REMOTE_ADDR'];//客戶端IP  
echo $_SERVER['SERVER_ADDR'];//服務器端IP  
echo $_SERVER['PHP_SELF'];//結果:"/index.php"   當前腳本的名稱(不包括路徑和查詢字符串)  
echo $_SERVER["HTTP_REFERER"];//鏈接到當前頁面的來源url  
echo gethostbyname("www.v1pin.com");//獲取指定域名的IP地址  
echo getenv("REMOTE_ADDR");//獲取客戶端IP地址  
echo getenv("SERVER_ADDR");//獲取服務器端IP地址 
/** 
 * 第8題:mysql中 IFNULL 控制流函數;IFNULL() 
 * IFNULL(): 
 *      (1)它有兩個參數,並且對第一個參數進行判斷。 
 *      (2)如果第一個參數不是NULL,函數就會向調用者返回第一個參數;如果是NULL,將返回第二個參數; 
 * 例如: 
 *      SELECT IFNULL(1,2), IFNULL(NULL,10), IFNULL(4*NULL,'false');//結果:"1 10  false" 
 */ 
/** 
 * 第9題:簡述include與require的區別? 
 * 相同點: 
 *      (1)include與require都能把另外一個文件包含到當前文件中 
 * 異同點: 
 *      (1)使用include時,當包含的文件不存在時系統會報出警告級別的錯誤,但並不影響程序的後續執行. 
 *      (2)使用require時,當包含的文件不存在時系統會先報出警告級別的錯誤,接着又報出一個致命性的錯誤,將終止程序的後續執行. 
 *      (3)require只會解釋包含的文件一次,不會再解釋第二次,因而效率相對較高;而include則會重複的解釋包含的文件 
 *      (4)載入時機不同:require在運行前載入包含文件,include在運行時載入包含文件 
/** 
 * 第10題:如何獲取一個字符串中指定的字符? 
 */  
  
 $str="abcdefg";  
 echo $str{2}."<br/>";  
/** 
 * 第13題:addslashes()與 htmlspecialchars() 區別 
 * 
 * 區別: 
 
 *   (1)addslashes()函數主要在指定的預定義字符前添加反斜槓,這些預定義字符主要包括: 
 * 
 *      單引號 (') 
 *      雙引號 (") 
 *      反斜槓 (\) 
 *      NULL 
 * 
 *      addslashes()函數的主要作用是保證這些預定義字符能夠正確入庫,僅此而已 
 * 
 * 
 * (2)htmlspecialchars()函數把一些預定義的字符轉換爲HTML實體,這些預定義字符主要包括: 
 * 
 *       
 *      & (和號)      成爲 & 
 *      " (雙引號)     成爲 " 
 *      ' (單引號)     成爲 ' 
 *      < (小於)       成爲 < 
 *      > (大於)       成爲 > 
 * 
 *      echo htmlspecialchars($str, ENT_COMPAT);  //默認,僅編碼雙引號 
 *      echo htmlspecialchars($str, ENT_QUOTES);  //編碼雙引號和單引號 
 *      echo htmlspecialchars($str, ENT_NOQUOTES);//不編碼任何引號 
 * 
 */  
//第17題:如何使用 array_multisort() 函數實現對多維數組進行排序?  
//模擬從數據庫中查詢出來的記錄(提示:二維數組)  
$arr[] = array("age"=>20,"name"=>"小強");  
$arr[] = array("age"=>21,"name"=>"李偉");  
$arr[] = array("age"=>20,"name"=>"小亮");  
$arr[] = array("age"=>22,"name"=>"黎明");  
   
foreach ($arr as $key=>$value){  
    $age[$key]  = $value['age']; //排序字段 "age"  
    $name[$key] = $value['name'];//排序字段 "name"  
}  
  
/** 
 * 1、對 $arr 數組進行排序 
 *    首先按照年齡從大到小的順序排列,如果年齡相同再按照名字的順序排序,類似於sql中的order by 
 * 2、注意事項: 
 *    (1)$age和$name  等價於 數據表的"age"和"name"列字段,類似於 "order by age desc,name asc"  
 *    (2)排序順序標誌: 
 *          SORT_ASC - 按照上升順序排序 
 *          SORT_DESC - 按照下降順序排序 
 *    (3)排序類型標誌: 
 *          SORT_REGULAR - 將項目按照通常方法比較 
 *          SORT_NUMERIC - 將項目按照數值比較 
 *          SORT_STRING  - 將項目按照字符串比較 
 *    (4)排序標誌的默認值爲: SORT_ASC 和 SORT_REGULAR 
 *    (5)每個一維數組後指定的排序標誌僅僅對該一維數組有效,一個一維數組不能指定兩個同類的排序標誌 
 *    (6)該函數會改變數字索引,其它索引不改變 
 * 
 */  
array_multisort($age,SORT_NUMERIC,SORT_DESC,$name,SORT_STRING,SORT_ASC,$arr);  
echo "<pre>";print_r($arr);exit;  
/** 
 * 結果: 等價於 "select * from user order by age desc,name asc"; 
 * Array( 
 *   [0] => Array 
 *       ( 
 *           [age] => 22 
 *           [name] => 黎明 
 *       ) 
 *   [1] => Array 
 *       ( 
 *           [age] => 21 
 *           [name] => 李偉 
 *       ) 
 *   [2] => Array 
 *       ( 
 *           [age] => 20 
 *           [name] => 小亮 
 *       ) 
 *   [3] => Array 
 *       ( 
 *           [age] => 20 
 *           [name] => 小強 
 *       ) 
 * ) 
 */ 
/** 
 * 第27題:交換數組中的鍵和值 
 */  
$a=array(  
    0=>"Dog",  
    1=>"Cat",  
    2=>"Horse"  
);  
echo "<pre>";  
print_r(array_flip($a));  
  
/** 
 * 經array_flip()數組函數處理後的結果: 
 * Array( 
 *   [Dog] => 0 
 *   [Cat] => 1 
 *   [Horse] => 2 
 *  ) 
 */ 
/** 
 * 第39題:開啓php.ini文件中的safe_mode選項,會影響到哪些函數的應用?至少說出四個 
 * 
 *  答:主要影響文件操作類函數、程序執行類函數 等等 
 *      如:pathinfo()、basename()、fopen()、exec() 等等 
 */  
/** 
* 第41題:如何通過form表單控制上傳文件的大小? 
* 
*  (1)答:在form表單中,通過隱藏域MAX_FILE_SIZE控制上傳文件的大小,它必須放在文件域之前才能夠起作用。 
* 
*  (2)解析:在客戶端控制上傳文件,應用的form表單中的enctype和method屬性,以及隱藏域 MAX_FILE_SIZE 
*      enctype="multipart/form-data"    //指定表單編碼數據方式 
*      method="post"                    //指定數據的傳輸方式 
*      <input type="hidden" name="MAX_FILE_SIZE" value="10000" /> //通過隱藏域控制上傳文件的大小(單位爲字節),該值不能超過php.ini配置文件中 upload_max_filesize 選項設置的值 
*/ 
/** 
 * 第43題:如何將 1234567890 轉換成 1,234,567,890 每三位用逗號隔開的形式? 
 */  
echo number_format("1234567890")."<br/>";         //結果:1,234,567,890      默認以逗號作爲分隔符        
echo number_format("1234567890",2)."<br/>";           //結果:1,234,567,890.00       參數2-指定小數位數  
echo number_format("1234567890",2,",",".")."<br/>"; //結果:1.234.567.890,00     參數2-指定小數位數 參數3-規定替代小數點符號的字符串  參數4-規定用作千位分隔符的字符串  
/** 
 * 第45題:stripos()、strpos()、strripos()、strrpos() 字符串函數的區別? 
 * 
 *  (1)stripos():返回字符串在另一字符串中第一次出現的位置(大小寫不敏感) 
 *  (2)strpos() :返回字符串在另一字符串中首次出現的位置(對大小寫敏感) 
 *  (3)strripos():查找字符串在另一字符串中最後出現的位置(對大小寫不敏感) 
 *  (4)strrpos():查找字符串在另一字符串中最後出現的位置(對大小寫敏感) 
/** 
 * 第48題:如何用php的環境變量得到一個網頁地址的內容? 
 * 如:"http://www.baidu.com/index.php?id=10" 
 */  
  
echo $_SERVER['REQUEST_URI'];//結果:"/index.php?id=10"
/** 
 *第50題:如何使用php實現雙向隊列? 
 */  
class Deque{  
    public $queue;  
    public function __construct(){//構造函數,創建一個數組  
        $this->queue = array();  
    }  
  
    public function addFirst($item){//array_unshift() 函數在數組開頭插入一個或多個元素。  
        return array_unshift($this->queue , $item);  
    }  
  
    public function removeFirst(){  
        return array_shift($this->queue);//PHP array_shift() 函數刪除數組中的第一個元素  
    }  
  
    public function addLast($item){//給數組末尾追加元素,無指定下標,默認爲數字  
        return array_push($this->queue , $item);  
    }  
  
    public function removeLast(){  
        return array_pop($this->queue);//PHP array_pop() 函數刪除數組中的最後一個元素  
    }  
}  
//第51題:統計一維數組中所有值出現的次數?返回一個數組,其元素的鍵名是原數組的值;鍵值是該值在原數組中出現的次數  
$array=array(4,5,1,2,3,1,2,"a","a");  
  
$ac=array_count_values($array);  
  
/** 
 * 輸出結果: 
 * Array( 
 *   [4] => 1 
 *   [5] => 1 
 *   [1] => 2 
 *   [2] => 2 
 *   [3] => 1 
 *   [a] => 2 
 * ) 
 */  
echo "<pre>";print_r($ac);  
//第53題:str_word_count() 函數計算字符串中的單詞數?  
  
/** 
 * 輸出結果:2 
 */  
echo str_word_count("Hello world!");//參數二:默認0,返回單詞的數目  
  
/** 
 * 輸出結果: 
   Array( 
    [0] => Hello 
    [1] => world 
   ) 
 */  
echo "<pre>";print_r(str_word_count("Hello world!",1));//參數二:1-返回包含字符串中的單詞的數組  
  
/** 
 * 輸出結果: 
   Array( 
    [0] => Hello 
    [6] => world 
   ) 
 */  
echo "<pre>";print_r(str_word_count("Hello world!",2));//參數二:2-返回一個數組,其中的鍵是單詞在字符串中的位置,值是實際的單詞. 
/** 
 *  第56題:redis與memcached區別? 
 * 
 *  不同點: 
 * 
 *      (1)redis中並不是所有數據在有效期內只能常駐內存的(如果需要,可定期同步持久化到磁盤),這是和memcached相比一個最大的區別(memcached中的數據在有效期內是以鍵值對的形式常駐內存的) 
 *      (2)redis不僅僅支持簡單的鍵值對類型的數據,同時還提供list,set,hash等數據結構的存儲;memcached僅支持簡單的鍵值對類型的數據,但是memcached卻可以緩存圖片、視頻等等數據 
 *      (3)redis支持數據的備份,即master-slave模式的數據備份 
 *      (4)redis支持數據的持久化和數據同步,可以將內存中的數據保存在磁盤中,重啓系統後可以再次加載進行使用,緩存數據不會因此而丟失.memached緩存數據是常駐內存的,重啓系統後數據就沒了 
 *      (5)redis可以通過expire設定有效期,memcached在set數據的時候可以指定要緩存的數據永不過期 
 *      (6)redis可以做一主多從;memcached也可以做一主多從 
 *      (7)redis當物理內存用完時,可以將一些很久沒用到的value交換到磁盤;memcached當物理內存用完後就會自動清理一些早期的數據 
 * 
 *  相同點: 
 * 
 *      (1)redis和memcached都是將數據存放在內存中,都是內存數據庫 
 *      (2)redis和memcached都可以做一主多從 
 * 
 *  性能: 
 * 
 *      (1)redis根據其官方的測試結果:在50個併發的情況下請求10w次,寫的速度是110000次/s,讀的速度是81000次/s 
 *      (2)redis將鍵名與值的最大上限各自設定爲512MB;memcached則<span id="transmark"></span>將鍵名限制在250字節,值也被限制在不超過1MB,且只適用於普通字符串. 
 * 
 *      何時使用memcached: 
 * 
 *      (1)小型靜態數據:當我們需要緩存小型靜態數據的時候可以考慮memcached,最具代表性的例子就是HTML代碼片段;因爲memcached的內部內存管理機制雖然不像redis的那樣複雜,但卻更具實際效率,這是因爲memcached在處理元數據時所消耗的內存資源相對更少.作爲memcached所支持的惟一一種數據類型,字符串非常適合用於保存那些只需要進行讀取操作的數據,因爲字符串本身無需進行進一步處理<span id="transmark"></span>. 
 * 
 */

//第58題:文件緩存的使用案例  
public function &get($key, $cache_time = '') {  
        if(empty ($cache_time)) {  
            $cache_time = $this->cache_time;//緩存時間  
        } else {  
            $cache_time = intval($cache_time);//緩存時間  
        }  
        $cache_encode_key  = $this->get_key($key);//獲取一個唯一的長字符串  
                //緩存文件的命名和緩存文件的存放位置  
        $filename = $this->cache_dir.'/'.substr($cache_encode_key,0,2).'/'.substr($cache_encode_key,2,2).'/'.$cache_encode_key.".cache.php";  
        if(!is_file($filename) || time() - filemtime($filename) > $cache_time) {//如果緩存文件不存在或者緩存文件過期,則返回false  
            return false;  
        } else {  
            return unserialize(file_get_contents($filename));//如果緩存文件存在且未過期,那麼讀取緩存文件內容並返回  
        }  
    }  
    public function set($key,$data) {  
        $cache_encode_key  = $this->get_key($key);  
        $cache_dir  = $this->cache_dir.'/'.substr($cache_encode_key,0,2).'/'.substr($cache_encode_key,2,2).'/';//緩存文件的緩存目錄  
        $filename   = $cache_dir.$cache_encode_key.".cache.php";//緩存文件名  
        if( $this->mkpath($cache_dir) ) {//遞歸創建緩存目錄  
            $out    = serialize($data);//將要緩存的數據序列化  
            file_put_contents($filename, $out);//將序列化的數據寫入到緩存文件中  
        }  
    }  
    public function add($key, $data) {  
        $cache_encode_key   = $this->get_key($key);  
        $cache_dir  = $this->cache_dir.'/'.substr($cache_encode_key,0,2).'/'.substr($cache_encode_key,2,2).'/';//緩存目錄  
        $filename   = $cache_dir.$cache_encode_key.".cache.php";//緩存文件名  
        if(is_file($filename)) {//如果緩存文件存在,則返回false  
            return false;  
        } else {//如果緩存文件不存在,則生成一個新的緩存文件到緩存目錄  
            $this->set($key, $data);  
        }  
    }  
    public function del($key) {  
        $cache_encode_key   = $this->get_key($key);  
        $cache_dir  = $this->cache_dir.'/'.substr($cache_encode_key,0,2).'/'.substr($cache_encode_key,2,2).'/';//緩存目錄<span id="transmark"></span>  
        $filename   = $cache_dir.$cache_encode_key.".cache.php";//緩存文件名  
        if(is_file($filename)) {//如果緩存文件存在則返回false<span id="transmark"></span>  
            return false;  
        } else {//如果緩存文件不存在,則刪除緩存文件  
            @unlink($filename);  
        }  
    }  
  
        public function get_key($key){  
                return md5(CACHE_KEY.$key);//md5加密字符串  
        }  

//第60題:php如何讀取php.ini配置文件中的配置選項的值  
echo ini_get('post_max_size');//獲取上傳文件的最大尺寸  
echo get_cfg_var('post_max_size');//獲取上傳文件的最大尺寸  

/** 
 *第62題:__call是魔術方法 
 *      __call是魔術方法是指請求的方法不存在的時候採用的哪種處理方式;如果請求的方法名存在(跟參數列表無關),則不會調用此魔術方法 
 */  
class MethodTest {  
     /** 
      * 再如: 
      *       public function __call($funName, $args){//參數1-要調用的方法名   參數2-傳遞給要調用方法的參數列表 
      *             switch (count($args)) { 
      *                 case 0: 
      *                     return $this->$funName(); 
      *                 case 1: 
      *                     return $this->$funName($args[0]); 
      *                 case 2: 
      *                     return $this->$funName($args[0], $args[1]); 
      *                 case 3: 
      *                     return $this->$funName($args[0], $args[1], $args[2]); 
      *                 case 4: 
      *                     return $this->$funName($args[0], $args[1], $args[2], $args[3]); 
      *                 case 5: 
      *                     return $this->$funName($args[0], $args[1], $args[2], $args[3], $args[4]); 
      *                 default: 
      *                     return call_user_func_array($this->$funName, $args); 
      *             } 
      *     } 
      */  
     public function __call($name,$arguments) {//參數1-調用的方法名 參數2-傳遞給調用方法的參數列表  
        if(method_exists($this,$name)){  
            return $this->$name();  
        }else{    
            echo "調用的方法 $name() 不存在;傳遞給 $name() 方法的參數列表如下:".implode(',',$arguments)."\n";  
        }  
     }  
}  
$obj = new MethodTest();  
//結果:調用的方法 runTest() 不存在;傳遞給 runTest() 方法的參數列表如下:李四,張三   
$obj->runTest('李四','張三');//方法名、參數列
/**  
 * 第65題:php中的重寫與重載 
 * 首先來了解兩個概念: 
 *      重寫/覆蓋:  指子類重寫了父類的同名方法,但重寫後的同名方法的參數個數及類型沒有限制             <span id="transmark"></span>發生在子類與父類之間  
 *      重載:     指本類中存在多個同名方法,但參數類型/個數不同,當傳不同的參數時調用不同的方法         發生在本類內部  
 * PHP中,不允許存在多個同名方法. 因此,不能夠完成java,c++中的這種重載;但是,PHP的靈活,可以模擬達到類似的效果  
*/  
  
class human{  
      public function say($name){  
            echo $name,' 吃了嗎?<br />';  
      }  
}  
  
class stu extends human{  
  
      /* 
       * 報錯:Fatal error: Cannot redeclare stu::say() in D:\wamp\www\php\61.php on line 28,因爲在PHP中,不允許存在多個同名方法,沒有重載概念這一說。 
       * public function say($a,$b,$c){ 
       *        echo '哥仨好'; 
       * } 
      */  
      public function say(){  
            echo '切克鬧,卡貓百比<br />';  
      }  
        
}  
  
$li=new stu();  
$li->say();//結果:切克鬧,卡貓百比;  
$li->say('binghui');//結果:切克鬧,卡貓百比;上面這個過程叫重寫  
  
  
  
//在PHP中模擬重載的方法  
class Calc {   
    public function area() {   
        //判斷一個調用area時,得到的參數個數   
        $args = func_get_args();//獲取參數個數   
        if(count($args) == 1) {   
            return 3.14 * $args[0] * $args[0];   
        } else if(count($args) == 2) {   
            return $args[0] * $args[1];   
        } else {   
            return '未知圖形';   
        }   
    }   
}   
$calc = new Calc();   
//計算圓的頁面   
echo $calc->area(10),'<br />';   
//計算矩形的面積   
echo $calc->area(5,8); 















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章