PHP知識點-1

1.字符串的使用

可將字符串看成一個字符的集合來使用,可獨立訪問每一個字符。僅適用於單字節字符(字母、數字、半角標點符號),像中文等不可用(utf8下,中文3字節表示)
$str = "abcd";
echo $str[3];   // d
echo $str{0};   // a
//另外一種方式
也可使用str_split把全部字符分割成數組。
$strArr = str_spilt($str);   //一樣不適合中文
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
)
function mb_str_split($str){
    return preg_split('/(?<!^)(?!$)/u', $str );   //反向預搜索
}
$str='博客';
mb_str_split($str);
打印結果以下:
Array
(
    [0] => 博
    [1] => 客
)

2.轉換類型

平時 咱們知道在變量前,加上(int), (string), (float) 之類的便可進行顯示轉換,下面介紹一種,可直接轉換爲null的 轉換,。
(unset) //轉換爲NULLphp

$a = 'a';
$a = (unset)$a;  //此時$a 爲 NULL
//換種方式
$a = 'a';
unset($a);
dd($a);
//報錯
PHP Notice:  Undefined variable: a in test.php on line 39

Notice: Undefined variable: a in test.php on line 39

3.isset 和 empty, is_null 對變量的檢測

3.1 isset 要檢測變量不存在則, 返回 false; 但須要注意,變量是否自己爲 Null值, 若是是,也返回 false; 都不知足則返回true了 。
爲了更方便檢測變量是否存在,可以使用
建議用array_key_exists判斷html

$a = null;
$varExists = array_key_exists('a', get_defined_vars());
if($varExists){
        echo '變量a是存在的';
}


3.2 empty, 檢測變量不存在,與各個空值,0值都爲true, 不然爲 false
3.3 is_null
當參數知足下面三種狀況時,is_null()將返回TRUE,其它的狀況就是FALSE
一、它被賦值爲NULL
二、它尚未賦值
三、它未定義,至關於unset(),將一個變量unset()後,不就是沒有定義嗎前端

4.static 的部分用法

咱們都知道 static 能夠直接定義靜態變量和 靜態方法, 不管是調用靜態變量和靜態方法, 用 :: 便可調用, 若是是本類,則使用self 調用, 若是是在類
外部,則使用類名進行調用, 但這裏對其不進行過多贅述,這些都是比較經常使用。下面講下不經常使用的。數據庫

static在類中的延遲靜態綁定;數組

延遲靜態綁定是指容許在一個靜態繼承的上下文中引用被調用類。
延遲綁定的意思爲:static::再也不爲定義當前方法所在的類,而是實際運行時所在的類。
(總的意思就是子類繼承了父類後,父類中使用了一個靜態方法或變量,如static::A(), 但方法A不存在於父類中,
存在於子類中,這樣寫是正確的,不會由於方法不存在而報錯,由於static 修飾的A 會在執行過程當中,綁定到具體的子類
上,只要保證子類有此方法便可)
注:它能夠用於(但不限於)靜態方法的調用。
self::,表明本類(當前代碼所在類)
    永遠表明本類,由於在類編譯時已經被肯定。
    即,子類調用父類方法,self卻不表明調用的子類。
parent:: 表明父類
static::,表明本類(調用該方法的類)
    用於在繼承範圍內引用靜態調用的類。
    運行時,才肯定表明的類。
    static::再也不被解析爲定義當前方法所在的類,而是在實際運行時計算的。
除了簡單的static延遲綁定的用法,還有一種轉發調用,
forward_static_call_array()(該函數只能在方法中調用)將轉發調用信息(不過多贅述,相似於本節的第8點,PHP反射),
歸納實例以下:
class A {
    public static function fooStatic() {
        static::who();
    }
    public static function who() {
        echo __CLASS__."aaa\n";
    }
}
class B extends A {
    public static function testStatic() {
        A::fooStatic();
        B::fooStatic();
        C::fooStatic();
        parent::fooStatic();
        self::fooStatic();
    }
    public static function who() {
        echo __CLASS__."bbb\n";
    }
}
class C extends B {
    public static function who() {
        echo __CLASS__."ccc\n";
    }
}
C::testStatic();
你們一塊兒來獲得答案:

5. array_merge 和 + , 合併數組

5.1 array_merge 合併兩個或多個數組的時候, 若是鍵名是非數字,則會自動合併到一塊兒,但若出現重複的鍵名,後面的會覆蓋前面的。若鍵名爲數字,其會根據前一個數組的索引值,自動給後面的更改索引值爲前面的遞增,也就是說會改變原有的鍵名。網絡

5.2 + 合併數組, 使用+ 號 合併數組,鍵名相同的狀況下,最早出現的鍵名會被保留, 而且即便鍵名是數字,也不會被從新編排,這個特性對部分業務場景會很是有用。angular2

5.3 array_push, 僅僅是把對應值徹底放到數組末尾, 原來的結構會被保留,整個做爲一個新的值, 鍵名跟着前一個遞增。這與array_merge 有所區別函數

5.4 array_combine, 兩個參數, 第一個參數,做爲新數組的鍵, 第二個參數做爲新數組的值。 並非給原有數組增添新值。因此其實他不一樣於 上面三個的做用。 光從名字上看容易混淆。優化

$a = ['a', 'b', 'c'];
$b = ['5' => 'test'];
$c = [1, 2, 3];

$arrayMerge   = array_merge($a, $b);
$arrayPlus    = $a + $b;
$arrayCombine = array_combine($a, $c);
array_push($a, $b);
// $arrayMerge
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => test
)
// $arrayPlus
Array
(
    [0] => a
    [1] => b
    [2] => c
    [5] => test
)
// $arrayCombine
Array
(
    [a] => 1
    [b] => 2
    [c] => 3
)
// array_push
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => Array
        (
            [5] => test
        )

)

6. 指針

數組的內部指針:
current/pos 返回當前被內部指針指向的數組單元的值,並不移動指針。
key         返回數組中當前單元的鍵名,並不移動指針
next        將數組中的內部指針向前移動一位,並返回移動後當前單元的值。先移動,再取值。
prev        將數組的內部指針倒回一位,並返回移動後當前單元的值先移動,再取值。
end         將數組的內部指針指向最後一個單元,並返回最後一個單元的值
reset       將數組的內部指針指向第一個單元,並返回第一個數組單元的值
each        返回數組中當前的鍵/值對並將數組指針向前移動一步。
            返回的是一個由鍵和值組成的長度爲4的數組,下標0和key表示鍵,下標1和value表示值
在執行each()以後,數組指針將停留在數組中的下一個單元或者當碰到數組結尾時停留在最後一個單元。若是要再用 each 遍歷數組,必須使用 reset()。
1. 以上指針操做函數,除了key(),若指針移出數組,則返回false。而key()移出則返回null。
2. 若指針非法,不能進行next/prev操做,能進行reset/end操做
3. current/next/prev     若遇到包含空單元(0或"")也會返回false。而each不會!

list    把數組中的值賦給一些變量。list()是語言結構,不是函數。
僅能用於數字索引的數組並假定數字索引從0開始
/* 可用於交換多個變量的值 */ 
list($a, $b) = array($b, $a);
例:list($drink, , $power) = array('coffee', 'brown', 'caffeine');
1. 複製數組,其指針位置也會被複制。
    特例:若是數組指針非法,則拷貝的數組指針會重置,而原數組的指針不變。
    【指針問題】
        誰第一個進行寫操做,就會開闢一個新的值空間。與變量(數組變量)值傳遞給誰無關。
        數組函數current()被定義爲寫操做,故會出現問題。
        foreach遍歷的是數組的拷貝,當被寫時,纔會開闢一個新的值空間。
            即,foreach循環體對原數組進行寫操做時,纔會出現指針問題。
            若是開闢新空間時指針非法,則會初始化指針。
2. 若是指針位置出現問題,則reset()初始化一下就可解決。

7. 序列化(串行化)

# 數據傳輸均是字符串類型
# 除了資源類型,都可序列化
# 序列化在存放數據時,會存放數據自己,也會存放數據類型
做用:1.在網絡傳輸數據時;2.爲了將數組或對象放在磁盤時
# 序列化
serialize        產生一個可存儲的值的表示
string serialize ( mixed $value )
- 返回字符串,此字符串包含了表示value的字節流,能夠存儲於任何地方。
- 有利於存儲或傳遞 PHP 的值,同時不丟失其類型和結構。
# 反序列化
unserialize        從已存儲的表示中建立PHP的值
mixed unserialize ( string $str [, string $callback ] )
- 對單一的已序列化的變量進行操做,將其轉換回PHP的值。

8.PHP反射

有時候咱們咱們爲了能創建更好的代碼結構,並能複用代碼,就須要用到一些語言的特性來幫助咱們完成任務,好比咱們此次新建的倉庫 trinity_middle_service, 咱們須要利用PHP自帶函數, 如call_user_func_array, 便可簡單實現分發。使用方式以下:編碼

class Order{
    public function getBasicInfo($orderId, $write = false)
    {
    }
}
$detailServiceInstance = new Order();
$functionName = 'getBasicInfo';
$params[0] = 1000001;    //或 $params['orderId'] = 1000001
$params[1] = true;       //或 $params['write'] = true
call_user_func_array([$detailServiceInstance, $functionName], $params);

從以上代碼可看出, call_user_func_array 第一個參數是個數組, 該數組中0下標的值 爲 一個類的實例, 1下標的 是這個實例中存在的方法; 第二個參數即 對應函數須要的參數了,該參數爲數組形式,call_user_func_array 會自動 按順序對應每個參數,因此在這裏,參數的順序很重要,不管是使用數字鍵名或字符鍵名,都必須一一對應函數具體的參數,這樣才能正確實現函數的分發。

8.1 反射的應用

使用call_user_func_array,咱們能夠簡單的實現分發,而且各個參數,也都很清晰。可是若是須要更加靈活的運用這個函數,咱們還須要引入PHP的反射機制,如 PHP自帶的 ReflectionMethod 類,

咱們能夠經過這個類,來直接獲取到某個類中具體方法的各種信息,如參數個數,參數名,是否有默認值等等。代碼以下:
$object = new Order();
$functionName = 'getBasicInfo';
$reflectionObj = new \ReflectionMethod($object, $functionName);
//經過以上的代碼後,就能夠直接經過$reflectionObj獲取相關信息了,以下
$reflectionObj->isPublic();   //可判斷該方法是否爲公有方法, 還有isPrivate, isProtected, isStatic等等
$reflectionObj->getParameters();   //可獲取該方法全部參數,是個數組,可 foreach獲取具體的參數
foreach($reflectionObj->getParameters() as $arg) {
    if(array_key_exists($arg->name, $params)) {
        $callParams[$arg->name] = $params[$arg->name];
    } else {
        $paramVal = null;
        if ($arg->isOptional()) {  // 或使用isDefaultValueAvailable, 檢測是否有可用的默認值
            $paramVal = $arg->getDefaultValue();
        }
        $callParams[$arg->name] = $paramVal;
    }
}
具體參數: https://www.php.net/manual/zh/class.reflectionmethod.php

還有 ReflectionClass 能夠獲取一些類的信息,用法都是相似的。

8.2 調用不存在的方法

__call & __callStatic (魔術方法)
當調用類中一個不存在或者沒有權限訪問的方法的時候,就會自動調用__call()方法。和__call對應靜態方法的調用是__callStatic, 配合PHP反射,對代碼進行優化,可對一些特殊的基礎業務功能作到,
如工單, trinity 內部都是用了相似方法。

9. move_uploaded_file

該函數是前端文件上傳文件到後臺後可能用到的函數,上傳後,咱們會經過$_FILES['file']'tmp_name', 使用

move_uploaded_file($tmp_name, $savePath);

會把臨時存到數據庫的 如: /tmp/phpwTJzUw 文件給移動走,致使若是後面的代碼還要用到$_FILES全局變量的時候,會出現找不到文件的問題。

10.引用傳遞

在使用array_pop等函數時, array_pop的參數 是引用傳遞,在編碼過程當中有時候會把 參數直接寫成函數返回值,這樣在 5.3之後是不容許的, 會報出致命錯誤(嚴格模式下)。

You will see:
PHP Strict Standards:  Only variables should be passed by reference in - on line 3

Strict Standards: Only variables should be passed by reference in - on line 3
d
以上來自於: https://www.php.net/manual/zh/function.array-pop.php

按引用傳遞參數的函數在被按值傳遞調用時行爲發生改變. 此前函數將接受按值傳遞的參數, 如今將拋出致命錯誤. 以前任何期待傳遞引用可是在調用時傳遞了常量或者字面值 的函數, 須要在調用前改成將該值賦給一個變量。
以上來自於:PHP手冊附錄從PHP 5.2.x 移植到 PHP 5.3.x 部分
https://www.php.net/manual/zh/migration53.incompatible.php

而實際上看起來沒有錯, 只須要把那個函數返回值賦值給一個變量,再把變量當作參數傳入就能夠了。
如,在代碼中常常會寫到:

error_reporting(E_STRICT);
$testArr = ['a','b','c','c','d'];
$popValue = array_pop(array_unique($testArr));  
// 以上代碼會報錯,必須使用
$testArr = ['a','b','c','c','d'];
$testArr = array_unique($testArr)
$popValue = array_pop($testArr);
相關文章
相關標籤/搜索