2019年PHP面试题整理

    xiaoxiao2022-07-02  104

    这段时间在面试php开发岗位,现在有时间就来整理一些我遇到的一些面试题目。

    一、MYSQL索引

    1.索引的类型 答:MySQL目前主要有以下几种索引类型: 1)普通索引(INDEX); 2)唯一索引(UNIQUE INDEX); 3)全文索引(FULLTEXT)(全文索引是MyISAM的一个特殊索引类型,主要用于全文检索); 4)单列索引、多列索引; 5)组合索引(最左前缀)。

    2.唯一索引和主键索引区别 答:1)主键为一种约束,唯一索引为一种索引,本质上就不同; 2)主键创建后一定包含唯一性索引,而唯一索引不一定就是主键; 3)主键不允许空值,唯一索引可以为空; 4)主键可以被其他表引用,而唯一索引不可以; 5)主键只允许一个,唯一索引允许多个; 6)主键和索引都是键,主键是逻辑键,索引为物理键,即主键不实际存在。

    3.索引失效 答:1)最佳左前缀原则(组合索引,不按索引定义时制定的顺序,最左优先); 2)like模糊查询时,以%开头,导致索引失效; 3)使用“!=”和“<>”都会使索引失效,如果是主键或者索引列是整数,索引不会失效; 4)遇到null值,索引失效; 5)索引列上的显式或者隐式运算,导致索引失效; 6)如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引(如select * from USER where name=123;); 7)用or连接导致索引失效(or条件有未建立索引的列导致索引失效)。

    4.索引的坏处 答:1)创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加; 2)索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间。如果要建立聚簇索引,那么需要的空间就会更大; 3)当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。

    5.索引的方法 答:主要有以下几种索引方法:B-Tree,Hash,R-Tree。 1)B-Tree: B-Tree是最常见的索引类型,所有值(被索引的列)都是排过序的,每个叶节点到跟节点距离相等。所以B-Tree适合用来查找某一范围内的数据,而且可以直接支持数据排序(ORDER BY)B-Tree在MyISAM里的形式和Innodb稍有不同: MyISAM表数据文件和索引文件是分离的,索引文件仅保存数据记录的磁盘地址, InnoDB表数据文件本身就是主索引,叶节点data域保存了完整的数据记录。 2)Hash索引: a.仅支持"=",“IN"和”<=>"精确查询,不能使用范围查询: 由于Hash索引比较的是进行Hash运算之后的Hash值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的Hash算法处理之后的Hash; b.不支持排序: 由于Hash索引中存放的是经过Hash计算之后的Hash值,而且Hash值的大小关系并不一定和Hash运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算; c.在任何时候都不能避免表扫描: 由于Hash索引比较的是进行Hash运算之后的Hash值,所以即使取满足某个Hash键值的数据的记录条数,也无法从Hash索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果; d.检索效率高,索引的检索可以一次定位,不像B-Tree索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以Hash索引的查询效率要远高于B-Tree索引; e.只有Memory引擎支持显式的Hash索引,但是它的Hash是nonunique的,冲突太多时也会影响查找性能。Memory引擎默认的索引类型即是Hash索引,虽然它也支持B-Tree索引。 3)R-Tree索引: R-Tree在MySQL很少使用,仅支持geometry数据类型,支持该类型的存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种。

    二、TP5和Laravel框架的区别

    答:thinkPHP更适合国人的编码习惯,主要区别为: 1.渲染模版方式的不同,在Laravel框架里,使用return view()来渲染模版,而ThinkPHP里则使用了$this->display()的方式渲染模版; 2.在Laravel框架里,由于其考虑到了跨站请求伪造, 所以如果使用form表单以post方式进行传值时,如果不再form表单中加入{{csrf_field()}}则会报出TokenMethodnotfound的语法错误;而TP框架则需要自己手动完成防止跨站攻击的代码; 3.Laravel是一个重路由的框架(5.4),所有的功能都是由路由发起的,哪怕没有控制器方法,只要写了路由就能够访问,thinkPHP(3.2),必须要有控制器方法才能正常访问; 4.laravel具有强大的社区化扩展,(composer扩展自动加载); 5.laravel具有强大的Blade模版引擎; 6.中间件,Laravel特点,可以实现访问前后的处理,例如请求和返回,权限认证等; 7.条件判断语句书写方式的差异: Laravel框架里 if else判断语句和foreach语句 书写时必须以@if开头、 以@endif结尾,如果没有则报语法错误,@foreach、@endforeach同理(前端模板里面); 而TP框架则和PHP语法规则使用方式一致直接if else语句判断和foreach循环遍历。

    三、PHP中有哪些魔术方法

    答:PHP 将所有以 __(两个下划线)开头的类方法保留为魔术方法。所以在定义类方法时,除了上述魔术方法,建议不要以 __ 为前缀。 1).__construct(),类的构造函数。 1.1: 作用: 通常构造方法被用来执行一些有用的初始化任务,如对成员属性在创建对象时赋予初始值。 1.2: 声明格式:

    function __constrct([参数列表]){ 方法体 //通常用来对成员属性进行初始化赋值 }

    2.__destruct(),类的析构函数。 2.1:作用:析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。析构函数在脚本关闭时调用,此时所有的 HTTP 头信息已经发出。脚本关闭时的工作目录有可能和在 SAPI(如 apache)中时不同。 3.__call(),在对象中调用一个不可访问方法时调用。 3.1:作用:为了避免当调用的方法不存在时产生错误,而意外的导致程序中止,可以使用 __call() 方法来避免; 3.2:格式:

    function __call(string $function_name, array $arguments) { // 方法体 }

    4.__callStatic(),用静态方式中调用一个不可访问方法时调用,与__call类似。 5.__get(),获得一个类的成员变量时调用。 6.__set(),设置一个类的成员变量时调用。 7.__isset(),当对不可访问属性调用isset()或empty()时调用。 8.__unset(),当对不可访问属性调用unset()时被调用。 9.__sleep(),执行serialize()时,先会调用这个函数。 10.__wakeup(),执行unserialize()时,先会调用这个函数。 11.__toString(),类被当成字符串时的回应方法。 12.__invoke(),调用函数的方式调用一个对象时的回应方法。 13.__set_state(),调用var_export()导出类时,此静态方法会被调用。 14.__clone(),当对象复制完成时调用。 15.__autoload(),尝试加载未定义的类。 16.__debugInfo(),打印所需调试信息。

    四、session和cookie区别

    答:1.cookie数据存放在客户的浏览器上,session数据放在服务器上。 2.cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗 考虑到安全应当使用session。 3.session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能 ,考虑到减轻服务器性*能方面,应当使用COOKIE。 4. 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。 5.所以建议: 将登陆信息等重要信息存放为SESSION 其他信息如果需要保留,可以放在COOKIE中。

    五、排序算法

    1.面试问到快速排序,讲的不是很清楚,自己回来整理运行下。

    <?php //从小到大排序|快速排序 function quick_sort($arr){ if(count($arr)<=0){ return $arr; } $middle=$arr[0]; $rightArr=$leftArr=array(); for($i=1;$i<count($arr);$i++){ if($arr[$i]>$middle){ $rightArr[]=$arr[$i]; }else{ $leftArr[]=$arr[$i]; } } $left=quick_sort($leftArr); $right=quick_sort($rightArr); return array_merge($left,array($middle),$right); } $arr=array(12,78,1,3,6,79,45,41,0,12,78); $arr=quick_sort($arr); print_r($arr); ?>

    六、函数相关

    1.array+array 与 array_merge的区别 答:两种方式都是进行数组的合并,但合并结果会有不同: 1)键名为数字时: “+” 会保留最先出现的那个值; array_merge() 会附加到后面; 2)键名为字符时: “+”会保留最先出现的那个值; array_merge()会覆盖掉前面相同的键名的值。

    2.数组函数 答: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_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_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 — 计算数组中的单元数目,或对象中的属性个数 current — 返回数组中的当前单元 each — 返回数组中当前的键/值对并将数组指针向前移动一步 end — 将数组的内部指针指向最后一个单元 extract — 从数组中将变量导入到当前的符号表 in_array — 检查数组中是否存在某个值 key_exists — 别名 array_key_exists key — 从关联数组中取得键名 krsort — 对数组按照键名逆向排序 ksort — 对数组按照键名排序 list — 把数组中的值赋给一组变量 natcasesort — 用“自然排序”算法对数组进行不区分大小写字母的排序 natsort — 用“自然排序”算法对数组排序 next — 将数组中的内部指针向前移动一位 pos — current 的别名 prev — 将数组的内部指针倒回一位 range — 根据范围创建数组,包含指定的元素 reset — 将数组的内部指针指向第一个单元 rsort — 对数组逆向排序 shuffle — 打乱数组 sizeof — count 的别名 sort — 对数组排序 uasort — 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联 uksort — 使用用户自定义的比较函数对数组中的键名进行排序 usort — 使用用户自定义的比较函数对数组中的值进行排序

    3.字符串函数 答:addcslashes — 以 C 语言风格使用反斜线转义字符串中的字符

    addcslashes ( string $str , string $charlist ) : string 返回字符串,该字符串在属于参数 charlist 列表中的字符前都加上了反斜线。

    addslashes — 使用反斜线引用字符串

    返回字符串,该字符串为了数据库查询语句等的需要在某些字符前加上了反斜线。这些字符是单引号(')、双引号(")、反斜线(\)与 NUL(NULL 字符)。

    bin2hex — 函数把包含数据的二进制字符串转换为十六进制值 chop — rtrim 的别名 chr — 返回指定的字符 chunk_split — 将字符串分割成小块 convert_cyr_string — 将字符由一种 Cyrillic 字符转换成另一种 convert_uudecode — 解码一个 uuencode 编码的字符串 convert_uuencode — 使用 uuencode 编码一个字符串 count_chars — 返回字符串所用字符的信息 crc32 — 计算一个字符串的 crc32 多项式 crypt — 单向字符串散列 echo — 输出一个或多个字符串 explode — 使用一个字符串分割另一个字符串 fprintf — 将格式化后的字符串写入到流 get_html_translation_table — 返回使用 htmlspecialchars 和 htmlentities 后的转换表 hebrev — 将逻辑顺序希伯来文(logical-Hebrew)转换为视觉顺序希伯来文(visual-Hebrew) hebrevc — 将逻辑顺序希伯来文(logical-Hebrew)转换为视觉顺序希伯来文(visual-Hebrew),并且转换换行符 hex2bin — 转换十六进制字符串为二进制字符串 html_entity_decode — Convert HTML entities to their corresponding characters htmlentities — 将字符转换为 HTML 转义字符 htmlspecialchars_decode — 将特殊的 HTML 实体转换回普通字符 htmlspecialchars — 将特殊字符转换为 HTML 实体 implode — 将一个一维数组的值转化为字符串 join — 别名 implode lcfirst — 使一个字符串的第一个字符小写 levenshtein — 计算两个字符串之间的编辑距离 localeconv — Get numeric formatting information ltrim — 删除字符串开头的空白字符(或其他字符) md5_file — 计算指定文件的 MD5 散列值 md5 — 计算字符串的 MD5 散列值 metaphone — Calculate the metaphone key of a string money_format — 将数字格式化成货币字符串 nl_langinfo — Query language and locale information nl2br — 在字符串所有新行之前插入 HTML 换行标记 number_format — 以千位分隔符方式格式化一个数字 ord — 转换字符串第一个字节为 0-255 之间的值 parse_str — 将字符串解析成多个变量 print — 输出字符串 printf — 输出格式化字符串 quoted_printable_decode — 将 quoted-printable 字符串转换为 8-bit 字符串 quoted_printable_encode — 将 8-bit 字符串转换成 quoted-printable 字符串 quotemeta — 转义元字符集 rtrim — 删除字符串末端的空白字符(或者其他字符) setlocale — 设置地区信息 sha1_file — 计算文件的 sha1 散列值 sha1 — 计算字符串的 sha1 散列值 similar_text — 计算两个字符串的相似度 soundex — Calculate the soundex key of a string sprintf — Return a formatted string sscanf — 根据指定格式解析输入的字符 str_getcsv — 解析 CSV 字符串为一个数组 str_ireplace — str_replace 的忽略大小写版本 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 转义的字符串 stripos — 查找字符串首次出现的位置(不区分大小写) stripslashes — 反引用一个引用字符串 stristr — strstr 函数的忽略大小写版本 strlen — 获取字符串长度 strnatcasecmp — 使用“自然顺序”算法比较字符串(不区分大小写) strnatcmp — 使用自然排序算法比较字符串 strncasecmp — 二进制安全比较字符串开头的若干个字符(不区分大小写) strncmp — 二进制安全比较字符串开头的若干个字符 strpbrk — 在字符串中查找一组字符的任何一个字符 strpos — 查找字符串首次出现的位置 strrchr — 查找指定字符在字符串中的最后一次出现 strrev — 反转字符串 strripos — 计算指定字符串在目标字符串中最后一次出现的位置(不区分大小写) strrpos — 计算指定字符串在目标字符串中最后一次出现的位置 strspn — 计算字符串中全部字符都存在于指定字符集合中的第一段子串的长度。 strstr — 查找字符串的首次出现 strtok — 标记分割字符串 strtolower — 将字符串转化为小写 strtoupper — 将字符串转化为大写 strtr — 转换指定字符 substr_compare — 二进制安全比较字符串(从偏移位置比较指定长度) substr_count — 计算字串出现的次数 substr_replace — 替换字符串的子串 substr — 返回字符串的子串 trim — 去除字符串首尾处的空白字符(或者其他字符) ucfirst — 将字符串的首字母转换为大写 ucwords — 将字符串中每个单词的首字母转换为大写 vfprintf — 将格式化字符串写入流 vprintf — 输出格式化字符串 vsprintf — 返回格式化字符串 wordwrap — 打断字符串为指定数量的字串

    4.多字节字符串 答:mb_check_encoding — 检查字符串在指定的编码里是否有效 mb_chr — Get a specific character mb_convert_case — 对字符串进行大小写转换 mb_convert_encoding — 转换字符的编码 mb_convert_kana — Convert “kana” one from another (“zen-kaku”, “han-kaku” and more) mb_convert_variables — 转换一个或多个变量的字符编码 mb_decode_mimeheader — 解码 MIME 头字段中的字符串 mb_decode_numericentity — 根据 HTML 数字字符串解码成字符 mb_detect_encoding — 检测字符的编码 mb_detect_order — 设置/获取 字符编码的检测顺序 mb_encode_mimeheader — 为 MIME 头编码字符串 mb_encode_numericentity — Encode character to HTML numeric string reference mb_encoding_aliases — Get aliases of a known encoding type mb_ereg_match — Regular expression match for multibyte string mb_ereg_replace_callback — Perform a regular expression search and replace with multibyte support using a callback mb_ereg_replace — Replace regular expression with multibyte support mb_ereg_search_getpos — Returns start point for next regular expression match mb_ereg_search_getregs — Retrieve the result from the last multibyte regular expression match mb_ereg_search_init — Setup string and regular expression for a multibyte regular expression match mb_ereg_search_pos — Returns position and length of a matched part of the multibyte regular expression for a predefined multibyte string mb_ereg_search_regs — Returns the matched part of a multibyte regular expression mb_ereg_search_setpos — Set start point of next regular expression match mb_ereg_search — Multibyte regular expression match for predefined multibyte string mb_ereg — Regular expression match with multibyte support mb_eregi_replace — Replace regular expression with multibyte support ignoring case mb_eregi — Regular expression match ignoring case with multibyte support mb_get_info — 获取 mbstring 的内部设置 mb_http_input — 检测 HTTP 输入字符编码 mb_http_output — 设置/获取 HTTP 输出字符编码 mb_internal_encoding — 设置/获取内部字符编码 mb_language — 设置/获取当前的语言 mb_list_encodings — 返回所有支持编码的数组 mb_ord — Get code point of character mb_output_handler — 在输出缓冲中转换字符编码的回调函数 mb_parse_str — 解析 GET/POST/COOKIE 数据并设置全局变量 mb_preferred_mime_name — 获取 MIME 字符串 mb_regex_encoding — Set/Get character encoding for multibyte regex mb_regex_set_options — Set/Get the default options for mbregex functions mb_scrub — Description mb_send_mail — 发送编码过的邮件 mb_split — 使用正则表达式分割多字节字符串 mb_strcut — 获取字符的一部分 mb_strimwidth — 获取按指定宽度截断的字符串 mb_stripos — 大小写不敏感地查找字符串在另一个字符串中首次出现的位置 mb_stristr — 大小写不敏感地查找字符串在另一个字符串里的首次出现 mb_strlen — 获取字符串的长度 mb_strpos — 查找字符串在另一个字符串中首次出现的位置 mb_strrchr — 查找指定字符在另一个字符串中最后一次的出现 mb_strrichr — 大小写不敏感地查找指定字符在另一个字符串中最后一次的出现 mb_strripos — 大小写不敏感地在字符串中查找一个字符串最后出现的位置 mb_strrpos — 查找字符串在一个字符串中最后出现的位置 mb_strstr — 查找字符串在另一个字符串里的首次出现 mb_strtolower — 使字符串小写 mb_strtoupper — 使字符串大写 mb_strwidth — 返回字符串的宽度 mb_substitute_character — 设置/获取替代字符 mb_substr_count — 统计字符串出现的次数 mb_substr — 获取部分字符串

    5.对二维数组进行排序 答:array_multisort() 可以用来一次对多个数组进行排序,或者根据某一维或多维对多维数组进行排序。 如下例子,根据字段last_name对数组$data进行降序排列: 例1:

    $last_names = array_column($data,'last_name'); array_multisort($last_names,SORT_DESC,$data);

    例2:

    $ar = array( array("10", 11, 100, 100, "a"), array( 1, 2, "2", 3, 1) ); array_multisort($ar[0], SORT_ASC, SORT_STRING, $ar[1], SORT_NUMERIC, SORT_DESC);

    本例中在排序后,第一个数组将变成 “10”,100,100,11,“a”(被当作字符串以升序排列)。第二个数组将包含 1, 3, “2”, 2, 1(被当作数字以降序排列)。

    最新回复(0)