PHP面试题(遇到的)

1,开源框架的区别和优缺点:

Laravel 设计,优缺点
优点
   1,集合了php新的特性,以及各种各样的设计模式,loc容器,依赖注入,门面,契约
   2,需要composer 安装,内置大量的方法供开发者使用,具有强大的社区化扩展(composer 扩展自动加载)
   3,使用blade模板引擎,很强大
   4,内置了哈希加密单向加密方法,更安全
   5,laravel框架使用return view(); 来渲染模板
   6,是一个重路由的框架,所有的功能由路由发起的
   7,中间件,可以实现访问前后的处理。例如请求和返回,权限认证
   8,判断语句在view视图页面需要加@符号

缺点
   1,基于组件式的框架,所以比较臃肿

ThinkPHP设计,优缺点
优点
   1,借鉴JAVA思想,基于PHP5,部署简单只需要一个入口文件,就可以完成,
   2,自带模板引擎,独特验证和自动填充
   3,使用$this->display(); 方式渲染模板
   4,Thinkphp3.2必须要有控制器方法才能正常访问
   5,轻量级的中型框架
   6,易于上手,有丰富的中文文档
   7,框架的兼容性较强,PHP4和PHP5完全兼容,支持UTF-8
   8,适合用于中小型项目的开发
   9,国内用的人很多,遇到问题都可以查到文档或者有人解答

缺点:
   1,对ajax 的支持不是很好
   2,目录结构混乱,需要花时间整理
   3,上手容易,但是深入学习较难 

YII设计,优缺点
是一个基于组件的高性能的php框架,用于开发Web应用,严格OOP编写,完善的库引用以及全面的教程
优点
  1,纯OOP思想
  2,用于大规模的Web应用
  3,模型使用方便
  4,开发速度快,运行速度也快。性能优异且功能丰富
  5,使用命令行工具
  6,支持composer包管理工具

缺点:
  1,对Model层的指导和考虑较少
  2,文档实例较少
  3,英文太多

2,PHP5与PHP7 区别

1,性能提升,PHP7比PHP5性能提升了两倍
2,以前的许多致命错误,现在改成抛出异常
3,PHP7 比PHP5 移除了一些老的不在支持的sapi(服务器端应用编程端口)和扩展
4,新增了空接合操作符
5,新增了结合比较运算符
6,新增加了函数的返回类型声明
7,新增了标量类型声明
8,新增了匿名类

3,为什么PHP7比PHP5性能提升了

1,变量存储字节减小,减少内存占用,提升变量操作速度
2,改善数组结构,数组元素和hash映射表被分配在同一块内存里,降低了内存占用,提升了cpu缓存命中率
3,改进了函数的调用机制,通过优化参数传递的环节,减少了一些指令,提高执行效率

4,计算题

1)

<?php
class A{
    public $num = 100;
}
$objA = new A();
$objB = $objA;
$objC = clone $objA;
$objA->num = 200;
$objD = clone $objB;
echo $objB->num;   // 200
echo "<br>";
echo $objC->num;   // 100
echo "<br>";
echo $objD->num;   // 200

2)

<?php
$array = array(
    1    => 'abc',
    1.5  => 'abc',
    true => 'abc',
);
echo count($array);  // 1

3)

<?php
$array = [1, 2, 4];
foreach($array as &$value){
    $value *= 2;
}
$value = [];
$value[0] = 9;
$value[1] = 10;
print_r($array);  // array(0 => 2, 1 => 4, 2 => array(0 => 9, 1 => 10));
print_r($value);  // array(0 => 9, 1 => 10);

4) PHP输出Js代码

<?php
header('Content-Type:text/html; charset=utf-8');

$string_js = <<<mark
   <script language="javascript" type="text/javascript">
       alert("hello php编程世界");
   </script>
mark;

echo $sting_js;

5,缓存穿透,缓存击穿,缓存雪崩

1,缓存穿透
   描述:指缓存和数据库中都没有的数据,而用户不断发起请求。
   解决方案:接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截,
            从缓存取不到的数据,在数据库中也没有取到,也可以将key-value对 写为key-null,
       缓存有效时间可以设置短点,如30秒。这样可以防止攻击用户反复用同一个id攻击。
2,缓存击穿
   描述:指缓存中没有但数据库中有的数据,这时由于并发用户特别多,同时读缓存没读到数据,
      又同时去数据库取数据,引起数据库压力瞬间增大,造成过大压力。
   解决方案:设置热点数据永远不过期。
3,缓存雪崩
   描述:指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机。
     和缓存穿透不同的是,缓存击穿指并发查询同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
   解决方案:缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
       如果缓存数据库是分布式部署,将热点数据均匀分布在不同缓存数据库中。
       设置热点数据永远不过期。

6,Mysql 数据题

1) 添加一条张三的数学为75
insert into stu_sub(id,Suid,Subid,score) values(null,1,2,75);
2) 查询每位同学的平均分大于等于80
SELECT
 	s. NAME AS NAME,
 	avg(st.score) AS score
 FROM
 	student s
 LEFT JOIN stu_sub st ON s.id = st.Suid
 WHERE
 	score >= 80
 GROUP BY
 	st.suid;
3) 学科总分排名为第二的学生
SELECT
	s. NAME AS NAME,
	sum(st.score) AS score
FROM
	student s
LEFT JOIN stu_sub st ON s.id = st.Suid
GROUP BY
	st.suid
ORDER BY
	score DESC
LIMIT 1,1;

7,Mysql 联合查询内连接,左连接,右连接,全连接区别

内连接(inner join): 显示的数据是两张表的相关的信息。查询结果两张表数据都有数据,并且字段都不为空
左连接(left join): 主表在前,附表在后,查询结果是主表的全部信息和附表与主表相关的信息数据,部分字段可能为空
右连接(right join): 主表在后,附表在前,查询结果是主表的全部信息和附表与主表相关的信息数据,部分字段可能为空
全连接(full join): 显示两张表的全部信息

8,XSS攻击,Sql注入

XSS攻击:
    条件:1)需要向web页面注入恶意代码
          2)恶意代码能被浏览器成功执行
    解决办法:
         过滤用户输入的 检查用户输入的内容中是否有非法内容。
        如<>(尖括号)、”(引号)、 ‘(单引号)、%(百分比符号)、;(分号)、()(括号)、&(& 符号)、+(加号)等。、严格控制输出。
         可以利用下面这些函数对出现xss漏洞的参数进行过滤
         1、htmlspecialchars() 函数,用于转义处理在页面上显示的文本。
         2、htmlentities() 函数,用于转义处理在页面上显示的文本。
         3、strip_tags() 函数,过滤掉输入、输出里面的恶意标签。
         4、header() 函数,使用header("Content-type:application/json"); 用于控制 json 数据的头部,不用于浏览。
         5、urlencode() 函数,用于输出处理字符型参数带入页面链接中。
         6、intval() 函数用于处理数值型参数输出页面中。
         7、自定义函数,在大多情况下,要使用一些常用的 html 标签,以美化页面显示,如留言、小纸条。那么在这样的情况下,要采用白名单的方法使用合法的标签显示,过滤掉非法的字符。

各语言示例:
        PHP的htmlentities()或是htmlspecialchars()。
        Python的cgi.escape()。
        ASP的Server.HTMLEncode()。
        ASP.NET的Server.HtmlEncode()或功能更强的Microsoft Anti-Cross Site Scripting Library
        Java的xssprotect(Open Source Library)。
   Node.js的node-validator。
Sql注入:
    概括:通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击
    原理:
          1)当应用程序使用输入内容来构造动态sql语句以访问数据库时,会发生sql注入攻击。
          2)如果代码使用存储过程,而这些存储过程作为包含未筛选的用户输入的字符串来传递,也会发生sql注入
    解决办法:
          1) 永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度的方式进行处理;然后对单引号和双"-"等敏感符号进行转换等。
          2) 不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
          3) 永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
          4) 不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
          5) 应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装

9,PHP7 特性

1,类型的声明
   可以使用字符串(string),整数(int),浮点数(float),布尔值(boot),来声明函数的参数类型与函数返回值
2,set_exception_handler() 不在保证收到的一定是Exception 对象
3,新增操作符 "<=>"
   语法:$c = $a <=> $b
   如果 $a > $b, $c的值为1
   如果 $a == $b, $c的指为0
   如果 $a < $b, $c的值为-1
4,新增操作符 "??"
   如果变量存在且值不为NULL,它就会返回自身的值,否则返回它的第二个操作数
5,define() 定义常量数组
6,AST:Abstract Syntax Tree,抽象语法树
   PHP5: PHP代码 ->Parser语法解析->OPCODE->执行
   PHP7: PHP代码 ->Parser语法解析->AST->OPCODE->执行
7,匿名函数
   $anonymous_func = function(){return 'function';};
   echo $anonymous_func(); // 输出function
8,Unicode 字符格式支持(echo "\u{9999}")
9,Unserialize 提供过滤特性
   防止非法数据进行代码注入,提供了更安全的反序列化数据
10,命名空间引用优化
    // PHP7以前语法的写法 
     use FooLibrary\Bar\Baz\ClassA; 
     use FooLibrary\Bar\Baz\ClassB; 
    // PHP7新语法写法 
     use FooLibrary\Bar\Baz\{ ClassA, ClassB};

   
1,废弃扩展
 Ereg 正则表达式
 Mysql
 Sybase_ct
2,废弃的特性
 不能使用同名的构造函数,实例方法不能用静态方法的方式调用
3,废弃的函数
 方法调用
     call_user_method();
     call_user_method_array();
 改为:
     call_user_func();
     call_user_func_array();
 加密相关函数
    mcrypt_generic_end();
    mcrypt_ecb();
    mcrypt_cbc();
    mcrypt_cfb();
    mcrypt_ofb();
4,废弃的用法
   $HTTP_RAW_POST_DATA 变量被移除,使用php://input 来代替
   ini 文件里面不再支持#开头的注释,使用 ";"
   移除了ASP格式的支持和脚本语法的支持: <% 和 <script language=php>

10,Yii框架如何保存和处理错误,异常

默认情况下,Yii会将异常处理分配给CApplication::handleException, 将错误处理分配给CApplication::handleError,但是可以通过在入口文件中定义YII_ENABLE_EXCEPTION_HANDLER, YII_ENABLE_ERROR_HANDLER两个常量为false禁止使用Yii的异常和错误接管机制。

YII_DEBUG常量(默认为false, 可以在入口文件中设置)对错误信息的显示有很重要的影响,debug模式下,错误的输出是最详细的。而程序一旦投入运行,则应将YII_DEBUG修改为false。

无论是否处于debug模式,Yii程序产生错误时均会将相关错误信息进行记录(错误级别为error, 分类默认为application)。不同之处是debug模式时会直接在web页上显示详细信息。

CApplication:: handleError($code,$message,$file,$line)

特别注意restore_error_handler,restore_exception_handler两个函数,如果没有这两个函数的调用,那么在后续的错误处理过程中,当再次产生异常或是错误时,又会调用CApplication:: handleError ,从而可能造成死循环,故Yii在此处临时禁止了使用CApplication:: handleError 接管后续的错误和异常(使用php默认的错误处理机制),这就保证了不会因之产生循环调用。
PHP错误的处理当产生错误时,PHP会在日志中记录哪些信息?错误代码(即PHP的E_ERROR E_WARNING  E_STRICT E_DEPRECATED)消息内容(如 Undefined vaiable $input)产生错误的文件路径产生错误的行号额外的跟踪回溯信息(这是通过debug_backtrace实现的)当前URL除了记录相应日志之外,Yii还会对错误进行后续处理(如中断运行、显示错误页等),默认情况下错误的处理会交给CErrorHandler组件处理(但可以通过给CApplicaton绑定onError事件处理器而实现错误处理的二次接管,此处的设计很灵活!)。

11,Linux 查看日志命令

1,tail 
       -n  是显示行号;相当于nl命令;例子如下:
            tail -100f test.log      实时监控100行日志
            tail  -n  10  test.log   查询日志尾部最后10行的日志;
            tail -n +10 test.log    查询10行之后的所有日志;

    head:  

        跟tail是相反的,tail是看后多少行日志;例子如下:

            head -n 10  test.log   查询日志文件中的头10行日志;
            head -n -10  test.log   查询日志文件除了最后10行的其他所有日志;

    cat: 

        tac是倒序查看,是cat单词反写;例子如下:

            cat -n test.log |grep "debug"   查询关键字的日志

2. 应用场景一:按行号查看---过滤出关键字附近的日志

     1)cat -n test.log |grep "debug"  得到关键日志的行号
     2)cat -n test.log |tail -n +92|head -n 20  选择关键字所在的中间一行. 然后查看这个关键字前10行和后10行的日志:

            tail -n +92表示查询92行之后的日志
            head -n 20 则表示在前面的查询结果里再查前20条记录

3. 应用场景二:根据日期查询日志

      sed -n '/2014-12-17 16:17:20/,/2014-12-17 16:17:36/p'  test.log

      特别说明:上面的两个日期必须是日志中打印出来的日志,否则无效;

                      先 grep '2014-12-17 16:17:20' test.log 来确定日志中是否有该 时间点

 

4.应用场景三:日志内容特别多,打印在屏幕上不方便查看
    (1)使用more和less命令,

           如: cat -n test.log |grep "debug" |more     这样就分页打印了,通过点击空格键翻页

    (2)使用 >xxx.txt 将其保存到文件中,到时可以拉下这个文件分析

            如:cat -n test.log |grep "debug"  >debug.txt

12,Linux 查看文件行号范围的命令 (查看大文件100-500行数据)

cat filename | head -n 500 | tail -n +100


  1、cat filename 打印文件所有内容

  2、tail -n 100 打印文件最后100行的数据

        cat filename tail -n 100

  3、tail -n +100 打印文件第100行开始以后的内容

       cat filename tail -n +100 

  4、head -n 100 打印前100的内容  

       cat filename head -n 100

* 补充 查看文件有多少行

   wc -l filename

     查看最后100行的数据

   cat filename | tail -n 100

13,url正则匹配

$url = 'http://www.baidu.com';
$preg = '/\b(([\w-]+:\/\/?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/)))/';
preg_match_all($preg, $url,$array);
var_dump($array);

14,Apache 与 Nginx 区别

Apache特点:
1,apache 的 rewrite 比 nginx 强大,在 rewrite 频繁的情况下,用 apache
2,apache 发展到现在,模块超多,基本想到的都可以找到
3,apache 更为成熟,少 bug ,nginx 的 bug 相对较多
4,apache 超稳定
5,apache 对 PHP 支持比较简单,nginx 需要配合其他后端用
6,apache 在处理动态请求有优势,nginx 在这方面是鸡肋,一般动态请求要 apache 去做,nginx 适合静态和反向。
7,apache 仍然是目前的主流,拥有丰富的特性,成熟的技术和开发社区

Nginx特点:
1,轻量级,采用 C 进行编写,同样的 web 服务,会占用更少的内存及资源
2,抗并发,nginx 以 epoll and kqueue 作为开发模型,处理请求是异步非阻塞的,负载能力比 apache 高很多,而 apache 则是阻塞型的。在高并发下 nginx 能保持低资源低消耗高性能 ,而 apache 在 PHP 处理慢或者前端压力很大的情况下,很容易出现进程数飙升,从而拒绝服务的现象。
3,nginx 处理静态文件好,静态处理性能比 apache 高三倍以上
4,nginx 的设计高度模块化,编写模块相对简单
5,nginx 配置简洁,正则配置让很多事情变得简单,而且改完配置能使用 -t 测试配置有没有问题,apache 配置复杂 ,重启的时候发现配置出错了,会很崩溃
6,nginx 作为负载均衡服务器,支持 7 层负载均衡
7,nginx 本身就是一个反向代理服务器,而且可以作为非常优秀的邮件代理服务器
8,启动特别容易, 并且几乎可以做到 7*24 不间断运行,即使运行数个月也不需要重新启动,还能够不间断服务的情况下进行软件版本的升级
9,社区活跃,各种高性能模块出品迅速

总结:
    
    两者最核心的区别在于 apache 是同步多进程模型,一个连接对应一个进程,而 nginx 是异步的,多个连接(万级别)可以对应一个进程。
    一般来说,需要性能的 web 服务,用 nginx 。如果不需要性能只求稳定,更考虑 apache ,后者的各种功能模块实现得比前者,例如 ssl 的模块就比前者好,可配置项多。epoll(freebsd 上是 kqueue ) 网络 IO 模型是 nginx 处理性能高的根本理由,但并不是所有的情况下都是 epoll 大获全胜的,如果本身提供静态服务的就只有寥寥几个文件,apache 的 select 模型或许比 epoll 更高性能。当然,这只是根据网络 IO 模型的原理作的一个假设,真正的应用还是需要实测了再说的。    
   

15,PHP中 href 和 onclick 访问顺序

一般情况下是先 onclick 再 href,在ie10下遇到个问题,只执行href,onclick没有反映。


<a href="javascript:alert(true);" onclick="alert(true);return false;"></a>

16,邮箱正则匹配

/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@([a-z0-9-]|163)+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/

 

未完待续,持续更新

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值