PhpDig.net

What is PhpDig?
PhpDig is a PHP MySQL based
Web Spider & Search Engine.




unpack

Name

unpack — Parses a binary string according to a user-defined format.

Synopsis

array unpack(format, binary_string);
string format: Format to use when unpacking
string binary_string: Binary string to unpack

Returns

Associative array; FALSE on error

Description

unpack() is the complement of pack() - it transforms binary data into an associative array based on the format specified.

The format string consists of a format character, optionally followed by an integer. Depending on the format character, the integer either indicates a length or a quantity. The integer should be followed by a string. The string is used as the key for entries in the associative array that are created by the format code. If the format code creates more than one entry in the array, the array keys will have a number placed after the name. The string should end with a forward slash (/) to indicate that this format code has ended and a new one is beginning.

A simple example of how unpack() works may be the best way to explain it. A call to the function looks like this:

$data = unpack ('C2byte/@3/n2agent #', 'abcdefgh');
The first argument is the format string. The format string defines how the data argument should be parsed. In this example, the format string specifies that the data argument should be parsed into two unsigned bytes and two unsigned 16-bit numbers. The parsed data is stored in an associative array and placed in the $data variable. The $data array looks as follows if passed to the var_dump() function. ( var_dump() is a great tool for debugging and learning. It prints the type and value of any argument passed to it - even including complex values such as nested arrays and objects.)
array(4) {
  ["byte1"] =>    int(97)
  ["byte2"] =>    int(98)
  ["agent #1"] => int(25701)
  ["agent #2"] => int(26215)
}
Don't worry if you are still shaking your head - unpack() can be a bit hard to grasp when you first start using it. Play around with the preceding example and review the detailed breakdown of the following format string.

Character(s) Meaning
C Get a byte of data from the binary_string argument. Interpret the data as an unsigned byte.
2 Get two of the previously specified format codes.
byte Use byte as the array key for the data parsed by the previous format code. If the format code grabs more than one piece of data, the array keys are numbered from 1 to n. In this case, the array keys are named byte1 and byte2.
/ Indicates that a new format code is coming.
@ Move to the byte offset specified by the following number. Remember that the first position in the binary string is 0.
3 Move to the fourth byte in the binary string.
/ Start a new format code.
n Get two bytes of data from the binary string and interpret them as unsigned 16-bit network order (big-endian) numbers.
2 Grab two of the previous format codes.
agent # Use agent # as the array key.


For more information on the various format codes, see the pack() function.

Version

PHP Version: 3+, 4+

See also

To convert a list of values into a binary string

pack()

Example

Example 902. Display the ASCII character codes for an entire string

echo implode (' ',unpack ('C*', 'abcdef'));

Output:
97 98 99 100 101 102

Example 903. Show the format of a dbf database file

<pre>
<?php
# For more information on the format of dbf database files
# visit http://www.e-bachmann.dk/docs/xbase.htm

$file = "/tmp/sushi_eaten.dbf";

# Ensure that the file is big enough to be a db file
($filesize = filesize ($file)) > 68
    or die ("File <i>$file</i> is not large enough to be a dbf file.");

# Open a binary read-only connection to the file
$fp = fopen ($file, 'rb')
    or die ("File <i>$file</i> cannot be opened.");

# Get the top of the dbf file header
$data = fread ($fp, 32)
    or die ("Could not read data from file <i>$file</i>");

# Create the format for unpacking the header data
$header_format = 
    'H2id/' .           # Grab two Big-Endian hex digits
    'CYear/' .          # Grab an unsigned bit
    'CMonth/' .         # Grab an unsigned bit
    'CDay/' .           # Grab an unsigned bit
    'L# of Records/' .  # Grab an unsigned long (32 bit number)
    'SHeader Size/' .   # Grab an unsigned short (16 bit number)
    'SRecord Size';     # Grab an unsigned short (16 bit number)

# Unpack the header data
$header = unpack ($header_format, $data);

# Convert the year value to a full four digits
$header['Year'] += 1900;

# Display the data stored in $data
print_r ($header);

# Make sure that the file is the right size
if ($filesize != $size = $header['Header Size'] + ($header['Record Size'] * $header['# of Records']))
    die ("File <i>$file</i> is not a valid dbf file. Perhaps the file has been corrupted?");

# Get the rest of the dbf file header
$data = fread ($fp, $header['Header Size'] - 34)
    or die ("Could not read data from file <i>$file</i>");
    
# Create the format for unpacking the data that describes the format of the records in the file
$record_format = 
    'A11Field Name/' .  # Grab 11 alphanumeric characters
    'AField Type/' .    # Grab a single alphanumeric character
    'x4/' .             # Skip 4 bytes forward
    'CField Length/' .  # Grab an unsigned bit
    'CField Precision'; # Grab an unsigned bit

for ($offset = 0; $offset < strlen ($data); $offset += 32) {
    print_r (unpack ("@$offset/$record_format", $data));
}
?>
</pre>

Example 904. Create a read-only version of Perl's vec() function

<?php
function vector ($value, $offset, $bits) {
    # Ensure that the bit argument is 1, 2, 4, 8, 16, or 32
    if (! in_array ($bits, array (1,2,4,8,16,32))) {
        trigger_error ('<b>vector()</b> The bit argument must be one of the '
           . 'following values: 1, 2, 4, 8, 16, or 32');
        return FALSE;
    }

    # Cast $value to type string
    $value = (string) $value;

    # Convert the string to any array of ASCII character values
    # One odd behavior of unpack is that the array it makes will
    # have a starting index of 1, instead of 0.
    $str = unpack ('c*', $value);

    # Find the character in the string where the offset starts
    # Add 1 to compensate for the odd starting index in the $string array
    $chr = floor ($offset * $bits / 8) + 1;

    # For values less than 8 bits, we only need to work within a single character
    if ($bits < 8) {
        # Find the offset of the desired bytes within the character
        $bit_offset = $offset * $bits % 8;

        # Create a bit mask to use with & to help us extract our data
        $mask       = (pow (2, $bits) - 1) << $bit_offset;

        # Return the needed bytes from the character
        return ($str[$chr] & $mask) >> $bit_offset;
    }

    # If we need more than four bits, grab multiple characters
    for ($byte = 0; ($byte * 8) < $bits; ++$byte) {
        $output = ($output << 8) + $str[$chr + $byte];
    }

    return $output;
}
?>



PHP Functions Essential Reference. Copyright © 2002 by New Riders Publishing (Authors: Zak Greant, Graeme Merrall, Torben Wilson, Brett Michlitsch). This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is presently available at http://www.opencontent.org/openpub/). The authors of this book have elected not to choose any options under the OPL. This online book was obtained from http://www.fooassociates.com/phpfer/ and is designed to provide information about the PHP programming language, focusing on PHP version 4.0.4 for the most part. The information is provided on an as-is basis, and no warranty or fitness is implied. All persons and entities shall have neither liability nor responsibility to any person or entity with respect to any loss or damage arising from the information contained in this book.

Powered by: vBulletin Version 3.0.7
Copyright ©2000 - 2005, Jelsoft Enterprises Ltd.
Copyright © 2001 - 2005, ThinkDing LLC. All Rights Reserved.