逻辑题
1.字符串” ”,” ”,” ”,”x20”分别代表什么
答案: 回车符 换行符 跳格 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
函数
概念题
答案:
MVC由Model(模型), View(视图)和Controller(控制器)组成,PHP MVC可以更高效地管理好3个不同层的PHP代码。
Model:数据信息存取层。
View:view层负责将应用的数据以特定的方式展现在界面上。
Controller:通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
3.在页面中引用CSS有几种方式?(前端问题)
答案:在页面中使用CSS有3中方式:
4.优化MYSQL数据库的方法
答案:
5.描述一下php开发中常见的几种攻击以及解决方案
答案:SQL注入:
解决这个问题的办法是,将 PHP 的内置 mysql_real_escape_string() 函数用作任何用户输入的包装器。这个函数对字符串中的字符进行转义,使字符串不可能传递撇号等特殊字符并让 MySQL 根据特殊字符进行操作。
跨站点脚本攻击(XSS):
strip_tags() 函数,这个函数可以清除任何包围在 HTML 标记中的内容
或者使用htmlspecialchars() 函数。
6.PHP里面是区分大小写的吗?
答案:
PHP对于系统函数、用户自定义函数、类名称等是不区分大小写的
PHP中的变量和常量是区分大小写的
对于文件名又因服务器操作系统而定,linux中区分,Win不区分
答案:
$_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定义的方法,能否通过”对象名::方法名“这样的形式来调用?
9.请介绍Session的原理
每一个访问的用户都会得到一个自己独有的session ID,这个session ID会存放在响应头里的cookie中,之后发送给客户端。
当用户第二次访问该站点时,浏览器会带着本地存放的cookie(里面存有上次得到的session ID)随着请求一起发送到服务器,
参考《Session原理简述》
10.没有通过static定义的方法,能否通过”对象名::方法名“这样的形式来调用?
答案:不能。会产生一个strict错误,但在会继续执行代码。参考《PHP静态调用非静态方法》。这篇文章里面还讲到了一个概念“calling
scope”。静态调用并不是说有::就是静态调用,而是看calling scope。$this指针指向的对象就是这个方法被调用时刻的calling scope。
对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题
答案:
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的前提之一。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;
认证成功后,认证系统应该生成统一的认证标志(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》
(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";
- }
- }
- }