반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 받은 트랙백

글 보관함


지난번 글에서는 pdf2text($filename) 함수에 있는 for 문 중간 까지 했습니다.

그 중간에 getObjectOptions() 함수를 call 하는 부분 바로 전까지 했는데요.


그 전까지는 PDF 안의 내용을 일단 바이너리 파일로 받아서 obj,endobj 구문별로 나는 다음에 다시 그 안의 내용을 stream,endstream 구문별로 나눴습니다.


그 stream 별로 나눈 값을 for 문 안에서 계속 getObjectOptions() 함수로 던져서 어떤 일을 하도록 시키는데.. 오늘은 그 어떤일이 어떤일인지 공부할 것 같습니다.


PDF 안의 내용을 가져오는 함수는 file_get_contents() 함수였고 그 바이너리 파일들을 다시 세분화 시킬 때 사용했던 함수가 PCRE 함수인 preg_match_all() 과 preg_match() 였었습니다.


그리고 추가로 PHP 정규 표현식 (regular expressions)과 PDF 구조에 대해서 알아야 했구요.


이제 getObjectOptions() 함수에 대해 알아보겠습니다.


function getObjectOptions($object) {
    $options = array();
    if (preg_match("#<<(.*)>>#ismU", $object, $options)) {
        $options = explode("/", $options[1]);
        @array_shift($options);

        $o = array();
        for ($j = 0; $j < @count($options); $j++) {
            $options[$j] = preg_replace("#\s+#", " ", trim($options[$j]));
           
            if (strpos($options[$j], " ") !== false) {
                $parts = explode(" ", $options[$j]);
                $o[$parts[0]] = $parts[1];
            } else
                $o[$options[$j]] = true;
        }
        $options = $o;
        unset($o);
    }

    return $options;
}


여기서도 PCRE 함수가 쓰이네요.

바이너리 파일 내용을 처리하기 위해서 이 함수들은 필수로 이해하고 있어야 할 것 같습니다.


우선 처음에 $options 라는 배열을 만들고 pdf2text() 함수 내에서 던져준 PDF 내의 각 stream 을 가지고 다룹니다.


preg_match("#<<(.*)>>#ismU", $object, $options)


받은 stream 블럭인 $object 안의 내용을 정규표현식인 #<<(.*)>>#ismU 로 구분해서 아까 만든 배열변수인 $options 에 담습니다.

정규표현식 #<<(.*)>>#ismU 가 뭔지 정확히 알면 좋겠는데...

혹시 정규표현식에 강하신 분 계시면 댓글에 이게 정확히 무엇을 말하는지 알려 주시면 감사하겠습니다.





그 다음은 explode() 함수를 썼습니다. 이 함수는 문자열을 특정 기준으로 자르는 함수입니다.

예제를 하나 보면요.


<?php
$str 
'one|two|three|four';

// positive limit
print_r(explode('|'$str2));

// negative limit (since PHP 5.1)
print_r(explode('|'$str, -1));
?>


이 소스를 돌리면 그 결과값은 아래와 같습니다.

Array
(
    [0] => one
    [1] => two|three|four
)
Array
(
    [0] => one
    [1] => two
    [2] => three
)


첫번째 파라미터는 구분자이고 두번째 파라미터는 작업할 문자열 그리고 마지막 파라미터는 limit 이라고 하는데요. 이 세번째는 옵션입니다.

위의 소스를 보면 2를 넣으면 두개로 구분해서 첫번째 | 를 기준으로 구분하고 나머지는 모두 한개의 값으로 처리하는군요.

두번째 소스는 마이너스 값을 넣었는데 | 구분자 이전의 값을 나누는 것 같습니다.

비슷한 함수로는 정규식을 사용해서 구분하는 preg_split() 이 있구요 반대되는 함수로는 implode() 함수가 있습니다.


지금 배우는 소스에서는 $options = explode("/", $options[1]); 로 구분자 / 을 기준으로 options 를 모두 나눴습니다.

여기서 / 는 뭐를 나타내는 것일까요?


지난번 글에 Hello World! 를 표시한 PDF 의 바이너리 파일을 보면 << , >> 구문 안에 어떤 정보들이 들어있고 그 안에 각각의 정보들이 / 나눠져 있는 걸 볼 수 있습니다.

/ 이 무슨 의미인지 알려면 PDF 구조에 대해 공부해야 할 것 같습니다.


obj, stream,<<,>>,/ 대충 지금까지 나온 PDF 내부에서 사용되는 기호입니다. 


하여간 / 로 나는 값을 PHP 의 array_shift() 함수로 돌립니다.

배열의 첫번쨰 요소를 없애버리는 겁니다. 그리고 두번째 요소가 첫번째 요소로 되는거죠.


<?php
$stack 
= array("orange""banana""apple""raspberry");
$fruit array_shift($stack);
print_r($stack);
?>


이렇게 하면 결과가 아래와 같이 됩니다.

Array
(
    [0] => banana
    [1] => apple
    [2] => raspberry
)


Hello World! PDF 의 바이너리를 보면 / 다음엔 Size, Root 이런 문자가 오는데 이걸 없애 버리는 건가요?


하여간 그 다음으로 넘어가면 $o라는 배열 변수를 만듭니다.

그래서 방금전에 explode 까지 한 결과값인 $options 배열을 for 문으로 돌립니다.



$options 배열의 각각의 요소를 다시 preg_replace() 함수를 이용해서 변환을 시켜주네요.


preg_replace("#\s+#", " ", trim($options[$j]));


#\s+# 로 변환을 하고 그 결과값의 좌우 공백을 없앤 값을 $options 배열에 다시 넣어줍니다.


그리고 $options[$j] 안에 공백이 있으면 다시 그 공백을 기준으로 나눠서 $parts 변수에 담습니다.

그 다음에 방금 전 만들어 주었던 $o 의 $parts[0] 에 $parts[1] 을 담습니다.

만약 공백이 없다면 $o[$options[$j]] 에 true 값을 대입시킵니다.


그래서 이 $o  변수를 $options 에 담은 다음에 그 값을 return 합니다.


여기까지가 getObjectOptions() 메소드가 하는 일 입니다.


정리하면 #<<(.*)>>#ismU 으로 나누고 그걸 다시 / 으로 나누고 배열을 shift 한 다음에 배열안의 내용을 #\s+# 로 나눠서 공백이 있으면 공백을 기준으로 다시 나누고 공백이 없으면 $o[$options[$j]] 를 true 로 해서 이 $o의 값을 $options 에 담아서 return 을 해 줍니다.


정규표현식이 정확히 무엇을 하라는 것인지 알고 싶네요.

혹시 아시는 분 설명 부탁드려요.


오늘은 여기까지 할거구요.


위의 만들어진 $options 값을 pdf2text() 메소드에서 받아서 어떻게 처리하는지 다음에 알아 볼께요.


반응형

Comment

이전 1 2 3 4 5 6 7 8 9 10 다음