php优化

1. If a method c++an be static, declare it static. Speed improvement is by a factor of 4. 如果一个方法可静态化,就对它做静态声明。速率可提升至4倍。

2. echo is faster than print. echo 比 print 快。

3. Use echo’s multiple parameters instead of string concatenation. 使用echo的多重参数(译注:指用逗号而不是句点)代替字符串连接。

4. Set the maxvalue for your for-loops before and not in the loop. 在执行for循环之前确定最大循环数,不要每循环一次都计算最大值。

5. Unset your variables to free memory, especially large arrays. 注销那些不用的变量尤其是大数组,以便释放内存。

6. Avoid magic like __get, __set, __autoload 尽量避免使用__get,__set,__autoload.

7. require_once() is expensive require_once()代价昂贵。

8. Use full paths in includes and requires, less time spent on resolving the OS paths. 在包含文件时使用完整路径,解析操作系统路径所需的时间会更少。

继续阅读“php优化”

Redis类

phpredis是php的一个扩展,效率是相当高有链表排序功能,对创建内存级的模块业务关系

很有用;以下是redis官方提供的命令使用技巧:

下载地址如下:

https://github.com/owlient/phpredis(支持redis 2.0.4)
Redis::__construct构造函数
$redis = new Redis();

connect, open 链接redis服务
参数
host
: string,服务地址
port
: int,端口号
timeout
: float,链接时长 (可选, 默认为 0 ,不限链接时间)
注: 在redis.conf中也有时间,默认为300

pconnect, popen 不会主动关闭的链接
参考上面

继续阅读“Redis类”

Boolean 布尔类型

这是最简单的类型。boolean 表达了真值,可以为 TRUEFALSE

语法

要指定一个布尔值,使用关键字 TRUEFALSE。两个都不区分大小写。

<?php
$foo = true; // assign the value TRUE to $foo
?>

通常运算符所返回的 boolean 值结果会被传递给控制流程。

// == 是一个操作符,它检测两个变量是否相等,并返回一个布尔值
if ($action == “show_version”) {
echo “The version is 1.23”;
}

// 这样做是不必要的…
if ($show_separators == TRUE) {
echo “<hr>\n”;
}

// …因为可以使用下面这种简单的方式:
if ($show_separators) {
echo “<hr>\n”;
}

转换为布尔值

要明确地将一个值转换成 boolean,用 (bool) 或者 (boolean) 来强制转换。但是很多情况下不需要用强制转换,因为当运算符,函数或者流程控制结构需要一个 boolean 参数时,该值会被自动转换。

当转换为 boolean 时,以下值被认为是 FALSE

  • 布尔值 FALSE 本身
  • 整型值 0(零)
  • 浮点型值 0.0(零)
  • 空字符串,以及字符串 “0”
  • 不包括任何元素的数组
  • 不包括任何成员变量的对象(仅 PHP 4.0 适用)
  • 特殊类型 NULL(包括尚未赋值的变量)
  • 从空标记生成的 SimpleXML 对象

所有其它值都被认为是 TRUE(包括任何资源)。

-1 和其它非零值(不论正负)一样,被认为是 TRUE

var_dump((bool) “”);        // bool(false)
var_dump((bool) 1);         // bool(true)
var_dump((bool) -2);        // bool(true)
var_dump((bool) “foo”);     // bool(true)
var_dump((bool) 2.3e5);     // bool(true)
var_dump((bool) array(12)); // bool(true)
var_dump((bool) array());   // bool(false)
var_dump((bool) “false”);   // bool(true)

PHP截断函数mb_substr()介绍

mb_substr获取字符串的部分

string mb_substr ( string $str , int $start [, int $length = NULL [, string $encoding = mb_internal_encoding() ]] )

根据字符数执行一个多字节安全的 substr() 操作。 位置是从 str 的开始位置进行计数。 第一个字符的位置是 0。第二个字符的位置是 1,以此类推。

参数

str

从该 string 中提取子字符串。

start

str 中要使用的第一个字符的位置。

length

str 中要使用的最大字符数。 If omitted or NULL is passed, extract all characters to the end of the string.

encoding

encoding 参数为字符编码。如果省略,则使用内部字符编码。

返回值

mb_substr() 函数根据 startlength 参数返回 str 中指定的部分。

$str = ‘这样一来我的字符串就不会有乱码^_^’;

echo “mb_substr:” . mb_substr($str, 0, 7, ‘UTF-8’);
//结果:这样一来我的字
echo ”
“;

echo “mb_strcut:” . mb_strcut($str, 0, 6, ‘utf-8’);
//结果:这样

可以截断中英混合字符串不出现乱码。

empty()和isset()函数的区别

empty检查一个变量是否为空

如果 var 是非空或非零的值,则 empty() 返回 FALSE。换句话说,“”0“0”NULLFALSEarray()var $var; 以及没有任何属性的对象都将被认为是空的,如果 var 为空,则返回 TRUE

除了当变量没有置值时不产生警告之外,empty()(boolean) var 的反义词。

empty() 与 isset() 的一个简单比较。

<?php
$var = 0;
// 结果为 true,因为 $var 为空
if (empty($var)) {
echo ‘$var is either 0 or not set at all’;
}

// 结果为 false,因为 $var 已设置
if (!isset($var)) {
echo ‘$var is not set at all’;
}
?>

注意:

因为是一个语言构造器而不是一个函数,不能被 可变函数 调用。

empty() 只检测变量,检测任何非变量的东西都将导致解析错误。换句话说,后边的语句将不会起作用: empty(addslashes($name))

isset检测变量是否设置

检测变量是否设置,并且不是 NULL

如果已经使用 unset() 释放了一个变量之后,它将不再是 isset()。若使用 isset() 测试一个被设置成 NULL 的变量,将返回 FALSE。同时要注意的是一个 NULL 字节(”\0″)并不等同于 PHP 的 NULL 常数。

如果 var 存在并且值不是 NULL 则返回 TRUE,否则返回 FALSE

Warning

isset() 只能用于变量,因为传递任何其它参数都将造成解析错误。若想检测常量是否已设置,可使用 defined() 函数。

注意:

因为是一个语言构造器而不是一个函数,不能被 可变函数 调用。

如果使用 isset() 来检查对象无法访问的属性,如果 __isset() 方法已经定义则会调用这个重载方法。

Mencache

1、什么是Memcache

分布式高速缓存系统,存储在内存中

2、什么时候使用Memcache

在应用和数据库当中添加一个缓冲层,当第一次读取数据后,把数据存储在Memcache中,当第二次或者之后读取数据时,就从Memcache中读取,从而减轻Mysql数据库等服务器的压力。

Memcache使用场景:

  1. 非持久化存储:对数据存储要求不高
  2. 分布式存储:不适合单机使用
  3. key/value存储:格式简单,不支持List、Array数据格式

Memcache服务端和客户端的安装,自行google 百度。

PHP中使用Memcache

系统类:addServer,addServers,getStats,getVersion

数据类:add,set,delete,flush,replace,increment,get

进阶类:setMulti,deleteMulti,getMulti,getResultCode,getResultMessage

$m = new Memcached();
$m->addServer(‘127.0.0.1’,11211);
$m->add(‘mkey’,’mvalue’,600); // 参数1:键 参数2:键对应的值 参数3:保存时间(秒)
$m->set(‘mkey1’, ‘mvalue1’, 600); // 当对应键没有值存在时,新增一条,当存在时,覆盖掉原来的值

// increment 对缓存值进行自增
$m->set(‘num’, 5, 0);
$m->increment(‘num’, 2); // 对num所对应对值自增2
// decrement 对缓存值进行自减
$m->decrement(‘num’, 3); // 对num所对应的值自减3

// 删除数据
$m->delete(‘mkey’); // 删除对应键值对
$m->flush(); // 清空memcache所有缓存值,慎用

echo $m->get(‘mkey’); // 获取键所对应的值

// 一次设置多个值、一次获取多个值、一次删除多条数据
$array = array(
‘key’ => ‘value’,
‘key2’ => ‘value2’,
);
$m->setMulti($array, 0); // 参数1:键值对数组 参数2:保存时间
$res = $m->getMulti(array(‘key’, ‘key2’)); // 参数:键数组
print_r($res);
$m->deleteMulti(array(‘key’, ‘key2’)); // 参数:键数组

echo $m->getResultCode(); // 获取上一次操作返回的编码
echo $m->getResultMessage(); // 获取上一次操作返回的信息

封装自己的Memcache类

扩展性

可调试

尽量简便的操作,一个方法多种功能

 

项目中使用Memcache

1.即时生成缓存

2.提前生成缓存

3.永久缓存

ascii码对照表

ASCII控制字符

二进制 十进制 十六进制 缩写 可以显示的表示法 名称/意义
0000 0000 0 00 NUL 空字符(Null)
0000 0001 1 01 SOH 标题开始
0000 0010 2 02 STX 本文开始
0000 0011 3 03 ETX 本文结束
0000 0100 4 04 EOT 传输结束
0000 0101 5 05 ENQ 请求
0000 0110 6 06 ACK 确认回应
0000 0111 7 07 BEL 响铃
0000 1000 8 08 BS 退格
0000 1001 9 09 HT 水平定位符号
0000 1010 10 0A LF 换行键
0000 1011 11 0B VT 垂直定位符号
0000 1100 12 0C FF 换页键
0000 1101 13 0D CR 归位键
0000 1110 14 0E SO 取消变换(Shift out)
0000 1111 15 0F SI 启用变换(Shift in)
0001 0000 16 10 DLE 跳出数据通讯
0001 0001 17 11 DC1 设备控制一(XON 启用软件速度控制)
0001 0010 18 12 DC2 设备控制二
0001 0011 19 13 DC3 设备控制三(XOFF 停用软件速度控制)
0001 0100 20 14 DC4 设备控制四
0001 0101 21 15 NAK 确认失败回应
0001 0110 22 16 SYN 同步用暂停
0001 0111 23 17 ETB 区块传输结束
0001 1000 24 18 CAN 取消
0001 1001 25 19 EM 连接介质中断
0001 1010 26 1A SUB 替换
0001 1011 27 1B ESC 跳出
0001 1100 28 1C FS 文件分割符
0001 1101 29 1D GS 组群分隔符
0001 1110 30 1E RS 记录分隔符
0001 1111 31 1F US 单元分隔符
0111 1111 127 7F DEL 删除

ASCII可显示字符

二进制 十进制 十六进制 图形
0010 0000 32 20 (空格)(␠)
0010 0001 33 21 !
0010 0010 34 22
0010 0011 35 23 #
0010 0100 36 24 $
0010 0101 37 25  %
0010 0110 38 26 &
0010 0111 39 27
0010 1000 40 28 (
0010 1001 41 29 )
0010 1010 42 2A *
0010 1011 43 2B +
0010 1100 44 2C ,
0010 1101 45 2D
0010 1110 46 2E .
0010 1111 47 2F /
0011 0000 48 30 0
0011 0001 49 31 1
0011 0010 50 32 2
0011 0011 51 33 3
0011 0100 52 34 4
0011 0101 53 35 5
0011 0110 54 36 6
0011 0111 55 37 7
0011 1000 56 38 8
0011 1001 57 39 9
0011 1010 58 3A :
0011 1011 59 3B ;
0011 1100 60 3C <
0011 1101 61 3D =
0011 1110 62 3E >
0011 1111 63 3F ?
二进制 十进制 十六进制 图形
0100 0000 64 40 @
0100 0001 65 41 A
0100 0010 66 42 B
0100 0011 67 43 C
0100 0100 68 44 D
0100 0101 69 45 E
0100 0110 70 46 F
0100 0111 71 47 G
0100 1000 72 48 H
0100 1001 73 49 I
0100 1010 74 4A J
0100 1011 75 4B K
0100 1100 76 4C L
0100 1101 77 4D M
0100 1110 78 4E N
0100 1111 79 4F O
0101 0000 80 50 P
0101 0001 81 51 Q
0101 0010 82 52 R
0101 0011 83 53 S
0101 0100 84 54 T
0101 0101 85 55 U
0101 0110 86 56 V
0101 0111 87 57 W
0101 1000 88 58 X
0101 1001 89 59 Y
0101 1010 90 5A Z
0101 1011 91 5B [
0101 1100 92 5C \
0101 1101 93 5D ]
0101 1110 94 5E ^
0101 1111 95 5F _
二进制 十进制 十六进制 图形
0110 0000 96 60 `
0110 0001 97 61 a
0110 0010 98 62 b
0110 0011 99 63 c
0110 0100 100 64 d
0110 0101 101 65 e
0110 0110 102 66 f
0110 0111 103 67 g
0110 1000 104 68 h
0110 1001 105 69 i
0110 1010 106 6A j
0110 1011 107 6B k
0110 1100 108 6C l
0110 1101 109 6D m
0110 1110 110 6E n
0110 1111 111 6F o
0111 0000 112 70 p
0111 0001 113 71 q
0111 0010 114 72 r
0111 0011 115 73 s
0111 0100 116 74 t
0111 0101 117 75 u
0111 0110 118 76 v
0111 0111 119 77 w
0111 1000 120 78 x
0111 1001 121 79 y
0111 1010 122 7A z
0111 1011 123 7B {
0111 1100 124 7C |
0111 1101 125 7D }
0111 1110 126 7E ~

PHP实现页面静态化

1-1 明确动态页面和静态页面

静态网页是由浏览器直接从服务器下载到浏览者所在机器上浏览的。
动态网页需要服务器执行(运算)成静态网页的内容,然后由浏览器下载到浏览者所在机器上浏览。
静态网页是任何网站的根基,因为浏览者浏览的内容永远是从服务器传回的静态网页的内容。
动态与静态网页并不矛盾,网站设计中往往是先使用DreamWeaver等工具设计静态网页,之后将PHP等程序嵌入静态网页中完成网站设计。
动态网页中一般会包含静态网页的内容,比如:PHP代码中通常包含HTML或CSS。
静态网页中不能包含动态网页的内容。比如:如果HTML中包含PHP的内容,那就是动态网页了。
动态网页通常与数据库相连,来完成页面的显示。比如:一个文章显示系统,可以只通过一个动态网页Display.php显示数据库中的多篇文章。而静态网页无法实现此功能。
采用动态网页可以实现很多动态功能,比如Blog登录,BBS讨论,购物车等。
由于动态网页需要服务器执行(运算),因此将消耗服务器资源,访问速度会慢于静态网页。
当网站有大数据量时,应该使用动态网页管理,减少网站维护工作量。
当网站服务器压力过大或者访问量太大时,应该使用静态页面显示。
当网站有大的数据量而且访问量很大时,应该使用动态页面管理维护网站内容,同时生成静态页面用于显示。
动态网页的网址显示方式通常带有”?”,比如http://www.mangolau.com/mangolau.php?id=999&name=monkey ,这种网址属于搜索引擎不友好的URL,应该使用urlrewrite改为静态网页的URL显示方式,比如类似于 http://www.mangolau.com/mangolau_999_monkey.html 的URL。
动态网页是需要服务器端执行的程序,由于人的原因可能使动态网页程序产生漏洞,这些漏洞可能会被黑客利用。比如我们常说的”挂马”。

1-2 关于优化页面相应时间

 

1-3 关于动态URL地址设置静态形式

1-4 静态化详细介绍

2-1 buffer认知

2-2 PHP实现页面纯静态化原理

2-3 纯静态化案例简介

2-4 纯静态化案例之步骤解析

2-5 纯静态化案例实现

2-6 触发系统生成纯静态化页面的三种方式

2-7 方式一:页面添加缓存时间

2-8 方式二:手动触发方式

2-9 方式三:crontab定时扫描程序

2-10 局部动态化案例实现(一)

2-11 局部动态化案例实现(二)

2-12 局部动态化案例实现(三)

3-1 PHP处理伪静态

3-2 WEB服务器rewrite配置

3-3 Apache下rewrite配置

3-4 Nginx下rewrite配置

PHP中将字符串转化为整数(int) intval() printf() 性能测试

背景、概述
  早在Sql注入横行的前几年,字符串转化为整数就已经被列为每个web程序必备的操作了。web程序将get或post来的id、整数等值强制经过转化函数转化为整数,过滤掉危险字符,尽可能降低系统本身被Sql注入的可能性。
现如今,虽然Sql注入已经逐渐淡出历史舞台,但是,为了保证web程序的正常运行,减少出错概率,更好的保证用的满意度,我们同样需要将用户的不正确输入转化为我们所需要的。
转化方式
在PHP中,我们可以使用3种方式将字符串转化为整数。
1.强制类型转换方式
  强制类型转换方式,就是“在要转换的变量之前加上用括号括起来的目标类型”(摘自PHP手册“类型戏法”节)的方式。

<?php
$foo = “1”; // $foo 是字符串类型
$bar = (int)$foo; // $bar 是整型
?>

对于整型来说,强制转换类型名称为int或者integer。

2.内置函数方式
  内置函数方式,就是使用PHP的内置函数intval进行变量的转换操作。

<?php
$foo = “1”; // $foo 是字符串类型
$bar = intval($foo); // $bar 是整型
?>

intval函数的格式为:
  int intval(mixed $var [, int $base]); (摘自PHP手册)
虽然PHP手册中明确指出,intval()不能用于array和object的转换。但是经过我测试,转换array的时候不会出任何问题,转换值为1,而不是想象中的0。恐怕是因为在PHP内部,array类型的变量也被认为是非零值得缘故吧。转换object的时候,PHP会给出如下的 notice:
Object of class xxxx could not be converted to int in xxxxx.php on line xx
转换值同样为1。
3.格式化字符串方式
格式化字符串方式,是利用sprintf的%d格式化指定的变量,以达到类型转换的目的。

<?php
$foo = “1”; // $foo 是字符串类型
$bar = sprintf(“%d”, $foo); // $bar 是字符串类型
?>

严格意义上讲sprintf的转换结果还是string型,因此它不应该算是字符串转化为整数的方式。但是经过他处理之后的字符串值确实已经成为了“被强制转化为字符串类型的整数”。
实际测试
上面介绍了PHP中,将字符串转化为整数的3种方式。对于一般的程序员来说,看到这里就算结束了,下面的部分是针对变态程序员的。
1.基本功能测试
  设定以下数组:

<?php
$a[] = “1”;
$a[] = “a1”;
$a[] = “1a”;
$a[] = “1a2”;
$a[] = “0”;
$a[] = array(‘4’,2);
$a[] = “2.3”;
$a[] = “-1”;
$a[] = new Directory();
?>

使用三种方式依次转化上面给出的数组中的元素,查看转换情况。程序源代码如下:

<?php
$a[] = “1”;
$a[] = “a1”;
$a[] = “1a”;
$a[] = “1a2”;
$a[] = “0”;
$a[] = array(‘4’,2);
$a[] = “2.3”;
$a[] = “-1”;
$a[] = new Directory();
// int
print “(int)<br />”;
foreach($a as $v)
{
var_dump((int)$v);
print “<br />”;
}
// intval
print “intval();<br />”;
foreach($a as $v)
{
var_dump(intval($v));
print “<br />”;
}
// sprintf
print “sprintf();<br />”;
foreach($a as $v)
{
var_dump(sprintf(“%d”, $v));
print “<br />”;
}
?>

 

程序的最终运行结果如下(已经去掉转换object时出现的notice):

(int)
int(1)
int(0)
int(1)
int(1)
int(0)
int(1)
int(2)
int(-1)
int(1)
intval();
int(1)
int(0)
int(1)
int(1)
int(0)
int(1)
int(2)
int(-1)
int(1)
sprintf();
string(1) “1”
string(1) “0”
string(1) “1”
string(1) “1”
string(1) “0”
string(1) “1”
string(1) “2”
string(2) “-1”
string(1) “1”
由此可以看出,三种转换的结果是完全一样的。那么从功能上讲,3种方式都可以胜任转换工作,那么接下来的工作就是看哪一种效率更高了。
2.性能测试
被测试字符串是我们在注入工作中可能会使用到的一种:

<?php
$foo = “1′;Select * …”;
?>
获取时间点的函数如下(用于获取测试起始点和结束点,以计算消耗时间):

<?php
**
* Simple function to replicate PHP 5 behaviour
*/
function microtime_float()
{
list($usec, $sec) = explode(” “, microtime());
return ((float)$usec + (float)$sec);
}
?>

(摘自PHP手册microtime()函数节)
测试过程是使用每种方式转换变量$foo 1000000次(100万次),并将各自的消耗时间输出,总共进行三组测试,尽可能降低误差。测试程序如下:
<?php
function microtime_float()
{
list($usec, $sec) = explode(” “, microtime());
return ((float)$usec + (float)$sec);
}
$foo = “1′;Select * …”;

// (int)
$fStart = microtime_float();
for($i=0;$i<1000000;$i++)
{
$bar = (int)$foo;
}
$fEnd = microtime_float();
print “(int):” . ($fEnd – $fStart) . “s<br />”;
// intval()
$fStart = microtime_float();
for($i=0;$i<1000000;$i++)
{
$bar = intval($foo);
}
$fEnd = microtime_float();
print “intval():” . ($fEnd – $fStart) . “s<br />”;
// sprintf()
$fStart = microtime_float();
for($i=0;$i<1000000;$i++)
{
$bar = sprintf(“%d”, $foo);
}
$fEnd = microtime_float();
print “sprintf():” . ($fEnd – $fStart) . “s<br />”;
?>

最终的测试结果:
(int):0.67205619812012s
intval():1.1603000164032s
sprintf():2.1068270206451s
(int):0.66051411628723s
intval():1.1493890285492s
sprintf():2.1008238792419s
(int):0.66878795623779s
intval():1.1613430976868s
sprintf():2.0976209640503s

虽然这个测试有点变态(谁会连续转换100w次的整数?),但是由此可以看出,使用强制类型转换将字符串转化为整数速度是最快的。
总结
使用强制类型转换方式将字符串转化为整数是最直接的转化方式之一(可以直接获得整型的变量值)。从代码可读性角度上讲,sprintf方式代码比较长,而且其结果有可能还需要再次进行强制类型转换,而intval函数是典型的面向过程式转换,强制类型转换则比较直接的将“我要转化”这个思想传递给阅读者。从效率上讲,强制类型转换方式也是最快速的转化方式。因此,对于经常进行转化工作的程序员,我推荐使用这种方式。