簡體   English   中英

PHP關聯多維數組 - 僅打印選定的鍵

[英]PHP associative multidimentional array - print only selected keys

我有一個從圖像中取出的數組

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 
}

我選擇了這些鍵作為示例,因為其中一些是二級的,有些實際上是數組本身..

還有一個問題是,理論上密鑰可以復制(用戶密鑰) - 但是駐留在不同的二級數組中(因此不會名義上重復)。

我想我需要首先“扁平化”它,然后以某種方式“傳遞”我想要的鍵的數組 - 但我似乎無法真正做到正確。

有人知道任何現成的類/功能/片段嗎?

編寫一個遞歸函數,將多維數組轉換為平數數組,並消除重復鍵或您不想要的鍵。

function multi2flat($array) 
{
    $return = array();
    array_walk_recursive($array, function($a) use (&$return) { $return[] = $a; });
    return $return;
}

您不一定需要將其展平 - 實際上,這樣做可能會覆蓋您提到的可能出現在多個子陣列中的那些鍵。 您只需要能夠使用遞歸成功遍歷數組(包括嵌套數組)(例程將從頭到尾讀取單個數組,但會為遇到的每個子數組遞歸調用自身)。 一旦你可以像這樣走路,那么你可以簡單地將你遇到的鍵與你想要的鍵進行比較。

如果您希望特定版本的密鑰出現在多個位置,那么您將不得不以某種方式限定它們(“范圍”它們) - 例如,使用COMPUTED.Height而不僅僅是Height。 你的行走算法必須跟蹤通過數組的路徑(即它走過的父數組鏈以獲得那么遠)以允許這種比較。

免責聲明 ;可能做古怪的東西,沒有經過充分測試 - 應該沒問題)

最后編輯 ; 第一個更好,因為它不排除數組值( 如坐標等

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)
}
<?

$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' ) ) );

?>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM