APC(Alternative PHP Cache)는 eAccelerator 처럼 PHP 캐싱을 수행합니다.

- APC 설치
APC를 다운로드 후 설치를 진행합니다.
http://pecl.php.net/package/APC
[root@yongbok ~]# cd /usr/local/src
[root@yongbok ~]# wget http://pecl.php.net/get/APC-3.1.3p1.tgz
[root@yongbok ~]# tar xzvf APC-3.1.3p1.tgz
[root@yongbok ~]# cd APC-3.1.3p1
[root@yongbok ~]# /usr/local/php5/bin/phpize
[root@yongbok ~]# ./configure --enable-apc --with-php-config=/usr/local/php5/bin/php-config
[root@yongbok ~]# make && make install
Installing shared extensions: /usr/local/php5/lib/php/extensions/no-debug-non-zts-20060613/
[root@yongbok ~]# ls -l /usr/local/php5/lib/php/extensions/no-debug-non-zts-20060613 | grep apc
-rwxr-xr-x 1 root wheel 542184 1 25 02:54 apc.so

php.ini 파일에 아래 내용을 추가 합니다.
[root@yongbok ~]# vi /usr/local/apache2/conf/php.ini
[APC]
extension_dir=/usr/local/php5/lib/php/extensions/no-debug-non-zts-20060613
extension=apc.so
apc.mode=shm
apc.file_md5=1
apc.ttl=3600
apc.idle=900
apc.hash_buckets=256
apc.max_file_size=1024
apc.cachedir=/tmp
apc.mmap_file_mask=/tmp/apc.XXXXXX


아파치를 재시작 후 phpinfo 를 이용하여 APC를 확인합니다.
[root@yongbok ~]# /usr/local/apache2/bin/apachectl restart
[root@yongbok ~]# echo '<?php phpinfo(); ?>' > /var/www/html/phpinfo.php




출처 : http://www.cyworld.com/ruo91/3591174


1. http://pecl.php.net/package/apc 에서 다운로드
2. tar -xvzf APC-3.1.9.tgz
3. cd APC-3.1.9
4. ....../php/bin/phpize
5. ./configure --enable-apc-mmap --with-apxs=/home/apache/bin/apxs --with-php-config=/home/php/bin/php-config
6. make
7. make install
php 의 extension 모듈 위치 확인할 것.
8. php.ini 수정하기
extension_dir=설정한위치로적용
예) ....../php/lib/php/extensions/no-debug-zts-20090626/apc.so
extension_dir=....../php/lib/php/extensions
extension="no-debug-zts-20090626/apc.so"

extension="apc.so"
apc.enabled=1
apc.shm_segments=1
apc.shm_size=256
apc.ttl=7200
apc.user_ttl=7200
apc.num_files_hint=1024
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.enable_cli=1
apc.include_once_override=1

[출처] php apc 추가하기|작성자 밍구

[번역] PHP 코드를 최적화하는 40가지 팁

가끔 PHP로 웹페이지를 작성할 일이 있는데, 유용한 팁을 우연히 보게 되어 한글로 옮겨적어본다.

원문: Reinhold Weber씨의 40 Tips for optimizing your php Code

  1. 메쏘드가 static이 될 수 있다면 static으로 선언하라. 4배 빨라진다.
  2. echo가 print보다 빠르다.
  3. 문자열을 이어붙이지 말고, echo를 이용하여 여러 개의 파라미터를 적어라.
  4. for 루프을 위핸 최대값(탈출조건)을 루프 안에서가 아니고 루프 시작 이전에 지정하라.
  5. 메모리를 해제하기 위해 변수를 unset하라. 특히 커다란 배열은 그래야 된다.
  6. get, set, __autoload와 같은 마법을 피해라.
  7. require_once()는 비싸다.
  8. include와 require를 사용할 때, 경로를 찾는데 시간이 적게 걸리는 full path를 사용하라.
  9. 스크립트가 언제 실행했는지 알고 싶으면 time()보다 $_SERVER['REQUEST_TIME']이 좋다.
  10. 정규표현식보다는 가능하면 strncasecmp나 strpbrk, stripos를 사용하라.
    1. 역주
    2. strncasecmp: 두 문자열의 앞쪽 일부가 대소문자 구분없이 일치하는지 확인할 때 사용
    3. strpbrk: 문자 집합에 속한 특정 문자가 문자열에 나타나는지 확인할 때 사용
    4. stripos: 대소문자 구분없이 특정 문자열이 다른 문자열에 포함되는지 확인할 때 사용
  11. str_replace가 preg_replace보다 빠르지만, strtr은 str_replace보다 4배 빠르다.
  12. 만약 문자열 교체 같은 함수가 배열과 문자열을 인자로 받아들이면, 그리고 그 인자 리스트가 길지 않다면, 배열을 한 번에 받아들여서 처리하는 것 대신에 한 번에 문자열을 하나씩 넘겨서 처리하는 것을 고려해봐라.
  13. 여러 개의 if/else if 문장 대신에 select 문장을 사용하는 게 더 좋다.
  14. @를 이용한 에러 출력 방지는 매우 느리다.
  15. Apache의 mod_deflate를 켜라.
    1. 역주
    2. mod_deflate는 서버의 출력을 클라이언트에게 보내기 전에 압축하는 모듈임
  16. DB를 다 사용했으면 연결을 닫아라.
  17. $row['id']가 $row[id]보다 7배 빠르다.
  18. 에러 메시지는 비싸다.
  19. for 루프의 표현식 안에서 함수를 사용하지 마라. for ($x = 0; $x < count($array); $x)에서 count() 함수가 매번 호출된다.
  20. 메쏘드 안에서 지역 변수를 증가시키는 것이 거의 함수 안에서 지역 변수를 호출(증가?)하는 것만큼 빠르다.
  21. 전역 변수를 증가시키는 것이 지역 변수를 증가시키는 것보다 2배 느리다.
  22. 객체의 멤버변수를 증가시키는 것이 지역 변수를 증가시키는 것보다 3배 느리다.
  23. 값이 지정되지 않은 지역 변수를 증가시키는 것이 미리 초기화된 변수를 증가시키는 것보다 9~10배 느리다.
  24. 전역 변수를 함수 안에서 사용하지 않으면서 그저 선언하기만 해도 (지역 변수를 증가시키는 것만큼) 느려진다. PHP는 아마 전역 변수가 존재하는지 알기 위해 검사를 하는 것 같다.
  25. 메쏘드 호출은 클래스 안에서 정의된 메쏘드의 갯수에 독립적인 듯 하다. 왜냐하면 10개의 메쏘드를 테스트 클래스에 추가해봤으나 성능에 변화가 없었기 때문이다.
  26. 파생된 클래스의 메쏘드가 베이스 클래스에서 정의된 것보다 더 빠르게 동작한다.
  27. 한 개의 매개변수를 가지고 함수를 호출하고 함수 바디가 비어있다면(함수 내부에서 아무것도 실행하지 않는다면) 그것은 7~8개의 지역변수를 증가시키는 것과 똑같은 시간을 차지한다. 비슷한 메쏘드 호출은 마찬가지로 15개의 지역변수를 증가시키는 연산쯤 된다.
  28. 문자열을 이중 따옴표 대신에 단일 따옴표로 둘러싸는 것은 좀 더 빠르게 해석되도록 한다. 왜냐하면 PHP가 이중 따옴표 안의 변수를 찾아보지만 단일 따옴표 안에서는 변수를 찾지 않기 때문이다. 물론 문자열 안에서 변수를 가질 필요가 없을 때만 이렇게 사용할 수 있다.
  29. 문자열을 echo할 때 마침표 대신에 쉼표로 분리하는 것이 더 빠르다.
    1. 주의: 이것은 여러 문자열을 인자로 받아들이는 함수인 echo로만 작동한다.
  30. Apache에 의해 PHP 스크립트는 정적 HTML 페이지보다 최소 2에서 10배 느리게 서비스된다. 더 많은 정적 HTML 페이지와 더 적은 스크립트를 사용하려고 노력하라.
  31. PHP 스크립트는 캐시되지 않으면 매번 재 컴파일된다. 컴파일 시간을 제거함으로써 25~100%만큼의 성능을 증가시키기 위해 PHP 캐싱 도구를 설치하라.
  32. 가능한 한 많이 캐시하라. memcached를 사용하라. memcached는 고성능 메모리 객체 캐싱 시스템이다.
  33. 문자열을 가지고 작업하며 문자열이 특정 길이인지 확인할 필요가 있을 때, strlen() 함수를 쓸 것이다. 이 함수는 계산없이 zval 구조체에서 사용할 수 있는 이미 알려진 문자열 길이를 반환하기 때문에 매우 빠르다. 그러나 strlen()이 함수이기 때문에 여전히 조금 느리다. 왜냐하면 함수 호출은 언급된 함수의 실행 뒤에 lowercase와 hashtable lookup같은 여러 개의 연산을 호출하기 때문이다. 어떤 경우에는 isset() 트릭을 이용하여 코드의 스피드를 증가시킬 수도 있다.
    if (strlen($foo) < 5) { echo "Foo is too short"; }
    if (!isset($foo{5})) { echo "Foo is too short"; }

    isset()을 호출하는 것은 strlen()과는 달리 isset()이 언어 기본문법이고 함수가 아니기 때문에 함수 찾와 lowercase 작업을 필요로 하지 않으므로 strlen()보다 더 빠를 수도 있다. 이것은 가상적으로 문자열의 길이를 결정하는 실제 코드에 과부하가 없다는 것을 의미한다.

  34. 변수 $i의 값을 증가시키거나 감소키킬 때, $i++은 ++$i보다 조금 더 느릴 수 있다. 이것은 PHP의 특징이고 다른 언어에는 해당되지 않으니 좀 더 빨라질 것을 기대하면서 C나 Java 코드를 바꾸러 가지 마라. 안 빨라질 것이다. ++$i는 PHP에서 좀 더 빠른데 그것은 $i++에 4개의 opcode가 사용되는 대신에 3개만 필요하기 때문이다. 후증가는 사실 증가될 임시변수의 생성을 초래한다. 반면에 전증가는 원래 값을 직접 증가시킨다. 이것은 opcode가 Zend의 PHP optimizer처럼 최적화하는 최적화 기법의 하나이다. 모든 opcode optimizer들이 이 최적화를 수행하는 것은 아니고 많은 ISP와 server들이 opcode optimizer없이 수행되고 있기 때문에 명심하는 게 좋을 것이다.
  35. 모든 것이 OOP일 필요는 없다. 종종 그것은 너무 많은 과부하가 된다. 각각의 메쏘드와 객체 호출은 메모리를 많이 소비한다.
  36. 모든 데이터 구조를 클래스로 구현하지 마라. 배열도 유용하다.
  37. 메쏘드를 너무 많이 분리하지 마라. 어떤 코드를 정말 재사용할지 생각해봐라.
  38. 항상 메쏘드의 코드를 나중에 필요할 때 분리할 수 있다.
  39. 수많은 미리 정의된 함수를 활용해라.
  40. 매우 시간을 소비하는 함수가 있다면, C 확장으로 작성하는 것을 고려해봐라.
  41. 당신의 코드를 프로파일해봐라. 프로파일러는 코드의 어떤 부분이 가장 많은 시간을 소비하는지 보여준다. Xdebug 디버거는 이미 프로파일러를 포함하고 있다. 프로파일링은 전체적인 병목을 보여준다.
  42. Apache 모듈로 사용가능한 mod_gzip은 실행 중에 데이터를 압축하여 전송할 데이터를 80%까지 줄일 수 있다.

Daniel Vecchiato님(?)의 Using Zend Framework components in Code Igniter에서 잘 설명이 되어있는데요.

CodeIgniter가 아니더라도 일반 php 프로그래밍에서도 적용이 가능합니다.

참고할 부분은 include_path에 Zend Framework가 설치된 경로를 추가하는 부분인데요.

  1. ini_set('include_path', ini_get('include_path').':'.Zend Framework Path);

입니다. 기본적인 php 설명은 생략합니다. ^^;

다만 저는 개인적으로 만들어놓은 Framework를 사용하고 부족한 부분을 외부 Library는 따로 모아서 관리하고 최대한 가벼운 Library를 사용하기 위해 global function을 만들어 사용하고 있습니다. php5를 php4처럼 사용하는 것이 좀 걸리지만...

여하튼 제가 사용하는 방법은... 부끄럽지만....

  1. function load_library($filename, $extend = false)
  2. {
  3. require_once SYSPATH.'libraries/'.$filename.'.php';

    if (true === $extend && defined('EXTEND_LIBRARY') === false) {

  4. ini_set('include_path', ini_get('include_path').':'.SYSPATH.'libraries/');
  5. define('EXTEND_LIBRARY', true);
  6. }
  7. }

SYSPATH는 Using Zend Framework components in Code Igniter에 나와있는 BASEPATH와 비슷한 개념입니다. 물론 Window의 경우는 굵게 표시된 ':' 대신 ';'을 사용하셔야 합니다. Using Zend Framework components in Code Igniter에서 처럼

결론은 include_path에 설치 경로를 추가.

출처 : http://egg.pe.kr/147


쓴이 : 카폐인(nonots@hanmail.net)
쓴때 : 2009-04-02 나른한 오후
도움 : 바다웹호스팅 http://www.badaweb.co.kr

1. 개요

phpmyadmin 은 많이 쓰지만 거기 있는 고급 기능들은
대부분 거의 안써왔는데.. 얼마전 한 고객이 DB ERD 구조도
보내 달라고 해서 귀찮았던 적이 있다.
원격 DB 서버를 일반적인 ERD 툴로 접속하려면 포트, 아이피 열어주고
방화벽 열어주고.. 귀찮은데.. phpmyadmin 에서 웹모드로 DB Designer
를 구현해 놓아서 편리하다.
..
어제 하루종일 인터넷 검색해봐도 허탕이었는데..
등잔밑이 어두웠다..



2. 미리 할 일

1) phpmyadmin 최신버전 설치한다. 2.5 버전 이상에서 가능하다는데
이왕이면 http://phpmyadmin.net 에서 현재 최신버전 3.1.3 이상을 다운받아 압축풀고
설치한다.


2) scripts/create_tables.sql 파일로 db 와 테이블을 생성한다.
이부분이 중요하다. 고급기능을 위해 필요한 정보를 별도 테이블에 저장해야한다.
이 파일을 보면 phpmyadmin 라는 DB 를 만들고 테이블 여러개를 생성한다.

mysql -uroot -proot_pwd < scripts/create_tables.sql

명령어로 밀어 넣은뒤, 이 DB 에 접근할 사용자
예를 들어, pma 를 추가한후 phpmyadmin 에 접근 권한을 준다.

GRANT SELECT, INSERT, DELETE, UPDATE ON `phpmyadmin`.* TO 'pma'@localhost;


3) config.sample.inc.php 파일을 config.inc.php 로 복사한다.
일반적으로 설치하듯이 직관적으로 세팅한다.
이 파일 마지막 부분에 주석처리된 아래 부분 주석 풀어준다.

....
$cfg['Servers'][$i]['controluser'] = 'pma'; // phpmyadmin DB 에 grant 된 사용자
$cfg['Servers'][$i]['controlpass'] = 'kw1934';
/* Advanced phpMyAdmin features */
$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin'; // 사용할 DB, 변경가능할듯
$cfg['Servers'][$i]['bookmarktable'] = 'pma_bookmark';
$cfg['Servers'][$i]['relation'] = 'pma_relation';
$cfg['Servers'][$i]['table_info'] = 'pma_table_info';
$cfg['Servers'][$i]['table_coords'] = 'pma_table_coords';
$cfg['Servers'][$i]['pdf_pages'] = 'pma_pdf_pages';
$cfg['Servers'][$i]['column_info'] = 'pma_column_info';
$cfg['Servers'][$i]['history'] = 'pma_history';
$cfg['Servers'][$i]['designer_coords'] = 'pma_designer_coords';
....

만약 DB 에 root 권한이 없다면 phpmyadmin 이라는 DB 를 별도 생성을 못하니까,
자신의 DB 로 막바로 해도 될꺼다.
그리고 controluser, controlpass 부분도 db 사용자 와 같게 하면 될꺼 같다.
안해 봐서 모름.


4) 웹브라우저로 설치된 phpmyadmin 에 접속한후 왼쪽 메뉴에서 DB 명 하나를 클릭한 후
오른쪽 본문 상단에 보면 "Designer" 라는 메뉴가 보인다. 클릭하면 된다.
직관적으로 사용하면 된다.
결과를 PDF 파일로 저장도 된다는데 해보지는 않았음.



3. 마무리

오래전에 phpdbdesigner 라는 게 있었는데 더이상 개발이 안되어서 관심을 가지지 않았는데
알고보니 그 기능이 phpmyadmin 에 흡수되었더군요.
..
eyeOS 1.8.5 로 버전업하면서..
웹브라우저로 참 많은짓을 하는구나.. 하는 생각을..
..
나른한 오후.. 졸린다..
..
아참.. php, mysql 옛날버전(?)은 잘 안될겁니다.
#####################################################
## 쓴이 : 카폐인(nonots@hanmail.net)
## 쓴때 : 2009-04-02 나른한 오후
## 도움 : 바다웹호스팅 http://www.badaweb.co.kr
## 제목 : phpMyAdmin 에서 DB Designer 기능 사용하기
#####################################################

1. 개요

phpmyadmin 은 많이 쓰지만 거기 있는 고급 기능들은
대부분 거의 안써왔는데.. 얼마전 한 고객이 DB ERD 구조도
보내 달라고 해서 귀찮았던 적이 있다.
원격 DB 서버를 일반적인 ERD 툴로 접속하려면 포트, 아이피 열어주고
방화벽 열어주고.. 귀찮은데.. phpmyadmin 에서 웹모드로 DB Designer
를 구현해 놓아서 편리하다.
..
어제 하루종일 인터넷 검색해봐도 허탕이었는데..
등잔밑이 어두웠다..



2. 미리 할 일

1) phpmyadmin 최신버전 설치한다. 2.5 버전 이상에서 가능하다는데
이왕이면 http://phpmyadmin.net 에서 현재 최신버전 3.1.3 이상을 다운받아 압축풀고
설치한다.


2) scripts/create_tables.sql 파일로 db 와 테이블을 생성한다.
이부분이 중요하다. 고급기능을 위해 필요한 정보를 별도 테이블에 저장해야한다.
이 파일을 보면 phpmyadmin 라는 DB 를 만들고 테이블 여러개를 생성한다.

mysql -uroot -proot_pwd < scripts/create_tables.sql

명령어로 밀어 넣은뒤, 이 DB 에 접근할 사용자
예를 들어, pma 를 추가한후 phpmyadmin 에 접근 권한을 준다.

GRANT SELECT, INSERT, DELETE, UPDATE ON `phpmyadmin`.* TO 'pma'@localhost;


3) config.sample.inc.php 파일을 config.inc.php 로 복사한다.
일반적으로 설치하듯이 직관적으로 세팅한다.
이 파일 마지막 부분에 주석처리된 아래 부분 주석 풀어준다.

....
$cfg['Servers'][$i]['controluser'] = 'pma'; // phpmyadmin DB 에 grant 된 사용자
$cfg['Servers'][$i]['controlpass'] = 'kw1934';
/* Advanced phpMyAdmin features */
$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin'; // 사용할 DB, 변경가능할듯
$cfg['Servers'][$i]['bookmarktable'] = 'pma_bookmark';
$cfg['Servers'][$i]['relation'] = 'pma_relation';
$cfg['Servers'][$i]['table_info'] = 'pma_table_info';
$cfg['Servers'][$i]['table_coords'] = 'pma_table_coords';
$cfg['Servers'][$i]['pdf_pages'] = 'pma_pdf_pages';
$cfg['Servers'][$i]['column_info'] = 'pma_column_info';
$cfg['Servers'][$i]['history'] = 'pma_history';
$cfg['Servers'][$i]['designer_coords'] = 'pma_designer_coords';
....

만약 DB 에 root 권한이 없다면 phpmyadmin 이라는 DB 를 별도 생성을 못하니까,
자신의 DB 로 막바로 해도 될꺼다.
그리고 controluser, controlpass 부분도 db 사용자 와 같게 하면 될꺼 같다.
안해 봐서 모름.


4) 웹브라우저로 설치된 phpmyadmin 에 접속한후 왼쪽 메뉴에서 DB 명 하나를 클릭한 후
오른쪽 본문 상단에 보면 "Designer" 라는 메뉴가 보인다. 클릭하면 된다.
직관적으로 사용하면 된다.
결과를 PDF 파일로 저장도 된다는데 해보지는 않았음.



3. 마무리

오래전에 phpdbdesigner 라는 게 있었는데 더이상 개발이 안되어서 관심을 가지지 않았는데
알고보니 그 기능이 phpmyadmin 에 흡수되었더군요.
..
eyeOS 1.8.5 로 버전업하면서..
웹브라우저로 참 많은짓을 하는구나.. 하는 생각을..
..
나른한 오후.. 졸린다..
..
아참.. php, mysql 옛날버전(?)은 잘 안될겁니다.

#####################################################
## 쓴이 : 카폐인(nonots@hanmail.net)
## 쓴때 : 2009-04-02 나른한 오후
## 도움 : 바다웹호스팅 http://www.badaweb.co.kr
## 제목 : phpMyAdmin 에서 DB Designer 기능 사용하기
#####################################################

1. 개요

phpmyadmin 은 많이 쓰지만 거기 있는 고급 기능들은
대부분 거의 안써왔는데.. 얼마전 한 고객이 DB ERD 구조도
보내 달라고 해서 귀찮았던 적이 있다.
원격 DB 서버를 일반적인 ERD 툴로 접속하려면 포트, 아이피 열어주고
방화벽 열어주고.. 귀찮은데.. phpmyadmin 에서 웹모드로 DB Designer
를 구현해 놓아서 편리하다.
..
어제 하루종일 인터넷 검색해봐도 허탕이었는데..
등잔밑이 어두웠다..



2. 미리 할 일

1) phpmyadmin 최신버전 설치한다. 2.5 버전 이상에서 가능하다는데
이왕이면 http://phpmyadmin.net 에서 현재 최신버전 3.1.3 이상을 다운받아 압축풀고
설치한다.


2) scripts/create_tables.sql 파일로 db 와 테이블을 생성한다.
이부분이 중요하다. 고급기능을 위해 필요한 정보를 별도 테이블에 저장해야한다.
이 파일을 보면 phpmyadmin 라는 DB 를 만들고 테이블 여러개를 생성한다.

mysql -uroot -proot_pwd < scripts/create_tables.sql

명령어로 밀어 넣은뒤, 이 DB 에 접근할 사용자
예를 들어, pma 를 추가한후 phpmyadmin 에 접근 권한을 준다.

GRANT SELECT, INSERT, DELETE, UPDATE ON `phpmyadmin`.* TO 'pma'@localhost;


3) config.sample.inc.php 파일을 config.inc.php 로 복사한다.
일반적으로 설치하듯이 직관적으로 세팅한다.
이 파일 마지막 부분에 주석처리된 아래 부분 주석 풀어준다.

....
$cfg['Servers'][$i]['controluser'] = 'pma'; // phpmyadmin DB 에 grant 된 사용자
$cfg['Servers'][$i]['controlpass'] = 'kw1934';
/* Advanced phpMyAdmin features */
$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin'; // 사용할 DB, 변경가능할듯
$cfg['Servers'][$i]['bookmarktable'] = 'pma_bookmark';
$cfg['Servers'][$i]['relation'] = 'pma_relation';
$cfg['Servers'][$i]['table_info'] = 'pma_table_info';
$cfg['Servers'][$i]['table_coords'] = 'pma_table_coords';
$cfg['Servers'][$i]['pdf_pages'] = 'pma_pdf_pages';
$cfg['Servers'][$i]['column_info'] = 'pma_column_info';
$cfg['Servers'][$i]['history'] = 'pma_history';
$cfg['Servers'][$i]['designer_coords'] = 'pma_designer_coords';
....

만약 DB 에 root 권한이 없다면 phpmyadmin 이라는 DB 를 별도 생성을 못하니까,
자신의 DB 로 막바로 해도 될꺼다.
그리고 controluser, controlpass 부분도 db 사용자 와 같게 하면 될꺼 같다.
안해 봐서 모름.


4) 웹브라우저로 설치된 phpmyadmin 에 접속한후 왼쪽 메뉴에서 DB 명 하나를 클릭한 후
오른쪽 본문 상단에 보면 "Designer" 라는 메뉴가 보인다. 클릭하면 된다.
직관적으로 사용하면 된다.
결과를 PDF 파일로 저장도 된다는데 해보지는 않았음.



3. 마무리

오래전에 phpdbdesigner 라는 게 있었는데 더이상 개발이 안되어서 관심을 가지지 않았는데
알고보니 그 기능이 phpmyadmin 에 흡수되었더군요.
..
eyeOS 1.8.5 로 버전업하면서..
웹브라우저로 참 많은짓을 하는구나.. 하는 생각을..
..
나른한 오후.. 졸린다..
..
아참.. php, mysql 옛날버전(?)은 잘 안될겁니다.

암호화에 대한 기본 상식

암호화(Encryption)의 방식에는 단방향 암호화, 대칭 암호화, 비대칭 암호화가 있다.

단방향 암호화(One-way Encryption)는 복호화할 수 없도록 하는 방식이다. 이 방식에서는 해시 알고리즘(Hash Algorithm)을 사용하는데, 이 과정을 통해 고유한 지문(Fingerprint)을 생성한다.

일반적으로, 단방향 암호화를 통해 얻은 값으로는 복호화가 불가능하다고 하는데 원문이 짧거나 일반적으로 널리 사용되는 문자열일 경우에는 무작위 값 입력을 통한 공격(Brute Force Attack)을 통해 무력화되기 쉽다.

MD5, SHA1 등이 대표적인 해시 알고리즘이다.

대칭 암호화(Symmetric Encryption)는 키(Key)를 통해 동일한 알고리즘으로 암호화/복호화를 하는 방법이다. 이 방식은 2차 세계대전 중에 암호화 기계(Enigma Machine)에 사용된 방식이다.

암호화/복호화에 필요한 키가 유출되지만 않는다면 매우 안전한 방식이다. DES, TWOFISH, GOST 등이 대표적인 알고리즘이다.

비대칭 암호화(Asymmetric Encryption)는 SSL 같은 방식이라고 하는데, 자세한 내용은 모르므로 넘어가겠다.

이 글에서는 PHP에서 대칭 암호화 방식을 통한 암호화/복호화에 대해 설명하겠다.

Mcrypt 라이브러리의 설치와 설정

PHP에서는 Mcrypt 라이브러리를 통해 대칭 암호화를 지원한다. 따라서 Mcrypt를 이용하려면 라이브러리를 추가로 설치해 주어야 한다.

http://mcrypt.sourceforge.net/에서 Mcrypt 라이브러리를 다운로드 받을 수 있으며, 윈도우 서버라면 http://files.edin.dk/php/win32/mcrypt/에서 컴파일된 라이브러리 파일을 다운로드 받아 사용할 수 있다. 작동하도록 설정하려면 php.ini의 설정을 변경해 주어야 하는데, 자세한 설정 방법은 http://www.php.net/manual/kr/book.mcrypt.php 에서 확인할 수 있다.

데비안 계열 리눅스 서버라면 터미널에서 다음의 명령어를 입력하는 것으로 Mcrypt를 설치와 설정을 완료할 수 있다.

1.$ sudo apt-get install php5-mcrypt
2.$ sudo apt-get install libmcrypt4
3.$ sudo /etc/init.d/apache2 restart

Mcrypt를 이용한 암호화/복호화 예제

다음의 코드를 보면 쉽게 이해할 수 있다.

01.$key = "열쇠";
02.$plainData = "개인정보";
03.$encryptedDataOnBinary = mcrypt_ecb(MCRYPT_GOST, $key, $plainData, MCRYPT_ENCRYPT);
04.$encryptedData = base64_encode($encryptedDataOnBinary);
05.echo "암호화 할 평문 : ".$plainData;
06.echo "<BR>
07.";
08.echo "암호화 결과로 나온 바이너리 값: ".$encryptedDataOnBinary;
09.echo "<BR>
10.";
11.echo "암호화 결과를 아스키 코드로 변환한 값 : ".$encryptedData;

앞서 설명했듯, 대칭 암호화를 하기 위해서는 키가 필요하다. 이 예제에서는 $key로 "열쇠"라는 임의의 문자열을 넣었는데 실제로는 더 복잡하고 고유한 것을 사용하는 것이 좋겠다. $plainData는 암호화 할 대상을 말한다. 이 예제에서는 예로 "개인정보"라는 문자열을 넣어보았다.

mcrypt는 여러 기본 함수를 제공하는데, 그 중 이번에는 mcrypt_ecb() 함수를 이용했다. 참고로 ECB란 전자 부호표 모드(Electric CodeBook mode)의 약자다. mcrypt_ecb() 함수에는 네 가지 값을 넣어주어야 하는데, Mcrypt에서 제공하는 알고리즘 상수, 키, 암호화 할 값, 암호화/복호화를 위한 상수가 그것이다.

Mcrypt에서는 DES, TWOFISH, GOST 등 많은 알고리즘을 지원하는데 이 목록은 http://www.php.net/manual/en/mcrypt.ciphers.php에서 확인할 수 있다. 이 예제에서는 GOST 방식을 사용하기 위해 MCRYPT_GOST라는 상수를 사용했다. 또한 이 예제에서는 암호화을 할 것이므로 MCRYPT_ENCRYPT라는 상수도 넣었다.

이렇게 Mcrypt를 통해 암호화를 하면 그 결과로 바이너리(Binary) 값을 반환한다. 즉, 컴퓨터만 이해할 수 있는 2진수 데이터를 반환한다는 의미다. 따라서 브라우저는 "'ӫ�{3�ѠO#�c�ʾfBg�"와 같이 인간도, 브라우저도 이해할 수 없는 결과를 출력할 것이다.

이 문제는 base64_encode() 함수를 이용함으로써 해결할 수 있다. 결과적으로 "8UHT/jWsIopHDCUpbfJLIA=="와 같이 아스키 코드로 변환한 값을 얻을 수 있다. 이로써 암호화가 성공적으로 이루어졌다.

이제 복호화 코드를 보자.

1.$decryptedDataOnBinary = base64_decode($encryptedData);
2.$decryptedData = mcrypt_ecb(MCRYPT_GOST, $key, $decryptedDataOnBinary, MCRYPT_DECRYPT);
3.echo "바이너리 값으로 다시 변환한 암호화 결과 값 : ".$decryptedDataOnBinary;
4.echo "<BR>
5.";
6.echo "바이너리 값을 복호화 한 결과 값 : ".$decryptedData;

앞서 (아스키 코드로 까지) 암호화한 결과 값을 base64_decode() 함수를 이용해 다시 바이너리 값으로 변환한다. 이 값을 다시 mcrypt_ecb() 함수를 이용해 복호화 하기 위해, 앞서 암호화하기 위해 사용했던 알고리즘의 상수인 MCRYPT_GOST, 앞서 암호화 하기 위해 사용했던 키, 바이너리로 다시 변환한 암호화 결과 값, 복호화를 위한 상수 MCRYPT_DECRYPT를 넣는다. 그 결과로 복호화 된 결과 값인 $decryptedData를 출력하면 "개인정보"라는 문자열을 얻게 된다. 이로써 복호화도 성공적으로 이루어졌다.

위의 결과를 아래와 같이 함수로 정리하면 편리하게 사용할 수 있다.

01.// mcrypt.php
02.$key = "1dasd12WESA12dsaasd456TGDFsd";
03.
04./**
05.* 데이터 암호화 함수
06.*/
07.function function_for_encryption($plain_data){
08. global $key;
09. $encrypted_data_on_binary = mcrypt_ecb (MCRYPT_SERPENT, $key, $plain_data, MCRYPT_ENCRYPT);
10. $encrypted_data = base64_encode($encrypted_data_on_binary);
11. return $encrypted_data;
12.}
13.
14./**
15.* 데이터 복호화 함수
16.*/
17.function function_for_decryption($encrypted_data){
18. global $key;
19. $decrypted_data_on_binary = base64_decode($encrypted_data);
20. $plain_data = mcrypt_ecb (MCRYPT_SERPENT, $key, $decrypted_data_on_binary, MCRYPT_DECRYPT);
21. return $plain_data;
22.}

Mcrypt를 이용한 암호화/복호화를 DB 입력/조회에 적용하기

이제 암호화/복호화를 DB 입력/조회에 적용해 보겠다.

DB에는 mailing_list라는 테이블이 있고 그 안에 no, name, email, date라는 필드가 있고 no 필드는 int이며 Auto Increment, 나머지 필드는 모두 varchar라고 가정한다.

POST 값으로 다음과 같은 메일링리스트 가입 정보를 받았다고 가정하자.

1.Array (
2. [name] => testman
3. [email] => test@example .com
4. [date] => 20110521
5.)

이제 POST로 넘겨받은 모든 값을 암호화 해서 DB에 입력할 것이다.

01.// insertDB.php
02.include ./dbConnect.php; // DB 연결 (구체적인 코드는 생략한다)
03.include ./mcrypt.php;
04.
05.foreach($_POST as $key => $value) {
06. $_POST[$key] = function_for_encryption($value);
07.}
08.$query = "INSERT INTO `mailing_list` (`name`, `email`, `date`)
09. VALUES ('{$_POST['name']}', '{$_POST['email']}', '{$_POST['date']}')";
10.$result = mysql_query($query);

이제 mailing_list 테이블의 모든 데이터를 조회해서 복호화 한 다음, 화면에 출력할 것이다.

01.//selectDB.php
02.include ./dbConnect.php; //DB 연결 (구체적인 코드는 생략한다)
03.include ./mcrypt.php;
04.
05.$query = "SELECT * `mailing_list`";
06.$result = mysql_query($query);
07.$number_of_rows = mysql_num_rows($result);
08.for ($i=0; $i<$number_of_rows; $i++){
09. $row = mysql_fetch_array($result);
10. foreach($row as $key => $value) {
11. if ($key=='no') {
12. continue; // $row['no']는 복호화 할 필요가 없다.
13. }
14. $row[$key] = function_for_decryption($value);
15. }
16. echo "번호 : ".$row['no']." 이름 : ".$row['name']." 이메일 : ".$row['email']." 날짜".$row['date'];
17.}
 

+ Recent posts