pack函数的简单使用

pack函数主要作用是把数据压缩为二进制字符串。qq纯净ip数据库数据存储就是使用pack进行封装。本文为pack的简单应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?php
class Db {
private $file = null;
private $struct = array(
'name' => 'a8',
'age' => 'S',
'email' => 'a30'
);
private $length = 40;
private function init()
{
$file = fopen('./test.db', 'ab+');
$this->file = $file;
}
public function __construct()
{
if($this->file === null) {
$this->init();
}
}
public function add($data)
{
$binary = '';
foreach($data as $k => $row) {
$struct = $this->struct[$k];
$binary .= pack($struct, $row);
}
fwrite($this->file, $binary);
}
public function read($id = 1)
{
rewind($this->file);
$data = array();
if(!fseek($this->file, $this->length * ($id -1))) {
$data['name'] = unpack('a8', fread($this->file, 8))[1];
$data['age'] = unpack('S', fread($this->file, 2))[1];
$data['email'] = unpack('a30', fread($this->file, 30))[1];
}
return $data;
}
public function __destruct()
{
fclose($this->file);
}
}

存储数据

1
2
3
4
5
6
7
$data = array(
'name' => 'lisi' . time(),
'age' => 100,
'email' => 'jjjjj@qq.com'
);
$db = new Db();
$db->add($data);

读取数据

1
2
3
4
5
6
7
8
9
10
11
$data = $db->read(1);
print_r($data);
/*
Array
(
[name] => lisi1418
[age] => 100
[email] => jjjjj@qq.com
)
*/

不使用strrev和数组函数实现字符串反转

反转一个字符串很容易使用strrev函数即可,假如没有strrev函数也没有数组函数怎么显示字符串反转。

  • 背景知识

    1
    2
    string 中的字符可以通过一个从 0 开始的下标,用类似 array 结构中的方括号包含对应的数字来访问和修改,比如 $str[42]。
    可以把 string 当成字符组成的 array。函数 substr() 和 substr_replace() 可用于操作多于一个字符的情况。 -- php手册
  • 代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    <?php
    function reverseString($string)
    {
    $length = strlen($string);
    $reverseString = '';
    while($length--) {
    $reverseString .= $string[$length];
    }
    return $reverseString;
    }
    $str = "Hello world";
    echo reverseString($str); //dlrow olleH
    ```php
    使用str_split 函数也可以。
    ```php
    $array = str_split($str);
    print_r($array);
    /**
    Array
    (
    [0] => H
    [1] => e
    [2] => l
    [3] => l
    [4] => o
    [5] =>
    [6] => w
    [7] => o
    [8] => r
    [9] => l
    [10] => d
    )
    */

参考 字符串反转,神奇的算法-读《编程珠玑(第二版)》 有更高效的写法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
function ReverseString(&$s, $from, $to)
{
while ($from < $to)
{
$t = $s[$from];
$s[$from++] = $s[$to];
$s[$to--] = $t;
}
}
function LeftRotateString($s, $n, $m)
{
$m %= $n; //若要左移动大于n位,那么和%n 是等价的
ReverseString($s, 0, $m - 1); //反转[0..m - 1],套用到上面举的例子中,就是X->X^T,即 abc->cba
ReverseString($s, $m, $n - 1); //反转[m..n - 1],例如Y->Y^T,即 def->fed
ReverseString($s, 0, $n - 1); //反转[0..n - 1],即如整个反转,(X^TY^T)^T=YX,即 cbafed->defabc。
return $s;
}
echo LeftRotateString('abcdef', 6, 3); //defabc

php获取视频文件编码信息

使用ffmpeg

1
2
FFmpeg是一个自由软件,可以运行音频和视频多种格式的录影、转换、流功能[1],
包含了libavcodec ─这是一个用于多个项目中音频和视频的解码器库,以及libavformat——一个音频与视频格式转换库。
  • 安装ffmpeg
1
2
3
4
5
6
#rpm -ivh http://apt.sw.be/redhat/el6/en/i386/rpmforge/RPMS/rpmforge-release-0.5.3-1.el6.rf.i686.rpm
#yum install ffmpeg ffmpeg-devel
#ffmpeg -v
FFmpeg version 0.6.5, Copyright (c) 2000-2010 the FFmpeg developers
  • 使用命令行获取文件信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # ffmpeg -i 庞麦郎_-_我的滑板鞋.mp4
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '庞麦郎_-_我的滑板鞋.mp4':
    Metadata:
    major_brand : isom
    minor_version : 512
    compatible_brands: isomiso2avc1mp41
    encoder : Lavf54.6.100
    Duration: 00:03:36.48, start: 0.000000, bitrate: 2778 kb/s
    Stream #0.0(und): Video: h264, yuv420p, 1920x1080 [PAR 1:1 DAR 16:9], 2674 kb/s, 25 fps, 25 tbr, 25025 tbn, 50 tbc
    Stream #0.1(und): Audio: aac, 44100 Hz, stereo, s16, 97 kb/s
    At least one output file must be specified
  • 使用正则提取需要的信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <?php
    function getVideoFormat($file)
    {
    $ffmpeg = "/usr/bin/ffmpeg";
    ob_start();
    passthru(sprintf($ffmpeg.' -i "%s" 2>&1', $file));
    $info = ob_get_contents();
    ob_end_clean();
    preg_match('/Video:\s(?<format>.*?),/', $info, $match);
    return $match;
    }
    $file = __DIR__ . '/庞麦郎_-_我的滑板鞋.mp4';
    var_dump(getVideoFormat($file));
    /*
    array(3) {
    [0]=>
    string(12) "Video: h264,"
    ["format"]=>
    string(4) "h264"
    [1]=>
    string(4) "h264"
    }
    */

使用getID3类库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
require_once('../getid3/getid3.php');
// Initialize getID3 engine
$getID3 = new getID3;
$filename = __DIR__ .'/../庞麦郎_-_我的滑板鞋.mp4';
// Analyze file and store returned data in $ThisFileInfo
$ThisFileInfo = $getID3->analyze($filename);
print_r($ThisFileInfo['video']);
/*
Array
(
[dataformat] => quicktime
[resolution_x] => 1920
[resolution_y] => 1080
[fourcc] => avc1
[frame_rate] => 25
)
*/

DateTime类的常见用法

  • 初始化
1
2
3
4
//默认为当前时间
$tz = new DateTimezone('Asia/Shanghai');
echo (new DateTime('now', $tz))->format('Y-m-d H:i:s'); //2014-12-04 12:04:55
$d = new DateTime('+1 day', $tz); //2014-12-05 12:04:55
  • 设置时区

    1
    2
    $d = new DateTime(null, new DateTimezone('Asia/Shanghai'));
    $d->setTimezone('Asia/Shanghai');
  • 设置/获取时间戳

    1
    2
    echo $d->getTimestamp(); //1417664087
    echo $d->setTimestamp(1417664087)->format('Y-m-d H:i:s'); //2014-12-04 11:34:47
  • 修改时间

    1
    2
    3
    //明天当前时间 (使用关键字day、week、month year 进行修改)
    使用modify
    echo $d->modify('+1 day')->setTime(0, 0, 0)->format('Y-m-d H:i:s');

或者使用 sub、add

1
2
echo $d->sub(new DateInterval('P1D'))->format('Y-m-d H:i:s');
echo $d->add(new DateInterval('P1D'))->format('Y-m-d H:i:s');

  • 比较日期大小

    1
    2
    3
    4
    5
    $t = new DateTimezone('Asia/Shanghai');
    $d1 = new DateTime('2014-12-01', $t);
    $d2 = new DateTime('2014-12-02', $t);
    echo $d1 > $d2 ? 'd1 bigger than d2' : 'd1 less than d2';
  • 获取日期间的差异

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    $diff = $d1->diff($d2);
    print_r($diff);
    DateInterval Object
    (
    [y] => 0
    [m] => 0
    [d] => 1
    [h] => 0
    [i] => 0
    [s] => 0
    [weekday] => 0
    [weekday_behavior] => 0
    [first_last_day_of] => 0
    [invert] => 0
    [days] => 1
    [special_type] => 0
    [special_amount] => 0
    [have_weekday_relative] => 0
    [have_special_relative] => 0
    )