今天接到一个任务如下
在命令行模式下,
用PHP, 解压下面zip文件(到临时文件)
解析后,读取.upg文件,在offset 8处,读32个字节出来,输出到控制台
一,解析需求
1.要在控制台读取参数
2.在PHP中解压参数中的.zip文件,然后将zip文件中包含的文件解压到一个临时目录
3.读取临时目录里的.upg文件,然后将其中的第8~32的字符读出来,将字符转换成16进制,然后转换成ascll码输出
4.删除临时目录
二.实现
1.读取控制台的参数
在PHP中,读取命令行中的参数有几种,我亲自测试成功的有以下两种
(1)使用$argv参数
echo "argv:".var_dump($argv);
可以看到php 后面带有的参数都被读到了再$argv参数中,而我们真正需要的只是mcw.zip这个参数,所以我们需要用到end($arr)这个函数
var_dump(end($argv));
到这里我们就完成了第一个任务:读取参数获得需要节要的zip文件
2.在PHP中解压参数中的.zip文件,然后将zip文件中包含的文件解压到一个临时目录
解压zip文件使用ZipArchive 这个类。先定义一个ZipArchive实例,然后将我们的zip文件解压到一个目录下面
$route = "temp";
$zip = new ZipArchive();
if ($zip->open($file) === true){
$mcw = $zip->extractTo($route);//解压到$route这个目录中
$zip->close();
}
可以看到已经解压出来了,接下来就是要读取mcw.upg这个文件了。
3.读取临时目录里的.upg文件,然后将其中的第8~32的字符读出来
先把整个文件都读取出来,然后只获取第一行(因为8~32字节的数据在第一行,所以我们只需要读第一行就可以了)。
将第一行中的每个字符都转换成16进制
这里使用到了bin2hex这个函数转换
$temp = substr($line,$i,1);
$str .= bin2hex($temp);
这样将第一行每个字符都转换成16进制之后,我们就开始截取8~32字节的字符了。因为每个字符转换成16进制之后就会变成两个数字,所以每次截取字符串相邻的两个字符
$result = substr($str,$start*2,$offset*2);
if ($mcw){
$this->getBytes($file1,8,32);
}
public function getBytes($file,$start,$offset){
//转换成16进制
$content = file($file);
$line = $content[0];
$str = "";
for ($i = 0;$i < strlen($line); $i++){
$temp = substr($line,$i,1);
$str .= bin2hex($temp);
}
//截取字符
$result = substr($str,$start*2,$offset*2);
$this->toAscll($result);
}
到这里为止我们就将8~32个字节的字符的16进制读取出来了,但是我们仍然还需要将它转换为ascll码
因为遇到0就是结束了,所以在8~32个字符中,只要出现0就不再处理了。
for ($i = 0;$i < strlen($str); $i+=2){
$temp = substr($str,$i,2);
if ($temp == "00"){
break;
}
array_push($arr,$temp);
}
因为上面得到的两个16进制的数字,还不是完整的16进制表达,完整的16进制表达式0x12,这样的表示,所以要在每个字符前面加上0x。然后使用chr()函数将它转换成ascll码
for ($i = 0;$i
到此,已经可以输出我们想要的结果了
(4)删除临时目录
因为我们把数据解压到一个临时目录里面,所以当我们程序结束之后就要把它删除了。
使用unlink($file)删除一个文件,使用rmdir($dir)删除一个目录
public function deleteFile($url,$file1,$file2){
//删除压缩后的目录
if (file_exists($file1)){
if (unlink($file1) && unlink($file2)){
rmdir($url);
}
}
}
全部代码如下
open($file) === true){
$mcw = $zip->extractTo($route);
$zip->close();
if ($mcw){
$this->getBytes($file1,8,32);
$this->deleteFile($route,$file1,$file2);
}
}
}
public function getBytes($file,$start,$offset){
//转换成16进制
$content = file($file);
$line = $content[0];
$str = "";
for ($i = 0;$i < strlen($line); $i++){
$temp = substr($line,$i,1);
$str .= bin2hex($temp);
}
//截取字符
$result = substr($str,$start*2,$offset*2);
$this->toAscll($result);
}
public function deleteFile($url,$file1,$file2){
//删除压缩后的目录
if (file_exists($file1)){
if (unlink($file1) && unlink($file2)){
rmdir($url);
}
}
}
public function toAscll($str){
//每两个数字作为一个asc码,遇到零就结束
$arr = [];
for ($i = 0;$i < strlen($str); $i+=2){
$temp = substr($str,$i,2);
if ($temp == "00"){
break;
}
array_push($arr,$temp);
}
for ($i = 0;$igetZipFile($file);