PHP日常笔记

2015-12-11

PHP开发环境

使用docker容器内的php环境

1.在 /usr/local/bin/ 里创建一个名为 php 的文件

sudo touch /usr/local/bin/php

2.使其可执行:

sudo chmod +x /usr/local/bin/php

3.编辑文件(使用 sudo)并粘贴以下代码 /app/github/m1 是工作路径,m1 是容器名:

command="docker exec -w /app/github/m1 -i m1 php "$@""
$command

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) {
}
{}

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 扩展库