1

我有一个从图像中获取的数组

exif_read_data($image, 0, true)

数组本身可以包含未知数量的键/值(也可以是 0) 数组在某些部分也是多维的。

exif_read_data 中的数组示例:

Array
(
    [FILE] => Array
        (
            [FileName] => f-20110129_004_pp.jpg
            [FileDateTime] => 0
            [FileSize] => 3566966
            [FileType] => 2
            [MimeType] => image/jpeg
            [SectionsFound] => ANY_TAG, IFD0, THUMBNAIL, EXIF, GPS
        )

    [COMPUTED] => Array
        (
            [html] => width="2576" height="1936"
            [Height] => 1936
            [Width] => 2576
            [IsColor] => 1
            [ByteOrderMotorola] => 0
            [ApertureFNumber] => f/2.8
            [Thumbnail.FileType] => 2
            [Thumbnail.MimeType] => image/jpeg
        )

    [IFD0] => Array
        (
            [ImageWidth] => 2576
            [ImageLength] => 1936
            [BitsPerSample] => Array
                (
                    [0] => 8
                    [1] => 8
                    [2] => 8
                )

            [Make] => Nokia
            [Model] => N900
            [Orientation] => 1
            [SamplesPerPixel] => 3
            [XResolution] => 3000000/10000
            [YResolution] => 3000000/10000
            [ResolutionUnit] => 2
            [Software] => Adobe Photoshop CS5 Windows
            [DateTime] => 2011:01:29 09:37:30
            [YCbCrPositioning] => 1
            [Exif_IFD_Pointer] => 276
            [GPS_IFD_Pointer] => 658
        )

    [THUMBNAIL] => Array
        (
            [Compression] => 6
            [XResolution] => 72/1
            [YResolution] => 72/1
            [ResolutionUnit] => 2
            [JPEGInterchangeFormat] => 978
            [JPEGInterchangeFormatLength] => 5525
        )

    [EXIF] => Array
        (
            [ExposureTime] => 1/500
            [FNumber] => 14/5
            [ExposureProgram] => 0
            [ISOSpeedRatings] => 100
            [ExifVersion] => 0210
            [DateTimeOriginal] => 2011:01:29 09:37:30
            [DateTimeDigitized] => 2011:01:29 09:37:30
            [ShutterSpeedValue] => 8/1
            [ApertureValue] => 297/100
            [LightSource] => 0
            [Flash] => 0
            [FocalLength] => 26/5
            [FlashPixVersion] => 0100
            [ColorSpace] => 1
            [ExifImageWidth] => 2576
            [ExifImageLength] => 1936
            [CustomRendered] => 0
            [ExposureMode] => 0
            [WhiteBalance] => 0
            [DigitalZoomRatio] => 1/1
            [SceneCaptureType] => 0
            [GainControl] => 0
            [Contrast] => 0
            [Saturation] => 0
        )

    [GPS] => Array
        (
            [GPSVersion] => 
            [GPSLatitudeRef] => N
            [GPSLatitude] => Array
                (
                    [0] => 22/1
                    [1] => 12937/1000
                    [2] => 0/1
                )

            [GPSLongitudeRef] => E
            [GPSLongitude] => Array
                (
                    [0] => 113/1
                    [1] => 32886/1000
                    [2] => 0/1
                )

            [GPSAltitudeRef] => 
            [GPSAltitude] => 255/1
            [GPSTimeStamp] => Array
                (
                    [0] => 9/1
                    [1] => 37/1
                    [2] => 30/1
                )

            [GPSMapDatum] => WGS-84
            [GPSDateStamp] => 2011:01:29
        )

)

我的问题是如何创建一个只显示我选择的键的函数,作为键/值对,即使它位于数组的第二维或第三维?

例如 - 从上面的数组中,如果我只想选择[ImageWidth] , [ImageLength] , [XResolution] , [GPSTimeStamp] and [GPSLatitude] ..

我会将它传递给如下函数:

$keys_array = (ImageWidth , ImageLength, XResolution, GPSTimeStamp , GPSLatitude) 

进而

function select_keys_from_array ($keys_array='') {  
// if $keys_array=='' then get all ..
//identify the dimension or flatten - and get only my keys and display key/value 
}

我选择了这些键作为示例,因为它们中的一些位于第二级,而有些实际上是数组本身..

还有一个问题是理论上可以复制密钥(用户密钥) - 但驻留在不同的二级数组中(因此名义上不复制。)

我想我需要先“压平”它,然后以某种方式“传递”一组我想要的键 - 但我似乎无法真正做到正确。

有人知道那种东西的任何现成的类/函数/片段吗?

4

4 回答 4

1

编写一个递归函数,将多维数组转换为平面数组并消除重复键或您不想要的键。

function multi2flat($array) 
{
    $return = array();
    array_walk_recursive($array, function($a) use (&$return) { $return[] = $a; });
    return $return;
}
于 2012-03-28T07:22:35.850 回答
1

您不一定需要将其展平 - 事实上,这样做可能会覆盖您提到的那些可能出现在多个子阵列中的键。您只需要能够使用递归成功地遍历数组,包括嵌套数组(该例程将从头到尾读取单个数组,但会为遇到的每个子数组递归调用自身)。一旦你可以像这样走路,那么你就可以简单地将你遇到的键与你想要的键进行比较。

如果您想要出现在多个位置的特定版本的键,那么您将不得不以某种方式限定它们(“范围”它们) - 例如,使用 COMPUTED.Height 而不仅仅是 Height。您的步行算法必须跟踪通过数组的路径(即,它已经步行到那么远的父数组链)以允许进行这种比较。

于 2012-03-28T07:24:06.807 回答
1

免责声明;可能会做一些古怪的事情,没有经过全面测试——不过应该没问题)

最后编辑;第一个更好,因为它不排除数组值(例如坐标等

function array_by_keys_recursive(array $keys, array $array) {
    $results = array();
    foreach ($keys as $key) {
        if (isset($array[$key])) {
            $results[$key] = $array[$key];
            continue;
        }
        foreach ($array as $value) {
            if (\is_array($value)) {
                $results = \array_replace($results,
                    \array_by_keys_recursive(array($search), $value));
            }
        }
    }
    return $results;
}

测试:

$array = array(
    'a' => 1,
    'b' => 2,
    'c' => array(
        'd' => 3,
        'e' => 4,
    ),
    'f' => 5,
    'g' => array(
        'h' => array(
            'i' => 6,
            'j' => 7,
        ),
        'k' => 8,
    ),
);

\var_dump(\array_by_keys_recursive(array('a', 'b', 'c', 'h', 'i', 'j'), $array));

结果:

array(6) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  ["c"]=>
  array(2) {
    ["d"]=>
    int(3)
    ["e"]=>
    int(4)
  }
  ["h"]=>
  array(2) {
    ["i"]=>
    int(6)
    ["j"]=>
    int(7)
  }
  ["i"]=>
  int(6)
  ["j"]=>
  int(7)
}
于 2012-03-28T07:32:14.830 回答
1
<?

$x = Array
(
    'FILE' => Array
        (
            'FileName' => 'f-20110129_004_pp.jpg',
            'FileDateTime' => 0,
            'FileSize' => 3566966,
            'FileType' => 2,
            'MimeType' => 'image/jpeg',
            'SectionsFound' => 'ANY_TAG, IFD0, THUMBNAIL, EXIF, GPS',
        ),

    'COMPUTED' => Array
        (
            'html' => 'width="2576" height="1936"',
            'Height' => 1936,
            'Width' => 2576,
            'IsColor' => 1,
            'ByteOrderMotorola' => 0,
            'ApertureFNumber' => 'f/2.8',
            'Thumbnail.FileType' => 2,
            'Thumbnail.MimeType' => 'image/jpeg',
        ),

    'IFD0' => Array
        (
            'ImageWidth' => 2576,
            'ImageLength' => 1936,
            'BitsPerSample' => Array
                (
                    '0' => 8,
                    '1' => 8,
                    '2' => 8,
                ),

            'Make' => 'Nokia',
            'Model' => 'N900',
            'Orientation' => 1,
            'SamplesPerPixel' => 3,
            'XResolution' => '3000000/10000',
            'YResolution' => '3000000/10000',
            'ResolutionUnit' => 2,
            'Software' => 'Adobe Photoshop CS5 Windows',
            'DateTime' => '2011:01:29 09:37:30',
            'YCbCrPositioning' => 1,
            'Exif_IFD_Pointer' => 276,
            'GPS_IFD_Pointer' => 658,
        ),

    'THUMBNAIL' => Array
        (
            'Compression' => 6,
            'XResolution' => '72/1',
            'YResolution' => '72/1',
            'ResolutionUnit' => 2,
            'JPEGInterchangeFormat' => 978,
            'JPEGInterchangeFormatLength' => 5525,
        ),

    'EXIF' => Array
        (
            'ExposureTime' => '1/500',
            'FNumber' => '14/5',
            'ExposureProgram' => 0,
            'ISOSpeedRatings' => 100,
            'ExifVersion' => '0210',
            'DateTimeOriginal' => '2011:01:29 09:37:30',
            'DateTimeDigitized' => '2011:01:29 09:37:30',
            'ShutterSpeedValue' => '8/1',
            'ApertureValue' => '297/100',
            'LightSource' => 0,
            'Flash' => 0,
            'FocalLength' => '26/5',
            'FlashPixVersion' => '0100',
            'ColorSpace' => 1,
            'ExifImageWidth' => 2576,
            'ExifImageLength' => 1936,
            'CustomRendered' => 0,
            'ExposureMode' => 0,
            'WhiteBalance' => 0,
            'DigitalZoomRatio' => '1/1',
            'SceneCaptureType' => 0,
            'GainControl' => 0,
            'Contrast' => 0,
            'Saturation' => 0,
        ),

    'GPS' => Array
        (
            'GPSVersion' => '',
            'GPSLatitudeRef' => 'N',
            'GPSLatitude' => Array
                (
                    '0' => '22/1',
                    '1' => '12937/1000',
                    '2' => '0/1',
                ),

            'GPSLongitudeRef' => 'E',
            'GPSLongitude' => Array
                (
                    '0' => '113/1',
                    '1' => '32886/1000',
                    '2' => '0/1',
                ),

            'GPSAltitudeRef' => '',
            'GPSAltitude' => '255/1',
            'GPSTimeStamp' => Array
                (
                    '0' => '9/1',
                    '1' => '37/1',
                    '2' => '30/1',
                ),

            'GPSMapDatum' => 'WGS-84',
            'GPSDateStamp' => '2011:01:29',
        ),

);

function get_values( $data, $keys ) {
    $ret = Array();
    foreach( $data as $k => $v ) {
        if( is_array( $v ) ) {
            $t = get_values( $v, $keys );
            if( is_array( $t ) && sizeOf( $t ) > 0 ) {
                $ret[$k] = $t;
            }
        } else {
            if( in_array( $k, $keys ) ) {
                $ret[ $k ] = $v;
            }
        }
    }
    return $ret;
}

print_r( get_values( $x, Array( 'ImageWidth', 'ImageLength', 'XResolution', 'GPSLatitude' ) ) );

?>

于 2012-03-28T07:45:44.267 回答