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);
相关文章
相关标签/搜索