PHP 面试知识点整理归纳

基础篇
了解大部分数组处理函数
    array_chunk — 将一个数组分割成多个
    array_column — 返回数组中指定的一列
    array_combine — 创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值(另一种意义的合并数组)
    array_flip — 交换数组中的键和值
    array_key_exists — 检查数组里是否有指定的键名或索引
    array_key_first — Gets the first key of an array
    array_key_last — Gets the last key of an array
    array_keys — 返回数组中部分的或所有的键名
    array_merge — 合并一个或多个数组
    array_pop — 弹出数组最后一个单元(出栈)
    array_push — 将一个或多个单元压入数组的末尾(入栈)
    array_rand — 从数组中随机取出一个或多个单元
    array_reverse — 返回单元顺序相反的数组
    array_search — 在数组中搜索给定的值,如果成功则返回首个相应的键名
    array_shift — 将数组开头的单元移出数组
    array_slice — 从数组中取出一段
    array_sum — 对数组中所有值求和
    array_unique — 移除数组中重复的值
    array_unshift — 在数组开头插入一个或多个单元
    array_values — 返回数组中所有的值
    arsort — 对数组进行逆向排序并保持索引关系
    asort — 对数组进行排序并保持索引关系
    count — 计算数组中的单元数目,或对象中的属性个数
    current — 返回数组中的当前单元
    in_array — 检查数组中是否存在某个值
    krsort — 对数组按照键名逆向排序
    ksort — 对数组按照键名排序
    list — 把数组中的值赋给一组变量
    shuffle — 打乱数组
    sort — 对数组排序
    uasort — 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联
    uksort — 使用用户自定义的比较函数对数组中的键名进行排序
    usort — 使用用户自定义的比较函数对数组中的值进行排序
字符串处理函数 ,区别 mb_ 系列函数
    chunk_split — 将字符串分割成小块
    explode — 使用一个字符串分割另一个字符串
    implode — 将一个一维数组的值转化为字符串
    lcfirst — 使一个字符串的第一个字符小写
    ltrim — 删除字符串开头的空白字符(或其他字符)
    md5 — 计算字符串的 MD5 散列值
    money_format — 将数字格式化成货币字符串
    nl2br — 在字符串所有新行之前插入 HTML 换行标记
    number_format — 以千位分隔符方式格式化一个数字
    ord — 返回字符的 ASCII 码值
    rtrim — 删除字符串末端的空白字符(或者其他字符)
    str_replace — 子字符串替换
    str_ireplace — str_replace 的忽略大小写版本
    str_repeat — 重复一个字符串
    str_shuffle — 随机打乱一个字符串
    str_split — 将字符串转换为数组
    stripos — 查找字符串首次出现的位置(不区分大小写)
    strpos — 查找字符串首次出现的位置
    strstr — 查找字符串的首次出现
    stristr — strstr 函数的忽略大小写版本
    strlen — 获取字符串长度
    strrchr — 查找指定字符在字符串中的最后一次出现
    strrev — 反转字符串
    strripos — 计算指定字符串在目标字符串中最后一次出现的位置(不区分大小写)
    strrpos — 计算指定字符串在目标字符串中最后一次出现的位置
    strtok — 标记分割字符串
    strtolower — 将字符串转化为小写
    strtoupper — 将字符串转化为大写
    substr_count — 计算字串出现的次数
    substr_replace — 替换字符串的子串
    substr — 返回字符串的子串
    trim — 去除字符串首尾处的空白字符(或者其他字符)
    ucfirst — 将字符串的首字母转换为大写
    ucwords — 将字符串中每个单词的首字母转换为大写
    wordwrap — 打断字符串为指定数量的字串
普通字符串处理函数和mb_系列函数的区别:
不同编码的个别语言(比如中文)所占字节数不同,一个汉字在GB2312编码下占2个字节,在UTF-8(是变长编码)编码下占2-3个字节,普通字符串处理函数是按每个字符1字节来处理的,而mb_系列的函数在使用时可以多指定一个编码参数,方便处理不同编码的中文。
最简单的例子,strlen()会返回一个字符串所占字节数,而mb_strlen()会返回一个字符串的字符数。再比如,substr($str2, 2, 2)在$str为中文时可能会正好截取到一个汉字的一部分,这时就会发生乱码,而mb_substr($str, 2, 2, ‘utf-8’)指定编码后就不会发生乱码问题了,中文时即是取几个汉字。
& 引用,结合案例分析
PHP 的引用允许用两个变量来指向同一个内容。
$a =& $b;
$a 和 $b 在这里是完全相同的,这并不是 $a 指向了 $b 或者相反,而是 $a 和 $b 指向了同一个地方;
引用做的第二件事是用引用传递变量
function foo(&$var)
{    $var++; }
$a=5;
foo($a);
将使 $a 变成 6。这是因为在 foo 函数中变量 $var 指向了和 $a 指向的同一个内容。
引用不是指针,下面的结构不会产生预期的效果:
function foo(&$var)
{    $var =& $GLOBALS[“baz”];    }
foo($bar);
当 unset 一个引用,只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了。例如:
$a = 1;
$b =& $a;
unset($a);
不会 unset  $b,只是 $a。
== 与 === 区别
简单来说,==是不带类型比较是否相同(比如数字100 == ‘100’结果为true),===是带类型比较是否相同(比如100 == ‘100’结果为false),官方手册的解释也类似:
isset 与 empty 区别
看到一个简洁代码的解释:
再具体说:$a不存在和$a = null 两种情况在isset看来为true,其余为false(包括$a = ‘’;)
$a = null, 0, false, ‘ ’, 或不存在时在empty看来为true,其余为false。
再多说一句,isset用来判断变量是否存在;empty用来判断变量是否有值;这里要特别注意0这个值在某些表单验证情况下可能是有效值,此时不能仅用empty判断变量是否有值,需要另作处理。
全部魔术函数理解
    __construct 类的构造函数,常用来给类的属性赋值,注意事项:
如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用 parent::__construct()。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为 private 的话)
    __destruct 析构函数,析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。
    __call,__callStatic 在对象中调用一个不可访问方法时,__call() 会被调用。在静态上下文中调用一个不可访问方法时,__callStatic() 会被调用,作为调用类中不存在的方法时对开发者的一个友好提示
    __set,__get,__isset ,__unset 在给不可访问属性赋值时,__set() 会被调用;读取不可访问属性的值时,__get() 会被调用;当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用;当对不可访问属性调用 unset() 时,__unset() 会被调用。
    __sleep,__wakeup  serialize() 函数会检查类中是否存在一个魔术方法 __sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。如果该方法未返回任何内容,则 NULL 被序列化,并产生一个 E_NOTICE 级别的错误.返回父类的私有成员的名字,常用于提交未提交的数据,或类似的清理操作;与之相反,unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源。__wakeup() 经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作
    __toString 用于当直接echo $obj(一个对象)时该显示什么内容,必须返回一个字符串且不能在方法内抛出异常
    __invoke  当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用,例如function __invoke($x) {  var_dump($x); } $obj = new CallableClass; $obj(5);会输出int(5)
    __set_state 调用 var_export() 导出类时,此静态 方法会被调用。本方法的唯一参数是一个数组,其中包含按 array(‘property’ => value, …) 格式排列的类属性
    __clone  对象复制可以通过 clone 关键字来完成(如果可能,这将调用对象的 __clone() 方法)。对象中的 __clone() 方法不能被直接调用。
    $copy_of_object = clone $object; 当对象被复制后,PHP 5 会对对象的所有属性执行一个浅复制(shallow copy)。所有的引用属性 仍然会是一个指向原来的变量的引用。当复制完成时,如果定义了 __clone() 方法,则新创建的对象(复制生成的对象)中的 __clone() 方法会被调用,可用于修改属性的值(如果有必要的话)。
    __debugInfo 当var_dumo(new Class)(参数为一个对象时),该方法可以控制显示的内容,若没有定义此方法,var_dump()将默认展示对象的所有属性和方法
static、$this、self 区别
$this通俗解释就是当前类的一个实例,不必多说,主要是static::和self::的区别

这将打印出来A
另一方面static::它具有预期的行为

这将打印出来B
这在PHP 5.3.0中称为后期静态绑定。它解决了调用运行时引用的类的限制。
private、protected、public、final 区别
public:权限是最大的,可以内部调用,实例调用等。
protected: 受保护类型,用于本类和继承此类的子类调用。
private: 私有类型,只有在本类中使用。
static:静态资源,可以被子类继承。
abstract:修饰抽象方法,没有方法体,由继承该类的子类来实现。
final:表示该变量、该方法已经“完成”,不可被覆盖。修饰类时该类不能被继承。
(因此final和abstract不能同时出现)
OOP 思想
简单理解:
面向对象的编程就是编出一个人来,这个人可以做很多种动作,跑,跳,走,举手…他能做什么取决于你如何组合这些动作,有些动作在一些功能中是不用的。
而层次化的编程(面向过程)就是造出一个具体的工具,他只能干这样一件事,条件——结果。
抽象类、接口 分别使用场景
接口通常是为了抽象一种行为,接口是一种规范,在设计上的意义是为了功能模块间的解耦,方便后面的功能扩展、维护,接口不能有具体的方法;
抽象类可以有具体的方法,也可以有抽象方法,一旦一个类有抽象方法,这个类就必须声明为抽象类,很多时候是为子类提供一些共用方法;
所以,抽象类是为了简化接口的实现,他不仅提供了公共方法的实现,让你可以快速开发,又允许你的类完全可以自己实现所有的方法,不会出现紧耦合的问题。
应用场合很简单了
1 优先定义接口
2 如果有多个接口实现有公用的部分,则使用抽象类,然后集成它。
举个简单的例子:有一个动物接口,内有动物叫声和动物说你好两个方法,在实现该接口时各个动物的叫声肯定是不同的,但是他们都在说你好是相同的,此时就可以用抽象类,把相同的说你好的方法抽象出去,就不用在每个动物类中写了。
Trait 是什么东西
Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。
Trait 和 Class 相似,但仅仅旨在用细粒度和一致的方式来组合功能。 无法通过 trait 自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个 Class 之间不需要继承。
简单理解:Trait为不支持多继承的php实现了多继承,使用时不是用extends继承,而是在类内部用 use 类名 表示。
重名方法优先级问题:当前类的成员覆盖 trait 的方法,而 trait 则覆盖被继承的方法。
echo、print、print_r 区别(区分出表达式与语句的区别)
Echo,print是语言结构,print_r和var_dump是常规功能
print并且echo或多或少相同; 它们都是显示字符串的语言结构。差异很微妙:print返回值为1,因此可以在表达式中使用,但echo具有void返回类型; echo可以采用多个参数,尽管这种用法很少见; echo比print快一点。(就个人而言,我总是使用echo,从不print。)
var_dump打印出变量的详细转储,包括其类型大小和任何子项的类型和大小(如果它是数组或对象)。
print_r以更易于阅读的格式化形式打印变量(数组或对象):不能传递字符串,它省略了类型信息,不给出数组大小等。
var_dump, print_r根据我的经验,通常在调试时更有用。当您不确切知道变量中的值/类型时,它尤其有用。考虑这个测试程序:
$values = array(0, 0.0, false, ”);
var_dump($values);
print_r ($values);
随着print_r你不能告诉之间的区别0和0.0,或false和”:
array(4) {
  [0]=>  int(0)
  [1]=>  float(0)
  [2]=>  bool(false)
  [3]=>  string(0) “”
}
Array(
    [0] => 0
    [1] => 0
    [2] =>
    [3] => )
__construct 与 __destruct 区别
在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。
析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。和构造函数一样,父类的析构函数不会被引擎暗中调用。要执行父类的析构函数,必须在子类的析构函数体中显式调用 parent::__destruct()。此外也和构造函数一样,子类如果自己没有定义析构函数则会继承父类的。析构函数即使在使用 exit() 终止脚本运行时也会被调用。在析构函数中调用 exit() 将会中止其余关闭操作的运行。
static 作用(区分类与函数内)手册 、SOF
声明类属性或方法为静态,就可以不实例化类而直接访问。静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。
为了兼容 PHP 4,如果没有指定访问控制,属性和方法默认为公有。
由于静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用。
静态属性不可以由对象通过 -> 操作符来访问,但可以由对象通过 :: 来访问
用静态方式调用一个非静态方法会导致一个 E_STRICT 级别的错误。
就像其它所有的 PHP 静态变量一样,静态属性只能被初始化为文字或常量,不能使用表达式。所以可以把静态属性初始化为整数或数组,但不能初始化为另一个变量或函数返回值,也不能指向一个对象。
也可以用一个值等于类名的字符串变量来动态调用类。但该变量的值不能为关键字 self,parent 或 static,比如有个class A{}, 则可以用$a=’A’; $a::这样调用
在类之外(即:在函数中),static变量是在函数退出时不会丢失其值的变量。在同一函数的不同调用中维护的变量只有一个值。从PHP手册的例子:

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年3月10日
下一篇 2019年3月11日

相关推荐