PHP日常笔记

2015-12-11

php控制header头缓存时间

<?php
header('Expires: '.gmdate('D, d M Y H:i:s', time()+'86400').' GMT');
header('Cache-Control:max-age=86400');
header('Pragma:cache');
?>

PHP空数组转空对象

这个问题在与IOS、安卓客户端调试API的时候遇到,非空数组经过json_encode后会转为{}形式的对象(java里称字典)

而空数组会直接转成[]形式,这样造成客户端解析异常。

解决办法是在输出前强制转成object对象:

<?php
$a =array();
var_dump($a);
echo json_encode($a);
echo "\n";
$b = (object)$a;
var_dump($b);
echo json_encode($b);

输出:

array(0) {
}
[]
object(stdClass)#1 (0) {
}
{}

round() 函数对浮点数进行四舍五入

语法

float round( float val ,[int precision] )

返回将 val 根据指定精度 precision(十进制小数点后数字的数目)进行四舍五入的结果。

precision 也可以是负数或零(默认值)。

float精度丢失问题需要用BC函数库

要使用 BC 这个函数库,要在编译 PHP 程序时加入 –enable-bcmath 的选项。

bcadd:	 将二个高精确度数字相加。
bccomp:	 比较二个高精确度数字。
bcdiv:	 将二个高精确度数字相除。
bcmod:	 取得高精确度数字的余数。
bcmul:	 将二个高精确度数字相乘。
bcpow:	 求一高精确度数字次方值。
bcscale: 配置程序中所有 BC 函数库的默认小数点位数。
bcsqrt:	 求一高精确度数字的平方根。
bcsub:	 将二个高精确度数字相减。

static的属性,在内存中只有一份,为所有的实例共用。

使用self:: 关键字访问当前类的静态成员

使用parent::调用父类方法

abstract 抽象类 抽象方法

PHP 方法修饰符

Public(公开): 可以自由的在类的内部外部读取、修改。

Private(私有): 只能在这个当前类的内部读取、修改。

Protected(受保护):能够在这个类和类的子类中读取和修改。

Final (最终的) 不能被继承,也没有子类。

PHP序列化函数:

serialize()和unserialize():一个是进行序列化存储,另一个则是进行序列化恢复

PHP instatnceof运算符保障代码安全

使用instanceof运算符,可以判断当前实例是否可以有这样的一个形态。当前实例使用 instanceof与当前类,父类(向上无限追溯),已经实现的接口比较时,返回真。

代码格式:实例名 instanceof 类名

<?php
class User{
private $name;
public function getName(){
return "UserName is ".$this->name;
}
}

class NormalUser extends User {
private $age = 99;
public function getAge(){
return "age is ".$this->age;
}
}

class UserAdmin{ //操作.
public static function getUserInfo(User $_user){
if($_user instanceof NormalUser ){
echo $_user->getAge();
}else{
echo "类型不对,不能使用这个方法.";
}
}
}
$User = new User(); // 这里new的是User.
UserAdmin::getUserInfo($User);
?>

程序运行结果:

类型不对,不能使用这个方法.

PHP Ajax 跨域允许多个域名访问

根据系统变量HTTP_ORIGIN请求头返回不同结果:

<?php
$origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';

$allow_origin = array(
'http://client1.malu.me',
'http://client2.malu.me'
);

if(in_array($origin, $allow_origin)){
header('Access-Control-Allow-Origin:'.$origin);
}
?>

防注入

addslashes()

该函数在指定的预定义字符前添加反斜杠.

预定义字符是:

  • 单引号(’)
  • 双引号(”)
  • 反斜杠(\)
  • NULL

ECshop中addslashes_deep的原型

<?php
function addslashes_deep($value) {
if (empty($value)) {
return $value; //如为空,直接返回;
} else {
return is_array($value) ? array_map('addslashes_deep', $value): addslashes($value);
} //递归处理数组,直至遍历所有数组元素;
}

mysql_real_escape_string()

该函数转义 SQL 语句中使用的字符串中的特殊字符。

特殊字符包括:

  • \x00
  • \n
  • \r
  • \
  • \x1a

如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。

<?php
function check_input($value)
{
// 去除斜杠
if (get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
// 如果不是数字则加引号
if (!is_numeric($value)) {
$value = "'" . mysql_real_escape_string($value) . "'";
}
return $value;
}

$con = mysql_connect("localhost", "hello", "321");
if (!$con) {
die('Could not connect: ' . mysql_error());
}

// 进行安全的 SQL
$user = check_input($_POST['user']);
$pwd = check_input($_POST['pwd']);
$sql = "SELECT * FROM users WHERE
user=
$user AND password=$pwd";

mysql_query($sql);

mysql_close($con);
?>

字符过滤的机制无法根本解决注入,完美解决方案就是使用拥有Prepared Statement机制的PDO和MYSQLi来代替mysql_query(注:mysql_query自 PHP 5.5.0 起已废弃,并在将来会被移除):

PDO:

<?php
$pdo = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute(array('name' => $name));

foreach ($stmt as $row) {
// do something with $row
}
?>

MYSQLi

<?php
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name);

$stmt->execute();

$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// do something with $row
}
?>

防XSS

对传入值强转,或者使用htmlspecialchars()

htmlspecialchars()函数把预定义的字符转换为 HTML 实体。

预定义的字符是:

  • & (和号)
  • ” (双引号)
  • ’ (单引号)
  • < (小于)
  • (大于)

如需把特殊的 HTML 实体转换回字符,请使用 htmlspecialchars_decode() 函数。

php编码转换

用iconv进行gbk转utf-8 或者gb2312转utf-8的时候经常出现乱码问题,推荐另外一个扩展函数:mb_convert_encoding

mb_convert_encoding的用法见官方: http://cn.php.net/manual/zh/function.mb-convert-encoding.php

注:需要先enable mbstring 扩展库