【职造便利店】PHP 面试指南
2022-08-16 14:08:19 0 举报
AI智能生成
登录查看完整内容
面试中,常考知识点
作者其他创作
大纲/内容
一个类中可以出现多个同名方法,参数个数和类型不一样
自动调用、魔术方法
属性不存在或者权限不够访问的时候自动触发
访问
__get
设置
__set
判定
__isset
删除
__unset
属性重载
方法不存在或者权限不够的时候自动触发
__call
__callStatic
方法重载
overload(重载)
安装到 vendor
install
获取依赖最新版本,升级 composer.lock 文件
update
添加新的依赖包
require
获取帮助信息
list
以交互方式填写 composer.json 文件信息
init
在当前项目中搜索依赖包
search
列举所有可用的资源包
show
检测 composer.json 文件是否有效
validate
更新 composer 工具到最新版本
self-update
基于 composer 创建一个新的项目
create-project
composer
addcslashes() 返回在指定的字符前添加反斜杠的字符串。addslashes() 返回在预定义的字符前添加反斜杠的字符串。bin2hex() 把 ASCII 字符的字符串转换为十六进制值。chop() 删除字符串右侧的空白字符或其他字符。chr() 从指定的 ASCII 值返回字符。count_chars() 返回有关字符串中所用字符的信息。crc32() 计算字符串的 32 位 CRC。crypt() 单向的字符串加密法(hashing)。echo() 输出一个或多个字符串。explode() 把字符串打散为数组。hex2bin() 把十六进制值的字符串转换为 ASCII 字符。html_entity_decode() 把 HTML 实体转换为字符。htmlentities() 把字符转换为 HTML 实体。htmlspecialchars_decode() 把一些预定义的 HTML 实体转换为字符。htmlspecialchars() 把一些预定义的字符转换为 HTML 实体。implode() 返回由数组元素组合成的字符串。join() implode() 的别名。lcfirst() 把字符串的首字符转换为小写。ltrim() 移除字符串左侧的空白字符或其他字符。md5() 计算字符串的 MD5 散列。md5_file() 计算文件的 MD5 散列。metaphone() 计算字符串的 metaphone 键。money_format() 返回格式化为货币字符串的字符串。nl_langinfo() 返回特定的本地信息。nl2br() 在字符串中的每个新行之前插入 HTML 换行符。number_format() 以千位分组来格式化数字。ord() 返回字符串中第一个字符的 ASCII 值。parse_str() 把查询字符串解析到变量中。print() 输出一个或多个字符串。printf() 输出格式化的字符串。rtrim() 移除字符串右侧的空白字符或其他字符。sha1() 计算字符串的 SHA-1 散列。sha1_file() 计算文件的 SHA-1 散列。similar_text() 计算两个字符串的相似度。soundex() 计算字符串的 soundex 键。sprintf() 把格式化的字符串写入变量中。sscanf() 根据指定的格式解析来自字符串的输入。str_getcsv() 把 CSV 字符串解析到数组中。str_ireplace() 替换字符串中的一些字符(对大小写不敏感)。str_pad() 把字符串填充为新的长度。str_repeat() 把字符串重复指定的次数。str_replace() 替换字符串中的一些字符(对大小写敏感)。str_rot13() 对字符串执行 ROT13 编码。str_shuffle() 随机地打乱字符串中的所有字符。str_split() 把字符串分割到数组中。str_word_count() 计算字符串中的单词数。strcasecmp() 比较两个字符串(对大小写不敏感)。strchr() 查找字符串在另一字符串中的第一次出现。(strstr() 的别名。)strcmp() 比较两个字符串(对大小写敏感)。strcoll() 比较两个字符串(根据本地设置)。strcspn() 返回在找到某些指定字符的任何部分之前,在字符串中查找的字符数。strip_tags() 剥去字符串中的 HTML 和 PHP 标签。stripcslashes() 删除由 addcslashes() 函数添加的反斜杠。stripslashes() 删除由 addslashes() 函数添加的反斜杠。stripos() 返回字符串在另一字符串中第一次出现的位置(对大小写不敏感)。stristr() 查找字符串在另一字符串中第一次出现的位置(大小写不敏感)。strlen() 返回字符串的长度。strnatcasecmp() 使用一种\"自然排序\"算法来比较两个字符串(对大小写不敏感)。strnatcmp() 使用一种\"自然排序\"算法来比较两个字符串(对大小写敏感)。strncasecmp() 前 n 个字符的字符串比较(对大小写不敏感)。strncmp() 前 n 个字符的字符串比较(对大小写敏感)。strpbrk() 在字符串中查找一组字符的任何一个字符。strpos() 返回字符串在另一字符串中第一次出现的位置(对大小写敏感)。strrchr() 查找字符串在另一个字符串中最后一次出现。strrev() 反转字符串。strripos() 查找字符串在另一字符串中最后一次出现的位置(对大小写不敏感)。strrpos() 查找字符串在另一字符串中最后一次出现的位置(对大小写敏感)。strspn() 返回在字符串中包含的特定字符的数目。strstr() 查找字符串在另一字符串中的第一次出现(对大小写敏感)。strtok() 把字符串分割为更小的字符串。strtolower() 把字符串转换为小写字母。strtoupper() 把字符串转换为大写字母。strtr() 转换字符串中特定的字符。substr() 返回字符串的一部分。substr_compare() 从指定的开始位置(二进制安全和选择性区分大小写)比较两个字符串。substr_count() 计算子串在字符串中出现的次数。substr_replace() 把字符串的一部分替换为另一个字符串。trim() 移除字符串两侧的空白字符和其他字符。ucfirst() 把字符串中的首字符转换为大写。ucwords() 把字符串中每个单词的首字符转换为大写。vfprintf() 把格式化的字符串写到指定的输出流。vprintf() 输出格式化的字符串。vsprintf() 把格式化字符串写入变量中。wordwrap() 打断字符串为指定数量的字串
子主题
字符串
array() 创建数组。array_change_key_case() 把数组中所有键更改为小写或大写。array_chunk() 把一个数组分割为新的数组块。array_column() 返回输入数组中某个单一列的值。array_combine() 通过合并两个数组来创建一个新数组。array_count_values() 用于统计数组中所有值出现的次数。array_diff() 比较数组,返回差集(只比较键值)。array_diff_assoc() 比较数组,返回差集(比较键名和键值)。array_diff_key() 比较数组,返回差集(只比较键名)。array_diff_uassoc() 比较数组,返回差集(比较键名和键值,使用用户自定义的键名比较函数)。array_diff_ukey() 比较数组,返回差集(只比较键名,使用用户自定义的键名比较函数)。array_fill() 用给定的键值填充数组。array_fill_keys() 用指定键名的给定键值填充数组。array_filter() 用回调函数过滤数组中的元素。array_flip() 交换数组中的键和值。array_intersect() 比较数组,返回交集(只比较键值)。array_intersect_assoc() 比较数组,返回交集(比较键名和键值)。array_intersect_key() 比较数组,返回交集(只比较键名)。array_intersect_uassoc() 比较数组,返回交集(比较键名和键值,使用用户自定义的键名比较函数)。array_intersect_ukey() 比较数组,返回交集(只比较键名,使用用户自定义的键名比较函数)。array_key_exists() 检查指定的键名是否存在于数组中。array_keys() 返回数组中所有的键名。array_map() 把数组中的每个值发送到用户自定义函数,返回新的值。array_merge() 把一个或多个数组合并为一个数组。array_merge_recursive() 递归地合并一个或多个数组。array_multisort() 对多个数组或多维数组进行排序。array_pop() 删除数组的最后一个元素(出栈)。array_product() 计算数组中所有值的乘积。array_push() 将一个或多个元素插入数组的末尾(入栈)。array_rand() 返回数组中一个或多个随机的键。array_reduce() 通过使用用户自定义函数,以字符串返回数组。array_replace() 使用后面数组的值替换第一个数组的值。array_replace_recursive() 递归地使用后面数组的值替换第一个数组的值。array_reverse() 以相反的顺序返回数组。array_search() 搜索数组中给定的值并返回键名。array_shift() 删除数组中首个元素,并返回被删除元素的值。array_slice() 返回数组中被选定的部分。array_splice() 删除并替换数组中指定的元素。array_sum() 返回数组中值的和。array_udiff() 比较数组,返回差集(只比较值,使用一个用户自定义的键名比较函数)。array_udiff_assoc() 比较数组,返回差集(比较键和值,使用内建函数比较键名,使用用户自定义函数比较键值)。array_udiff_uassoc() 比较数组,返回差集(比较键和值,使用两个用户自定义的键名比较函数)。array_uintersect() 比较数组,返回交集(只比较值,使用一个用户自定义的键名比较函数)。array_uintersect_assoc() 比较数组,返回交集(比较键和值,使用内建函数比较键名,使用用户自定义函数比较键值)。array_uintersect_uassoc() 比较数组,返回交集(比较键和值,使用两个用户自定义的键名比较函数)。array_unique() 删除数组中的重复值。array_unshift() 在数组开头插入一个或多个元素。array_values() 返回数组中所有的值。array_walk() 对数组中的每个成员应用用户函数。array_walk_recursive() 对数组中的每个成员递归地应用用户函数。arsort() 对关联数组按照键值进行降序排序。asort() 对关联数组按照键值进行升序排序。compact() 创建包含变量名和它们的值的数组。count() 返回数组中元素的数目。current() 返回数组中的当前元素。each() 返回数组中当前的键/值对。end() 将数组的内部指针指向最后一个元素。extract() 从数组中将变量导入到当前的符号表。in_array() 检查数组中是否存在指定的值。key() 从关联数组中取得键名。krsort() 对数组按照键名逆向排序。ksort() 对数组按照键名排序。list() 把数组中的值赋给一些变量。natcasesort() 用“自然排序”算法对数组进行不区分大小写字母的排序。natsort() 用“自然排序”算法对数组排序。next() 将数组中的内部指针向前移动一位。pos() current() 的别名。prev() 将数组的内部指针倒回一位。range() 创建包含指定范围单元的数组。reset() 将数组的内部指针指向第一个元素。rsort() 对数组逆向排序。shuffle() 将数组打乱。sizeof() count() 的别名。sort() 对数组排序。uasort() 使用用户自定义的比较函数对数组中的键值进行排序。uksort() 使用用户自定义的比较函数对数组中的键名进行排序。usort() 使用用户自定义的比较函数对数组进行排序。
数组
函数
我们可以先写一个粗粒度的类,满足业务需求。随着业务的发展,如果粗粒度的类越来越庞大,代码越来越多,这个时候,我们就可以将这个粗粒度的类,拆分成几个更细粒度的类。这就是所谓的持续重构
一个类或者模块只负责完成一个职责(或者功能)
单一职责(Single Responsibility Principle)
软件实体(模块、类、方法等)应该“对扩展开放、对修改关闭”
添加一个新的功能应该是,在已有代码基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法等)。
对扩展开放、修改关闭
开闭原则(Open Closed Principle)
子类对象(object of subtype/derived class)能够替换程序(program)中父类对象(object of base/parent class)出现的任何地方,并且保证原来程序的逻辑行为(behavior)不变及正确性不被破坏。
里式替换原则(Liskov Substitution Principle)
客户端不应该被强迫依赖它不需要的接口。其中的“客户端”,可以理解为接口的调用者或者使用者。
接口隔离原则(Interface Segregation Principle)
框架提供了一个可扩展的代码骨架,用来组装对象、管理整个执行流程。程序员利用框架进行开发的时候,只需要往预留的扩展点上,添加跟自己业务相关的代码,就可以利用框架来驱动整个程序流程的执行。
这里的“控制”指的是对程序执行流程的控制,而“反转”指的是在没有使用框架之前,程序员自己控制整个程序的执行。在使用框架之后,整个程序的执行流程可以通过框架来控制。流程的控制权从程序员“反转”到了框架。
控制反转(IOC)
不通过 new() 的方式在类内部创建依赖类对象,而是将依赖的类对象在外部创建好之后,通过构造函数、函数参数等方式传递(或注入)给类使用。
依赖注入框架”。我们只需要通过依赖注入框架提供的扩展点,简单配置一下所有需要创建的类对象、类与类之间的依赖关系,就可以实现由框架来自动创建对象、管理对象的生命周期、依赖注入等原本需要程序员来做的事情。
依赖注入(DI)
高层模块(high-level modules)不要依赖低层模块(low-level)。高层模块和低层模块应该通过抽象(abstractions)来互相依赖。除此之外,抽象(abstractions)不要依赖具体实现细节(details),具体实现细节(details)依赖抽象(abstractions)。
依赖反转原则(DIP)
依赖反转原则(Dependency Inversion Principle)
DI 容器底层最基本的设计思路就是基于工厂模式的。DI 容器相当于一个大的工厂类,负责在程序启动的时候,根据配置(要创建哪些类对象,每个类对象的创建需要依赖哪些其他类对象)事先创建好对象。当应用程序需要使用某个类对象的时候,直接从容器中获取即可。正是因为它持有一堆对象,所以这个框架才被称为“容器”。
DI 容器负责的是整个应用中所有类对象的创建。
DI 容器负责的事情要比单纯的工厂模式要多。比如,它还包括配置的解析、对象生命周期的管理。
我们将需要由 DI 容器来创建的类对象和创建类对象的必要信息(使用哪个构造函数以及对应的构造函数参数都是什么等等),放到配置文件中。容器读取配置文件,根据配置文件提供的信息来创建对象。
配置解析
将所有类对象的创建都放到一个工厂类中完成
对象创建
对象生命周期管理
简单的 DI 容器的核心功能
DI容器
SOLID 原则
由一个 master 进程和多个 worker进程组成
master 进程启动时,会创建一个socket,但是不会接受、处理请求,而是由 fork 出的 worker 子进程完成请求
master 主要工作是管理 worker,负责 fork 和 kill worker 进程
nginx 的子进程通过 epoll 管理套接字,非阻塞模型,只处理活跃的套接字
多进程模型
sapi_startup
SAPI 注册
php_module_startup
解析 php-fpm.conf
fpm_conf_init_main
分配用于记录 worker 进程运行信息的结构
fpm_scoreboard_init_main
创建一个全双工管道
fpm_signals_init_main
创建每个 worker pool 的socket 套接字,启动后 worker 将监听此 socket 接受请求
fpm_sockets_init_main
启动 master 的事件管理,用于管理 I/O、定时事件
fpm_event_init_main
fpm_init
fork 子进程
启动进程管理器
子进程返回 main 中
master 进入 fpm_event_loop 事件循环
fpm_run
初始化
Fpm 初始化
worker 进程不断 Accept 请求,读取并解析 FastCGI,执行 PHP 脚本,返回,关闭,继续监听
阻塞在 fcgi_accept_request
等待请求
fastcgi 请求到达后被 worker 接受,然后开始接受并解析请求数据,直到 request 数据完全到达
解析请求
此阶段会调用每个扩展的 PHP_RINT_FUNCTION
执行 php_request_startup
请求初始化
由 php_execute_script完成 PHP 脚本的编译执行
执行 PHP 脚本
此阶段调用每个扩展的 PHP_RSHUTDOWN_FUNCTION,然后进入步骤一,等待下一个请求
请求完成后执行 php_request_shutdown
关闭请求
请求处理
进入事件循环
调用 fpm_run 后不再返回
master 进程管理
FastCGI
命名参数优,仅仅指定必填参数,跳过可选参数。
构造方法缩短语句,仅在小括号中赋值
属性声明多类型
Match 表达式
?->
nullsafe
数字与字符串的比较
数据验证错误抛 error,且规范格式
Tracing JIT
Function JIT
即时编译 JIT
8.0
PHP
0 条评论
回复 删除
下一页