PHP面试题汇总(基础)
文章内容主要参考:https://github.com/ycrao/mynotes
1. echo(),print(),print_r()的区别?
三者均可以输出信息,但是各有自己的特点:
类型 | 输出变量个数 | 输出变量类型 | 返回值 | 速度 | |
---|---|---|---|---|---|
echo | 语言结构 | 一个或多个 | 简单类型变量,如int、string | 无 | 最快 |
语言结构 | 一个 | 简单类型变量,如int、string | int | 快 | |
print_r | 函数 | 一个 | 复杂类型,如数组、对象 | bool | 慢 |
2. 语句include和require的区别是什么?
在失败的时候:
include
产生一个 warning
,而 require
直接产生错误中断;
require
在运行前载入;
include
在运行时载入;
require_once
和 include_once
可以避免重复包含同一文件。
3. php中传值与传引用有啥区别?
&表示传引用;
函数中参数传引用会将参数进行改变;
一般在输出参数有多个的时候可以考虑使用引用。
1 | $num = 10 |
4. 下面哪项没有将john添加到users数组中?
1 | (a) $users[] = 'john'; |
答案为bd,php 里面无 array_add
函数,d项为语法错误的表达。
5. HTTP协议中几个状态码的含义。
1 | 200 OK 客户端请求成功 |
6. 写出一些php魔术方法。
1 | __construct() 实例化类时自动调用。 |
7. MySQL存储引擎 MyISAM 和 InnoDB 的区别
MyISAM | InnoDB | |
---|---|---|
构成上的区别 | 每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。 .frm文件存储表定义。 数据文件的扩展名为.MYD (MYData)。 索引文件的扩展名是.MYI (MYIndex)。 | 基于磁盘的资源是InnoDB表空间数据文件(.frm和它的日志文件(.ibd),InnoDB 表的大小只受限于操作系统文件的大小,一般为 2GB |
事务处理上方面 | MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持 | InnoDB提供事务支持事务,外部键(foreign key)等高级数据库功能 |
SELECT UPDATE,INSERT,Delete操作 | 如果执行大量的SELECT,MyISAM是更好的选择 | 1.如果你的数据执行大量的INSERT**或**UPDATE,出于性能方面的考虑,应该使用InnoDB表 2.DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除。 3.LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,但是对于使用的额外的InnoDB特性(例如外键)的表不适用 |
AUTO_INCREMENT类型的字段 | 在MyISAM表中,可以和其他字段一起建立联合索引 | 对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引 |
表的具体行数 | select count() from table,MyISAM只要简单的读出保存好的行数,注意的是,当count()语句包含 where条件时,两种表的操作是一样的 | InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行 |
锁 | 表锁 | 提供行锁(locking on row level),提供与 Oracle 类型一致的不加锁读取(non-locking read in SELECTs),另外,InnoDB表的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表, 例如update table set num=1 where name like “%aaa%” |
8. 说出一些MySQL优化方法?
1 | a. 设计良好的数据库结构,允许部分数据冗余,尽量避免join查询,提高效率。 |
9. 下面$r的结果是:
1 |
|
A true
B false
答案为A
10. 说下php中empty()和isset()的区别。
Expression | gettype() | empty() | is_null() | isset() | boolean : if($x) |
---|---|---|---|---|---|
$x = “”; | string | TRUE | FALSE | TRUE | FALSE |
$x = null; | NULL | TRUE | TRUE | FALSE | FALSE |
var $x; | NULL | TRUE | TRUE | FALSE | FALSE |
$x is undefined | NULL | TRUE | TRUE | FALSE | FALSE |
$x = array(); | array | TRUE | FALSE | TRUE | FALSE |
$x = array(‘a’, ‘b’); | array | FALSE | FALSE | TRUE | TRUE |
$x = false; | boolean | TRUE | FALSE | TRUE | FALSE |
$x = true; | boolean | FALSE | FALSE | TRUE | TRUE |
$x = 1; | integer | FALSE | FALSE | TRUE | TRUE |
$x = 42; | integer | FALSE | FALSE | TRUE | TRUE |
$x = 0; | integer | TRUE | FALSE | TRUE | FALSE |
$x = -1; | integer | FALSE | FALSE | TRUE | TRUE |
$x = “1”; | string | FALSE | FALSE | TRUE | TRUE |
$x = “0”; | string | TRUE | FALSE | TRUE | FALSE |
$x = “-1”; | string | FALSE | FALSE | TRUE | TRUE |
$x = “php”; | string | FALSE | FALSE | TRUE | TRUE |
$x = “true”; | string | FALSE | FALSE | TRUE | TRUE |
$x = “false”; | string | FALSE | FALSE | TRUE | TRUE |
引用:PHP 类型比较表
isset
用于检测变量是否被设置,使用 isset()
测试一个被设置成 NULL 的变量,将返回 FALSE
。empty
如果 var
是非空或非零的值,则 empty()
返回 FALSE
。换句话说,""、0、"0"、NULL、FALSE、array()、var $var;
以及没有任何属性的对象都将被认为是空的,如果 var
为空,则返回 TRUE
。
如果变量为 0
,则empty()
会返回TRUE
,isset()
会返回TRUE
;
如果变量为空字符串,则empty()
会返回TRUE,isset()
会返回TRUE
;
如果变量未定义,则empty()
会返回TRUE
,isset()
会返回FLASE
。
注意:isset()
只能用于变量,因为传递任何其它参数都将造成解析错误。若想检测常量是否已设置,可使用 defined()
函数。
当要 判断一个变量是否已经声明的时候 可以使用 isset
函数;
当要 判断一个变量是否已经赋予数据且不为空 可以用 empty
函数;
当要 判断 一个变量 存在且不为空 先 isset
函数 再用 empty
函数;
11. cookie和session的区别、cookie禁用后session还可以用吗?
工作流程:
以下以PHP为例:
- 你第一次访问网站时,
- 服务端脚本中开启了Session
session_start();
, - 服务器会生成一个不重复的 SESSIONID 的文件
session_id();
,比如在/var/lib/php/session
目录 - 并将返回(Response)如下的HTTP头
Set-Cookie:PHPSESSIONID=xxxxxxx
- 客户端接收到
Set-Cookie
的头,将PHPSESSIONID
写入cookie - 当你第二次访问页面时,所有Cookie会附带的请求头(Request)发送给服务器端
- 服务器识别
PHPSESSIONID
这个cookie,然后去session目录查找对应session文件, - 找到这个session文件后,检查是否过期,如果没有过期,去读取Session文件中的配置;如果已经过期,清空其中的配置
区别:
1、cookie就是服务器发放给客户端的一些标识,保存在客户端,让客户端每次请求的时候带上,以区分不同的用户;
2、session是服务器存放在自己那里的用户相关的数据,用每次用户带来的cookie去提取出来,恢复一个之前访问的历史或者相关环境。
3、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗 考虑到安全应当使用session。
4、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE。
5、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie
参考:
- https://segmentfault.com/q/1010000007715137
- http://blog.csdn.net/baidu_31337243/article/details/48954445
12. 说出常用的10个数组方法
in_array(判断数组中是否有某个元素)var_dump(in_array(0, array(false, 1))) //true
implode(将数组按照一定规律分解)
json_encode(将数组转化成json)
sort(排序,有很多排序的函数这里就说一个)
array_push(将一个活多个单元压入数组的末尾)
array_merge(合并数组)
array_key_exists(检查键名是否存在于数组中)
array_unique(去除数组中重复的值,只能对一位数组起作用)
array_shift(移除数组中第一个单元)
13. 说出平时常用的操作字符串的方法,并解决具体问题
substr(截取字符串)
strlen(获取字符串长度)
strpos(查找字符串首次出现的位置)
str_replace(字符串替换)
explode(字符串拆分转数组)
implode(数组拼接转字符串)
strtoupper(将所有字母变成大写)
strtolower
ucfirst(将字符串的首字母变成大写)
ucwords(将字符串中每个单词的首字母变成大写)
strrev(反转字符串,其实不是很常用)
substr_replace(替换字符串的子串,注意与str_replace的区别)
strip_tags(去除html和php标记,可以选择保留想要的标签)
trim(去除空格)
14. 正则表达式
贪婪模式与非贪婪模式
默认情况下,正则表达式会采用贪婪模式,使用?或U修饰符可以实现非贪婪模式。
比如a后面有多个b,”abbbbbbbb”。默认/a.+/则会匹配到最后一个b,
1 |
|
运行结果:1
2
3
4
5
6
7
8
9
10int(1)
array(1) {
[0]=>
string(10) "abbbbbbbbb"
}
int(1)
array(1) {
[0]=>
string(2) "ab"
}
preg_match和preg_match_all区别
用法都是相同的:func($pattern, $subject, &$matches, $flags, $offset)
返回值:正确匹配返回1,否则返回0
不同:preg_match会使用$pattern对subject进行一次匹配,subject有多个子串也满足$pattern,matches也只会返回第一个子组的所有匹配结果,
preg_match_all则会执行全局正则表达式匹配。1
2
3
4
5
6
7
$pattern = "|<[^>]+>(.*)</[^>]+>|U";
$subject = "<b>example: </b><div align=left>this is a test</div>";
preg_match($pattern, $subject, $matches);
var_dump($matches);
preg_match_all($pattern, $subject, $matches);
var_dump($matches);
运行结果:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23array(2) {//第一组
[0]=>
string(16) "<b>example: </b>"
[1]=>
string(9) "example: "
}
array(2) {
[0]=>
array(2) {//全局完全匹配
[0]=>
string(16) "<b>example: </b>"
[1]=>
string(36) "<div align=left>this is a test</div>"
}
[1]=>
array(2) {
[0]=>
string(9) "example: "//匹配的子组
[1]=>
string(14) "this is a test"//匹配的子组
}
}
常用正则表达式
1 | 网址(URL) [a-zA-z]+://[^\s]* |
参考
15. php自动加载方法
尝试加载未定义的类
__autoload方法
PHP7.2.0以后会丢弃1
2
3
4
5
6$db = new DB();
function __autoload($className)
{
echo $className;
exit();
}
spl_autoload_register
小的项目用autoload自动加载还可以,一个项目中只能用一个autoload方法。大的项目就需要使用spl_autoload_register指定函数进行自动加载的操作了。spl_autoload_register — 注册给定的函数作为 __autoload 的实现
普通方法
1
2
3
4
5
6
7 function load1($className)
{
echo 1;
require $className . '.php';
}
spl_autoload_register('load1'); //将load1函数注册到自动加载队列中。
$db = new DB(); //找不到DB类,就会自动去调用刚注册的load1函数了
类的静态方法1
2
3
4
5
6
7
8
9
10
11class autoloading{
//必须是静态方法,不然报错
public static function load($className)
{
require $className . '.php';
}
}
//2种方法都可以
spl_autoload_register(array('autoloading','load'));
spl_autoload_register('autoloading::load');
$db = new DB(); //会自动找到