시중에서 소프트웨어를 구입하고 사용하려면 반드시 컴퓨터에 그 프로그램을 설치해야 합니다. 그리고 해당 소프트웨어의 업데이트 버전이 발표되었을 때에는 수시로 업데이트 프로그램도 실행하여 해당 소프트웨어를 항상 최신 버전으로 유지합니다. 그러나 인터넷에서 배포되는 웹 프로그램은 약간 상황이 다릅니다. 이 블로그에서 사용하고 있는 워드프레스나 익스프레스엔진과 같은 PHP 기반 웹 프로그램은 파일 관리 시스템이 적용되어 있지 않기 때문에 초보자가 처음 사용할 때에는 업데이트조차 매우 힘듭니다. 만약 이 글에서 소개하는 스크립트가 앞서 언급했던 웹 프로그램들에 적용되는 경우에는 초보자도 매우 쉽게 익스프레스 엔진을 설치 할 수 있게 될 것입니다.
※ 참고: 이 글은 2014년 1월 3일에 작성된 글입니다. 현재 워드프레스와 익스프레스엔진에는 고유의 파일시스템이 적용되어 자동업데이트 기능을 제공하고 있습니다.
PHP 전용 파일 시스템이 필요한 이유
PHP는 웹 프로그래머가 쉽게 웹 프로그램을 개발할 수 있게 해주는 쉬운 프로그래밍 언어입니다. 그러나 PHP는 개발자가 아닌 그냥 일반적인 사용자라면 약간 어려울 수도 있는 언어입니다. 특히 웹 프로그램을 업데이트할 때 매우 어렵습니다. 왜냐하면 업데이트 버전이 발표되는 경우에는 사용자가 수정된 파일을 인터넷에서 직접 다운로드를 해야 하고, 설치를 할 때에는 FTP 프로그램을 이용하여 사용자가 직접 업데이트 된 파일을 웹 서버에 업로드해야 하는 이유 때문입니다. 만약 이와 같은 문제점들이 모두 해결되고 인터넷에서 모든 업데이트를 해결할 수 있다면 사용자는 매우 쉽고 빠르게 웹 사이트 또는 블로그를 관리할 수 있을 것입니다.
Windows의 NTFS 또는 리눅스의 ext3 와 같은 파일시스템을 PHP에서도 사용할 수 있다면 PHP 초보자가 어려워하는 웹 프로그램의 업데이트 문제를 쉽게 해결할 수 있을 것입니다. 필자가 생각하는 PHP 전용 파일 시스템이란 일반적인 파일시스템 개념을 넘어서는 압축까지 지원하는 파일시스템입니다. 파일시스템이라는 이름이 매우 거창하게 들릴 수도 있겠지만 하나의 파일 시스템을 만드는 것과 같은 방법으로 하나의 거대한 시스템을 만들어보고자 이와 같은 이름을 지어보았습니다.
PHP 전용 파일 시스템 소스코드
이 스크립트는 필자가 직접 작성한 스크립트입니다. 필자가 생각하는 이 스크립트의 최종적인 모습은 완벽한 압축을 지원하고, 여러 개의 파일을 하나의 파일로 만들 수 있는 기능을 지원하여, 개발자가 업데이트 파일을 만들 때 또는 사용자가 웹 프로그램을 업데이트할 때 편리한 기능을 제공하는 것입니다. 별도의 프로그램 없이 인터넷에서 곧바로 웹 프로그램을 업데이트를 할 수만 있다면 사용자는 매우 쉽게 해당 웹 소프트웨어를 사용할 수 있을 것입니다. 또한 개발자는 간단하게 업데이트 파일을 배포할 수 있으므로 좀 더 빠른 개발이 가능할 것입니다.
※ 이 스크립트는 앞서 소개했던 암호화 시스템을 필요로 합니다. → 2017/10/03 [PHP] Mcrypt 라이브러리 활용 암호화 시스템 by Walter Erzsamatory
※ 사용 예제는 소스코드 하단에 있습니다.
require_once 'EES.class.php'; final class EPS { protected static $_instance = NULL; protected $_ees = NULL; protected $_default_uid = NULL; protected $_packages = NULL; protected function __construct () { $this->_ees = EES::getInstance()->setIv(); $this->_default_uid = 0; $this->_packages = array(); } public static function getInstance () { if (self::$_instance === NULL) { self::$_instance = new self(); } return self::$_instance; } public function create ($uid='') { if (!$uid) { if (isset($this->_packages[$this->_default_uid])) { $this->_default_uid++; } } else { $this->_default_uid = $uid; } $this->_packages[$this->_default_uid] = new stdClass(); $this->_packages[$this->_default_uid]->root = new stdClass(); return $this; } public function addFileByContents ($dir, $filename, $contents) { if (!($dir == '/' || $dir === '')) { if ($dir[strlen($dir)-1] == '/') { $temp = ''; for ($i=0; $i<(strlen($dir)-1); $i++) { $temp .= $dir[$i]; } $dir = $temp; unset($temp); } if (!(preg_match('/^([a-zA-Z\/]+)$/', $dir))) { return $this; } else { if (preg_match('/([\/]+)/', $dir)) { $temp = explode('/', $dir); $temp2 = ''; for ($i=0; $i<count($temp); $i++) { if (!$temp2) { $temp2 .= $temp[$i]; } else { $temp2 .= '->'.$temp[$i]; } $this->_addDirectory($temp2); } $dir = $temp2; unset($temp); unset($temp2); } else { $this->_addDirectory($dir); } } } if (preg_match('/^([a-zA-Z]*)\.([a-zA-Z]+)$/', $filename)) { $filename = str_replace('.', '_', $filename); eval(" if (!isset(\$this->_packages[\$this->_default_uid]->root->{$dir}->{$filename})) { \$this->_packages[\$this->_default_uid]->root->{$dir}->{$filename} = new stdClass(); \$this->_packages[\$this->_default_uid]->root->{$dir}->{$filename}->type = 'file'; } \$this->_packages[\$this->_default_uid]->root->{$dir}->{$filename}->content = \$contents; "); } return $this; } public function setDefaultUid ($uid) { if (isset($this->_packages[$uid])) { $this->_default_uid = $uid; } return $this; } public function convertToGz ($uid = '') { if (!$uid) { $uid = $this->_default_uid; } if (isset($this->_packages[$uid])) { $temp = serialize($this->_packages[$uid]); $temp = $this->_ees->encrypt($temp); return gzcompress($temp, 9); } else { return $this; } } public function convertFromGz ($gz, $uid = '') { if (!$uid) { $uid = $this->_default_uid; } if (isset($this->_packages[$uid])) { return $this; } $temp = gzuncompress($gz); $temp = $this->_ees->decrypt($temp); $this->_packages[$uid] = unserialize($temp); return $this; } private function _addDirectory ($dir) { eval(" if (!isset(\$this->_packages[\$this->_default_uid]->root->{$dir})) { \$this->_packages[\$this->_default_uid]->root->{$dir} = new stdClass(); \$this->_packages[\$this->_default_uid]->root->{$dir}->type = 'directory'; } "); } public function display ($uid = '') { if (!$uid) { $uid = $this->_default_uid; } print_r($this->_packages[$uid]); } }
EPS::getInstance()->create()->addFileByContents('abc/one/', 'index.php', 'abcd1') ->addFileByContents('abc/two/', 'index.php', 'abcd2') ->addFileByContents('abc/two/', 'erzsamatory.php', 'abcd2(1)') ->addFileByContents('abc/two/', 'package.php', 'abcd2(2)') ->addFileByContents('abc/two/', 'system.php', 'abcd2(3)') ->addFileByContents('abc/three/', 'index.php', 'abcd3') ->addFileByContents('abc/three/a', 'a.php', 'abcd3a') ->addFileByContents('abc/three/b', 'b.php', 'abcd3b') ->addFileByContents('abc/three/b', 'c.php', 'abcd3c') ->addFileByContents('abc/three/', 'e.php', 'abcd3e') ->addFileByContents('abc/four/', 'index.php', 'abcd4') ->addFileByContents('abc/five/', 'index.php', 'abcd5') ->addFileByContents('abc/six/', 'index.php', 'abcd6'); EPS::getInstance()->convertFromGz(EPS::getInstance()->convertToGz(), 5)->display(5);
※ 위 소스코드는 개발중이므로 오류가 발생할 수 있습니다.
타이틀 이미지: ChrisDag, First 15 drives (a natural RAID6 set), Flickr. CC BY 2.0.