2017年3月7日14:23:21
其实计划很久但是移植没时间去收集和处理弄成一个完整的文件
SVN地址: https://git.oschina.net/zxadmin/live_z
目前基础部分更新到79题,高级部分,我博客里面有些,但是需要整理成文档
直接下载即可,不定时更新 最新版情趣svn地址下载,但是为什么需要登录我就不知道了
PHP面试大全 ZX1.1版
版本说明:基于部分网络+个人+部分群网友帮助集合而成。如果有错误的地方,请联系博主
修改完成版会重新发布
个人博客:http://www.cnblogs.com/zx-admin/
SVN地址:https://git.oschina.net/zxadmin/live_z
如果你能熟练背诵或者掌握以下资料,BAT问题不大
1.php基础部分
1.1堆栈
2.php高级部分
2.1 单点登录
2.2 ajax p3p 多站点登录
2.3 php SPL
2.4 php MVC框架
2.5异常处理
2.6 权限系统rbac
2.7支持的协议和封装协议
2.8 编译php扩展
2.9 SSL
2.10 设计模式
3.php核心及内核,c部分
3.1设计模式
3.2反射机制
3.3 网站安全问题
4.linux服务搭建,nginx apche php-fpm +项目代码管理
5.mysql基础+复杂语句
6,mysql sql优化+死锁问题+主从+中间件
7.数据库分库,分表问题
8.网站基础架构,到大流量,大并发
9.非关系数据库 redis mongodb
10.服务SOA化
11.自己写简单php框架
12.各种协议tcp http udp socket ftp
13.c做php扩展
14.支付宝,微信,网银支付等
15.缓存系统 文件缓存 数据库缓存 redis缓存 等
16.算法 php相关 排序,冒泡,二分查找,单链表,双链表,环形链表等
17.大数据,云平台(粗略介绍)
一些没法归类的问题
关于面试的一些废话和寄语!
1.php基础部分
1. 简述两种屏蔽php程序的notice警告的方法
初始化变量,文件开始设置错误级别或者修改php.ini 设置error_reporting
set_error_handler 和 @抑制错误
1.在程序中添加:error_reporting (E_ALL & ~E_NOTICE);
2.或者修改php.ini中的:error_reporting = E_ALL
改为:error_reporting = E_ALL & ~E_NOTICE
3.error_reporting(0);或者修改php.inidisplay_errors=Off
2. include_once和require_once 分别返回什么错误级别
include_once会系统警告并继续执行,require_once会发出系统警告但是会引致致命错误令脚本终止运行
3. 例举几个常用的魔术方法, 并说明作用?
魔术函数
1。__construct()
实例化对象时被调用,
当__construct和以类名为函数名的函数同时存在时,__construct将被调用,另一个不被调用。
2。__destruct()
当删除一个对象或对象操作终止时被调用。
3。__call()
对象调用某个方法,
若方法存在,则直接调用;
若不存在,则会去调用__call函数。
4。__get()
读取一个对象的属性时,
若属性存在,则直接返回属性值;
若不存在,则会调用__get函数。
5。__set()
设置一个对象的属性时,
若属性存在,则直接赋值;
若不存在,则会调用__set函数。
6。__toString()
打印一个对象的时被调用。如echo $obj;或print $obj;
7。__clone()
克隆对象时被调用。如:$t=new Test();$t1=clone $t;
8。__sleep()
serialize之前被调用。若对象比较大,想删减一点东东再序列化,可考虑一下此函数。
9。__wakeup()
unserialize时被调用,做些对象的初始化工作。
10。__isset()
检测一个对象的属性是否存在时被调用。如:isset($c->name)。
11。__unset()
unset一个对象的属性时被调用。如:unset($c->name)。
12。__set_state()
调用var_export时,被调用。用__set_state的返回值做为var_export的返回值。
13。__autoload()
实例化一个对象时,如果对应的类不存在,则该方法被调用。
魔术常量
1。__LINE__
返回文件中的当前行号。
2。__FILE__
返回文件的完整路径和文件名。如果用在包含文件中,则返回包含文件名。自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径,而在此之前的版本有时会包含一个相对路径。
3。__FUNCTION__
返回函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。
4。__CLASS__
返回类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。
5。__METHOD__
返回类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。
4. 类静态方法和实例化类方法比较及优缺点
5. 例如google,baidu等大型网站,当使用不同客户端(如手机和PC机)访问同样的URL时,呈现的页面却不相同,这是何原理?
简单的可以用user_agent判断,但是及其初步
可以的话通过服务器或者手机终端特征或者wap网关accept信息等
6. 请说明PHP中传值与传引用的区别。什么时候传值什么时候传引用?
传值只是把某一个变量的值传给了另一个变量,而引用则说明两者指向了同一个地方。
7. echo(),print(),print_r()的区别
echo是语言结构,无返回值;print功能和echo基本相同,不同的是print是函数,有返回值;print_r是递归打印,用于输出数组对象
echo与print:
它们都不是真正的函数,是一种语法结构(也有说print是函数,echo不是)。
echo和print 后面都可不用加(),如: echo ‘ok’; print ‘ok’;
运行速度echo稍快一些,因为echo并不返回值,print返回一个值int(1)。
结论:
1、一般用echo,除非三元运算时。$a=5; ($a==5) ? print ’5′: print 0;
2、echo 后一般不要跟()。
print_r是递归打印,主要用于输出数组对象。
print只能有一个参数,所以不能不能用”,”,而echo可以。
Sprintf 以一定的格式 格式化一个字符串
8. 如何实现字符串翻转?
用strrev函数呗,不准用PHP内置的就自己写:
[php] view plain copy 在CODE上查看代码片派生到我的代码片
strrev($str)
{
$len=strlen($str);
$newstr = '';
for($i=$len;$i>=0;$i--)
{
$newstr .= $str{$i};
}
return $newstr;
}
9. 实现中文字串截取无乱码的方法。
mb_substr()
10. 求两个日期的差数,求前一天
(strtotime(‘2007-3-6’)-strtotime(‘2007-2-5’))/3600*24
echo date('Y-m-d H:i:s', strtotime('-1 day'));
11. 如何用php的环境变量得到一个网页地址的内容?ip地址又要怎样得到?
$_SERVSR[‘REQUEST_URI’] , $_SERVER[‘REMOTE_ADDR’]
12. 使用五种以上方式获取一个文件的扩展名
get_ext1($file_name)
{ return strrchr($file_name, '.');}
2)
get_ext2($file_name)
{ return substr($file_name, strrpos($file_name, '.'));}
3)
get_ext3($file_name)
{ return array_pop(explode('.', $file_name));}
4)
get_ext4($file_name)
{ $p = pathinfo($file_name);
return $p['extension'];}
5)
get_ext5($file_name)
{ return strrev(substr(strrev($file_name), 0, strpos(strrev($file_name), '.')));}
13. 写几个常用的PHP的扩展的名称和作用
mysql、gd2、pdo、curl、mbstring、soap等,在php.ini中可以找到。尽量多了解一些扩展,了解他们的功能(能做什么)。
php通过使用php_ming 库(Ming库)快速生成 Flash 动画
14. MVC模式的了解
MVC是Model(模型)、View(视觉)、Controll(控制器)的缩写。
MVC(Model-View-Controller)介绍
模型(Model): 应用程序的模型部分关心的是欲显示的数据的细节。模型通常关注的是应用程序的业务逻辑部分,关注的是如何使用数据库来读取和保存数据。
视图(View): 视图关心的是用户显示的部分,它通常是HTML。
控制器(Controller):控制器将特定的模型和视图结合起来,保证将正确的数据显示到页面上。
还有部分未写。。。。。。。。。。。待补充
15. 能够使HTML和PHP分离开使用的模板
常用的模板引擎:smarty,还有PHPLib,FastTemplate,Savant等。
但是php自身也是模版引擎
16. 简述如何得到当前执行脚本路径,包括所得到参数。
访问http://temp.com/phpinfo.php?id=1
echo $_SERVER['SCRIPT_URL']; //得到/phpinfo.php
echo $_SERVER["SCRIPT_URI"]; //得到http://temp.com/phpinfo.php
echo $_SERVER["SCRIPT_FILENAME"]; //得到F:/www/Temp/phpinfo.php
echo $_SERVER["REQUEST_URI"]; //得到/phpinfo.php?id=1
echo $_SERVER["SCRIPT_NAME"]; //得到/phpinfo.php
17. 在PHP中,heredoc是一种特殊的字符串,它的结束标志必须__。
结束标识符所在的行不能包含任何其它字符除”;”
Heredoc
echo <<<END
This text is written to the screen as output and this $variable is parsed too. If you wanted you can have <span> HTML tags in here as well.</span> The END; remarks must be on a line of its own, and can’t contain any extra white space.
END;
18. 写出session的运行机制。
session创建时,是否会在服务端记录一个cookie?cookie里面的内容是什么?
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识-称为sessionid,如果已包含一个sessionid则说明以前已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含sessionid,则为此客户端创建一个session并且生成一个与此session相关联的sessionid,sessionid的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个sessionid将被在本次响应中返回给客户端保存。
保存这个sessionid的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发给服务器。一般这个cookie的名字都是类似于SEEESIONID。
由于cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把sessionid传递回服务器。经常被使用的一种技术叫做URL重写,就是把sessionid直接附加在URL路径的后面,附加方式也有两种,一种是作为URL路径的附加信息,表现形式为http://…../xxx;SEEESIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
另一种是作为查询字符串附加在URL后面,表现形式为http://…../xxx?SEEESIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
为了在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个SEEESIONID。
19. Cookie的原理及使用?
Cookie是网站保存在浏览器客户端的信息,也就是说保存在访客的机器里的变量,一般随着HTTP头发送到服务器端。在Cookie生效之后及失效之前,客户每次发出页面请求的时候(包括PHP页面和静态html页面),都会把Cookie一块发送到服务器,只要我们针对它进行相应的处理,就可以实现变量”追随”。
cookie可以跨越子域名。
比如我们在xiaofeicn.com下面注册个个cookie,那么可以在bbs.xiaofeicn.com上读取到该cookie。
session不可以跨越子域名:
比如我们在xiaofeicn.com下面注册个个session,那么不可以在bbs.xiaofeicn.com,www.xiaofeicn.com上读取到该session。
20. 请将数组的值用’,’号分隔并合并成字符串输出。如何将一个以’,’隔开的字符串分割成数组?
参考 implode.php 把数组变成字符串
要掌握implode和explode的用法。
21. 不用新变量直接交换现有两个变理的值
List($a,$b)
22. 表单中 get与post提交方法的区别?
a、Get 方法通过 URL 请求来传递用户的数据,将表单内各字段名称与其内容,以成对的字符串连接,置于 action 属性所指程序的 url 后,如http://www.domain.com/test.asp?name=51js&password=51js,数据都会直接显示在 url 上,就像用户点击一个链接一样;Post 方法通过 HTTP post 机制,将表单内各字段名称与其内容放置在 HTML 表头(header)内一起传送给服务器端交由 action 属性能所指的程序处理,该程序会通过标准输入(stdin)方式,将表单的数据读出并加以处理
b、 Get 方式需要使用 $_GET 来取得变量的值;而 Post 方式通过 $_POST 来访问提交的内容
c、Get 方式传输的数据量非常小,一般限制在 2 KB 左右,但是执行效率却比 Post 方法好;而 Post 方式传递的数据量相对较大,它是等待服务器来读取数据,不过也有字节限制,这是为了避免对服务器用大量数据进行恶意攻击。可在php.in中 对 post_max_size 进行设置。
建议:除非你肯定你提交的数据可以一次性提交,否则请尽量用 Post 方法
d、Get 方式提交数据,会带来安全问题,比如一个登陆页面,通过 Get 方式提交数据时,用户名和密码将出现在 URL 上,如果页面可以被缓存或者其他人可以访问客户这台机器,就可以从历史记录获得该用户的帐号和密码,所以表单提交建议使用 Post 方法;Post 方法提交的表单页面常见的问题是,该页面如果刷新的时候,会弹出一个对话框。
建议:出于安全性考虑,建议最好使用 Post 提交数据***********************************在B/S应用程序中,前台与后台的数据交互,都是通过HTML中Form表单完成的。Form提供了两种数据传输的方式——get和post。虽然它们都是数据的提交方式,但是在实际传输时确有很大的不同,并且可能会对数据产生严重的影响。虽然为了方便的得到变量值,Web容器已经屏蔽了二者的一些差异,但是了解二者的差异在以后的编程也会很有帮助的。
Form中的get和post方法,在数据传输过程中分别对应了HTTP协议中的GET和POST方法。二者主要区别如下:
a、Get是用来从服务器上获得数据,而Post是用来向服务器上传递数据。
b、Get将表单中数据的按照variable=value的形式,添加到action所指向的URL后面,并且两者使用”?”连接,而各个变量之间使用”&”连接;Post是将表单中的数据放在form的数据体中,按照变量和值相对应的方式,传递到action所指向URL。
c、Get是不安全的,因为在传输过程,数据被放在请求的URL中,而如今现有的很多服务器、代理服务器或者用户代理都会将请求URL记录到日志文件中,然后放在某个地方,这样就可能会有一些隐私的信息被第三方看到。另外,用户也可以在浏览器上直接看到提交的数据,一些系统内部消息将会一同显示在用户面前。Post的所有操作对用户来说都是不可见的。
d、Get传输的数据量小,这主要是因为受URL长度限制;而Post可以传输大量的数据,所以在上传文件只能使用Post(当然还有一个原因,将在后面的提到)。
e、Get限制Form表单的数据集的值必须为ASCII字符;而Post支持整个ISO10646字符集。
f、Get是Form的默认方法。
*.Post传输数据时,不需要在URL中显示出来,而Get方法要在URL中显示。
*.Post传输的数据量大,可以达到2M,而Get方法由于受到URL长度的限制,只能传递大约1024字节.
*.Post顾名思义,就是为了将数据传送到服务器段,Get就是为了从服务器段取得数据.而Get之所以也能传送数据,只是用来设计告诉服务器,你到底需要什么样的数据.Post的信息作为http请求的内容,而Get是在Http头部传输的。
23. session与cookie的区别?
session是服务器端缓存,cookie是客户端缓存。
cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。
24. Cookie、session的联系和区别,多台web服务器如何共享session
Session采用键值对 , 也就是说ID存放客户端 , 而值放在服务器端 , 是通过用户的ID去找服务器上对应的值 , 这种方式值放置在服务器端 ,有个时间限制 ,时间到则服务器自动释放.
Cookies则有两种方法 , 一种方法是把值保存在浏览器的变量中 , 当浏览器关闭时结束 , 另一种方法是保存在硬盘中 , 只要时间不过期 , 下次还可使用.
Session 是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一 SessionID提交到服务器端,来存取Session数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用Cookie,那么Session也 会失效。
服务器也可以通过URL重写的方式来传递SessionID的值,因此不是完全依赖Cookie。如果客户端Cookie禁用,则服务器可以自动通过重写URL的方式来保存Session的值,并且这个过程对程序员透明。
可以试一下,即使不写Cookie,在使用request.getCookies();取出的Cookie数组的长度也是1,而这个Cookie的名字就是JSESSIONID,还有一个很长的二进制的字符串,是SessionID的值。
25. 请说明在php.ini中safe_mode开启之后对于PHP系统函数的影响?
safe_mode是唯一PHP_INI_SYSTEM属性,必须通过php.ini或httpd.conf来设置。要启用safe_mode,只需修改php.ini: safe_mode = On 或者修改httpd.conf,定义目录:
Options FollowSymLinks php_admin_value safe_mode 1
重启apache后safe_mode就生效了。启动safe_mode,会对许多PHP函数进行限制,特别是和系统相关的文件打开、命令执行等函数。
默认情况下,所有操作文件的函数将只能操作与脚本UID相同的文件。
注意:如果在linux中启用了safe_mode,那么如果要在一个目录中创建一个目录,比如要在/upload中创建一个20081202,那么/upload目录所有者必须是apache的所有者。
26. isset()和empty()的区别
两者都是测试变量用的。但是isset()是测试变量是否被赋值,而empty()是测试一个已经被赋值的变量是否为空。如果一个变量没被赋值就引用在php里是被允许的,但会有notice提示。如果一个变量被赋空值,$foo=””或者$foo=0或者$foo=false,那么empty($foo)返回真,isset($foo)也返回真,就是说赋空值不会注销一个变量。要注销一个变量,可以用 unset($foo)或者$foo=NULL。
27. 使用哪些工具进行版本控制?
cvs,svn,git;
28.请写一个函数验证电子邮件的格式是否正确 (2分)
答:function checkEmail($email)
{
$pregEmail="/([a-z0-9]*[-_/.]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[/.][a-z]{2,3}([/.][a-z]{2})?/i";
return preg_match($pregEmail,$email);
}
29. 请写出PHP5权限控制修饰符
public(公共)
private(私用)
protected(继承)
final
static
const
30. 解析一个URL
$url ="http://ci.localhost/index.php/home/adminlogin";
//$url = "http://shopnc.localhost/shop/index.php?act=goods&op=index&goods_id=25220";
$s = parse_url($url);
var_dump($s);
$t = parse_str($s['query'],$arr);
var_dump($arr);
var_dump(pathinfo($url)); //不行
var_dump(basename($url));
var_dump(dirname($url));
//这种模式类型都不行,所以换个思路
$mm = $s['path'];
$g = explode("/",$mm);
var_dump($g);
//unset($g['0']);
//var_dump($g);
list($b,$n,$acttion,$function) = $g;
31.PHP配置指令作用域说明
PHP总共有4个配置指令作用域:(PHP中的每个指令都有自己的作用域,指令只能在其作用域中修改,不是任何地方都能修改配置指令的)
PHP_INI_PERDIR:指令可以在php.ini、httpd.conf或.htaccess文件中修改
PHP_INI_SYSTEM:指令可以在php.ini 和 httpd.conf 文件中修改
PHP_INI_USER:指令可以在用户脚本中修改
PHP_INI_ALL:指令可以在任何地方修改
32.可变变量
有时候使用可变变量名是很方便的。就是说,一个变量的变量名可以动态的设置和使用。一个普通的变量通过声明来设置
有些时候需要可扩展的多种支付类型可以写成
$identify = $this->identify; 入口标识,必须和类名一致
$pay = New $identify();
$pay->pay();
可变变量 也可以实现类似的可扩展的方法
$a = "whfbbs"; //whfbbs就是可变变量的名字
$$a = 'b';
echo $whfbbs;
33.$this 和 –>& 引用 的意思和区别
$this即是实例化对象本身, –>对象访问符 和c/c++类似,但是注意不是完全一样的
&在c里面叫取地址符,但是php里面完全不是,官方原文是:
在 PHP 中引用意味着用不同的名字访问同一个变量内容。这并不像 C 的指针:例如你不能对他们做指针运算,他们并不是实际的内存地址…… 查看引用不是什么了解更多信息。 替代的是,引用是符号表别名。注意在PHP 中,变量名和变量内容是不一样的, 因此同样的内容可以有不同的名字。最接近的比喻是 Unix 的文件名和文件本身——变量名是目录条目,而变量内容则是文件本身。引用可以被看作是 Unix 文件系统中的硬链接。
仅作为别名理解,足以
还有比如
foreach ($array as $key =>&$value) { }
并不会加速循环处理速度,仅是提供 $value可以修改修改其参数的值
function functionName(&$param) { }
仅传递进去,返回该值 引用传递
function functionName($param,&$error) { }
引用返回
不清楚的可以看下官方文档说明
(废话一句,我也认为php和c/c++的基本用法和数据结构类似,其实是大错特错,仅仅是类似,但是基本实现了壳,比如php7的严格数据返回格式)
34.Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in Unknown on line 0 错误
在很多接口对接中遇到的这个问题 ,主要原因就是 php7.0之前 always_populate_raw_post_data默认是0,需要设置成-1,必须在php.ini里面设置
7.0之后就没这问题了,属于遗留bug
Warning: Cannot modify header information - headers already sent in Unknown on line 0,也有可能是由这个引起的
35. = == === 的区别
= 赋值 == 比较类型必须一致,先转换类型在比较 ===同时比较类型和数值,都一致才是true
需要细细理解,因为php是弱语言类型,容易出现一些bug判断
36.遍历所有目录
function zx($dir){
if(is_dir($dir)){
$filesnames = scandir($dir);
foreach ($filesnames as $name) {
if($name!='.'&&$name!='..'){
echo $name;
}
if($name!='.'&&$name!='..'){
if(is_dir($name)){
zx($name);
}else{
echo '这是文件';
}
}
echo '<br>';
}
}
}
37.instanceof的作用, 经常在什么设计模式中使用
单例模式,但是其他的模式也会用到
38.计算几天前,几个月前,固定日子多少时间前
echo strtotime("now") . "<br>";
echo strtotime("15 October 1980") . "<br>";
echo strtotime("+5 hours") . "<br>";
echo strtotime("+1 week") . "<br>";
echo strtotime("+1 week 3 days 7 hours 5 seconds") . "<br>";
echo strtotime("next Monday") . "<br>";
echo strtotime("last Sunday");
输出的是时间戳需要date转换
$apply['apply_date'] 某月某日 时间戳
$contract['application_days'] 多天前
$days = "+".$contract['application_days']." days";
$first_pay_day =date("Y-m-d",strtotime($days,strtotime(date("Y-m-d", $apply['apply_date']))));
39.解决urlencode 没有吧=转换成%20 类似的问题
Rawurldecode这个函数 rawurlencode 最好使用这对函数
按照 RFC 1738 对 URL 进行编码
返回字符串,此字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数。这是在 RFC 1738 中描述的编码,是为了保护原义字符以免其被解释为特殊的 URL 定界符,同时保护 URL 格式以免其被传输媒体(像一些邮件系统)使用字符转换时弄乱。
与urlencode()的区别:
urlencode:
返回字符串,此字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格则编码为加号(+)。此编码与 WWW 表单 POST 数据的编码方式是一样的,同时与 application/x-www-form-urlencoded 的媒体类型编码方式一样。由于历史原因,此编码在将空格编码为加号(+)方面与 RFC1738 编码(参见 rawurlencode())不同。
40.如何在php中设置header头信息
建议参考:http://www.cnblogs.com/zx-admin/p/6172029.html
内容很多以下是几个简单demo
//定义编码
header( 'Content-Type:text/html;charset=utf-8 ');
//Atom
header('Content-type: application/atom+xml');
//CSS
header('Content-type: text/css');
//Javascript
header('Content-type: text/javascript');
//JPEG Image
header('Content-type: image/jpeg');
//JSON
header('Content-type: application/json');
//PDF
header('Content-type: application/pdf');
//RSS
header('Content-Type: application/rss+xml; charset=ISO-8859-1');
//Text (Plain)
header('Content-type: text/plain');
//XML
header('Content-type: text/xml');
//200 OK
header('HTTP/1.1 200 OK');
//设置一个404头:
header('HTTP/1.1 404 Not Found');
//设置地址被永久的重定向
header('HTTP/1.1 301 Moved Permanently');
//转到一个新地址
header('Location: http://www.example.org/');
//文件延迟转向:
header('Refresh: 10; url=http://www.example.org/');
print 'You will be redirected in 10 seconds';
//当然,也可以使用html语法实现
//<meta http-equiv="refresh" content="10;http://www.example.org/ />
//override X-Powered-By: PHP:
header('X-Powered-By: PHP/4.4.0');
header('X-Powered-By: Brain/0.6b');
//文档语言
header('Content-language: en');
//告诉浏览器最后一次修改时间
$time = time() - 60; // or filemtime($fn), etc
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $time).' GMT');
//告诉浏览器文档内容没有发生改变
header('HTTP/1.1 304 Not Modified');
//设置内容长度
header('Content-Length: 1234');
//设置为一个下载类型
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="example.zip"');
header('Content-Transfer-Encoding: binary');
//load the file to send:
readfile('example.zip');
//对当前文档禁用缓存
header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Pragma: no-cache');
//设置内容类型:
header('Content-Type: text/html; charset=iso-8859-1');
header('Content-Type: text/html; charset=utf-8');
header('Content-Type: text/plain'); //纯文本格式
header('Content-Type: image/jpeg'); //JPG***
header('Content-Type: application/zip'); // ZIP文件
header('Content-Type: application/pdf'); // PDF文件
header('Content-Type: audio/mpeg'); // 音频文件
header('Content-Type: application/x-shockw**e-flash'); //Flash动画
//显示登陆对话框
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Top Secret"');
print 'Text that will be displayed if the user hits cancel or ';
print 'enters wrong login data';
41.取得客户端IP
/**
* 获取客户端IP地址
* @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
* @return mixed
*/
function get_client_ip($type = 0) {
$type = $type ? 1 : 0;
static $ip = NULL;
if ($ip !== NULL) return $ip[$type];
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$pos = array_search('unknown',$arr);
if(false !== $pos) unset($arr[$pos]);
$ip = trim($arr[0]);
}elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
}elseif (isset($_SERVER['REMOTE_ADDR'])) {
$ip = $_SERVER['REMOTE_ADDR'];
}
// IP地址合法验证
$long = sprintf("%u",ip2long($ip));
$ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
return $ip[$type];
}
42.varchar和char有什么区别
char 长度是固定的,不管你存储的数据是多少他都会都固定的长度。
而varchar则处可变长度但他要在总长度上加1字符,这个用来存储位置。
char 固定长度,所以在处理速度上要比varchar快速很多,但是浪费存储空间,
所以对存储不大,但在速度上有要求的可以使用char类型,反之可以用varchar类型来实例
char (13)长度固定, 如'www.jb51.net' 存储需要空间 12个字符
varchar(13) 可变长 如'www.jb51.net' 需要存储空间 13字符
43.写代码来解决多进程/线程同时读写一个文件的问题
PHP是不支持多线程的,可以使用php的flock加锁函数实现。
$fp = fopen("/tmp/lock.txt", "w+");
if (flock($fp, LOCK_EX)) { // 进行排它型锁定
fwrite($fp, "Write something here\n");
flock($fp, LOCK_UN); // 释放锁定
} else {
echo "Couldn't lock the file !";
}
fclose($fp);
44.Mysql 的存储引擎,myisam和innodb的区别
a. MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.
b. MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快.
c. InnoDB不支持FULLTEXT类型的索引.
d. InnoDB 中不保存表的具体行数,也就是说,
执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,
但是MyISAM只要简单的读出保存好的行数即可.
e. 对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中,可以和其他字段一起建立联合索引。
f. DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除。
g. LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,
但是对于使用的额外的InnoDB特性(例如外键)的表不适用.
h. MyISAM支持表锁,InnoDB支持行锁。
45.对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题
a. 确认服务器是否能支撑当前访问量。
b. 优化数据库访问。
c. 禁止外部访问链接(盗链), 比如图片盗链。
d. 控制文件下载。
e. 使用不同主机分流。
f. 使用浏览统计软件,了解访问量,有针对性的进行优化。
46.判断一个数据是否是一个标准的json数据
function is_json($string) {
json_decode($string);
return (json_last_error() == JSON_ERROR_NONE);
}
define ('JSON_ERROR_NONE', 0);
JSON_ERROR_NONE 没有错误发生
JSON_ERROR_DEPTH 到达了最大堆栈深度
JSON_ERROR_STATE_MISMATCH 无效或异常的 JSON
JSON_ERROR_CTRL_CHAR 控制字符错误,可能是编码不对
JSON_ERROR_SYNTAX 语法错误
JSON_ERROR_UTF8 异常的 UTF-8 字符,也许是因为不正确的编码。JSON_ERROR_RECURSION One or more recursive references in the value to be
JSON_ERROR_INF_OR_NAN One or more NAN or INF values in the value to be
JSON_ERROR_UNSUPPORTED_TYPE 指定的类型,值无法编码。JSON_ERROR_INVALID_PROPERTY_NAME 指定的属性名无法编码。
JSON_ERROR_UTF16 畸形的 UTF-16 字符,可能因为字符编码不正确。
47.写一个简单的行为控制函数
//简单行为管理,如果请求此方法次数多于5次,就显示验证码 吧当前方法的name传进来,
//有效时间是5分钟,$return=1是增加,$return=2就是只是返回$_COOKIE[$name]的值
function behavior_function($function = __FUNCTION__, $class = __CLASS__, $return = 1) {
$name = 'behavior_' . $class . '_' . $function;
if ($return == 1) {
setcookie($name, $_COOKIE[$name] + 1, time() + 3000, "/");
} elseif ($return == 2) {
return $_COOKIE[$name] > 5 ? true : false;
}
}
48.三元运算
($a==5) ? print ‘5’:print 0;
49. PHP中的替代语法(冒号、endif、endwhile、endfor)
PHP 提供了一些流程控制的替代语法,包括 if,while,for,foreach 和 switch。替代语法的基本形式是把左花括号({)换成冒号(:),把右花括号(})分别换成 endif;,endwhile;,endfor;,endforeach; 以及 endswitch;。
Demo :
if ($a == 5):
echo "a equals 5";
elseif ($a == 6):
echo "!!!";
else:
echo "a is neither 5 nor 6";
endif;
注意:不支持在同一个控制块内混合使用两种语法
50.转钱的大写
//数字转大写 此函数只有到分
function cny($ns) {
static $cnums = array("零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"),
$cnyunits = array("圆", "角", "分"),
$grees = array("拾", "佰", "仟", "万", "拾", "佰", "仟", "亿");
list($ns1, $ns2) = explode(".", $ns, 2);
$ns2 = array_filter(array($ns2[1], $ns2[0]));
$ret = array_merge($ns2, array(implode("", _cny_map_unit(str_split($ns1), $grees)), ""));
$ret = implode("", array_reverse(_cny_map_unit($ret, $cnyunits)));
return str_replace(array_keys($cnums), $cnums, $ret);
}
function _cny_map_unit($list, $units) {
$ul = count($units);
$xs = array();
foreach (array_reverse($list) as $x) {
$l = count($xs);
if ($x != "0" || !($l % 4))
$n = ($x == '0' ? '' : $x) . ($units[($l - 1) % $ul]);
else
$n = is_numeric($xs[0][0]) ? $x : '';
array_unshift($xs, $n);
}
return $xs;
}
51.PHP支持的数据类型
四种标量类型:
boolean (布尔型)
integer (整型)
float (浮点型, 也称作 double)
string (字符串)
两种复合类型:
array (数组)
object (对象)
最后是两种特殊类型:
resource (资源)
NULL (NULL)
为了确保代码的易读性,本手册还介绍了一些伪类型:
mixed
number
callback
52.请说明在php.ini中safe_mode开启之后对于PHP系统函数的影响?
safe_mode是唯一PHP_INI_SYSTEM属性,必须通过php.ini或httpd.conf来设置。要启用safe_mode,只需修改php.ini: safe_mode = On 或者修改httpd.conf,定义目录:
Options FollowSymLinks php_admin_value safe_mode 1
重启apache后safe_mode就生效了。启动safe_mode,会对许多PHP函数进行限制,特别是和系统相关的文件打开、命令执行等函数。
默认情况下,所有操作文件的函数将只能操作与脚本UID相同的文件。
注意:如果在linux中启用了safe_mode,那么如果要在一个目录中创建一个目录,比如要在/upload中创建一个20081202,那么/upload目录所有者必须是apache的所有者
53.zend optimizer是什么
用优化代码的方法来提高php应用程序的执行速度,且可以解密Zend Guard加密过后代码,使之能够正常运行
54.设计一个缓存系统。写出思路。画出图。考虑命中,生存期等多种要素
55.数据库中的事务是什么?
事务(transaction)是作为一个单元的一组有序的数据库操作。如果组中的所有操作都成功,则认为事务成功,即使只有一个操作失败,事务也不成功。如果所有操作完成,事务则提交,其修改将作用于所有其他数据库进程。如果一个操作失败,则事务将回滚,该事务所有操作的影响都将取消
56.优化MYSQL数据库的方法
1、选取最适用的字段属性,尽可能减少定义字段长度,尽量把字段设置NOT NULL,例如'省份,性别',最好设置为ENUM
2、使用连接(JOIN)来代替子查询:
a.删除没有任何订单客户:DELETE FROM customerinfo WHERE customerid NOT in(SELECT customerid FROM orderinfo)
b.提取所有没有订单客户:SELECT FROM customerinfo WHERE customerid NOT in(SELECT customerid FROM orderinfo)
c.提高b的速度优化:SELECT FROM customerinfo LEFT JOIN orderid customerinfo.customerid=orderinfo.customerid
WHERE orderinfo.customerid IS NULL
3、使用联合(UNION)来代替手动创建的临时表
a.创建临时表:SELECT name FROM `nametest` UNION SELECT username FROM `nametest2`
4、事务处理:
a.保证数据完整性,例如添加和修改同时,两者成立则都执行,一者失败都失败
mysql_query("BEGIN");
mysql_query("INSERT INTO customerinfo (name) VALUES ('$name1')";
mysql_query("SELECT * FROM `orderinfo` where customerid=".$id");
mysql_query("COMMIT");
5、锁定表,优化事务处理:
a.我们用一个 SELECT 语句取出初始数据,通过一些计算,用 UPDATE 语句将新值更新到表中。
包含有 WRITE 关键字的 LOCK TABLE 语句可以保证在 UNLOCK TABLES 命令被执行之前,
不会有其它的访问来对 inventory 进行插入、更新或者删除的操作
mysql_query("LOCK TABLE customerinfo READ, orderinfo WRITE");
mysql_query("SELECT customerid FROM `customerinfo` where id=".$id);
mysql_query("UPDATE `orderinfo` SET ordertitle='$title' where customerid=".$id);
mysql_query("UNLOCK TABLES");
6、使用外键,优化锁定表
a.把customerinfo里的customerid映射到orderinfo里的customerid,
任何一条没有合法的customerid的记录不会写到orderinfo里
CREATE TABLE customerinfo
(
customerid INT NOT NULL,
PRIMARY KEY(customerid)
)TYPE = INNODB;
CREATE TABLE orderinfo
(
orderid INT NOT NULL,
customerid INT NOT NULL,
PRIMARY KEY(customerid,orderid),
FOREIGN KEY (customerid) REFERENCES customerinfo
(customerid) ON DELETE CASCADE
)TYPE = INNODB;
注意:'ON DELETE CASCADE',该参数保证当customerinfo表中的一条记录删除的话同时也会删除order
表中的该用户的所有记录,注意使用外键要定义事务安全类型为INNODB;
7、建立索引:
a.格式:
(普通索引)->
创建:CREATE INDEX <索引名> ON tablename (索引字段)
修改:ALTER TABLE tablename ADD INDEX [索引名] (索引字段)
创表指定索引:CREATE TABLE tablename([...],INDEX[索引名](索引字段))
(唯一索引)->
创建:CREATE UNIQUE <索引名> ON tablename (索引字段)
修改:ALTER TABLE tablename ADD UNIQUE [索引名] (索引字段)
创表指定索引:CREATE TABLE tablename([...],UNIQUE[索引名](索引字段))
(主键)->
它是唯一索引,一般在创建表是建立,格式为:
CREATA TABLE tablename ([...],PRIMARY KEY[索引字段])
8、优化查询语句
a.最好在相同字段进行比较操作,在建立好的索引字段上尽量减少函数操作
例子1:
SELECT * FROM order WHERE YEAR(orderDate)<2008;(慢)
SELECT * FROM order WHERE orderDate<"2008-01-01";(快)
例子2:
SELECT * FROM order WHERE addtime/7<24;(慢)
SELECT * FROM order WHERE addtime<24*7;(快)
例子3:
SELECT * FROM order WHERE title like "%good%";
SELECT * FROM order WHERE title>="good" and name<"good";
57.在PHP中,heredoc是一种特殊的字符串,它的结束标志必须?
heredoc的语法是用"<<<"加上自己定义成对的标签,在标签范围內的文字视为一个字符串
定界符
例子:
$str = <<<EOT后
my name is Jiang Qihui!
EOT;
58.InnoDB引擎中,如何开启一个排它的读写锁
lock tables test write; //经过测试启用另一个mysql回话都不能读和写test表,表明此答案是正确的(答案很简单,仅供回到,其他里面涉及的东西多的吓人)
59.面向对象中,self与$this的区别是?
this是指向当前对象的指针(姑且用C里面的指针来看吧),self是指向当前类的指针,parent是指向父类的指针(作者注,不能看做c的指针,只能看做类似别名的东西)
1.self可以访问本类中的静态属性和静态方法,可以访问父类中的静态属性和静态方法。用self时,可以不用实例化的
2.this可以调用本类中的方法和属性,也可以调用父类中的可以调的方法和属性,可以说除过静态和const常量,基本上其他都可以使用this联络
3.parent是指向父类的指针,一般我们使用parent来调用父类的构造函数
60.求两个日期的差数,例如2007-2-5 ~ 2007-3-6 的日期差数
$begin=strtotime('2007-2-5');
$end=strtotime('2007-3-6');
echo ($end-$begin)/(24*3600);
61.请简述数据库设计的范式及应用
一般第3范式就足以,用于表结构的优化,这样做既可以避免应用程序过于复杂同时也避免了SQL语句过于庞大所造成系统效率低下。
ANSWER:
第一范式:若关系模式R的每一个属性是不可再分解的,再属于第一范式。
第二范式:若R属于第一范式,且所有的非码属性都完全函数依赖于码属性,则为第二范式。
第三范式:若R属于第二范式,且所有的非码属性没有一个是传递函数依赖于候选码,则属于第三范式
62. mysql建立索引
(普通索引)->
创建:CREATE INDEX <索引名> ON tablename (索引字段)
修改:ALTER TABLE tablename ADD INDEX [索引名] (索引字段)
创表指定索引:CREATE TABLE tablename([...],INDEX[索引名](索引字段))
(唯一索引)->
创建:CREATE UNIQUE <索引名> ON tablename (索引字段)
修改:ALTER TABLE tablename ADD UNIQUE [索引名] (索引字段)
创表指定索引:CREATE TABLE tablename([...],UNIQUE[索引名](索引字段))
(主键)->
它是唯一索引,一般在创建表是建立,格式为:
CREATA TABLE tablename ([...],PRIMARY KEY[索引字段])
63.foo()和@foo()之间有什么区别?
@foo()控制错误输出 有些时候@无法完全一致错误显示,一定要设置错误显示级别
64.为了微信页面好看,将中文字符小于4的补充空格
function cn_string_to_4($str) {
if (mb_strlen($str, 'utf8') < 4) {
return $str = $str . str_repeat(' ', (4 - mb_strlen($str, 'utf8')));
}
return $str;
}
65.context上下文 php版解释
context翻译为上下文其实不是很好,只是翻译理解大概的作用,对于开发来说,context是对定义的使用的变量,常量或者说是配置,
部分的函数功能除了缺省值之外,往往需要手动设置一些定义量来配合当前语境,来适配开发者想法的需求,这些可以适配其他方法或者函数的
定义量就是context,数据来源有可能是变量,也可能是数据流,这些函数是为了适应更多其他函数调用或者方便开发者使用操作函数,
让开发者配合当前语境来设置,比如stream_context_create 通过设置选项来让file_get_contents实现更多需求的功能(php中例子)
比如fopen操作多个数据流,返回值可以区分不同的打开的数据流,这个不是很确切但是足以说明问题
66.php变量和数组大小限制
php.ini 的memory_limit的大小就是php变量的大小
67.php数组操作
$people = array("Bill", "Steve", "Mark", "David");
echo current(people)."<br>";//当前元素是Billechonext(people)."<br>";
echo current(people)."<br>";//现在当前元素是Steveechoprev(people)."<br>";
echo end(people)."<br>";//最后一个元素是Davidechoprev(people)."<br>";
echo current(people)."<br>";//目前的当前元素是Markechoreset(people)."<br>";
echo next($people) . "<br>"; // Bill 的下一个元素是 Steve
print_r (each($people)); // 返回当前元素的键名和键值(目前是 Steve),并向前移动内部指针
68.mysql替换制定的内容的 类似正则表达式的功能
content= 'asnfojassozxpdsgdspdps神龙架谁骄傲的骄傲搜ID飞机扫'
SELECT content FROM test WHERE id =1
吧zx替换成ZZZZ
UPDATE test SET content = REPLACE(content,'zx','ZZZZ') WHERE id =1
content = asnfojassoZZZZpdsgdspdps神龙架谁骄傲的骄傲搜ID飞机扫
吧ZZZZ到神龙架之间的内容替换成空
UPDATE test SET content =
INSERT(content, INSTR(content,'ZZZZ')+LENGTH('ZZZZ'), INSTR(content,'神农架')- INSTR(content,'ZZZZ')-LENGTH('神农架'),'')
WHERE id =1
content =
`INSERT`(str,pos,len,newstr)
str 需要替换的字段
pos其实位置
len 长度
newstr 需要替换的字符
69.PHP.ini中auto_prepend_file与auto_append_file的用法
使用auto_prepend_file与auto_append_file在所有页面的顶部与底部require文件。
php.ini中有两项:
auto_prepend_file 在页面顶部加载文件
auto_append_file 在页面底部加载文件
使用这种方法可以不需要改动任何页面,当需要修改顶部或底部require文件时,只需要修改auto_prepend_file与auto_append_file的值即可。
例如:修改php.ini,修改auto_prepend_file与auto_append_file的值。
auto_prepend_file = "/home/fdipzone/header.php"
auto_append_file = "/home/fdipzone/footer.php"
这样就不需要修改代码,但是移植的时候一定要记得加上这个配置
70.php吧字符串直接转换成数组处理
$str ='123456';
echo strlen($str) - 1;
echo '<br>';
echo $str{strlen($str) - 1};
echo '<br>';
echo $str[strlen($str) - 1];
以后处理即使很复杂的字符串,都可以很轻松的处理了
71. windows 和linux mysql怎么导入大文件的sql文件,防止超时
C:\wamp\bin\mysql\mysql5.5.20\bin\mysql -u root -p --default-character-set=utf8 tt < C:\22.sql
上面是windows,请记住一定要设置编码格式 tt 是数据库名称
linux
导出命令
/usr/local/Comsenz/mysql/bin/mysqldump -uroot -p shopnc > /root/22.sql
导入命令
/usr/local/Comsenz/mysql/bin/mysql -uroot -proot@ tt < /root/22.sql
72.php代码优化,因为内容过多目前只引用博客的内容,精简列下几点
http://www.cnblogs.com/zx-admin/p/4762961.html
用单引号代替双引号来包含字符串,这样做会更快一些。因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的“函数”(译注:PHP手册中说echo是语言结构,不是真正的函数,故把函数加上了双引号)。
PS:在单引号中,PHP不会自动搜寻变量、转义字符等,因此效率上快很多。而一般来说字符串是没有变量的,所以使用双引号会导致性能不佳。
1、如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍。
PS:事实上,function、method、static method的速度不会有太大差异。具体可见“PHP函数的实现原理及性能分析【转载】”一文。
2、row[′id′]的速度是row[′id′]的速度是row[id]的7倍。
PS:不太懂,貌似差异只有后者会先判断id这个宏是否存在,如果不存在则自动转变为字符串。
3、echo 比 print 快,并且使用echo的多重参数(译注:指用逗号而不是句点)代替字符串连接,比如echo str1,str1,str2。
PS:如果使用echo str1.str1.str2 就会需要 PHP 引擎首先把所有的变量连接起来,然后在输出,而echo str1,str1,str2,PHP 引擎就会按照循序输出他们
4、在执行for循环之前确定最大循环数,不要每循环一次都计算最大值,最好运用foreach代替。
PS:像count、strlen这样的操作其实是O(1)的,因此不会带来太多消耗,当然避免每次循环都计算是比较好的策略。最好用foreach代替for,这个效率更高,如果考虑到 foreach(arrayasarrayasvar)每次拷贝的消耗,可以使用foreach(array as &array as &var)这样的引用。
5、注销那些不用的变量尤其是大数组,以便释放内存。
PS:如果没有记错的话,unset($array)不会立刻释放内存,但随时释放是个好习惯。
6、尽量避免使用__get,__set,__autoload。
7、require_once()代价昂贵。
PS:require_once和include_once需要判重,因此效率上要低,但是5.2版本后效率问题已经基本解决。
8、include文件时尽量使用绝对路径,因为它避免了PHP去include_path里查找文件的速度,解析操作系统路径所需的时间会更少。
PS:支持,尽量少用iniset()来设置include_path。
9、如果你想知道脚本开始执行(译注:即服务器端收到客户端请求)的时刻,使用SERVER[′REQUESTTIME′]要好于time()。PS:SERVER[′REQUESTTIME′]要好于time()。PS:_SERVER['REQUEST_TIME']保存了发起该请求时刻的时间戳,而time()则返回当前时刻的Unix时间戳。
10、函数代替正则表达式完成相同功能。
PS:这种函数是指strtok、strstr、strpos、str_replace、substr、explode、implode等等。
11、str_replace函数比preg_replace函数快,但strtr函数的效率是str_replace函数的四倍。
PS:字符串操作比正则替换要快。
12、如果一个字符串替换函数,可接受数组或字符作为参数,并且参数长度不太长,那么可以考虑额外写一段替换代码,使得每次传递参数是一个字符,而不是只写一行代码接受数组作为查询和替换的参数。
PS:需要考虑到内置函数和用户自定义函数的开销差异,恐怕这种做法得不偿失。
13、使用选择分支语句(译注:即switch case)好于使用多个if,else if语句。
PS:php中switch支持数值和字符串变量,比C的switch要好用,建议使用。
14、用@屏蔽错误消息的做法非常低效,极其低效。
PS:有什么替代方法吗?没有的话还是不得不用的……
15、打开apache的mod_deflate模块,可以提高网页的浏览速度。
16、数据库连接当使用完毕时应关掉,不要用长连接。
PS:在连接之前,最好设置一下相应的超时机制,例如链接超时、读写超时、等待超时等。
17、错误消息代价昂贵。
18、在方法中递增局部变量,速度是最快的。几乎与在函数中调用局部变量的速度相当。
19、递增一个全局变量要比递增一个局部变量慢2倍。
20、递增一个对象属性(如:$this->prop++)要比递增一个局部变量慢3倍。
21、递增一个未预定义的局部变量要比递增一个预定义的局部变量慢9至10倍。
22、仅定义一个局部变量而没在函数中调用它,同样会减慢速度(其程度相当于递增一个局部变量)。PHP大概会检查看是否存在全局变量。
23、方法调用看来与类中定义的方法的数量无关,因为我(在测试方法之前和之后都)添加了10个方法,但性能上没有变化。
24、派生类中的方法运行起来要快于在基类中定义的同样的方法。
25、调用带有一个参数的空函数,其花费的时间相当于执行7至8次的局部变量递增操作。类似的方法调用所花费的时间接近于15次的局部变量递增操作。
26、Apache解析一个PHP脚本的时间要比解析一个静态HTML页面慢2至10倍。尽量多用静态HTML页面,少用脚本。
27、除非脚本可以缓存,否则每次调用时都会重新编译一次。引入一套PHP缓存机制通常可以提升25%至100%的性能,以免除编译开销。
28、尽量做缓存,可使用memcached。memcached是一款高性能的内存对象缓存系统,可用来加速动态Web应用程序,减轻数据库负载。对运算码 (OP code)的缓存很有用,使得脚本不必为每个请求做重新编译。
29、当操作字符串并需要检验其长度是否满足某种要求时,你想当然地会使用strlen()函数。此函数执行起来相当快,因为它不做任何计算,只返回在zval 结构(C的内置数据结构,用于存储PHP变量)中存储的已知字符串长度。但是,由于strlen()是函数,多多少少会有些慢,因为函数调用会经过诸多步骤,如字母小写化(译注:指函数名小写化,PHP不区分函数名大小写)、哈希查找,会跟随被调用的函数一起执行。在某些情况下,你可以使用isset() 技巧加速执行你的代码。
(举例如下)
if (strlen(foo) < 5) { echo “Foo is too short”foo) < 5) { echo “Foo is too short”$ }
(与下面的技巧做比较)
if (!isset(foo{5})) { echo “Foo is too short”foo{5})) { echo “Foo is too short”$ }
调用isset()恰巧比strlen()快,因为与后者不同的是,isset()作为一种语言结构,意味着它的执行不需要函数查找和字母小写化。也就是说,实际上在检验字符串长度的顶层代码中你没有花太多开销。
PS:长见识了。
30、当执行变量i的递增或递减时,i的递增或递减时,i++会比++i慢一些。这种差异是PHP特有的,并不适用于其他语言,所以请不要修改你的C或Java代码并指望它们能立即变快,没用的。++i慢一些。这种差异是PHP特有的,并不适用于其他语言,所以请不要修改你的C或Java代码并指望它们能立即变快,没用的。++i更快是因为它只需要3条指令(opcodes),$i++则需要4条指令。后置递增实际上会产生一个临时变量,这个临时变量随后被递增。而前置递增直接在原值上递增。这是最优化处理的一种,正如Zend的PHP优化器所作的那样。牢记这个优化处理不失为一个好主意,因为并不是所有的指令优化器都会做同样的优化处理,并且存在大量没有装配指令优化器的互联网服务提供商(ISPs)和服务器。
31、并不是事必面向对象(OOP),面向对象往往开销很大,每个方法和对象调用都会消耗很多内存。
32、并非要用类实现所有的数据结构,数组也很有用。
33、不要把方法细分得过多,仔细想想你真正打算重用的是哪些代码?
34、当你需要时,你总能把代码分解成方法。
PS:分解成方法要适当,行数少使用频率高的方法尽量用直接写代码,可以减少函数堆栈开销;且方法嵌套不宜过深,否则大大影响PHP的运行效率。
35、尽量采用大量的PHP内置函数。
36、如果在代码中存在大量耗时的函数,你可以考虑用C扩展的方式实现它们。
37、评估检验(profile)你的代码。检验器会告诉你,代码的哪些部分消耗了多少时间。Xdebug调试器包含了检验程序,评估检验总体上可以显示出代码的瓶颈。
38、mod_zip可作为Apache模块,用来即时压缩你的数据,并可让数据传输量降低80%。
39、在可以用 file_get_contents替代file、fopen、feof、fgets等系列方法的情况下,尽量用file_get_contents,因为他的效率高得多!但是要注意file_get_contents在打开一个URL文件时候的PHP版本问题;
PS:这个要记住,尽量使用file_get_contents和file_put_contents,不需要自己判断文件句柄打开是否成功。
40、尽量的少进行文件操作,虽然PHP的文件操作效率也不低的;
41、优化Select SQL语句,在可能的情况下尽量少的进行Insert、Update操作(在update上,我被恶批过);
42、尽可能的使用PHP内部函数(但是我却为了找个PHP里面不存在的函数,浪费了本可以写出一个自定义函数的时间,经验问题啊!);
PS:内置函数比用户自定义函数效率高了将近一个数量级。
43、循环内部不要声明变量,尤其是大变量:对象(这好像不只是PHP里面要注意的问题吧?);
PS:这个必须的,变量过多或者过大时,每次重分配的开销就无法忽略。
44、多维数组尽量不要循环嵌套赋值;
45、在可以用PHP内部字符串操作函数的情况下,不要用正则表达式;
46、foreach效率更高,尽量用foreach代替while和for循环;
47、用单引号替代双引号引用字符串;
PS:晕,这个不就是第一条吗?
48、“用i+=1代替i=i+1。符合c/c++的习惯,效率还高”;
49、对global变量,应该用完就unset()掉;
i++和++i++和++i的区别,这个很多公司问代码优化最后的一个问题,问题是这种写法在php在opcode层面的时候是++i性能更好,但是whocare,实际上,在执行成编译之后0.1之后,性能是一样的,呵呵,因为php是c编写的,只不过是opcode的时候回多出一个临时变量,是php语言自身解析代码的做法和c语言不一样,但是最终是有那么十万分一毫秒的损失,但是但就一个临时变量就是更改代码习惯,想想不觉得蛋疼吗?你一个功能方法使用的临时变量不知道有多少,在或者有人会说代码性能就是这么多个十万分之一累加起来的,其实这种扣细节的人,只不过是压工资的理由而已,实际开发,whofuckingcare你个i性能更好,但是whocare,实际上,在执行成编译之后0.1之后,性能是一样的,呵呵,因为php是c编写的,只不过是opcode的时候回多出一个临时变量,是php语言自身解析代码的做法和c语言不一样,但是最终是有那么十万分一毫秒的损失,但是但就一个临时变量就是更改代码习惯,想想不觉得蛋疼吗?你一个功能方法使用的临时变量不知道有多少,在或者有人会说代码性能就是这么多个十万分之一累加起来的,其实这种扣细节的人,只不过是压工资的理由而已,实际开发,whofuckingcare你个i++和++$i是怎么样写的,公司只关心你能不能完成某个功能模块,什么时间可以完成,我研究过很多开源cms的代码,实际中发现,完全都不是一回事,这些建议只有少一部分运用到实际开发中,开发更多是为了实现某种特殊目的而是做的,比如我需要实现很复杂的逻辑业务,或者我需要这个模块需要很好的性能,或者我需要做成接口,而这个时候往往和这些代码优化有屁关系
php的口号就是快,粗,易,面试你的人分要吧写c/c++,或者java的习惯拖进php,也没办法,其实这个时候你完全可以说,你应该是找个java或者c/c++程序员来写php
1. 短代码不等于快的代码
很多人在写程序时希望将代码写的越简洁越好,但是越短的代码有时候反而需要更长的执行时间。
2. 在写程序的时候更应该注重程序的扩展性,而不是追求速度。
3. 在优化你的代码之前,先看看跟数据库有关的部分,因为大多数应用程序的瓶颈在数据库而不是代码。
4. 微优化得不偿失
什么叫做微优化?就像前面所说的将正则表达式部分的代码改用字符串函数代替。这样做有以下缺点:
(1)花费时间较长
(2)不会根本上解决性能问题
(3)很有可能会破坏以前的代码从而产生未知的错误
(4)付出大于回报
还有关于代码结构的优化,也是重构的技巧
1,功能性代码,重复使用最好做成公用型函数,不一定需要做成完整的类,就是提取公共代码
2,常用静态常量,建议集中起来作为配置文件,全局使用
引用官方文档的一句话,很多时候不需要自作聪明的去优化代码,因为编译器会帮你完整这部分工作
作者注:php和c/c++完全不一样,不要以c/c++的理解去优化代码
73. php的内存回收机制
这个根据不用版本不同,5.X和7.X会有写不同
74. 支持的协议和封装协议
file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
常用的
php:// 访问各个输入/输出流
比如接受一些二进制的数据流 $data = urldecode(file_get_contents('php://input'));
其实这个用处很大,可以好好研究,特别是各种语言对接API的时候
php://input 是个可以访问请求的原始数据的只读流。 POST 请求的情况下,最好使用 php://input 来代替 $HTTP_RAW_POST_DATA,因为它不依赖于特定的 php.ini 指令。 而且,这样的情况下 $HTTP_RAW_POST_DATA 默认没有填充, 比激活 always_populate_raw_post_data 潜在需要更少的内存。 enctype="multipart/form-data" 的时候 php://input 是无效的
php://output
php://output 是一个只写的数据流, 允许你以 print 和 echo 一样的方式 写入到输出缓冲区。
php://fd
php://fd 允许直接访问指定的文件描述符。 例如 php://fd/3 引用了文件描述符 3。
php://memory 和 php://temp
php://memory 和 php://temp 是一个类似文件 包装器的数据流,允许读写临时数据。 两者的唯一区别是 php://memory 总是把数据储存在内存中, 而 php://temp 会在内存量达到预定义的限制后(默认是 2MB)存入临时文件中。 临时文件位置的决定和 sys_get_temp_dir() 的方式一致。
php://temp 的内存限制可通过添加 /maxmemory:NN 来控制,NN 是以字节为单位、保留在内存的最大数据量,超过则使用临时文件。
php://filter
php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。
php://filter 目标使用以下的参数作为它路径的一部分。 复合过滤链能够在一个路径上指定。详细使用这些参数可以参考具体范例。
75.获取系统和用定义的常量,方法,变量
get_defined_constants();//获取定义的常量
get_defined_vars();//获取定义的变量
get_defined_functions();//获取定义的方法
76. php运行模式的比较 cgi fast-cgi cli web模块模式 多线程
参考博客地址:http://www.cnblogs.com/zx-admin/p/4082992.html
http://www.cnblogs.com/zx-admin/p/5564984.html
在说明多线程的题前,需要弄清楚以下几个问题
1,ts 和 nts的区别
Thread Safe和NoneThread Safe
先说windows的,在php官网,在windows区域有在文件下在有
http://windows.php.net/download#php-7.0
文件名有很明显区分
VC14 x86 Non Thread Safe (2016-May-25 23:02:14)
VC14 x86 Thread Safe (2016-May-25 23:02:14)
VC6与VC9的区别:
VC6版本是使用Visual Studio 6编译器编译的,如果你的PHP是用Apache来架设的,那你就选择VC6版本。
VC9版本是使用Visual Studio 2008编译器编译的,如果你的PHP是用IIS来架设的,那你就选择 VC9版本。
VC9版本是针对IIS服务器的版本,没有对APACHE的支持,而VC6版本对IIS和apache都提供了支持
Windows版的PHP从版本5.2.1开始有Thread Safe和NoneThread Safe之分。
先从字面意思上理解,Thread Safe是线程安全,执行时会进行线程(Thread)安全检查,以防止有新要求就启动新线程的CGI执行方式而耗尽系统资源。Non Thread Safe是非线程安全,在执行时不进行线程(Thread)安全检查。
Linux上的PHP同样有NTS和TS版本的区别,默认是NTS版本,configure时加上--enable-maintainer-zts则编译为TS版本.什么时候需要TS版本呢?比如你要使用pthreads这个多线程的PECL扩展时,或者PHP以MOD_PHP嵌入多线程运行下的Apache,比如Apache在Linux上提供的Event MPM就是一个多进程多线程的工作模型,Windows上Apache采用的WinNT MPM也是一个多线程模型,这时都需要TS版本的PHP.
而如果以PHP-FPM(比如搭配Nginx或者Apache的mod_fastcgi)或者PHP-CGI(比如搭配Apache的mod_fcgid或者Win上的IIS)来运行PHP,则一般都不需要TS线程安全版本的PHP.这个在之前博客也说过
2,运行模式
1)CGI(通用网关接口 / Common Gateway Interface)
2)FastCGI(常驻型CGI / Long-Live CGI)
3)CLI(命令行运行 / Command Line Interface)
4)Web模块模式(Apache等Web服务器运行的模式)
5)ISAPI(Internet Server Application Program Interface)
备注:在PHP5.3以后,PHP不再有ISAPI模式,安装后也不再有php5isapi.dll这个文件。要在IIS6上使用高版本PHP,必须安装FastCGI 扩展,然后使IIS6支持FastCGI。
为什么要说运行模式呢?因为在有些扩展并发的时候,有些扩展只能在cli下运行,其实不是
3,php多线程
目前常用的扩展有pcnlt,POSIX ,pthreads,这三个比较多,但是与其说是多线程其实多进程,在并发的时候会巨急消耗内存所以用的时候,请注意,比如pcnlt,
真的多线程只有pthreads,但是本人没有确认过,参看http://zyan.cc/pthreads/,因为我现在的测试环境是nts的,所有测试就必须重新在做一个新环境
所以来不及测试,后续更新测试结果,还有一个问题就是php-fpm去管理php的内存带来的php并发效果不错,但是php-fpm会有一个坏处就是执行完之后,不会主动把内存
还给系统而是吧资源依然控制在php-fpm,所以为什么php第一次运行慢,第二次速度就上来了,这个就带来一个问题关于php-fpm分配内存的选择
dm有三种分配方式dynamic ,static,demand,光这个调优就得一片文章来讲,所以pcnlt在服务器正式环境使用 最好是吧内存弄大一些,而且并发数也不要多
不然很容易内存消耗过多,导致错误,这里还有一个地方值得注意的是,当php以静态模块在apache下运行的时候内存消耗是怎么样的,会及时还给系统吗?,和php-fpm管理内存对比也是值得注意的,这测试也是有必要去做的
如果实际项目需要使用建议使用 workerman swoole
1、cgi (Common Gateway Interface)
CGI即通用网关接口(Common Gateway Interface),它是一段程序, 通俗的讲CGI就象是一座桥,把网页和WEB服务器中的执行程序连接起来,它把HTML接收的指令传递给服务器的执行程序,再把服务器执行程序的结果返还给HTML页。CGI 的跨平台性能极佳,几乎可以在任何操作系统上实现。 CGI已经是比较老的模式了,这几年都很少用了。
每有一个用户请求,都会先要创建cgi的子进程,然后处理请求,处理完后结束这个子进程,这就是fork-and-execute模式。 当用户请求数量非常多时,会大量挤占系统的资源如内存,CPU时间等,造成效能低下。所以用cgi方式的服务器有多少连接请求就会有多少cgi子进程,子进程反复加载是cgi性能低下的主要原因。
如果不想把 PHP 嵌入到服务器端软件(如 Apache)作为一个模块安装的话,可以选择以 CGI 的模式安装。或者把 PHP 用于不同的 CGI 封装以便为代码创建安全的 chroot 和 setuid 环境。这样每个客户机请求一个php文件,Web服务器就调用php.exe(win下是php.exe,linux是php)去解释这个文件,然后再把解释的结果以网页的形式返回给客户机。 这种安装方式通常会把 PHP 的可执行文件安装到 web 服务器的 cgi-bin 目录。CERT 建议书
CA-96.11 建议不要把任何的解释器放到 cgi-bin 目录。
这种方式的好处是把web server和具体的程序处理独立开来,结构清晰,可控性强,同时缺点就是如果在高访问需求的情况下,cgi的进程fork就会成为很大的服务器负担,想 象一下数百个并发请求导致服务器fork出数百个进程就明白了。这也是为什么cgi一直背负性能低下,高资源消耗的恶名的原因。
CGI模式安装:
CGI已经是比较老的模式了,这几年都很少用了,所以我们只是为了测试。
安装CGI模式需要注释掉
LoadModule php5_module modules/libphp5.so 这行。如果不注释这行会一直走到handler模式。也就是模块模式。
然后在httpd.conf增加action:
Action application/x-httpd-php /cgi-bin/
如果在/cgi-bin/目录找不到php-cgi.可自行从php的bin里面cp一个。
然后重启apache,再打开测试页面发现Server API变成:CGI/FastCGI。说明成功切换为cgi模式。
问题:
1) 如果cgi程序放在/usr/local/httpd/cgi-bin/里无法执行,遇到403或500错误的话
打开apache错误日志 有如下提示: Permission denied: exec of
可以检查cgi程序的属性,按Linux contexts文件 里定义的,/usr/local/httpd/cgi-bin/里必须是httpd_sys_script_exec_t 属性。 通过ls -Z查看,如果不是则通过如下命令更改: chcon -t httpd_sys_script_exec_t /var/www/cgi-bin/*.cgi 如果是虚拟主机里的cgi,则参考问题2使之能正常使用普通的功能后,再通过chcon设置cgi文件的context为
httpd_sys_script_exec_t即可。chcon -R -t httpd_sys_script_exec_t cgi-bin/
2) apache错误提示:.... malformed header from script. Bad header=
根据提示说明有header有问题,查看文件输出的第一句话是什么,应该类似于如下
Content-type: text/plain; charset=iso-8859-1\n\n
或者Content-type:text/html\n\n
注意:声明好Content-type后要输出两个空行。
3)apache错误提示: Exec format error
脚本解释器设置错误。脚本第一行应该以'#!解释器路径'的形式, 填写脚本解释器的路径,如果是PERL程序,常见的路径为: #!/usr/bin/perl 或 #!/usr/local/bin/perl 如果是PHP程序,不需要填写解释器路径,系统会自动找到PHP。
2、fast-cgi模式
fast-cgi 是cgi的升级版本,FastCGI 像是一个常驻 (long-live) 型的 CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去 fork 一次 (这是 CGI 最为人诟病的 fork-and-execute 模式)。
FastCGI的工作原理是:
(1)、Web Server启动时载入FastCGI进程管理器【PHP的FastCGI进程管理器是PHP-FPM(php-FastCGI Process Manager)】(IIS ISAPI或Apache Module);
(2)、FastCGI进程管理器自身初始化,启动多个CGI解释器进程 (在任务管理器中可见多个php-cgi.exe)并等待来自Web Server的连接。
(3)、当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi。
(4)、FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在 WebServer中)的下一个连接。在正常的CGI模式中,php-cgi.exe在此便退出了。
在CGI模式中,你可以想象 CGI通常有多慢。每一个Web请求PHP都必须重新解析php.ini、重新载入全部dll扩展并重初始化全部数据结构。使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。
Fastcgi的优点:
1)从稳定性上看, fastcgi是以独立的进程池运行来cgi,单独一个进程死掉,系统可以很轻易的丢弃,然后重新分 配新的进程来运行逻辑.
2)从安全性上看,Fastcgi支持分布式运算. fastcgi和宿主的server完全独立, fastcgi怎么down也不会把server搞垮.
3)从性能上看, fastcgi把动态逻辑的处理从server中分离出来, 大负荷的IO处理还是留给宿主server, 这样宿主server可以一心一意作IO,对于一个普通的动态网页来说, 逻辑处理可能只有一小部分, 大量的图片等静态
FastCGI缺点:说完了好处,也来说说缺点。从我的实际使用来看,用FastCGI模式更适合生产环境的服务器。但对于开发用机器来说就不太合适。因为当使用 Zend Studio调试程序时,由于 FastCGI会认为 PHP进程超时,从而在页面返回 500错误。这一点让人非常恼火,所以我在开发机器上还是换回了 ISAPI模式。
3、cli模式
cli是php的命令行运行模式,大家经常会使用它,但是可能并没有注意到(例如:我们在linux下经常使用 "php -m"查找PHP安装了那些扩展就是PHP命令行运行模式;有兴趣的同学可以输入php -h去深入研究该运行模式)
4、模块模式
模块模式是以mod_php5模块的形式集成,此时mod_php5模块的作用是接收Apache传递过来的PHP文件请求,并处理这些请求,然后将处理后的结果返回给Apache。如果我们在Apache启动前在其配置文件中配置好了PHP模块(mod_php5), PHP模块通过注册apache2的ap_hook_post_config挂钩,在Apache启动的时候启动此模块以接受PHP文件的请求。
除了这种启动时的加载方式,Apache的模块可以在运行的时候动态装载,这意味着对服务器可以进行功能扩展而不需要重新对源代码进行编译,甚至根本不需要停止服务器。我们所需要做的仅仅是给服务器发送信号HUP或者AP_SIG_GRACEFUL通知服务器重新载入模块。但是在动态加载之前,我们需要将模块编译成为动态链接库。此时的动态加载就是加载动态链接库。 Apache中对动态链接库的处理是通过模块mod_so来完成的,因此mod_so模块不能被动态加载,它只能被静态编译进Apache的核心。这意味着它是随着Apache一起启动的。
Apache是如何加载模块的呢?我们以前面提到的mod_php5模块为例。首先我们需要在Apache的配置文件httpd.conf中添加一行:
该运行模式是我们以前在windows环境下使用apache服务器经常使用的,而在模块化(DLL)中,PHP是与Web服务器一起启动并运行的。(是apache在CGI的基础上进行的一种扩展,加快PHP的运行效率)
LoadModule php5_module modules/mod_php5.so
这里我们使用了LoadModule命令,该命令的第一个参数是模块的名称,名称可以在模块实现的源码中找到。第二个选项是该模块所处的路径。如果需要在服务器运行时加载模块,可以通过发送信号HUP或者AP_SIG_GRACEFUL给服务器,一旦接受到该信号,Apache将重新装载模块,而不需要重新启动服务器。
5、php 在nginx 中运行模式(nginx+PHP-FPM )
使用FastCGI方式现在常见的有两种stack:ligthttpd+spawn-fcgi;另外一种是nginx+PHP-FPM(也可以用spawn-fcgi)。
A、如上面所说该两种结构都采用FastCGI对PHP支持,因此HTTPServer完全解放出来,可以更好地进行响应和并发处理。因此lighttpd和nginx都有small, but powerful和efficient的美誉。
B、该两者还可以分出一个好坏来,spawn-fcgi由于是lighttpd的一部分,因此安装了lighttpd一般就会使用spawn-fcgi对php支持,但是目前有用户说ligttpd的spwan-fcgi在高并发访问的时候,会出现上面说的内存泄漏甚至自动重启fastcgi。即:PHP脚本处理器当机,这个时候如果用户访问的话,可能就会出现白页(即PHP不能被解析或者出错)。
另一个:首先nginx不像lighttpd本身含带了fastcgi(spawn-fcgi),因此它完全是轻量级的,必须借助第三方的FastCGI处理器才可以对PHP进行解析,因此其实这样看来nginx是非常灵活的,它可以和任何第三方提供解析的处理器实现连接从而实现对PHP的解析(在nginx.conf中很容易设置)。nginx可以使用spwan-fcgi(需要一同安装lighttpd,但是需要为nginx避开端口,一些较早的blog有这方面安装的教程),但是由于spawn-fcgi具有上面所述的用户逐渐发现的缺陷,现在慢慢减少使用nginx+spawn-fcgi组合了。
C、由于spawn-fcgi的缺陷,现在出现了新的第三方(目前还是,听说正在努力不久将来加入到PHP core中)的PHP的FastCGI处理器,叫做PHP-FPM(具体可以google)。它和spawn-fcgi比较起来有如下优点:
由于它是作为PHP的patch补丁来开发的,安装的时候需要和php源码一起编译,也就是说编译到php core中了,因此在性能方面要优秀一些;
同时它在处理高并发方面也优于spawn-fcgi,至少不会自动重启fastcgi处理器。具体采用的算法和设计可以google了解。
因此,如上所说由于nginx的轻量和灵活性,因此目前性能优越,越来越多人逐渐使用这个组合:nginx+PHP/PHP-FPM
总结:
目前在HTTPServer这块基本可以看到有三种stack比较流行:
(1)Apache+mod_php5
(2)lighttp+spawn-fcgi
(3)nginx+PHP-FPM
三者后两者性能可能稍优,但是Apache由于有丰富的模块和功能,目前来说仍旧是老大。有人测试nginx+PHP-FPM在高并发情况下可能会达到Apache+mod_php5的5~10倍,现在nginx+PHP-FPM使用的人越来越多。
77. 隐藏 PHP
统弱点的难度。在 php.ini 文件里设置 expose_php = off ,可以减少他们能获得的有用信息。
一些简单的方法可以帮助隐藏 PHP,这样做可以提高攻击者发现系另一个策略就是让 web 服务器用 PHP 解析不同扩展名。无论是通过 .htaccess 文件还是 Apache 的配置文件,都可以设置能误导攻击者的文件扩展名:
AddType application/x-httpd-php .asp .py .pl
使用未知的扩展名作为 PHP 的扩展名
AddType application/x-httpd-php .bop .foo .133t
用 HTML 做 PHP 的文件后缀
AddType application/x-httpd-php .htm .html
可以看头部信息只要是php,仅做一部分防御作用
78. 范围解析操作符 (::)
范围解析操作符(也可称作 Paamayim Nekudotayim)或者更简单地说是一对冒号,可以用于访问静态成员,类常量,还可以用于覆盖类中的属性和方法。
79. 判断文件是否引用成功
if (false === @include_once 'OpenID/RelyingParty.php') {
exit;
exit('引用XX失败,请确保文件路径正确');
}
80.
100.php7特性
2.堆栈的理解
都可以看做是一维数组来操作,队列先进先出,出列只能在列头,进列只能在列尾,堆栈是后进先出,进栈和出栈都是从栈顶
堆栈的工作原理是什么?
堆栈是一种抽象数据结构,其操作机理是后进先出。当你把新条目推进堆栈时,已经在堆栈内的任何条目都会压到堆栈的深处。同样的,把一个条目从堆栈移出则会让堆栈内的其他条目都向堆栈的顶部移动。只有堆栈最顶端的条目能从堆栈中取出,条目离开堆栈的顺序和它们被推进堆栈的顺序一样。你不妨回想下自动售货机的装货和取货过程就明白了。