分类 代码分析 下的文章

服务端接收不到Post请求的参数

今天用Fiddler模拟Post请求测试接口,发现服务端接收到的Post参数为空。
通过Fiddler记录了下真实Post请求的Header头,发现问题的原因在于Content-Type这个参数。

POST请求的Content-Type支持application/x-www-form-urlencoded 或 multipart/form-data 两种。

json_encode处理二进制的问题

$a = gzcompress('test'); 
 
echo 'before json : '; 
print_r($a); 
echo "\n"; 
echo 'after json : '; 
print_r(json_encode($a));

输出的结果为:

before json : x+I-.]
after json : null

json_encode后的结果为null,PHP手册上给了说明。

待编码的 value ,除了resource类型之外,可以为任何数据类型
该函数只能接受 UTF-8 编码的数据

如何解决呢?

$a = gzcompress('test'); 
 
echo 'before json : '; 
print_r($a); 
echo "\n"; 
echo 'after json : '; 
print_r(json_encode(base64_encode($a)));

输出结果为:

before json : x+I-.]
after json && base64 : "eJwrSS0uAQAEXQHB"

PHP关于64位整型的二进制实现

项目中用到一个C的二进制接口,需要通过php拼包请求接口同时解析返回的二进制包。
比较特殊的一点是,接口里有用到64位整型,但是php的pack/unpack原生并不支持64位整型,为了解决这个着实费了一番功夫。

实现原理

将一个64位整型转换成高位和低位的两个32位整型,通过两个32位整型的结构来表示一个64位整型。

实现代码

<?php
define("BIGINT_DIVIDER", 0x7fffffff + 1);

function split2Int(&$upper, &$lower, $value) {
    $lower = intval($value % BIGINT_DIVIDER);
    $upper = intval(($value - $lower) / BIGINT_DIVIDER);
}

function bigInt2float($upper, $lower) {
    return $upper * BIGINT_DIVIDER + $lower;
}

$num = 5000000000;
split2Int($upper, $lower, $num);

$buffer = pack('NN', $upper, $lower); // 大端序
$result = unpack('Nupper/Nlower', $buffer);

echo bigInt2float($upper, $lower); // 5000000000

参考资料:
PHP: pack/unpack补遗
PHP pack() format for signed 32 int - big endian
A 64 bit integer for PHP

PHP通过GET/POST获取到的参数被自动转义的问题

之前遇到过一次这个问题,当时以为是新装的扩展问题,排查一番后发现不是。这次又碰上了,当时忘了之前是怎么解决的了。

日志记录获取到的参数,类似如下:

'args' => '[1002,[{\\"tid\\":\\"1556\\",\\"pid\\":188204955,\\"

搜索一番,发现magic_quotes_gpc这个设置会影响到,直接去看php.ini设置,这里被设置成on了。

magic_quotes_gpc
影响到 HTTP 请求数据(GET,POST 和 COOKIE)。不能在运行时改变。在 PHP 中默认值为 on。

二进制的相关知识

位的概念:在计算机中,一个0或1称为一位(bit)。

字节:连续的八位称为一个字节(Byte),字节是计算机中可单独处理的最小单位。即以字节
为基本单位来解释信息,规定1个字节是8个二进制位。

通常1个ASCII码用1个字节存放,1个汉字用2个字节存放,双精度浮点实数用8个字节存放。
下面列表C语言中定义类型所占字节以及数据范围。

类型标识符类型说明长度(字节)范围备注
char字符型1-128 ~ 127-2^7~(2^7-1)
unsigned char无符字符型10 ~ 2550~(2^8-1)
short int短整型2-32768 ~ 32767-2^15~(2^15-1)
unsigned short int无符短整型20 ~ 655350~(2^16-1)
int整型4-2147483648 ~ 2147483647-2^31~(2^31-1)
unsigned int无符整型40 ~ 42949672950~(2^32-1)
float实型(单精度)41.1810-38 ~ 3.4010387位有效位
double实型(双精度)82.2310-308 ~ 1.791030815位有效位
long double实型(长双精度)103.3710-4932 ~ 1.1810493219位有效位

按照posix标准,一般整形对应的*_t类型为:

长度类型标识符
1字节uint8_t
2字节uint16_t
4字节uint32_t
8字节uint64_t

参考资料
http://my.oschina.net/goal/blog/195749
http://my.oschina.net/goal/blog/202378
http://my.oschina.net/goal/blog/202381