Deep parsing _php techniques for PHP reading binary streams (c-structured struct data files)

Source: Internet
Author: User
Tags fread mixed pack php code rewind strtok unpack

Although PHP was developed in C language, I am puzzled that PHP does not provide direct support for the struct of the struct body.
However, PHP provides the pack and unpack functions for binary (binary data) and PHP internal data interchange:

Copy Code code as follows:

String Pack (String $format [, Mixed $args [, mixed $ ...]])
Pack given arguments into binary string according to format.
Array unpack (string $format, String $data)
Unpacks from a binary string into an array according to the given format.

Among them, $format similar to Perl pack format, there are some of the following (Chinese is I add, there are inaccurate welcome to propose):
A nul-padded string, that is, "I" as a representation of "null character"
A space-padded string, space as a representation of "null character"
H Hex string, low nibble first, ascending bit order
H Hex string, high nibble first, descending bit order
C signed Char, signed Single-byte
C unsigned char, unsigned single byte
s signed short (always bit, machine byte)
S unsigned short (always bit, machine byte)
n unsigned short (always bit, big endian byte)
V unsigned short (always bit, little endian byte)
I signed integer (Machine dependent size and byte order)
I unsigned integer (machine dependent size and byte order)
L Signed long (always bit, machine byte order)
L unsigned long (always bit, machine byte order)
N unsigned long (always bit, big endian byte)
V unsigned long (always bit, little endian byte order)
f Float (machine dependent size and representation)
D double (machine dependent size and representation)
x NUL byte, useful when actually used as a skip over how many bytes
X back up one byte, backward 1 bytes
@ Nul-fill to absolute position is useful when it is actually used as a jump from the beginning to a byte
The actual use found that the "" "C" (that is, the string terminator) in PHP is not a terminator, but as a part of the string. Therefore, the "" "must be special treatment, in order to carry out struct and PHP internal data perfect mutual turn. such as Char name[10]; If the actual data is "6E 616E00", in the C language where the 5th position has a terminator, name should be "Bian", and the unpack conversion in PHP after the name is "Bian\0bian\0".
In the beginning I used the Strpos function to find the position of "the" and then to Substr intercept.

But very faint things happen, do not know is strpos bug or substr bug (in fact, test to know, lazy to try), some strings are no problem, some strings can only get empty value (that is, $name = = "). Very depressed, then found a strtok function, this is no problem.
It's hard to see so much, here's a complete PHP read the binary data stream (c language structure struct data) file Sample code:
First is the C struct definition example, in order to demonstrate, I write a simple point, the actual control of the $format format table should be no problem:

Copy Code code as follows:

struct Bianbian {
Char name[10];
Char pass[33];
int age;
unsigned char flag;
};

For example, there is a "file.dat" file, the content is the top of the n Bianbian structure. Read the PHP code:
Copy Code code as follows:

<?php
Following the struct to determine $format, note that the type of int is related to the machine environment, my 32-bit Linux is 4 length
$format = ' A10name/a33pass/iage/cflag ';
Determines how many length bytes a struct occupies, and it is not necessary to read only a single structure
$length = 10 + 33 + 4 + 1;
can also use fopen + Fread + fclose, but file_get_contents because it can be mmap, more efficient
$data = file_get_contents (' file.dat ', ' R ');
for ($i = 0, $c = strlen ($data); $i < $c; $i = = $length) {
$bianbian = Unpack ("$format", $data);
Reference Pass is PHP 5 only support, if use PHP4, have to use other method
foreach ($bianbian as & $value) {
if (is_string ($value)) {
$value = Strtok ($value, "the");
}
}
Print_r ($bianbian);
}
?>

Packs should be the opposite of unpack.
Incidentally, enclose the C language code for the build structure file:
Copy Code code as follows:

#include <stdio.h>
#include <string.h>

struct example
{
Char name[10];
Char pass[33];
int age;
unsigned char flag;
};

int main ()
{
Example test;
Example Read;
FILE *FP;

Test.age = 111;
Test.flag = 10;
strcpy (Test.name, "Hello world!");
strcpy (Test.pass, "zbl110119");

fp = fopen ("file.dat", "w+");
if (!FP)
{
printf ("Open File error!");
return-1;
}

Rewind (FP);
Fwrite (&test, sizeof (example), 1, FP);

Rewind (FP);
Fread (&read, sizeof (example), 1, FP);

printf ("%d,%s\n", Read.age, Read.name);

Fclose (FP);
return 0;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.