常见笔试题: 1.cookie和session cookie和session的区别是什么? Session储存在服务端,安全性高,可以储存多种数据类型。 Cookie 储存在浏览器,安全性低,用户可以
Session储存在服务端,安全性高,可以储存多种数据类型。
Cookie 储存在浏览器,安全性低,用户可以修改,只能储存key + 字符串类型,可以设置过期时间,数据不超3K。
客户端浏览器发起请求 ( 用户打开网站,输入账号密码,点击登录)
2、服务器接收并响应 ( 服务器接收请求,创建 Cookie,将用户信息存入,并将 Cookie 返回客户端浏览器,浏览器将 Cookie 保存至内存或本地文件)
3、客户端之后再发起请求 ( 将 Cookie 一起发给服务器)
4、服务器接收并响应 ( 服务器收到 Cookie 后,可以识别是哪位用户进行操作,再进行处理)
当用户第一次访问服务端资源时(如访问网站首页),服务器会为该用户创建一个唯一的Session ID,并且将其存储到用户浏览器的Cookie中,以便在后续的请求中传递这个ID。
2、服务器端会为每个Session ID创建一个对应的Session对象,该Session对象是存在于服务器内存中的一个数据结构。该对象可以存储用户特定的信息,如登录状态、购物车内容等
3、当用户进行其他操作并提交请求时,该请求会带上Session ID。服务器会从内存中查找对应的Session对象,并根据需要将相关数据添加或修改。
4、当用户关闭浏览器或长时间未活跃时,服务器将和该会话相关的Session对象从内存中删除,并删除用户浏览器中的Session ID Cookie
5、Session的工作原理背后的原则是通过在服务器中存储会话信息,确保WEB应用程序可以跟踪用户的状态和提供更加个性化的服务,但需要注意的是,当用户过多时,可能会导致服务器压力增大
传值:函数内对值的任何改变在函数外部都会被忽略,必须复制值,效率比传引用慢。
传引用:函数内对值的任何改变在函数外部也能反映出这些修改,不需要复制值,效率比传值高,通常用于大字符串或者大对象、大数组。
list( b , b, b,a)=array( a , a, a,b);
整数、字符串、布尔型、数组、对象、资源类型、NULL、浮点型
for需要先知道数组长度再操作,foreach不需要;
2、foreach效率比for高很多;
3、foreach直接通过结构体中next指针获取下一个值,而for循环需要根据key先进行一次hash才得到值
Include : 包含文件不存在时会产生一个警告,但是脚本继续允许,可以多次包含同一个文件,可以用incluede_once 代替。
Require:包含文件不存在时,脚本直接停止允许,文件只处理一次,速度比include快,可以用require_once 代替。
单引号:不能解析变量,速度比双引号快。
双引号:可以解析变量,速度比单引号慢。
在代码中能使用单引号,就不要使用双引号。
header (location:网址)。
2、Header(refresh:3,url=网址) 实现3秒后跳转。
Iconv,Mb_convet_encoding
Echo 和 print可以输出,echo不是函数,没有返回值,echo更快。Print是函数有返回值,用于打印字符串类型。Print_r 用于打印复合类型,如数组和对象等变量信息,调式中用。
isset判断变量是否存在,可以传入多个变量,若其中一个变量不存在则返回假;empty判断变量是否为空为假,只可传一个变量,如果为空为假则返回真。
两者都是定义常量使用:
const 是语言结构, define 是函数
const 可在类中使用, define 不可以
const 可以不同命名空间定义相同名称的常量, define 不可以
const 大小写敏感, define 默认敏感, 可通过第三个参数为 true 设置为不敏感
function ucstring($string){ return str_replace(' ', '', ucWords(str_replace('_', ' ', $string)));}
function numFORMate($number){ $str = (string) $number; $string = strrev($str); # 先反转 $length = strlen($string); # 获取长度 for($i = 0; $i < $length; $i = $i+3) { $new_string .= substr($string, $i, 3) . ','; } return strrev(rtrim($new_string, ','));}
echo date("Y年m月d日 H:i:s", strtotime("-1 day"));
# 案例1$a = "aabbzz"; $a++; echo $a;# 输出 aabcaa# 案例2if ('1e3' == '1000') echo 'yes'; # 输出 yes# 因为 1e3 是科学计数法, 1e3 等于 1 乘以10 的 3 次方# 案例3$data = ['a','b','c']; foreach($data as $k=>$v){ $v = &$data[$k];}# 输出数组值为 ['b','c','c']# 案例4$a= 0.1; $b = 0.7;if($a+$b == 0.8){ echo true; } else { echo false; }# 输出 空# echo false 输出空 , echo true 输出 1# php 浮点计算会转为 二进制, 0.1 + 0.7 = 0.7999999....# 案例5$a= 0;$b= 0;if($a = 3>0 || $b = 3>0){ $a++; $b++;}echo $a,$b;# 输出 11# 算数运算符 > 比较运算符 > 逻辑运算符(!除外) > 赋值
三层,有什么优点?
MVC三层分别指:业务模型、视图、控制器,由控制器层调用模型处理数据,然后将数据映射到视图层进行显示。
优点是:
①可以实现代码的重用性,避免产生代码冗余;
②M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。
array() — 数组的创建array_change_key_case — 将数组中的所有键名修改为全大写或小写array_chunk — 将一个数组分割成多个array_column — 返回输入数组中指定列的值array_combine — 创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值array_count_values — 统计数组中所有的值array_diff_assoc — 带索引检查计算数组的差集array_diff_key — 使用键名比较计算数组的差集array_diff_uassoc — 用用户提供的回调函数做索引检查来计算数组的差集array_diff_ukey — 用回调函数对键名比较计算数组的差集array_diff — 计算数组的差集array_fill_keys — 使用指定的键和值填充数组array_fill — 用给定的值填充数组array_filter — 使用回调函数过滤数组的元素array_flip — 交换数组中的键和值array_intersect_assoc — 带索引检查计算数组的交集array_intersect_key — 使用键名比较计算数组的交集array_intersect_uassoc — 带索引检查计算数组的交集,用回调函数比较索引array_intersect_ukey — 在键名上使用回调函数来比较计算数组的交集array_intersect — 计算数组的交集array_is_list — 判断给定的 array 是否为 listarray_key_exists — 检查数组里是否有指定的键名或索引array_key_first — 获取指定数组的第一个键array_key_last — 获取一个数组的最后一个键值array_keys — 返回数组中部分的或所有的键名array_map — 为数组的每个元素应用回调函数array_merge_recursive — 递归地合并一个或多个数组array_merge — 合并一个或多个数组array_multisort — 对多个数组或多维数组进行排序array_pad — 以指定长度将一个值填充进数组array_pop — 弹出数组最后一个单元(出栈)array_product — 计算数组中所有值的乘积array_push — 将一个或多个单元压入数组的末尾(入栈)array_rand — 从数组中随机取出一个或多个随机键array_reduce — 用回调函数迭代地将数组简化为单一的值array_replace_recursive — 使用传递的数组递归替换第一个数组的元素array_replace — 使用传递的数组替换第一个数组的元素array_reverse — 返回单元顺序相反的数组array_search — 在数组中搜索给定的值,如果成功则返回首个相应的键名array_shift — 将数组开头的单元移出数组array_slice — 从数组中取出一段array_splice — 去掉数组中的某一部分并用其它值取代array_sum — 对数组中所有值求和array_udiff_assoc — 带索引检查计算数组的差集,用回调函数比较数据array_udiff_uassoc — 带索引检查计算数组的差集,用回调函数比较数据和索引array_udiff — 用回调函数比较数据来计算数组的差集array_uintersect_assoc — 带索引检查计算数组的交集,用回调函数比较数据array_uintersect_uassoc — 带索引检查计算数组的交集,用单独的回调函数比较数据和索引array_uintersect — 计算数组的交集,用回调函数比较数据array_unique — 移除数组中重复的值array_unshift — 在数组开头插入一个或多个单元array_values — 返回数组中所有的值array_walk_recursive — 对数组中的每个成员递归地应用用户函数array_walk — 使用用户自定义函数对数组中的每个元素做回调处理array — 新建一个数组arsort — 对数组进行降向排序并保持索引关系asort — 对数组进行升序排序并保持索引关系compact — 建立一个数组,包括变量名和它们的值count — 统计数组、Countable 对象中所有元素的数量current — 返回数组中的当前值each — 返回数组中当前的键/值对并将数组指针向前移动一步end — 将数组的内部指针指向最后一个单元extract — 从数组中将变量导入到当前的符号表in_array — 检查数组中是否存在某个值key_exists — 别名 array_key_existskey — 从关联数组中取得键名krsort — 对数组按照键名逆向排序ksort — 对数组根据键名升序排序list — 把数组中的值赋给一组变量natcasesort — 用“自然排序”算法对数组进行不区分大小写字母的排序natsort — 用“自然排序”算法对数组排序next — 将数组中的内部指针向前移动一位pos — current 的别名prev — 将数组的内部指针倒回一位range — 根据范围创建数组,包含指定的元素reset — 将数组的内部指针指向第一个单元rsort — 对数组降序排序shuffle — 打乱数组sizeof — count 的别名sort — 对数组升序排序uasort — 使用用户定义的比较函数对数组进行排序并保持索引关联uksort — 使用用户自定义的比较函数对数组中的键名进行排序usort — 使用用户自定义的比较函数对数组中的值进行排序
# 1. 字符串统计strlen(); # 统计字符串长度, 中文占 3 个字节mb_strlen(); # 统计字符串长度, 中文占 1 个字节str_word_count($string, $format, $characters); # 统计字符串中单词的数量, 更多用法请查阅手册# 2. 字符串查找与替换str_replace($new, $old, $string); # 字符串替换操作, 区分大小写str_ireplace($new, $old, $string); # 字符串替换操作, 不区分大小写substr_replace($string, $replace, $start, $length); # 把一部分替换为另一个字符串substr_count($string, $search); # 统计一个字符串在另一字符串中出现的次数similar_text($string1, $string2, $percent); # 返回两个字符串字符串相同数量或相同百分比值strstr($string, $search, $before=false); # 查找字符串在另一个字符串中第一次出现的位置,并返回从该位置到字符串结尾或字符串开始的所有字符, 无则返回 FALSE, 区分大小写stristr($string, $search, $before=false); # 查找字符串在另一个字符串中第一次出现的位置,并返回从该位置到字符串结尾或字符串开始的所有字符, 无则返回 FALSE, 不区分大小写strchr($string, $search, $before=false); # strstr(); 的别名strrchr($string, $search); # 查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符, 无则返回 FALSE, 区分大小写strpos($string, $search, $start); # 返回字符串在另一字符串首次出现的位置, 区分大小写stripos($string, $search, $start); # 返回字符串在另一字符串首次出现的位置, 不区分大小写strrpos($string, $search, $start); # 返回字符串在另一字符串最后一次出现的位置, 区分大小写strripos($string, $search, $start); # 返回字符串在另一字符串最后一次出现的位置, 不区分大小写strspn($string, $charlist, $start, $length); # 返回在 $string 中包含 $charlist 参数中指定的字符数目。strcspan($string, $char, $start, $length); # 函数返回在找到任何指定的字符之前,在字符串查找的字符数(包括空格)。# 3. 字符分割及拼接explode($separator, $string); # 按 $separator 分隔 $string , 打散后重新组装成数组implode($separator, $array); # 用 $separator 分隔数组中的每个值, 转换成新字符串substr($string, $start, $length); # 中文占 3 个字节, 在 $string 字符串中, 从 $start 位置开始, 返回 $length 长度的字符串, $length 默认直到字符串结尾mb_substr($string, $start, $length); # 中文占 1 个字节, 在 $string 字符串中, 从 $start 位置开始, 返回 $length 长度的字符串, $length 默认直到字符串结尾 chunk_split($string, $length, $separator); # 将字符串按 $length 长度分割成小块, 以 $separator 分隔, 返回新字符串str_split($string, $length); # 将字符串按 $length 长度分割成小块, 返回数组# 4. 字符串比较 (两个字符串相同返回 0)strcmp($string1, $string2); # 比较两个字符串, 区分大小写strcasecmp($string1, $string2); # 比较两个字符串, 不区分大小写strncmp($string1, $string2, $length); # 比较两个字符串前 $length 长度, 区分大小写strncasecmp($string1, $string2, $length); # 比较两个字符串前 $length 长度, 不区分大小写strnatcmp($string1, $string2); # 使用"自然"算法来比较两个字符串, 区分大小写strnatcmp($string1, $string2); # 使用"自然"算法来比较两个字符串, 不区分大小写# 5. 大小写转换strtolower($string); # 全部字符串转为小写strtoupper($string); # 全部字符串转为大写lcfirst($string); # 字符串首字母小写ucfirst($string); # 字符串首字母大写ucwords($string); # 字符串每个单词首字母转为大写# 6. 生成与转化strrev(); # 反转字符串str_repeat($string, $multiplier); # 重复字符串 $multiplier 次str_pad($string, $length, $pad_string, $pad_type); # 把字符串填充指定长度, $pad_string 为填充的字符, $pad_type 为类型 (STR_PAD_RIGHT: 向右填充(默认) STR_PAD_LEFT: 向左填充 STR_PAD_BOTH: 两侧填充)wordwrap($string, $length); # 把字符串按指定长度折行str_shuffle(); # 随机打乱字符串number_format(); # 千位格式化数字parse_str(); # 把字符串解析成变量 例: parse_str("name=Chon&height=175");trim($string, $char); # 去除首尾处的 $char 字符, $char 默认为空格ltrim($string, $char) # 去除开头处的 $char 字符, $char 默认为空格rtrim($string, $char) # 去除结尾处的 $char 字符, $char 默认为空格# 7. html 标签相关联函数htmlentities(); # 把字符转为 html 实体html_entity_decode(); # 把 html 实体转为字符htmlspecialchars(); # 预定义字符(<>'"&)转 html 实体htmlspecialchars_decode(); # 把预定义 html 实体(& " ' < >) 转为字符nl2br(); # \n 转为
标签strip_tags(); # 去除字符串中的 html 标签addslashes(); # 指定预定义字符(<>'"&)前添加反斜线stripslashes(); # 删除由 addslashes() 添加的反斜线addcslashes($string, $char); # 在 $string 字符串中, 在 $char 的指定字符前添加反斜线stripcslashes(); # 删除由 addcslashes() 添加的反斜线quotemeta(); # 在字符串中预定义的字符(.\+*?[]^$())前添加反斜线chr(); # 返回不同 ASCII 值的字符ord(); # 返回字符串中第一个字符的 ASCII 值
LINE:文件中的当前行号。
FILE:文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。
DIR:文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。它等价于:dirname(FILE)。除非是根目录,否则目录中名不包括末尾的斜杠。
NAMESPACE:当前命名空间的名称。
TRAIT:Trait:的名字。Trait:名包括其被声明的作用域(例如:Foo\Bar)。
CLASS:当前类的名称。类名包括其被声明的作用域(例如:Foo\Bar)。当用在:trait:方法中时,CLASS:是调用:trait:方法的类的名字。
FUNCTION:当前函数的名称。匿名函数则为:{closure}。
METHOD:类的方法名。
ClassName::class:完整的类名。
1、__construct() 构造函数:构造函数是类中的一个特殊函数,当我们使用new关键字实例化对象时,相当于调用了类的构造函数。2、__destruct() 析构函数:析构函数在对象被销毁释放之前自动调用,不能带有任何的参数,常用于对象使用完以后,释放资源,关闭资源等。3、__set($key,$value) 给类私有属性赋值时自动调用,调用是给方法传递两个参数:需要设置的属性名、属性值。4、__get($key) 给获取类私有属性时自动调用,调用是给方法传递一个参数:需要获取的属性名。5、 __isset($key) 外部使用isset()函数检测私有属性时,自动调用。类外部使用isset();检测私有属性,默认检测不到(false),所以,我们可以使用__isset()函数,在自动调用时,返回内部检测结果6、__unset($key) 外部使用unset()函数删除私有属性时,自动调用7、__clone 当使用clone关键字,克隆对象时,自动调用clone函数,__clone()函数类似于克隆是使用的构造函数,可以给新克隆对象赋初值,克隆函数里面的$this指的是新克隆的对象。8、__tostring() 当使用echo等输出语句,直接打印对象时,调用 echo $zhangsan;那么, 可以指定__tostring()方法的返回值,返回值需要是字符串。9、__call() 调用类中未定义或未公开的方法时,会自动执行__call()方法,自动执行时,会给call方法传递两个参数,调用的方法名,(数组)调用的方法的参数列表。10、__autoload() 这是唯一一个不在类中使用的魔术方法,当实例化一个不存在的类时,自动调用这个魔术方法,可以实现自动加载类文件的功能。11、__sleep() 当执行对象串行化(将对象通过一系列操作,转化为字符串的过程,称为串行化)的时候,会自动执行__sleep()函数, __sleep()函数要求返回一个数组,数组中的值,就是可以串行化的属性, 不在数组中的属性,不能被串行化。12、__wakeup() 当反串行化对象时,自动调用__wakeup()方法,自动调用时,用于给反串行化产生的新对象的属性,进行重新赋值。13、__invoke 当尝试以调用函数的方式调用一个对象时, 会自动调用 __invoke 方法。
PHP 超级全局变量有: $GLOBALS 、$_SERVER 、$_REQUEST 、$_POST、$_GET 、$_FILES、$_ENV、$_COOKIE、$_SESSION。一、$_SERVERPHP_SELF : 当前执行脚本的文件名。SERVER_ADDR : 当前运行脚本所在服务器的IP地址SERVER_NAME : 当前运行脚本所在服务器的主机名。SERVER_PROTOCOL : 请求页面时通信协议的名称和版本。REQUEST_METHOD : 访问页面使用的请求方法。DOCUMENT_ROOT : 当前运行脚本所在的文档根目录,在服务器配置文件中定义。Http_ACCEPT_LANGUAGE : 当前请求头中 Accept-Language: 项的内容(如果存在)。例如,“en”REMOVE_ADDR : 浏览当前页面的用户IP 。SCRIPT_FILENAME : 执行的绝对路径。SCRIPT_NAME : 包含当前脚本的路径REQUEST_URI :URI用来指定要访问的页面PATH_INFO : 包含有客户端提供的,跟真实脚本名称之后并且在查询语句之前的路径信息。例如,当前脚本是通过 URL http://c.biancheng.net/php/path_info.php/some/stuff?foo=bar 被访问的,那么 $_SERVER['PATH_INFO'] 将包含 /some/stuff二 、 $_FILE$_FILE[file][name] : 客户端文件的原名称$_FILE[file][type] : 文件的MIME类型,需要浏览器提供,例如“image/png”$_FILE[file][size] : 文件大小$_FILE[file][tmp_name] : 文件被上传后在服务端储存的临时文件名。
Abstract : 类中的成员方法没有方法体,以();结束。不能实例化,若想使用抽象类,就必须定义一个类并且继承父类和实现抽象方法。
Final:类的使用这个类不可以有子类,即不能被继承。方法的使用表示这个成员的方法不可以在子类中被覆盖,即是不能被重写。
Interface:接口类,接口中只能有常量和抽象方法,子类覆盖父类时用implements关键字,必须将接口中的所有方法全部重写实现。
Trait: 实现多继承的类。
Static:静态类,不可以实例化,调用格式类名::属性名,不让使用$this,可以使用selef::属性名
Public: 外部、继承、自身都可以访问。
Protected:继承、自身都可以访问
Private: 只有自身可以访问
Static: 静态方法。
Var: pulic 的另外一个名称
abs(); # 返回数的绝对值 3.2ceil(); # 向上取整floor(); # 向下取整fmod(5.4, 1.3); # 浮点数取余 0.2max(3, 1, 5, 7); # 最大值 7min(4, 2, 6, 8); # 最小值 2mt_rand(1, 10); # 我这次的随机值为 382819pow(x, y); # 返回 x 的 y 次方 例: pow(2,2); 输出 4pi(); # 获取圆周率值, 返回值精度由 php.ini 中的 precision 指令控制, 3.1415926535898round(); # 浮点数四舍五入sqrt(16); # 返回数的平方根 4
date_default_timezone_set("Asia/Shanghai"); # 设置默认时区, 时区表链接: https://www.php.net/manual/en/timezones.phpdate_default_timezone_get(); # 获取默认时间值time(); # 返回当前的 Unix 时间戳microtime(); # 返回当前 Unix 时间戳的微秒数date($format, $timestamp); # 格式化一个本地时间/日期 例: date("Y-m-d H:i:s", time());getdate($timestamp); # 返回时间戳的时间日期的信息, 格式为关联数组strtotime(); # 将字符串解析为 Unix 时间戳
fopen($filename, $mode, $include_path, $context);$mode 为访问类型, 以下为可能的值“r” (只读方式打开,将文件指针指向文件头)“r+” (读写方式打开,将文件指针指向文件头)“w” (写入方式打开,清除文件内容,如果文件不存在则尝试创建之)“w+” (读写方式打开,清除文件内容,如果文件不存在则尝试创建之)“a” (写入方式打开,将文件指针指向文件末尾进行写入,如果文件不存在则尝试创建之)“a+” (读写方式打开,通过将文件指针指向文件末尾进行写入来保存文件内容)“x” (创建一个新的文件并以写入方式打开,如果文件已存在则返回 FALSE 和一个错误)“x+” (创建一个新的文件并以读写方式打开,如果文件已存在则返回 FALSE 和一个错误)fclose(); # 关闭已打开的文件指针# 文件属性clearstatcache(); # 消除运行结果的缓存file_exists(); # 检查文件或目录是否存在filesize(); # 取得文件大小filectime(); # 获取文件创建时间filemtime(); # 获取文件修改时间fileatime(); # 获取文件上次访问时间is_readable(); # 检查文件是否可读is_writable(); # 检查文件是否可写is_executable(); # 检查文件是否可执行is_file(); # 检查文件是否为常规文件stat(); # 获取文件大部分信息 详情看手册: https://www.php.net/manual/en/function.stat# 文件操作file_get_contents(); # 将整个文件读入一个字符串file_put_contents($file, $data, $mode); # 将一个字符串写入文件fwrite($filename, $string, $length); # 将 $string 写入文件, $length 为最大写入字节数fread($filename, $length); # 读取打开的文件, $length 为最大读取字节数feof(); # 检查文件指针是否为结束位置fgets(); # 从文件的指针中读取一行返回fgetc(); # 从文件的指针中读取单个字符返回file(); # 把文件内容读入一个数组中readfile(); # 读取一个文件,将文件内容写入到输出缓冲中。ftell(); # 返回文件指针当前的位置fseek($file, $offset); # 定位文件指针到某个位置rewind(); # 将文件指针指向文件的开头flock($file, $lock); # 锁定或释放文件# 文件上传下载is_uploaded_file(); # 判断文件是否是通过 HTTP POST 上传move_uploaded_file(); # 将上传的文件移动至新位置
basename($path, $suffix); # 返回路径中的文件名部分, 如果指定 $suffix , 则不显示扩展名dirname(); # 返回路径中的目录部分pathinfo(); # 返回文件路径的信息mkdir(); # 新建目录rmdir(); # 删除目录unlink(); # 删除文件copy($file, $to_file); # 拷贝文件rename($oldname, $newname); # 重命名一个文件或目录opendir(); # 打开目录句柄readdir(); # 从目录句柄中读取条目closedir(); # 关闭目录句柄rewinddir(); # 倒回目录句柄
面向对象强调对象的“抽象”、“封装”、“继承”、“多态”,相比面向过程该思想专注于通过对象的一些方法去解决问题,不同的功能可能由不同的对象来负责解决
面向过程:简称POP,以过程为中心的编程思想,用变量和函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了
封装指一个类可以有一些私有属性和方法,可以将私有属性和方法封装起来,对外只提供一部分接口,通过调用接口可以调用,但是外部并不知道具体属性和方法是什么。
一个类可以通过继承得到另外一个类的非私有属性和方法,这样就会被继承的类属性和方法就可以调用。
同一个父类实例化出来的子对象,通过调用同一个方法,且可以得到不相同的结果,这就是多态。
单例模式:单例模式是最常见的模式之一,在Web应用的开发中,常常用于允许在运行时为某个特定的类创建仅有一个可访问的实例。
class Model{}$model = new model();$model->objetc;
工厂模式:工厂模式是另一种非常常用的模式,正如其名字所示:确实是对象实例的生产工厂。某些意义上,工厂模式提供了通用的方法有助于我们去获取对象,而不需要关心其具体的内在的实现。
interface SystemFactory{ public function createSystem($type);} class MySystemFactory implements SystemFactory{ // 实现工厂方法 public function createSystem($type) { switch ($type) { case 'Mac': return new MacSystem(); case 'Win': return new WinSystem(); case 'linux': return new LinuxSystem(); } }} class System{ }class WinSystem extends System{ }class MacSystem extends System{ }class LinuxSystem extends System{ } //创建我的系统工厂$System_obj = new MySystemFactory();//用我的系统工厂分别创建不同系统对象var_dump($System_obj->createSystem('Mac'));//输出:object(MacSystem)#2 (0) { }var_dump($System_obj->createSystem('Win'));//输出:object(WinSystem)#2 (0) { }var_dump($System_obj->createSystem('Linux'));//输出:object(LinuxSystem)#2 (0) { }
抽象工厂:有些情况下我们需要根据不同的选择逻辑提供不同的构造工厂,而对于多个工厂而言需要一个统一的抽象工厂
class System{}class Soft{} class MacSystem extends System{}class MacSoft extends Soft{} class WinSystem extends System{}class WinSoft extends Soft{} interface AbstractFactory { public function CreateSystem(); public function CreateSoft();} class MacFactory implements AbstractFactory{ public function CreateSystem(){ return new MacSystem(); } public function CreateSoft(){ return new MacSoft(); }} class WinFactory implements AbstractFactory{ public function CreateSystem(){ return new WinSystem(); } public function CreateSoft(){ return new WinSoft(); }}//@test:创建工厂->用该工厂生产对应的对象 //创建MacFactory工厂$MacFactory_obj = new MacFactory();//用MacFactory工厂分别创建不同对象var_dump($MacFactory_obj->CreateSystem());//输出:object(MacSystem)#2 (0) { }var_dump($MacFactory_obj->CreateSoft());// 输出:object(MacSoft)#2 (0) { } //创建WinFactory$WinFactory_obj = new WinFactory();//用WinFactory工厂分别创建不同对象var_dump($WinFactory_obj->CreateSystem());//输出:object(WinSystem)#3 (0) { }var_dump($WinFactory_obj->CreateSoft());//输出:object(WinSoft)#3 (0) { }
适配器模式:这种模式允许使用不同的接口重构某个类,可以允许使用不同的调用方式进行调用。
interface Target { public function sampleMethod1(); public function sampleMethod2();} class Adaptee { public function sampleMethod1() { echo '++++++++'; }} class Adapter implements Target { private $_adaptee; public function __construct(Adaptee $adaptee) { $this->_adaptee = $adaptee; } public function sampleMethod1() { $this->_adaptee->sampleMethod1(); } public function sampleMethod2() { echo '————————'; }}$adapter = new Adapter(new Adaptee());$adapter->sampleMethod1();//输出:++++++++$adapter->sampleMethod2();//输出:———————— interface Target2 { public function sampleMethod1(); public function sampleMethod2();} class Adaptee2 { // 源角色 public function sampleMethod1() {echo '++++++++';}} class Adapter2 extends Adaptee2 implements Target2 { // 适配后角色 public function sampleMethod2() {echo '————————';} } $adapter = new Adapter2();$adapter->sampleMethod1();//输出:++++++++$adapter->sampleMethod2();//输出:————————
Facade(门面模式):门面模式 (Facade)又称外观模式,用于为子系统中的一组接口提供一个一致的界面。门面模式定义了一个高层接口,这个接口使得子系统更加容易使用:引入门面角色之后,用户只需要直接与门面角色交互,用户与子系统之间的复杂关系由门面角色来实现,从而降低了系统的耦。
class Camera { public function turnOn() {} public function turnOff() {} public function rotate($degrees) {}} class Light { public function turnOn() {} public function turnOff() {} public function changeBulb() {}} class Sensor { public function activate() {} public function deactivate() {} public function trigger() {}} class Alarm { public function activate() {} public function deactivate() {} public function ring() {} public function stopRing() {}} class SecurityFacade { private $_camera1, $_camera2; private $_light1, $_light2, $_light3; private $_sensor; private $_alarm; public function __construct() { $this->_camera1 = new Camera(); $this->_camera2 = new Camera(); $this->_light1 = new Light(); $this->_light2 = new Light(); $this->_light3 = new Light(); $this->_sensor = new Sensor(); $this->_alarm = new Alarm(); } public function activate() { $this->_camera1->turnOn(); $this->_camera2->turnOn(); $this->_light1->turnOn(); $this->_light2->turnOn(); $this->_light3->turnOn(); $this->_sensor->activate(); $this->_alarm->activate(); } public function deactivate() { $this->_camera1->turnOff(); $this->_camera2->turnOff(); $this->_light1->turnOff(); $this->_light2->turnOff(); $this->_light3->turnOff(); $this->_sensor->deactivate(); $this->_alarm->deactivate(); }} //client $security = new SecurityFacade();$security->activate();
Strategy(策略模式):策略模式主要为了让客户类能够更好地使用某些算法而不需要知道其具体的实现。
interface Strategy { // 抽象策略角色,以接口实现 public function do_method(); // 算法接口} class ConcreteStrategyA implements Strategy { // 具体策略角色A public function do_method() { echo 'do method A'; }} class ConcreteStrategyB implements Strategy { // 具体策略角色B public function do_method() { echo 'do method B'; }} class ConcreteStrategyC implements Strategy { // 具体策略角色C public function do_method() { echo 'do method C'; }} class Question{ // 环境角色 private $_strategy; public function __construct(Strategy $strategy) { $this->_strategy = $strategy; } public function handle_question() { $this->_strategy->do_method(); }} // client$strategyA = new ConcreteStrategyA();$question = new Question($strategyA);$question->handle_question();//输出do method A $strategyB = new ConcreteStrategyB();$question = new Question($strategyB);$question->handle_question();//输出do method B $strategyC = new ConcreteStrategyC();$question = new Question($strategyC);$question->handle_question();//输出do method C
Observer(观察者模式):某个对象可以被设置为是可观察的,只要通过某种方式允许其他对象注册为观察者。每当被观察的对象改变时,会发送信息给观察者。
interface IObserver{ function onSendMsg( $sender, $args ); function getName(); } interface IObservable{ function addObserver( $observer ); } class UserList implements IObservable{ private $_observers = array(); public function sendMsg( $name ){ foreach( $this->_observers as $obs ){ $obs->onSendMsg( $this, $name ); } } public function addObserver( $observer ){ $this->_observers[]= $observer; } public function removeObserver($observer_name) { foreach($this->_observers as $index => $observer) { if ($observer->getName() === $observer_name) { array_splice($this->_observers, $index, 1); return; } } } } class UserListLogger implements IObserver{ public function onSendMsg( $sender, $args ){ echo( "'$args' send to UserListLogger\n" ); } public function getName(){ return 'UserListLogger'; } } class OtherObserver implements IObserver{ public function onSendMsg( $sender, $args ){ echo( "'$args' send to OtherObserver\n" ); } public function getName(){ return 'OtherObserver'; } } $ul = new UserList();//被观察者 $ul->addObserver( new UserListLogger() );//增加观察者 $ul->addObserver( new OtherObserver() );//增加观察者 $ul->sendMsg( "Jack" );//发送消息到观察者 $ul->removeObserver('UserListLogger');//移除观察者 $ul->sendMsg("hello");//发送消息到观察者
来源地址:https://blog.csdn.net/m0_61420899/article/details/131300415
--结束END--
本文标题: PHP面试题
本文链接: https://lsjlt.com/news/391329.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0