지난번 글에서는 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('|', $str, 2));
// 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() 메소드에서 받아서 어떻게 처리하는지 다음에 알아 볼께요.
'etc. > PHP' 카테고리의 다른 글
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 7 (0) | 2013.01.16 |
---|---|
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 6 (0) | 2013.01.16 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 5 (0) | 2013.01.15 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 4 (0) | 2013.01.08 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 2 (0) | 2013.01.08 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 1 (0) | 2013.01.05 |
PHP와 XSL 로 XML 변환하기 (0) | 2012.12.21 |
PHP로 XML , JSON 다루기 (2) | 2012.08.24 |
-PHP - Proxy 통해 원격 파일 존재 여부 파악하기 (0) | 2012.07.19 |