2012-03-28 33 views
1

我已經使用PHP關聯多維陣列 - 打印僅選擇鍵

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 
} 

我已經選擇這些鍵作爲例子,因爲它們中的一些是二級的,並且一些實際上是陣列本身..

還有一個問題是,密鑰可以在理論上被複制(用戶密鑰) - (。和爲此不名義上覆制),但駐留在不同的第二級陣列

我想我需要「變平「首先,然後以某種方式」傳遞「我想要的密鑰陣列 - 但我似乎無法真正做到。

有人知道任何現成的類/功能/片段的那種事情?

+0

你應該使用通過樹循環遞歸函數?返回的條件應該是recurisvidad作爲參數傳遞的關鍵字。 – Lobo 2012-03-28 07:20:56

+0

嘗試遞歸... – TigerTiger 2012-03-28 07:21:20

回答

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) 
} 
+0

好的,這似乎工作,但可能重複的密鑰怎麼樣? – 2012-03-28 07:47:37

+0

@ObmerkNinenine有你去!它會將最後找到的「重複鍵」(整個數組*中的*)。 – Dan 2012-03-28 07:55:22

+0

嗯..現在我感到困惑:-)前者看起來像他們正在做的工作 - 不幸的是我在一箇舊的本地服務器 - 所以最後一個給我未定義的函數array_replace'() - 但看看你的例子 - 當它們在第二/第三級時它仍然返回一些鍵作爲數組。 – 2012-03-28 08:05:11

1

編寫一個遞歸函數,將多維數組轉換爲平坦數組,並消除重複鍵或不需要的鍵。

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

感謝您的回答 - 但我相信這正是我所要求的。 :-) – 2012-03-28 07:23:49

+0

好吧,看我更新的答案 – slash197 2012-03-28 07:35:33

1

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

如果你想要在多個位置出現特定版本的密鑰,那麼你將不得不以某種方式限定它們('scope') - 例如,使用COMPUTED.Height而不是Height。你的行走算法將不得不跟蹤通過數組的路徑(即它已經走過的父數組鏈)來進行比較。

+0

謝謝 - 從邏輯上說,你的答案很有意義(你把我的混亂想法變成文字) - 但從技術上說我不知道​​該怎麼做。是否有一些類似的類現成的課程? – 2012-03-28 07:26:56

+1

它聽起來可能並不令人望而生畏 - foreach是一種走遍數組元素的好方法。看看這個SO問題/答案:http://stackoverflow.com/questions/26007/iterating-over-a-complex-associative-array-in-php – JTeagle 2012-03-28 07:29:03

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

>