我遇到过的面试题及答案(一)
1、<?php echo count(strlen(“http://php.net”)); ?>的执行结果是?
答案:1
讲解:count(var)是用来统计数组或对象的元素个数的。当var是null或者空数组时,结果为0。如果var是普通变量,则返回1。正常情况下返回var中的元素或属性个数。
2、请说明php.ini中的safe_mode开启之后影响了哪些函数?
答案:Safe_mode是php的安全模式。开启之后,主要会对系统操作、文件、权限设置等方法产生影响,主要用来应对webshell。以下是受到影响的一些函数:ckdir,move_uploaded_file,chgrp,parse_ini_file,
chown,rmdir,copy,rename,fopen,require,highlight_file,show_source,include,symlink,link,touch,mkdir,unlink,exec,
shell_exec,pasathru,system,popen
需要注意的是:在php5.3以上版本,safe_mode被弃用,在php5.4以上版本,则将此特性完全去除了。
3、php5中魔术方法有哪几个?请举例说明各自的用法。
- __construct() :构造方法,当一个对象创建时调用此方法,使用此方法的好处是:可以使构造方法有一个独一无二的名称,无论它所在的类的名称是什么.这样你在改变类的名称时,就不需要改变构造方法的名称
- __destruct() :析构方法,PHP将在对象被销毁前(即从内存中清除前)调用这个方法。默认情况下,PHP仅仅释放对象属性所占用的内存并销毁对象相关的资源。
- 析构函数允许你在使用一个对象之后执行任意代码来清除内存。
- 当PHP决定你的脚本不再与对象相关时,析构函数将被调用。
- 在一个函数的命名空间内,这会发生在函数return的时候。
- 对于全局变量,这发生于脚本结束的时候。
- 如果你想明确地销毁一个对象,你可以给指向该对象的变量分配任何其它值。
- 通常将变量赋值勤为NULL或者调用unset
- __call() :调用对象不存在得方法时执行此函数。包括没有权限访问的方法
- __get() :当调用一个未定义的属性时访问此方法
- __set( $property, $value ) :给一个未定义的属性赋值时调用
- __isset() : 当在一个未定义的属性上调用isset()函数时调用此方法
- __unset() :当在一个未定义的属性上调用unset()函数时调用此方法
-
__toString() :toString方法在将一个对象转化成字符串时自动调用,比如使用echo打印对象时
如果类没有实现此方法,则无法通过echo打印对象,否则会显示:Catchable fatal error: Object of class test could not be converted to string in
此方法必须返回一个字符串
- __clone() :克隆对象时执行此函数。PHP5中的对象赋值是使用的引用赋值,如果想复制一个对象则需要使用clone方法,在调用此方法是对象会自动调用__clone魔术方法。如果在对象复制需要执行某些初始化操作,可以在__clone方法实现
- __autoload() :它会在试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。
注意: 在 __autoload 函数中抛出的异常不能被 catch 语句块捕获并导致致命错误。
- __sleep() :serialize之前被调用,可以指定要序列化的对象属性。
- __wakeup :unserialize之前被调用,可以执行对象的初始化工作。
- __set_state() :调用var_export时,被调用。用__set_state的返回值做为var_export的返回值(自PHP 5.1.0起有效)。
- __invoke() :将对象当作函数来使用时执行此方法,通常不推荐这样做。
- __callStatic它的工作方式类似于 __call() 魔术方法,__callStatic() 是为了处理静态方法调用
- PHP5.3.0以上版本有效。
- 它必须是公共的,并且必须被声明为静态的。
- 同样,__call() 魔术方法必须被定义为公共的,所有其他魔术方法都必须如此。
4、说几个常用的超全局变量。
-
$_GET ----->get传送方式
-
$_POST ----->post传送方式
-
$_REQUEST ----->可以接收到get和post两种方式的值
-
$GLOBALS ----->所有的变量都放在里面
-
$_FILES ----->上传文件使用
-
$_SERVER ----->系统环境变量
-
$_SESSION ----->会话控制的时候会用到
-
$_COOKIE ----->会话控制的时候会用到
5、说几个你知道的设计模式。
-
单例模式: 保证一个类仅有一个实例,并提供一个访问他的全局访问点例如框架中的数据库连接
-
策略模式: 针对一组算法,将每一个算法封装到具有共同接口的独立的类中,例如进入个人主页时,根据浏览者的不同,给予不同的显示与操作。
-
注册模式: 提供了在程序中有条理的存放并管理一组全局对象 (object),例如ZF框架中的Zend_Registry::set。
-
适配器模式: 将不同接口适配成统一的API接口,例如数据操作有mysql、mysqli、pdo等,可利用适配器模式统一接口
-
观察者模式: 一个对象通过添加一个方法使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。例如实现实现消息推送
-
装饰器模式: 不修改原类代码和继承的情况下动态扩展类的功能,例如框架的每个Controller文件会提供before和after方法
-
迭代器模式: 提供一个方法顺序访问一个聚合对象中各个元素,在PHP中将继承 Iterator 类
6、请写一个函数验证电子邮件的格式是否正确。
<?php
$str = "jianfeng@126.com";
regex="([a−z0−9\.−]+)@([\da−z\.−]+)\.([a−z\.]2,6)" ; //正则
return preg_match(regex,str);
?>
7、isset、empty、is_null的区别。
- isset 判断变量是否定义或者是否为空
- 变量存在返回ture,否则返回false
- 变量定义不赋值返回false unset一个变量,返回false
- 变量赋值为null,返回false
- empty:判断变量的值是否为空,能转换为false的都是空,为空返回true,反之返回false。
- "",0,"0",NULL,FALSE都认为为空,返回true
- 没有任何属性的对象都认为是空,返回true
- is_null:检测传入的值(值、变量、表达式)是否为null
- 定义了,但是赋值为Null,返回true
- 定义了,但是没有赋值,返回reue
- 被unset一个变量,返回true
8、 对于关系型数据库而言,索引是相当重要的概念,请回答有关索引的几个问题:
a)、索引的目的是什么?
-
快速访问数据表中的特定信息,提高检索速度
-
创建唯一性索引,保证数据库表中每一行数据的唯一性。
-
加速表和表之间的连接
-
使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间
b)、索引对数据库系统的负面影响是什么?
负面影响:
创建索引和维护索引需要耗费时间,这个时间随着数据量的增加而增加;索引需要占用物理空间,不光是表需要占用数据空间,每个索引也需要占用物理空间;当对表进行增、删、改、的时候索引也要动态维护,这样就降低了数据的维护速度。
c)、为数据表建立索引的原则有哪些?
-
在最频繁使用的、用以缩小查询范围的字段上建立索引。
-
在频繁使用的、需要排序的字段上建立索引
d)、 什么情况下不宜建立索引?
- 对于查询中很少涉及的列或者重复值比较多的列,不宜建立索引。
- 对于一些特殊的数据类型,不宜建立索引,比如文本字段(text)等。
9、PHP网站的主要攻击方式有哪些?
- 命令注入(Command Injection)
- eval 注入(Eval Injection)
- 客户端脚本攻击(Script Insertion)
- 跨网站脚本攻击(Cross Site Scripting, XSS)
- SQL 注入攻击(SQL injection)
- 跨网站请求伪造攻击(Cross Site Request
- Forgeries, CSRF)
- Session 会话劫持(Session Hijacking)
- Session 固定攻击(Session Fixation)
- HTTP 响应拆分攻击(HTTP Response Splitting)
- 文件上传漏洞(File Upload Attack)
- 目录穿越漏洞(Directory Traversal)
- 远程文件包含攻击(Remote Inclusion)
- 动态函数注入攻击(Dynamic Variable
- Evaluation)
- URL 攻击(URL attack)
- 表单提交欺骗攻击(Spoofed Form
- Submissions)
- HTTP 请求欺骗攻击(Spoofed HTTP Requests)
10、以下语句返回的结果中name列也许会出现 null 的情况,那么在name字段上使用什么函数可以将出现的 null 改为一个默认值。
SELECT a.id,b.name FROM tab1 AS a LEFT JOIN tab2 AS b ON(a.id = p.id) WHERE a.id > 10;
答:
SELECT a.id,IFNULL(b.name,'未定义') FROM tab1 AS a LEFT JOIN tab2 AS b ON(a.id = p.id) WHERE a.id > 10;
来看官方手册的解释:IFNULL(expr1,expr2) 。如果expr1不是NULL,IFNULL()返回expr1,否则它返回expr2。IFNULL()返回一个数字或字符串值,取决于它被使用的上下文环境。
不过经我测试,是有问题的,当 expr1=0而不是null时。他也返回了expr2;官方手册应改为当expr1为null或者0时,返回expr2。
好了,第一期先更新这十个吧,愿尽绵薄之力,帮助小伙伴们找到心仪的工作。敬请关注“我遇到过的面试题及答案(二)”。