* My-SQL
- mysql 공식 사이트 

http://www.mysql.com

- 로그인하는 방법

mysql -h 호스트 -u 아이디 -p

  => 패스워드를 입력

 mysql -u 아이디 -p패스워드

- 데이터베이스 보기

 show databases;

- 데이터베이스 사용 

use 데이터베이스명

- 테이블 목록 보기 

show tables;

- 종료하기 ( quit or \q )

- 데이터베이스 만들기 create database 데이터베이스이름;

- mysql에 새로운 사용자 계정 추가하기
  1) root 계정으로 접속  : mysql -u root -p
  2) mysql 데이터베이스 연결 : use mysql
  3) user 테이블에 새로운 사용자 계정 추가
 insert into user (host,user,password) values
 ('호스트','아이디',password('패스워드') ); // 패스워드는 반드시 암호화 처리
 IP => 특정 호스트
 % => 모든 호스트
 localhost => 로컬에서만 접속 가능
  4) db 테이블에 권한 추가
 insert into db values
 ('호스트','DB이름','아이디','y','y','y','y','y','y','y','y','y','y','y','y');
     권한 필드 12개 - 해당 DB의 모든 권한
  5) 권한 테이블 업데이트

 flush privileges;

* 관리자 패스워드 변경하기
  1) 관리자 계정으로 접속 : mysql -u root -p암호
  2) 암호 변경 ( 반드시 password() 함수를 사용하여 암호화해야 로그인이 가능함 )
 update user set password=password("변경할암호") where user='root';
  3) 권한 테이블 변경
 flush privileges;
* 실습문제
- mysql root 계정을 특정한 IP에서 접속가능하도록 설정하고 비밀번호를 변경하세요.
  허용 IP : 172.30.4.10, 172.30.4.11, 172.30.4.12(IP는 임의로 지정), localhost
  비밀번호 : oradba 로 통일
- 사용자 계정 추가 연습
  사용자아이디 : user2
  비밀번호 : 임의지정
  호스트 : 모든 호스트에서 접속 가능하도록 설정
  user2가 사용할 DB : myoradb, web

 
* root 암호를 분실했을 때의 해결 방법
- 암호 복구 방법 사용
  1. 현재 실행중인 mysql 데몬(mysqld-nt.exe)을 중지시킨다.
    프롬프트> net stop mysql  ( 또는 프로세스에서 강제 종료 )
  2. 사용권한을 조회하지 않는 옵션으로 mysql 데몬을 실행시킴
    프롬프트> mysqld-nt --skip-grant
  3. mysql에 접속(암호를 입력하지 않음)
    프롬프트> mysql -u root mysql
  4. root 암호 변경
  5. mysql 종료
  6. 현재 실행중인 데몬 종료( 프로세스에서 강제 종료 )
  7. 정상적인 옵션으로 mysql 데몬을 다시 실행함
    프롬프트>net start mysql   or  프롬프트>mysqld-nt
  8. 변경한 암호로 재접속

* mysql 명령어 연습
- 데이터베이스 접속
mysql -h 호스트 -u 아이디 -p암호 사용할DB => 암호가 노출됨
mysql -h 호스트 -u 아이디 -p 사용할DB => 암호가 노출되지 않음
- 데이터베이스 생성하기 : create database DB이름 => 관리자 계정만 가능
- 데이터베이스 삭제하기 : drop database DB이름  => 관리자 계정만 가능
- 데이터베이스 목록보기 : show databases
- 테이블 만들기 : create table 테이블명 ( ... );
- 테이블 목록보기 : show tables;
- 테이블 구조보기 : desc 테이블명;
- 필드 추가하기 : alter table 테이블명 add 필드명 자료형 before/after 필드명;
- 필드 삭제하기 : alter table 테이블명 drop 필드명;
- 필드 수정하기 : alter table 테이블명 change 이전필드명 새로운필드명 타입;
- 필드값 자동 증가 옵션 : auto_increment
 ex) alter table friend change num num int auto_increment;
- 테이블 이름 변경하기 : alter table 이전테이블명 rename 새테이블명;
- 테이블 삭제하기 : drop table 테이블명;
- 쿼리 일괄적용
프롬프트>mysql -u 아이디 -p비밀번호 DB이름 < 일괄쿼리파일

 


* 백업과 복구
- 백업
  mysql-data 하위 폴더를 복사하여 붙여넣기
  프롬프트>mysqldump -u 아이디 -p비밀번호 데이터베이스이름 > 백업파일명
- 복원
  프롬프트>mysql -u 아이디 -p비밀번호 데이터베이스이름 < 백업파일명
 

* mysql 과 php 의 연동
- mysql 연동 작업을 위해 제공되는 함수를 사용
- mysql에 접속 :
 $연결변수 = mysql_connect("호스트","아이디","패스워드");
- mysql 연결 해제 :
 mysql_close($연결변수);
- 사용할 DB 선택(p.191)
 mysql_select_db("DB이름","$연결변수"); // 프롬프트의 use DB 명령어에 해당
- 쿼리 실행( p.193 )
 mysql_query( "쿼리문", "$연결변수" ); // 쿼리문을 실행함, auto commit
- 한 레코드씩 가져오기
 $레코드저장변수 = mysql_fetch_array( $결과변수 )
- 레코드의 갯수 계산
 mysql_num_rows( $레코드결과변수 )

Posted by 토끼구이 달팽이맛나

 

'Apache Environment를 사용할 때 발생할 수 있는 SQL Injection 취약성'에 관한 핵심 정리

 

 

by Beist Security Study Group
(http://beist.org)

Members of Beist Research Group : beist and anonymous people
Members of Beist Study Group : beist, dars21, obhacker, passion, p-jackpot, jacaranda, cina, algot23

 

 

 

 

요약: 본 문서는 [이승진, Apache Environment를 사용할 때 발생할 수 있는 SQL Injection 취약성, 2003] 문서에서 제시한 기법을 Beist Security Study Group에서 핵심 내용만 간추려 정리한 문서이다. 일반적으로 magic_quotes_gpc 설정이 on으로 되어 있는 환경에선 SQL Injection 공격을 하기가 힘들다고 생각되는데 웹 프로그램에서 Apache Environment를 잘못 사용할 경우 SQL Injection을 성공할 수 있는 가능성이 있다. 본 문서는 이러한 문제에 대해서 다루고 있다.

 

 

 

 

 

 

 

1. 개요

대부분 웹 프로그램은 해당 프로그램에서 사용하는 정보를 유연하고 편리하게 관리하기 위해 데이터베이스와 연동하여 동작한다. 데이터베이스와 연동을 하기 위해서 웹 프로그램은 Parameter를 통해 데이터베이스에 보낼 데이터를 지정한다. 이때 데이터베이스로 넘어가는 Parameter를 악의적으로 조작하여 시스템에서 부당한 정보나 권한을 획득하는 공격 기법을 SQL Injection이라 한다.

[이승진, Apache Environment를 사용할 때 발생할 수 있는 SQL Injection 취약성, 2003] 문서에서는 웹 프로그램을 작성할 때 Apache Environment를 잘못 사용할 경우 일어날 수 있는 SQL Injection 기법에 대해서 제시하였다. 내용을 간단히 살펴보면 기존 웹 프로그램을 공격할 경우 magic_quotes_gpc 의 제한 때문에 SQL Injection 공격을 수행하기 힘든 경우가 종종 있었는데 위 문서에서는 Apache Environment를 잘못 사용할 경우 이를 우회하여 공격할 수 있는 방법에 대해서 나타내었다.

본 문서는 위 문서를 바탕으로 Beist Security Study Group에서 핵심적인 내용만 간략하게 정리 요약한 문서이다. 또한 본 문서는 SQL Injection 공격 기법에 관한 기초 지식 설명은 생략하였다.. 이에 관한 지식은 인터넷에서 쉽게 문서로 접할 수 있다.

 

 

 

 

 

 

2. 기술적인 내용

먼저 magic_quotes_gpc 가 무엇인지 간략히 알아보겠다. 해당 옵션에 관련된 PHP 옵션 정보를 인용하면,

 

 

--인용--

magic_quotes_gpc boolean

GPC (Get/Post/쿠키) 작동의 magic_quotes 상태를 설정합니다. magic_quotes on이면, 모든 ' (작은 따옴표), " (큰 따옴표), \ (백슬래쉬), NUL은 자동적으로 백슬래쉬로 이스케이프됩니다.

 

참고: magic_quotes_sybase 지시어도 ON이면 magic_quotes_gpc가 완전히 교체됩니다. 두 지시어를 모두 활성화하면 작은 따음표는 ''이스케이프합니다. 큰 따옴표, 백슬래쉬, NUL은 건들이지 않고, 이스케이프 하지 않습니다.

--인용--

 

 

, 결론을 내리면 PHP 설정에서 magic_quotes_gpc on으로 되어있을 때 SQL Injection 기법을 사용하기가 좀 더 어려워진다. 왜냐하면 SQL Injection 공격의 핵심이 되는 작은 따옴표, 큰 따옴표 등이 이스케이프 처리되어 공격에 이용할 수 없기 때문이다.

본 문서는 magic_quote_gpc 옵션이 on으로 되어있을 때, 이 옵션 자체를 우회하는 방법에 대해서 설명하지 않는다. 그러나 특정 웹 프로그램의 경우 Apache Environment 변수를 직접적으로 가져와 사용하는 경우가 있는데, 이때 취약성이 발생할 수 있고, 이에 관해서 초점을 맞춘다. 다음 코드를 보자.

 

 

env_test.php

<?

 

echo "HTTP_USER_AGENT : \t\t$HTTP_USER_AGENT\n";

echo "getenv(\"HTTP_USER_AGENT\") : \t" . getenv("HTTP_USER_AGENT") . "\n";

 

?>

 

 

위의 php 코드는 env_test.php 에 접근한 사용자의 웹 브라우저 정보에 대해서 2가지 형태로 출력해준다. 첫째는 $HTTP_USER_AGENT 변수이고, 둘째는 Apache 웹 서버로부터 물려 받은 환경 변수 HTTP_USER_AGENT getenv() 함수로 가져와 출력해준다. 다음과 같은 HTTP 요청을 보내서 결과를 보겠다.

 

 

[beist@localhost beist]$ telnet beist.org 80

Trying 222.239.227.44...

Connected to beist.org (222.239.227.44).

Escape character is '^]'.

GET /env_test.php HTTP/1.1

User-Agent: test

Host: beist.org

 

HTTP/1.1 200 OK

Date: Sun, 20 Nov 2005 07:58:39 GMT

Server: Apache/2.0.50 (Fedora)

X-Powered-By: PHP/4.3.8

Content-Length: 59

Connection: close

Content-Type: text/html; charset=euc-kr

 

HTTP_USER_AGENT :               test

getenv("HTTP_USER_AGENT") :     test

 

 

User-Agent 부분에 test를 입력한 결과, env_test.php 에서 각각 동일한 결과를 출력해주었다. 다음은 User-Agent Escape 문자를 포함하여 보낸 결과이다.

 

 

[beist@localhost beist]$ telnet beist.org 80

Trying 222.239.227.44...

Connected to beist.org (222.239.227.44).

Escape character is '^]'.

GET /env_test.php HTTP/1.1

User-Agent: test'hack

Host: beist.org

 

HTTP/1.1 200 OK

Date: Sun, 20 Nov 2005 08:00:10 GMT

Server: Apache/2.0.50 (Fedora)

X-Powered-By: PHP/4.3.8

Content-Length: 70

Connection: close

Content-Type: text/html; charset=euc-kr

 

HTTP_USER_AGENT :               test\'hack

getenv("HTTP_USER_AGENT") :     test'hack

 

 

이스케이프 문자를 포함하여 보낸 결과 서로 다른 출력을 보여주는 것을 확인할 수 있다. 이러한 원인을 살펴보면, getenv()를 이용하여 가져온 환경 변수는 PHP가 아닌 웹 서버에서 저장하고 있는 환경 변수이다. , PHP에서 어떠한 처리 과정을 거치기 이전의 변수이다. 그러므로 사용자가 보낸 데이터는 순수한 형태로 웹 서버의 환경 변수에 보관되어 있다. 반면에 $HTTP_USER_AGENT PHP에서 만들어낸 것으로, 웹 서버가 갖고 있는 HTTP_USER_AGENT 변수 값을 가져와 가공한 (여기서는 이스케이프 처리를 가공 과정의 한 예라고 볼 수 있다.) 것이다.

만약 위의 사례처럼 웹 프로그램에서 getenv() 함수를 이용하여 특정 환경 변수를 가져올 경우 이스케이프 처리가 되지 않으므로 해커 입장에서는 SQL Injection 공격에 유용하게 악용할 수도 있다. 이 공격 기법은 GET이나 POST등으로 전달되는 Parameter를 조작할 순 없기 때문에 공격에 한계가 있을 수도 있다. (대부분의 Parameter GET, POST로 전달되기 때문이다.) 그러나 실제로 이를 이용한 공격 기법이 적지 않게 잠재하고 있다고 생각된다. 의외로 웹 프로그램에서 getenv() 함수를 이용하여 환경 변수를 가져오는 경우가 많이 존재하기 때문이다.

취약 잠재 가능성을 가진 환경 변수를 예를 들어 HTTP_X_FORWARDED_FOR HTTP_USER_AGENT를 볼 수 있다. 이 환경 변수는 사용자가 마음대로 조작할 수 있는 변수인데 이를 악용할 경우 SQL Injection 공격을 할 수 있는 가능성이 존재한다. 물론 이외에도 getenv()를 이용하여 가져오는 모든 환경 변수도 주목해야 한다.

 

 

 

 

 

 

3. 마치는 말

본 문서에서는 핵심 원리에 대해서만 알아보았지만 SQL Injection에 대한 지식이 있다면 이를 응용하기 어렵지 않을 것이다. SQL Injection은 아직까지도 주요 웹 해킹 기법 중에 하나로 인식될 정도로 많이 사용되기 때문에 이 부분에 대해서 각별한 주의가 필요하다. 대부분 해킹 기법의 기술적인 최종 목표는 Shell을 획득하는 것이지만 웹 해킹의 특성 상 작지만 부당한 권한으로도 웹 사이트에 치명적인 피해를 입힐 수도 있기 때문에 더욱 주의가 요구된다.

이외의 연구로, magic_quotes_gpc에서 GPC GET, POST, COOKIE를 나타내기 때문에, HEAD 등의 Method로 요청할 경우엔 이스케이프가 어떻게 처리될지 살펴보았는데 내부적으로는 같은 Method로 취급하기 때문에 다른 HTTP Method로 보내더라도 이스케이프 처리가 되므로 안심해도 된다.

(또한 앞에서 HTTP_X_FORWARDED_FOR를 예로 들었는데, 본 문서와 직접적으로 관련은 없지만 이에 대해서 한가지 더 첨부하자면, 대부분 웹 프로그램은 이 변수 값을 신뢰하는 경향이 있다. 이것은 사용자의 주소를 나타내는 값인데, REMOTE_ADDR 변수 값과는 달리 사용자가 직접적으로 조작할 수 있기 때문에 가급적이면 사용을 피하고 굳이 사용을 한다면 적절한 조치를 취한 후 사용해야 한다.)

Posted by 토끼구이 달팽이맛나


Smarty QuickStart Guide(Smarty 빠르게 시작하기)에 오신 것을 환영해요~ 이 가이드는
Smarty에 처음 발을 적시는 당신에게 Smarty가 어떻게 동작하는지 안내해 줄 거랍니다.

우리는 여기서 몇 가지 가정을 해볼 생각인데요. 당신이 이미 웹 서버에 PHP를 어떻게 설
치해야 하는지라던가, Unix 파일 퍼미션들에 대한 기초지식이나 그리고 PHP가 어떻게 동작
한다든지 등에 대한 기초지식을 가지고 있어야 하겠지요. 만약 당신이 Unix 환경이 아닌
곳에서 Smarty를 사용하고 있다면 당신은 자신의 OS와 관련된 파일 파미션 시스템이 Unix
와 어떤 차이점을 가지고 있는지 알고 있을 필요가 있답니다.


INSTALLATION (설치하기)
-----------------------

Smarty 압축 파일을 풀면 당신은 Smarty.class.php, Smarty_Compiler.class.php,
Config_File.class.php 그리고 "plugins" 디렉토리 같은 여러 파일들을 볼 수 있을 텐데
우선 이 모든 파일들을 당신의 PHP include_path에 지정되어 있는 디렉토리 어딘가에 옮
길 필요가 있어요. 그러고 나서 PHP 스크립트에[역주: 원문에서는 PHP 스크립트라고 하
는 대신 "your application"이라고 했지만, 이 편이 더 이해가 빠를 것 같아 이렇게 번역
했습니다] require("Smarty.class.php") 문장을 적어주면 해당 클래스를 찾을 수 있게 되
겠지요. 음, 하지만 다른 방법으로 당신의 PHP 스크립트에 SMARTY_DIR 상수를 설정하는 방
법도 있어요. Smarty 클래스 파일들이 위치한 패스가 있는 디렉토리들은 이 두 가지 방식
을 사용할 수 있는데, 여기서 매우 중요한 것 하나는 SMARTY_DIR 패스를 지정할 때는 끝에
슬래쉬를 꼭 붙여야 한다는 것이겠죠!

자 그럼 이제 실제로 당신의 웹 서버의 Document Root 디렉토리 어딘가로 시야를 옮겨 보
도록 하지요. 이 가이드에서는 당신이 웹 서버의 Document Root에 만들 디렉토리 이름으
로 Smarty를 사용할 텐데, 모든 작업은 여기에서 이루어지고 있음을 잊지 마세요.


$> cd /home/htdocs
$> mkdir Smarty
$> cd Smarty


다음 차례는 Smarty가 사용할 디렉토리들을 만들 차례가 되겠군요.


$> mkdir templates
$> mkdir templates_c
$> mkdir configs


Smarty는 쓰기가 가능한 templates_c 디렉토리를 필요로 한답니다. 그러므로 당연히 당신
은 해당 디렉토리를 웹 서버 유저(보통 Unix에서는 "nobody:nobody"이 사용되고 Max OS에
서는 "www:www"이 사용되지요.[역주:레드햇 리눅스에서는 "apache:apache"가 사용됩니다])
가 쓰기가 가능하도록 해당 디렉토리의 소유주와 퍼미션을 아래와 같이 고쳐주어야겠지요.

물론 당신은 'chmod 777'을 사용할 수도 있어요. 음 그렇지만, 글쎄요. 많은 사용자들이
사용하는 시스템에서는 보안 문제도 있고 하니 별로 권장하고 싶지는 않군요. 이것에 대
해서는 메뉴얼에서 보다 많은 정보를 찾아보는 것이 좋을 것 같군요.


$> chown nobody:nobody templates_c
$> chmod 700 templates_c
$> ls -l
drwxrwxr-x 2 user group 512 Jan 18 14:18 configs/
drwxrwxr-x 2 user group 512 Jan 18 14:18 templates/
drwx------ 2 nobody nobody 512 Jan 18 14:18 templates_c/


위와 같이 하거나 덜 안전한 방법으로 아래와 같이 해 줄 수도 있어요.


$> chmod 777 templates_c
$> ls -l
drwxrwxr-x 2 user group 512 Jan 18 14:18 configs/
drwxrwxr-x 2 user group 512 Jan 18 14:18 templates/
drwxrwxrwx 2 user group 512 Jan 18 14:18 templates_c/


자 이제 당신은 index.php와 templates/index.tpl이라는 두 개의 파일을 만들 차례가 되
었네요. 물론 index.php는 당신의 웹 브라우져에서 부를 수 있는 것이어야겠지요.

index.tpl은 Smarty가 템플릿 파일로서 사용할 파일인데, 이것은 브라우져에서 직접 엑세
스되지는 않고, 오직 Smarty 클래스에 의해서만 접근된답니다[역주:실제로 위와 같이 하
면 웹 서버에 특별한 설정을 추가하지 않는 웹 브라우져를 통해 접근할 수 있습니다].


--------- index.php --------
<?php
require("Smarty.class.php");
$smarty = new Smarty;
$smarty->assign("Name","Ned");
$smarty->display("index.tpl");
?>


--------- templates/index.tpl --------
<HTML>
<TITLE>Hello</TITLE>
<BODY>
Hello, {$Name}!
</BODY>
</HTML>


자 이제 잘 작동하고 있는지 index.php를 당신의 웹 브라우져로부터 불러 보세요.

http://your.host.com/Smarty/index.php

당신의 브라우져로부터 "Hello, Ned!"를 볼 수 있나요? 그렇지 않다면 지금까지 위에서
해 온 과정들을 잘 따라 했는지 살펴보시고 다시 시도해 보세요. 아니면 메뉴얼에 있는
설치 작업에 관한 부분을 체크해 보고, 당신이 PHP 설치를 제대로 했는지도 살펴볼 필요
가 있을 거에요. 그래도 여전히 문제가 있다면 메일링 리스트에 질문을 던져 보던가 FAQ
에서 문제를 해결할 수 있을지도 모르겠네요.

이제 "Hello, Ned!"를 브라우져로부터 볼 수 있다구요? 좋아요~[역주: 차범근 스타일로
읽어 보세요. :)]

Smarty가 index.tpl를 어떻게 php 스크립트로 컴파일했는지 궁금하시다면 templates_c 디
렉토리를 찾아보시면 알 수 있어요. Smarty는 이렇게 맨 처음 한번만 컴파일하고 그 다음
에는 게속 이 컴파일된 스크립트를 가지고 작동하게 된답니다. 물론 index.tpl이 바뀌게
된다면 자동으로 재컴파일해서 대체하게 되지요[역주:이것은 JSP가 채택하고 있는 방식과
굉장히 유사하다고 볼 수 있습니다].

이런 이유로 당신은 templates_c 디렉토리에 대해서는 관심을 끄셔도 좋아요. 당신은 이
런 기술적 부분에 대해서 걱정할 필요가 하나도 없고, 이런 부분은 Smarty에게 떠넘겨 버
리면 되요. 참, 그리고 당신은 템플릿으로부터 컴파일된 PHP 스크립트를 볼 수 있고 그것
을 아마 고칠 수도 있을 거에요 하지만, 이것들을 고칠 생각은 절대로 하지 않는 게 신상
에 이로울 테죠?

여기까지 잘 되었다면, 이제 당신은 잘 작동하는 Smarty를 가지게 되었으므로 이제
Smarty에서 사용하고 있는 템플릿 언어의 특징들 중 몇 가지를 살펴보도록 하지요.


ASSIGNING VARIABLES (변수 대입)
-------------------------------

템플릿으로의 변수 대입은 변수와 값을 쌍으로 해서 직접 대입되게 되는데, 예를 들면 아래와 같이 소스가 구성된답니다.

--------- index.php --------
<?php
require("Smarty.class.php");
$smarty = new Smarty;
$smarty->assign("Name","Ned");
$smarty->assign(array(
"FirstName" => "Ned",
"LastName" => "Flanders",
"Address" => "Springfield"
));
$zipcode = "55555";
$smarty->assign("Zipcode",$zipcode);
$smarty->display("index.tpl");
?>


--------- templates/index.tpl --------
<HTML>
<TITLE>Hello</TITLE>
<BODY>
Hello, {$Name}!<br>
{$FirstName}, {$LastName}<br>
{$Address}, {$Zipcode}
</BODY>
</HTML>


당신은 변수들을 일 대 일로 대입할 수도 있고, 혹은 연관 배열을 사용할 수도 있고 대입
된 변수들을 추가할 수도 있는데, 이것에 대해서 메뉴얼에서 자세히 설명해주니까 그것을
참조하면 되겠지요.


INCLUDE (템플릿 포함하기)
-------------------------

이제는 Smarty에서 다른 템플릿 파일들을 어떻게 포함하는지 살펴보도록 하지요. 이것은
당신이 headers나 footers같은 반복적인 템플릿 데이터를 사용할 경우를 위한 것인데요.
이를 위해서는 templates/header.tpl과 templates/footer같은 별도의 템플릿 파일들을 만
들 필요가 있답니다.


--------- index.php --------
<?php
require("Smarty.class.php");
$smarty = new Smarty;
$smarty->assign("Name","Ned");
$smarty->assign(array(
"FirstName" => "Ned",
"LastName" => "Flanders",
"Address" => "Springfield"
));
$zipcode = "55555";
$smarty->assign("Zipcode",$zipcode);
$smarty->display("index.tpl");
?>

--------- templates/index.tpl --------
{include file="header.tpl" title="Home Page"}
Hello, {$Name}!<br>
{$FirstName}, {$LastName}<br>
{$Address}, {$Zipcode}
{include file="footer.tpl"}

--------- templates/header.tpl --------
<HTML>
<TITLE>{$title|default:"no title"}</TITLE>
<BODY>

--------- templates/footer.tpl --------
</BODY>
</HTML>


우리가 포함한 header.tpl에 어떻게 "title"이라는 변수를 넘겨주고 있는지 주목해 보세
요. 당신은 이런 식으로 당신이 원하는 더 많은 변수들을 넘겨줄 수 있어요. 포함된 템플
릿 파일들은 현재 템플릿 변수들을 모두 물려받게 되고 또한 위와 같이 넘겨진 변수들도
가지게 되는데, 이렇게 넘겨진 변수들은 오직 포함된 템플릿 파일에만 유효한 변수가 되
지요[역주: 함수에 넘겨진 변수는 함수 내에서만 접근되고 그 다음 사라지듯이 Smarty도
템플릿에서 포함한 파일로 이루어지는 변수 전달을 같은 방식으로 처리한다는 뜻입니다].

그리고 templates/header.tpl에서 $title 변수를 어떻게 출력하는지도 주목할 필요가 있
겠지요. 이것은 "default"라고 불리는 변수 변환자[역주: "variable modifier"가 원문인
데 변수 치환자라고 할까 하다가 이렇게 번역했습니다]를 사용한 모습이랍니다.

{$title}이라는 문장이 $title로 대입된 변수가 없으면 아무것도 하지 않는데 반하여
{$title|default:"no title"}이란 문장은 $title로 대입된 변수가 없어도 앞의 경우처럼
빈둥거리는 대신 "no title"이라는 출력을 수행한답니다.


IF/ELSEIF/ELSE
--------------

아래 에제는 매우 직접적인 문법을 보여주고 있을 뿐이랍니다. 메뉴얼에서 좀 더 자세하
게 이 문법에 대해 설명해 주니까 좀 더 알고 싶은 분은 메뉴얼을 참조하도록 하세요.


--------- templates/index.tpl --------
{include file="header.tpl" title="Home Page"}
{if $Name eq ""}
Hello, Noname!<br>
{elseif $Name eq "Ned"}
Hello, Neddy!<br>
{else}
Hello, {$Name}<br>
{/if}

{$FirstName}, {$LastName}<br>
{$Address}, {$Zipcode}
{include file="footer.tpl"}


SECTIONS: Dynamic Blocks (섹션: 동적 블럭)
------------------------------------------    

Smarty에서 {section} 기능을 사용하면 비교적 간단하게 배열들을 반복해서 출력할 수 있
어요. 여기서 section에는 두가지 속성이 필요로 한답니다. 하나는 name인데 말 그대로
이것은 section의 이름이랍니다[역주: 아래 예제를 보시면 아시겠지만, 이 name 속성은
템플릿 내에서 사용됩니다]. 그리고 또 다른 하나는 loop라는 속성인데, 이 loop는
section에서 몇 번이나 반복할 지 반복횟수를 설명하고 있는 배열의 이름을 가리킨답니
다[역주: 아래 예제에서 "FirstName"과 "LastName"이라는 변수와 함께 지정된 배열의 크
기가 3이므로 3번 반복하게 됩니다.]


--------- index.php --------
<?php
require("Smarty.class.php");
$smarty = new Smarty;
$smarty->assign("FirstName",array("Ned","Bart","Montgomery"));
$smarty->assign("LastName",array("Flanders","Simpson","Burns"));
$smarty->display("index.tpl");
?>

--------- templates/index.tpl --------
{include file="header.tpl" title="Home Page"}
{section name=people loop=$FirstName}
{$smarty.section.people.rownum} {$FirstName[people]} {$LastName[people]}<br>
{sectionelse}
There are no values to loop through.
{/section}
<p>
There were {$smarty.section.people.loop} names in this list.
{include file="footer.tpl"}


여기서 템플릿 내에서 사용된 {$smarty}라는 변수에 대해서 소개할 필요가 있을 것 같네
요. section 내에서 출력되는 변수들을 주목해 보세요. 이처럼 section 내에서 출력할 변
수들은 모두 반드시 섹션 이름으로 참조될 필요가 있음을 잊지 마세요. 이것은 당신이 출
력하고 싶은 값을 배열에서 현재 반복 횟수를 가지고 찾기 위해 필요한 거에요. 또한 내
부 템플릿 변수들을 가지고 현재 반복 중인 section의 총 반복횟수와 현재 반복 횟수 같
은 것도 출력이 가능하답니다. {sectoinelse}도 중요한 건데, 이것은 만일 반복할 배열인
$FirstName이 빈 배열의 경우 대신 출력되는 부분이 된답니다.

그리고 아래 예제에서 사용된 문법처럼 배열의 키들을 가지고 접근할 수도 있어요.


--------- index.php --------
<?php
require("Smarty.class.php");
$smarty = new Smarty;
$smarty->assign(array("ContactInfo" =>
         array(
             array("FirstName" => "Ned","LastName" => "Flanders"),
             array("FirstName" => "Monty","LastName" => "Burns")
             )
));
$smarty->display("index.tpl");
?>


--------- templates/index.tpl --------
{include file="header.tpl" title="Home Page"}
{section name=people loop=$ContactInfo}
{$ContactInfo[people].FirstName}
{$ContactInfo[people].LastName}<br>
{sectionelse}
There are no values to loop through.
{/section}
<p>
There were {$smarty.section.people.loop} names in this list.
{include file="footer.tpl"}

혹은 아래 예제처럼 당신은 복합 중첩 section 문을 시도해볼 수도 있답니다.

--------- index.php --------
<?php
require("Smarty.class.php");
$smarty = new Smarty;
$smarty->assign("FirstName",array("Ned","Bart","Montgomery"));
$smarty->assign("LastName",array("Flanders","Simpson","Burns"));
$smarty->assign("ContactNames",
        array(
         array("email","home","cell"),
         array("email","home"),
         array("email","home","fax")
         ));
$smarty->assign("ContactVals",
        array(
         array("ned@simpsons.com","555-666-7777","555-444-3333"),
         array("bart@simpsons.com","555-111-2222"),
         array("monty@simpsons.com","555-888-9999","555-234-5678"),
         ));

$smarty->display("index.tpl");
?>


--------- templates/index.tpl --------
{include file="header.tpl" title="Home Page"}
{section name=people loop=$FirstName}
{$smarty.section.people.rownum} {$FirstName[people]} {$LastName[people]}<br>
{section name=contacts loop=$ContactNames[people]}
{* for fun, lets bold every other row *}
{if $smarty.section.contacts.rownum is even}<b>{/if}
{$ContactNames[people][contacts]}: {$ContactVals[people][contacts]}<br>
{if $smarty.section.contacts.rownum is even}</b>{/if}
{/section}
<br>
{sectionelse}
There are no values to loop through.
{/section}
<p>
There were {$smarty.section.people.loop} names in this list.
{include file="footer.tpl"}

 

FOREACH (반복문)
----------------

특별히 당신이 오직 한 가지 변수를 통해 반복문을 만들고 싶다면, 그런 당신을 위해 좀
더 쉬운 방법으로 연관배열을 반복시킬 수도 있는데, 이를 보여주는 아래 예제는 Smarty
와 함께 제공하는 디폴트 index.php에서 작동하는 템플릿인데,


{foreach name=outer item=contact from=$contacts}
{foreach key=key item=item from=$contact}
{$smarty.foreach.outer.iteration}. contact {$key}: {$item}
{/foreach}
{foreachelse}
no contacts
{/foreach}


여기서 가능한 속성들로는 다음과 같은 것들이 있어요[역주: 아래의 item, key, from은
PHP에서는 foreach($array as $key=>$item)와 각각 대입된다고 생각하시면 됩니다]

from: 반복의 대상이 되는 배열
item: 배열의 현재 요소를 가리키는 변수의 이름
key: 배열의 현재 키를 가리키는 변수의 이름(선택적)
name: foreach의 이름 (선택적)

그리고 당신이 만일 'name'을 사용한다면 다음과 같이 보다 다양한 foreach 속성들을 추
가할 수도 있으며[역주: first, last, show는 무슨 소리를 하고 있는지 잘 모르겠습니다.
메뉴얼에도 이 부분은 설명한 게 없고요. 실제 예제를 작성해 봐야 알 것 같군요. --;],

name: foreach의 이름
iteration: 현재 반복 횟수
total: 반복할 전체 횟수
first: if it's first iteration
last: if it's last iteration
show: if foreach was shown at all

아래 있는 템플릿은 foreach의 모든 속성들을 출력해 주는 예제랍니다[역주:두번째
foreach 문장에서 $smarty.foreach.outer가 from 속성의 값으로 지정된 것을 주목하
시기 바랍니다. 여기에 contact를 지정한 경우 전혀 다른 출력이 나옵니다].


{foreach name=outer item=contact from=$contacts}
{foreach key=key item=item from=$smarty.foreach.outer}
{$key}: {$item}
{/foreach}
{/foreach}


자, 이제 Smarty에 들여놓은 당신의 발은 어느 정도 충분히 적셔졌을 거에요. 그러나, 아
직 config 파일 변수들이나, built-in 함수들, 커스텀 함수들, 변수 변환자 같은 굵직굵
직한 공부거리가 남아 있답니다. 지금 당장 메뉴얼을 읽으러 가세요[역주: 각종 템플릿
라이브러리 중에서 가장 방대한 양을 자랑하는 메뉴얼입니다. ^^;]. 메일링 리스트에도
가입하시는 것이 좋겠지요. 그럼 앞으로도 Smarty를 즐기시기를!!


역자가 추가한 문서 내 리소스
Smarty 웹 사이트 : http://smarty.php.net
Smarty 메일링 리스트 아카이브
일반: http://news.php.net/group.php?group=php.smarty.general
개발: http://news.php.net/group.php?group=php.smarty.dev
CVS: http://news.php.net/group.php?group=php.smarty.cvs

Posted by 토끼구이 달팽이맛나