PHP面试题(持续更新)

逻辑题

1.字符串”\r”,”\n”,”\t”,”\x20”分别代表什么

答案: \r 回车符  \n 换行符 \t跳格 \x20 16进制的32



2.以下语句输出的结果是什么

echo "$a",'$a',"\\\$a","${a}","$a"."$a","$a"+"$a";

答案:$a(3) '$a'($a) "\\\$a"(“\\”转义成“\”,“\$a”转义成“$a”,\$a) ${a}(3) "$a"(3) "."$a(3) "$a"+"$a"(6) 

结果:3$a\$a3336\$a



3.以下语句输出的结果是什么

setcookie("a","value");
print $_COOKIE['a'];

答案:(若只是这两段编码运行,则会提示PHP Notice: Undefined index: a)


4.php中将当前页面重定向到另一个页面怎么写?

答案:header("Location: 页面url");


5.什么是魔术引号(magic_quotes_gpc)

答案:魔术引号(Magic Quotes)是一个自动将进入 PHP 脚本的数据进行转义的过程。提示:最好在编码时不要转义而在运行时根据需要而转义,与addslashes()函数类似。


6.在类的方法中,如何调用其父类的同名方法? 

答案:parent::方法名


7.php中如何取得get,post参数,和上传的文件

答案:$_GET;$_POST;$_FILES


8.如何取得客户端的ip(要求取得一个int)

答案:$_SERVER["REMOTE_ADDR"] 再使用ip2long()函数转化为int类型(11位)。


9.include和require的区别

答案:include和require都是把一个页面引入当前页面,区别在于require的页面出现错误的时候,会终止退出,程序将不再执行。而include会提示错误,程序将继续执行。


10.extends的作用是什么 

答案:类的继承。


11.@test()和&test()的区别

答案:@屏蔽test()函数在执行中的警告提示;&test()引用test()函数。



12.array+array与array_merge()的区别 

答案:二者之间的区别是: 
1 键名为数字时,array_merge()不会覆盖掉原来的值,但+合并数组则会把最先出现的值作为最终结果返回,而把后面的数组拥有相同键名的那些值“抛弃”掉(不是覆盖) 
2 键名为字符时,+仍然把最先出现的值作为最终结果返回,而把后面的数组拥有相同键名的那些值“抛弃”掉,但array_merge()此时会覆盖掉前面相同键名的值

例子:$a = array(1,2,3,8); $b = array(1,3,5,6,7);

var_dump($a+$b); 返回结果array(0=>1,1=>2,2=>3,3=>8,4=>7);

var_dump(array_merge($a,$b)); 返回结果array(0=>1,1=>2,2=>3,3=>8,4=>1,5=>3,6=>5,7=>6,8=>7);



13.请列举最少3个php对象的魔术方法和说明它们的用途 

答案:
__construct() 构造方法 
__destruct() 析构方法 
__get() 控制私有的受保护的未定义的成员属性的访问 
__set() 对私有的受保护的未定义的成员属性进行赋值控制 
__isset() 对私有的受保护的未定义成员属性进行isset和empty的判断控制



14.什么是fpm(Linux维护问题)

答案:FastCGI Process Manager:FastCGI进程管理器



15.echo intval(0.58*100) 输出的结果是57,试分析这是为什么? 

答案:原因就是浮点数精度的问题。 
简单的十进制分数如同 0.1 或 0.7 不能在不丢失一点点精度的情况下转换为内部二进制的格式。这就会造成混乱的结果:例如,floor((0.1+0.7)*10) 通常会返回 7 而不是预期中的 8,因为该结果内部的表示其实是类似 7.9999999999…。这和一个事实有关,那就是不可能精确的用有限位数表达某些十进制分数。例如,十进制的 1/3 变成了 0.3333333…。所以永远不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等。如果确实需要更高的精度,应该使用任意精度数学函数或者 gmp 函数


概念题

1.PHP是什么

答案:PHP全称:Hypertext Preprocessor,是一种用来开发动态网站的服务器脚本语言。


2.什么是MVC?

答案:

MVC由Model(模型), View(视图)和Controller(控制器)组成,PHP MVC可以更高效地管理好3个不同层的PHP代码。

Model:数据信息存取层。

View:view层负责将应用的数据以特定的方式展现在界面上。

Controller:通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。


3.在页面中引用CSS有几种方式?(前端问题)

答案:在页面中使用CSS有3中方式:引用外部CSS文件;内部定义Style样式内联样式


4.优化MYSQL数据库的方法

答案:

语句方面:
1 使用索引,增加查询效率
2 优化查询语句,提高索引命中率
数据库涉及方面:
1 构造分库分表,提高数据库的存储和扩展能力
2 根据需要使用不同的存储引擎

5.描述一下php开发中常见的几种攻击以及解决方案 

答案:SQL注入: 
解决这个问题的办法是,将 PHP 的内置 mysql_real_escape_string() 函数用作任何用户输入的包装器。这个函数对字符串中的字符进行转义,使字符串不可能传递撇号等特殊字符并让 MySQL 根据特殊字符进行操作。 
跨站点脚本攻击(XSS): 
strip_tags() 函数,这个函数可以清除任何包围在 HTML 标记中的内容 
或者使用htmlspecialchars() 函数。


6.PHP里面是区分大小写的吗?

答案:

PHP对于系统函数、用户自定义函数、类名称等是不区分大小写的

PHP中的变量和常量是区分大小写的

对于文件名又因服务器操作系统而定,linux中区分,Win不区分


7.$_POST,$HTTP_RAW_POST_DATA 和 php://input 的区别?

答案:

$_POST:

是获取表单POST过来数据,MIME类型是“application/x-www-form-urlencoded”。可参考《什么是 MIME TYPE?

意思就是字段名和值都编码了,每个 key-value 对使用 ‘&’ 字符分隔开,key 和 value 使用 ‘=’ 分开,其他特殊字符都会被使用 urlencode 方式进行编码。

$HTTP_RAW_POST_DATA:

可以获取原始的POST数据,但需要在 php.ini 中设置开启,并且不支持 enctype="multipart/form-data"方式传递的数据

php://input:

可以获取原始的 POST 数据,并且比$HTTP_RAW_POST_DATA更少消耗内存,也不支持"multipart/form-data",

可以使用 file_get_contents() 函数去获取它的内容



8.没有通过static定义的方法,能否通过”对象名::方法名“这样的形式来调用?

答案:不能。会产生一个strict错误,但在会继续执行代码。参考《PHP静态调用非静态方法》。这篇文章里面还讲到了一个概念“calling scope”。静态调用并不是说有::就是静态调用,而是看calling scope。$this指针指向的对象就是这个方法被调用时刻的calling scope。



9.请介绍Session的原理

答案:

因为HTTP是无状态的,所以一次请求完成后客户端和服务端就不再有任何关系了,谁也不认识谁。

但由于一些需要(如保持登录状态等),必须让服务端和客户端保持联系,session ID就成了这种联系的媒介了。

当用户第一次访问站点时,PHP会用session_start()函数为用户创建一个session ID,这就是针对这个用户的唯一标识,

每一个访问的用户都会得到一个自己独有的session ID,这个session ID会存放在响应头里的cookie中,之后发送给客户端。

这样客户端就会拥有一个该站点给他的session ID。

当用户第二次访问该站点时,浏览器会带着本地存放的cookie(里面存有上次得到的session ID)随着请求一起发送到服务器,

服务端接到请求后会检测是否有session ID,如果有就会找到响应的session文件,把其中的信息读取出来;如果没有就跟第一次一样再创建个新的。

参考《Session原理简述



10.没有通过static定义的方法,能否通过”对象名::方法名“这样的形式来调用?

答案:不能。会产生一个strict错误,但在会继续执行代码。参考《PHP静态调用非静态方法》。这篇文章里面还讲到了一个概念“calling scope”。静态调用并不是说有::就是静态调用,而是看calling scope。$this指针指向的对象就是这个方法被调用时刻的calling scope。


11.对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题

答案:

a. 确认服务器是否能支撑当前访问量。

b. 优化数据库访问。(参考3.5)

c. 禁止外部访问链接(盗链), 比如图片盗链。

d. 控制文件下载。

e. 使用不同主机分流。

f. 使用浏览统计软件,了解访问量,有针对性的进行优化。



12.请介绍Session的原理

答案:

因为HTTP是无状态的,所以一次请求完成后客户端和服务端就不再有任何关系了,谁也不认识谁。

但由于一些需要(如保持登录状态等),必须让服务端和客户端保持联系,session ID就成了这种联系的媒介了。

当用户第一次访问站点时,PHP会用session_start()函数为用户创建一个session ID,这就是针对这个用户的唯一标识,

每一个访问的用户都会得到一个自己独有的session ID,这个session ID会存放在响应头里的cookie中,之后发送给客户端。

这样客户端就会拥有一个该站点给他的session ID。

当用户第二次访问该站点时,浏览器会带着本地存放的cookie(里面存有上次得到的session ID)随着请求一起发送到服务器,

服务端接到请求后会检测是否有session ID,如果有就会找到响应的session文件,把其中的信息读取出来;如果没有就跟第一次一样再创建个新的。

参考《Session原理简述


13.session共享问题解决方案

答案:

a. 客户端Cookie保存,以cookie加密的方式保存在客户端,每次session信息被写在客户端,然后经浏览器再次提交到服务器。

b. 服务器间Session同步,使用主-从服务器的架构,当用户在主服务器上登录后,通过脚本或者守护进程的方式,将session信息传递到各个从服务器中

c. 使用集群统一管理Session,当应用系统需要session信息的时候直接到session群集服务器上读取,目前大多都是使用Memcache来对Session进行存储。

d. 把Session持久化到数据库,目前采用这种方案时所使用的数据库一般为mysql。

参考《Session共享实现方案调研



14.测试php性能性能的工具,和找出瓶颈的方法。

答案:

XHProf(windows安装方法参照这里)是一个分层PHP性能分析工具。它报告函数级别的请求次数和各种指标,包

括阻塞时间,CPU时间和内存使用情况。

它有一个简单的HTML的用户界面,基于浏览器的性能分析用户界面能更容易查看,也能绘制调用关系图。参数值

查看



15.介绍一下常见的SSO(单点登陆)的原理。

答案:SSO是一种统一认证和授权机制,通过一个应用中的安全验证后,再访问其他应用中的受保护资源时,不再需要重新登录验证。

解决了用户只需要登录一次就可以访问所有相互信任的应用系统,而不用重复登录。

统一的认证系统是SSO的前提之一。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;

认证成功后,认证系统应该生成统一的认证标志(ticket),返还给用户。另外,认证系统还应该对ticket进行效验,判断其有效性。

参考《单点登录SSO


16.禁掉cookie的session使用方案

答案:

a. 通过 url 传值,把session id附加到url上(缺点:整个站点中不能有纯静态页面,因为纯静态页面session id 将无法继续传到下一页面)

b. 通过隐藏表单,把session id 放到表单的隐藏文本框中同表单一块提交过去(缺点:不适用<a>标签这种直接跳转的非表单的情况)

c. 直接配置php.ini文件,将php.ini文件里的session.use_trans_sid= 0设为1(好像在win上不支持)

d. 用文件、数据库等形式保存Session ID,在跨页过程中手动调用


17.PHP缓存技术有哪些? 

答案:

1. 全页面静态化缓存:也就是将页面全部生成html静态页面,用户访问时直接访问的静态页面,而不会去走php服务器解析的流程

2. 页面部分缓存:将一个页面中不经常变的部分进行静态缓存,而经常变化的块不缓存,最后组装在一起显示

3. 数据缓存:通过一个id进行请求的数据,将数据缓存到一个php文件中,id和文件是对应的,下次通过这个id进行请求时直接读php文件

4. 查询缓存:和数据缓存差不多,根据查询语句进行缓存;

5. 内存式缓存:redis和memcache

参考《PHP中9大缓存技术总结



18.JSON格式数据有哪些特点

答案:

a. JSON一种轻量级的数据交换格式。它基于ECMAScript的一个子集。

b. JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)

c. 这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成(网络传输速率)。

d. "名称/值"对的集合,不同语言中,它被理解为对象(object),记录(record),结构(struct),字典(dictionary),哈希表(hash table),键列表(keyed list)等

e. 值的有序列表,多数语言中被理解为数组(array)

参考《介绍JSON


19.HTTP协议header头域包含哪些
答案:

(1)通用头域
  通用头域包含请求和响应消息都支持的头域,通用头域包含Cache-Control、Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via。对通用头域的扩展要求通讯双方都支持此扩展,如果存在不支持的通用头域,一般将会作为实体头域处理。下面简单介绍几个在UPnP消息中使用的通用头域。

(2)Cache-Control头域

(3)Date头域

(4)Pragma头域

(5)请求消息

(6)Host头域

(7)Referer头域

(8)Range头域

(9)User-Agent头域

(10)Location响应头

(11)Server响应头

(12)实体

(13)Content-Type实体头

(14)Content-Range实体头

(15)Last-modified实体头

详细了解header http://www.cnblogs.com/petitprince/archive/2008/09/12/1289854.html


操作题

1.写一个排序算法,可以是冒泡排序或者是快速排序,假设待排序对象是一个维数组。(提示:不能使用系统已有函数,另外请仔细回忆以前学习过的基础知识)


    冒泡排序概念:两两交换数值,最小的值在最左边,就如最轻的气泡在最上边。对整列数两两交换一次,最小的数在最左边,每次都能得一个在剩下的数中的最小 的数,“冒”出来的数组成一个有序区间,剩下的值组成一无序区间,且有序区间中每一元素值都比无序区间的小。

答案:
$setarray = array('3','8','1','4','11','7');
var_dump(bubblesort($setarray));
function bubblesort($array) {
	$getlenght = count($array); //统计元素的数量
	for($i = 1;$i < $getlenght;$i++) {		
		for($j = $getlenght - 1;$j >= $i;$j--) {
			/**
			 *从末端开始
			 *从后一个元素和前一个元素佐比较,假如后面一个元素比前面的元素要小,两个元素的值互换
			 *键值在往前偏移一个,再以上面逻辑开始比较
			 *直到键值指向到0时候,数组最小的元素值在键值为0的位置
			 **/
			if($array[$j] < $array[$j - 1]) {
				$x = $array[$j];
				$array[$j] = $array[$j-1];
				$array[$j-1] = $x;
			}
		}
	}
	/*方法二:从起初值开始比较
	for($i = 1;$i < $getlenght;$i++) {
		for($k = 0;$k < $getlenght - $i;$k++) {
			if($array[$k] > $array[$k + 1]) {
				$x = $array[$k];
				$array[$k] = $array[$k + 1];
				$array[$k + 1] = $x;
			}
		}
	}*/
	return $array;	
}
 

        快速排序:首先我们要理解一下快速排序的原理:找到当前数组中的任意一个元素(一般选择第一个元素),作为标准,新建两个空数组,遍历整个数组元素,如果遍历到的元素比当前的元素要小,那么就放到左边的数组,否则放到右面的数组,然后再对新数组进行同样的操作,不难发现,这里符合递归的原理,所以我们可以用递归来实现。

答案:
$arr = array(6,3,8,6,4,2,9,5,1);
    //函数实现快速排序
    function quick_sort($arr) {
        //判断参数是否是一个数组
        if(!is_array($arr)) return false;
        //递归出口:数组长度为1,直接返回数组
        $length=count($arr);
        if($length <= 1) return $arr;
        //数组元素有多个,则定义两个空数组
        $left = $right = array();
        //使用for循环进行遍历,把第一个元素当做比较的对象
        for($i = 1;$i < $length;$i++) {
            //判断当前元素的大小
            if($arr[$i] < $arr[0]) {
                $left[] = $arr[$i];
            }
			else {
                $right[] = $arr[$i];
            }
        }
        //递归调用
        $left = quick_sort($left);
        $right = quick_sort($right);
        //将所有的结果合并
        return array_merge($left,array($arr[0]),$right);
    }
	//调用
	echo "<pre>";
	var_dump(quick_sort($arr));



2.实现一个字符串截取的函数,类似于substr,必须能够截取中文这种多字节编码。假设每个中文也是一个字符,普通的数字、符号、字母也是一个字符。(提示:GB编码的中文字符高位范围是 x81-xFE )

答案:
function GBSubstr($str, $len){
        $count = ;
        for($i=; $i<strlen($str); $i++){
                if($count == $len) break;
                if(preg_match("/[/x8-/xff]/", substr($str, $i, 1))) ++$i;
                ++$count;       
        }
        return substr($str, , $i);
}

function GBSubstr2($src, $start=, $length=){
        $suffix="";
        $len = strlen($src);
        if ( $len <= $length ) return $src;
       
        $cut_length = ;
        for( $idx = ; $idx<$length; $idx++){
                $char_value = ord($src[$idx]);
                if ( $char_value < x8 || ( $char_value & x4 ) )
                        $cut_length++;
                else
                        $cut_length = $cut_length + 3;
        }
        $curstr = substr($src, , $cut_length) ;
        preg_match('/^([/x-/x7f]|.{3})*/', $curstr, $result);
        return  $result[];
}



function CSubstr($str, $start=, $length, $charset="gbk", $suffix=false){
        if(function_exists("mb_substr")){
                return mb_substr($str, $start, $length, $charset);
        }
        $re['utf-8']        = "/[/x1-/x7f]|[/xc2-/xdf][/x8-/xbf]|[/xe-/xef][/x8-/xbf]{2}|[/xf-/xff][/x8-/xbf]{3}/";
        $re['gb2312']        = "/[/x1-/x7f]|[/xb-/xf7][/xa-/xfe]/";
        $re['gbk']                = "/[/x1-/x7f]|[/x81-/xfe][/x4-/xfe]/";
        $re['big5']                = "/[/x1-/x7f]|[/x81-/xfe]([/x4-/x7e]|/xa1-/xfe])/";
       
        preg_match_all($re[$charset], $str, $match);
                $slice = join("", array_slice($match[], $start, $length));

        if($suffix) {
                return $slice ."…";
        }
        return $slice;
}


3.写一个遍历指定目录下所有子目录和子文件的函数(提示:可以使用递归的方法)

答案:
function dir_all ( $path ) {
        $handler = opendir($path);
        while (false!==($tmp = readdir($handler))) { 
                if(is_dir( "$path/$tmp" )) {
                        if ($tmp=="." | $tmp=="..") continue;
                                echo $tmp."<br>/n";
                                dir_all ("$path/$tmp");
                } else {
                        echo $tmp ."<br>/n";
                }
        }
}



4.写出发贴数最多的十个人名字的SQL,利用下表:members(id,username,posts,pass,email)

答案:
select username,count(id) as times from members group by username order by times desc limit 10;



  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值