RSS구독하기:SUBSCRIBE TO RSS FEED
즐겨찾기추가:ADD FAVORITE
글쓰기:POST
관리자:ADMINISTRATOR
'Web_developing/PHP'에 해당되는 글 11
안녕하세요.

원래 수줍어서 이런거 못올립니다만 .

다른분들이 해결방법을 찾으셧으면 해서 올립니다 .



전 img 및 script rpc 를 이용하여 값을 넘길때.

해당 페이지 or 받는 페이지가 utf-8 이면

받는페이지에서


------------------------------------------------------------------------------------

// 값이 아래와 같다면
$a = "http://comefeel.com/tt/comefeel/entry/윈도우XP-속도-200-빠르게-하기?info=nom&elch=18";

$b = parse_url($a);
echo "<pre>";
print_r($b);

------------------------------------------------------------------------------------

위와같이 한다면 한글 부분이 깨져서 나옵니다.
정확한 인코딩도 다 해봤으나 유효 불가해서 아래와 같이
그냥 -_- 무식하게 (parse_url 처럼 혹은 비슷 ) 나눠 봤습니다.

좀더 좋은 팁이 있거나 좋은거 알고계신분은 정보 공유 합시다.


======================================

// 값이 아래와 같다면
$a = "http://comefeel.com/tt/comefeel/entry/윈도우XP-속도-200-빠르게-하기?info=nom&elch=18";

preg_match('@(^.*):\/\/(.*?)/([^?]*)\??(.*)@', $a, $matches);

 echo "<pre>";
 var_dump( ($matches) );

=======================================
2008/07/11 19:27 2008/07/11 19:27
이 글에는 트랙백을 보낼 수 없습니다
저 렴한 광랜의 등장과 대용량 하드디스크 가격의 하락, 그리고 Adobe 사의 플래시 플레이어(Flash Player), 플래시 비디오(Flash Video)의 등장으로 인터넷을 통한 비디오 공유가 정말 많이 보편화 되었습니다. 구글 비디오(http://video.google.com)와 YouTube(http://www.youtube.com)가 이미 이런 비디오 사업을 시작한지 오래됐지만, 여전히 공략할 수 있는 틈새 시장이 굉장히 많이 있다고 할 수 있는데, 그럼 우리도 한 번 틈새 시장을 공략해 보면 어떨까? PHP, 플래시, Adobe의 Flex를 이용해서 어떻게 하면 비디오 공유 사이트를 만들 수 있을까? 사실 알고보면 정말 쉽게 만들 수 있습니다.

여기서는 PHP를 이용해서 웹 사이트를 만드는 방법 그리고 Flex를 이용해서 Flash로 된 비디오 뷰어를 만드는 방법에 대해서 설명을 하겠습니다. 그럼 먼저 더 진행하기 전에 준비해야 하는 소프트웨어 몇 가지를 살펴보도록 하죠.

우선 서버쪽에서는 PHP와 MySQL이 필요합니다. MySQL은 비디오에 대한 정보(예를 들면, 비디오의 파일 이름, 미리보기 파일, 미리보기 파일의 너비와 높이, 제목, 그리고 기타 정보 등)를 저장하는데 사용되겠습니다. PHP는 전체적인 페이지를 구성하는데 사용되게 됩니다.

그리고 ffmpeg(http://ffmpeg.mplayerhq.hu/) 이라고 하는 유틸리티 프로그램도 필요한데요, 이 프로그램은 유저가 올리는 비디오 파일을 플래시 비디오 파일(FLV)로 변환하는 역할을 수행하게 됩니다. ffmpeg은 비디오의 변환외에도 비디오의 스냅샷을 찍어서 미리보기 파일을 만들어 낼 수도 있습니다. 이 ffmpeg을 이용하게 되면 사실상 어려운 작업을 손쉽게 처리할 수가 있어서 우리가 MyTube를 구현하는데 상당히 유용하게 활용이 됩니다.

클라이언트쪽에서는 두 가지 방법이 있는데요. 하나는 YouTube에서와 같이 HTML과 Flash를 같이 이용해서 인터페이스를 구성하는 방법이 있고, 두 번째로 플래시만으로 인터페이스를 구성하는 방법이 있습니다. 이 글에서는 Flex 프레임워크를 이용해서 비디오를 보고 등록된 비디오를 탐색하고 찾기 위해서 리스트를 생성하도록 할 예정입니다.

PHP로 서버쪽 코드 구성하기

서버쪽 코드 작성을 하기에 앞서, MySQL에 데이터 스키마를 생성해야 합니다. 우선 사용할 데이터베이스를 생성하기 위해서, 다음과 같이 mysqladmin 명령어를 사용합니다.
mysqladmin create movies 
스키마가 생성되었으면 데이터베이스를 로드합니다. 스키마 파일은 아래 [리스트 1]과 같습니다.

[리스트 1] movies.sql
DROP TABLE IF EXISTS movies; 
CREATE TABLE movies (
movieId INTEGER NOT NULL AUTO_INCREMENT,
title VARCHAR( 255 ),
source VARCHAR( 255 ),
thumb VARCHAR( 255 ),
width INTEGER,
height INTEGER,
PRIMARY KEY( movieId )
);
이제 위의 movies.sql 스키마 파일을 다음과 같은 명령어를 이용해서 데이터베이스에 테이블을 생성할 수 있습니다.
mysql movies < movies.sql 
데이터베이스에 무비 데이터를 넣기 위해서는 HTML을 이용해서 업로드 기능을 만들어야 합니다. 즉 비디오 파일을 받아서 플래시 비디오 파일로 변환하고 미리보기 파일을 만든후에 데이터베이스에 넣으면 되겠습니다.

업로드 페이지의 제작

비디오 파일을 업로드 하기 위한 HTML 파일은 다음 [리스트 2]에서 보는 것과 같이 아주 간단합니다.

[리스트 2] addmovie.html
<html>
<body>
<form enctype="multipart/form-data" method="post" action="upload.php">
<input type="hidden" name="MAX_FILE_SIZE" value="300000" />
<table>
<tr><td>Title</td><td><input type="text" name="title"></td></tr>
<tr><td>Movie</td><td><input type="file" name="movie"></td></tr>
</table>
<input type="submit" value="Upload" />
</form>
</body>
</html>
위 HTML은 입력받은 정보를 upload.php 페이지로 전송하게 되는데, 이 페이지에서 비디오를 변환하고 미리보기를 만들어 내고 데이터베이스에 저장하게 되는 것입니다. 다음의 upload.php 코드를 보도록 하겠습니다.

[리스트 3] upload.php
<html><body>
<?php
require "DB.php";

function converttoflv( $in, $out )
{
unlink( $out );
$cmd = "ffmpeg -v 0 -i $in -ar 11025 $out 2>&1";
$fh = popen( $cmd, "r" );
while( fgets( $fh ) ) { }
pclose( $fh );
}

function getthumbnail( $in, $out )
{
unlink( $out );
$cmd = "ffmpeg -i $in -pix_fmt rgb24 -vframes 1 -s 300x200 $out 2>&1";
$fh = popen( $cmd, "r" );
while( fgets( $fh ) ) { }
pclose( $fh );
}

function flv_import( $upfile, $fname, $title )
{
$fname = preg_replace( '/..*$/', '', basename( $fname ) );
$flvpath = "$fname.flv";
$thumbpath = "$fname.gif";

converttoflv( $upfile, "movies\$flvpath" );
getthumbnail( $upfile, "movies\$thumbpath" );

$dsn = 'mysql://root@localhost/movies';
$db =& DB::connect( $dsn );
if ( PEAR::isError( $db ) ) { die($db->getMessage()); }

$sth = $db->prepare( 'INSERT INTO movies VALUES ( 0, ?, ?, ?, ?, ? )' );
$db->execute( $sth, array( $title, $flvpath, $thumbpath, 300, 200 ) );
}

flv_import( $_FILES['movie']['tmp_name'], $_FILES['movie']['name'], $_POST['title'] );
?>
File sucessfully uploaded
</body></html>
위 코드에서 flv_import 함수를 중점적으로 봐야 합니다. flv_import 함수내에서 converttoflv 함수로 비디오 파일을 플래시 비디오 파일로 변경하고 있고, getthumbnail 함수로 미리보기 파일을 생성하고 있습니다. 그리고 다음으로 업로드가 완료된 무비에 대한 정보를 데이터베이스에 저장합니다. 위 리스트 3에 있는 FLV 플래시 비디오 파일과 미리보기 파일을 생성하는 함수는 ffmpeg 라는 명령어와 여러가지 명령어를 이용해서 변환을 수행하게 됩니다.

그럼 다음 [그림 1]처럼 addmovie.html 페이지를 브라우저로 한 번 보도록 하겠습니다.


[그림 1] 비디오를 업로드하는 페이지

여기서 비디오 파일을 지정하고 Upload 버튼을 눌러서 비디오 파일을 처리하기 위해 서버에 보낼 수가 있습니다.

사 실 upload.php 파일은 아주 기본적인 부분만 작성이 되어 있기때문에, 실제 서비스 용도로 사용하기 위해서는 에러 체크 루틴을 추가 적으로 작성해야 합니다. 그리고 그것보다도 더 큰 문제는 크기가 큰 비디오 파일을 업로드 하려고 할 때인데, 이런 경우에는 파일의 크기가 크기 때문에 비디오 변환 과정이 오래 걸리게 되고 유저의 대기시간이 상당히 길어지면서 더 큰 문제가 됩니다.

그럼 이런 문제를 해결하기 위한 방법은 뭐가 있을까요? 한 가지 방법으로 큰 크기의 비디오 파일이 업로드가 되면(10초 이상의 비디오 파일) 유저에게는 잠시 후에 비디오가 게시될 것이라고 말을 해 놓고 서버내의 다른 폴더에 비디오 파일을 저장한 후에 또 다른 스크립트를 이용해서 비디오를 변환하는 것입니다.

더 진행하기 전에 왜 꼭 플래시 비디오 파일로 변환을 해야 하는지에 대해서 생각을 해보도록 합시다. 그냥 원본 그대로 저장해도 되는데 왜 플래시 비디오로 변환을 하려고 하는 걸까요? 그건 원본 상태로 저장을 해 놓게 되면 각 비디오 파일의 타입 별로 비디오 플레이어를 찾아서 수행할 수 있는 코드를 작성을 해야만 하기 때문에, 굉장히 힘든 일이 될 것이라고 생각합니다.

이 과정을 플래시 파일로 변환하여 해결하게 되면 코드도 간단해지고 많은 OS에서 실행될 수 있도록 할 수도 있습니다.

그럼 이제 HTML과 플래시를 이용해서 유투브와 같은 입력양식을 간단하게 만들어 보겠습니다.

HTML과 플래시를 이용한 인터페이스 구성

입 력받은 URL을 가지고 플래시 비디오 파일을 재생하는 프로그램을 만들기 위해서는 Adobe Flex Builder 2를 이용해서 새로운 프로젝트를 만들어야 합니다. 새로운 프로젝트를 생성했다면 simplemovie.mxml 이라는 Flex 애플리케이션을 만들어야 합니다. 이 애플리케이션 파일의 내용은 다음 [리스트 4]와 같습니다.

[리스트 4] simplemovie.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:VBox backgroundColor="white" width="400" height="335">
<mx:VideoDisplay width="400" height="300" id="videoPlayer"
source="{Application.application.parameters.movie}" />
<mx:HBox width="100%" horizontalAlign="center">
<mx:Button label="Play" click="videoPlayer.play()" />
</mx:HBox>
</mx:VBox>
</mx:Application>
위 [리스트 4]에서 두가지 중요한 요소를 볼 수 있습니다 : VideoDisplay 요소는 비디오를 재생하는 역할을 하고 "Play"라는 이름을 가진 버튼은 비디오의 재생이 끝난 후에 유저가 클릭할 경우 비디오를 다시 재생하는 역할을 하게 됩니다.

VideoDisplay 요소는 "source"라는 속성을 가지게 되는데요, source 속성으로 재생해야 하는 플래시 비디오 파일의 URL을 지정하게 됩니다. 위 리스트에서 source 속성이 가지고 있는 값은 HTML 파일에 있는 <object>나 <embed> 태그에 있는 FlashVars 속성의 값이 되게 됩니다.

Flex Builder를 이용하게 되면 위 [리스트 4]의 simplemovie.mxml 프로그램을 simplemovie.swf 파일로 변환할 수가 있고, 변환된 swf 파일을 bin 디렉토리에서 PHP가 있는 곳의 디렉토리로 이동시켜야 합니다. 그리고 PHP 페이지를 하나 만들어서 비디오를 재생시킬 수가 있습니다. 다음 [리스트 5]를 보도록 하죠.

[리스트 5] simpletest.php
<?php
require "DB.php";

$moviebase = 'http://localhost:8080/movies/';

$dsn = 'mysql://root@localhost/movies';
$db =& DB::connect( $dsn );
if ( PEAR::isError( $db ) ) { die($db->getMessage()); }

$source = null;
$movieId = 1;
if ( array_key_exists( 'movie', $_GET ) )
$movieId = $_GET['movie'];

$movies = array();
$res = $db->query( 'SELECT movieId, source, title FROM movies' );
while( $row = $res->fetchrow( ) ) {
$movies []= $row;
if ( $row[0] == $movieId )
$source = $row[1];
}

if ( $source == null )
$source = $movies[0][1];
?>
<html>
<body>
<table>
<tr><td valign="top">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="400"
height="335"
codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
<param name="movie" value="simplemovie.swf" />
<param name="quality" value="high" />
<param name="flashVars" value="movie=<?php echo( $moviebase.$source ) ?>">
<embed src="simplemovie.swf" quality="high"
width="400" height="335" play="true"
loop="false"
quality="high"
flashVars="movie=<?php echo( $moviebase.$source ) ?>"
type="application/x-shockwave-flash"
pluginspage="http://www.adobe.com/go/getflashplayer">
</embed>
</object>
</td><td valign="top">
<?php
foreach( $movies as $movie ) {
?>
<a href="simptest.php?movie=<?php echo( $movie[0] )?>"><?php echo( $movie[2] )?></a><br/>
<?php
}
?>
</td></tr></table>
</body>
</html>
위 PHP 스크립트는 우선 데이터베이스에 접속한 후에 비디오 리스트를 받아오고 있습니다. 그리고 나서 URL을 통해서 넘어온 ID와 읽어온 비디오 리스트를 비교해서 동일한 ID를 가진 비디오가 있는지를 확인하게 됩니다. 동일한 ID를 찾을 경우 이 ID 값을 simplemovie.swf 파일로 넘기기 위해서 flashVars 속성에 지정하고 있습니다.

PHP 스크립트 다음 부분에서는 HTML 태그가 시작되고 simplemovie.swf 파일을 페이지에 표시하기 위한 태그인 <object>, <embed> 태그를 사용하고 있습니다. 물론 여기에 재생해야 하는 비디오에 대한 URL도 지정해 주고 있는 걸 볼 수 있습니다. 그리고 바로 아래에 현재 비디오외에 볼 수 있는 비디오에 대한 링크를 만들어 주고 있는 걸 볼 수 있습니다.

이제 웹 브라우저에서 [리스트 5]에 있는 페이지를 한 번 보도록 하겠습니다. 다음 [그림 2]와 같이 나오네요.


[그림 2] 간단한 비디오 플레이어와 함께 볼 수 있는 비디오에 대한 리스트가 출력되었다.

웹 브라우저를 열자마자 첫번째 비디오가 재생이 되게 되고, 오른쪽에 있는 비디오 리스트중에서 하나를 선택하면 페이지가 다시 로딩되면서 선택된 비디오가 재생되게 됩니다.

정말 간단하죠? Flex 파일 하나와 PHP 파일 하나, 그리고 데이터베이스만 가지고 위와 같이 비디오 공유 사이트를 만들었습니다.




Flex를 이용한 인터페이스 구성 파트 1


Flex 를 이용해서 원하는 비디오를 재생시키기 위해서는 Flex에게 재생시킬 수 있는 비디오의 리스트를 알려줘야만 합니다. 어떻게 해야하냐면 XML파일을 이용해서 Flex에게 비디오 리스트 정보를 넘겨줄 수가 있는데요, 여기서는 PHP로 다시 돌아가서 데이터베이스에서 비디오 리스트를 읽어들인 후에 XML로 출력하는 스크립트를 만들어 보도록 하겠습니다. 다음 [리스트 6]의 movies.php 파일을 보도록 하죠.

[리스트 6] movies.php
<?php
require "DB.php";

$moviebase = 'http://localhost:8080/movies/';

header( 'content-type: text/xml' );

$dsn = 'mysql://root@localhost/movies';
$db =& DB::connect( $dsn );
if ( PEAR::isError( $db ) ) { die($db->getMessage()); }
?>
<movies>
<?php
$res = $db->query( 'SELECT title, source, thumb, width, height FROM movies' );
while( $row = $res->fetchrow( ) ) {
?>
<movie title="<?php echo( $row[0] ) ?>" source="<?php echo( $moviebase.$row[1] ) ?>"
thumb="<?php echo( $moviebase.$row[2] ) ?>" width="<?php echo( $row[3] ) ?>"
height="<?php echo( $row[4] ) ?>" />
<?php
}
?>
</movies>
위 PHP 스크립트를 만든 후에 커맨드 라인에서 실행시키거나 브라우저에서 실행시키게 되면 다음 [그림 3]과 같은 XML 리스트를 볼 수가 있습니다.


[그림 3] XML로 표현된 비디오 리스트

이제 XML로 비디오 리스트 정보를 넘겨줄 수 있으니 전에 만들었던 simplemovie.mxml 파일을 좀 더 개선해 보도록 하겠습니다. 다음 [리스트 7]은 simplemovie.mxml의 업그레이드 된 버전입니다.

[리스트 7] mytube1.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="movieXmlData.send()">

<mx:HTTPService method="get" url="http://localhost:8080/movies.php"
id="movieXmlData" result="onGetMovies( event )" />

<mx:Script>
import mx.rpc.events.ResultEvent;
import mx.controls.VideoDisplay;
import mx.controls.List;
import mx.rpc.http.HTTPService;
import mx.collections.ArrayCollection;

[Bindable]
private var movies : ArrayCollection = new ArrayCollection();

public function onGetMovies( event : ResultEvent ) : void
{
var firstMovie : String = event.result.movies.movie[0].source.toString();
videoPlayer.source = firstMovie;

movies = event.result.movies.movie;
movieList.selectedIndex = 0;
}

public function onPrevious() : void
{
if ( movieList.selectedIndex == 0 )
movieList.selectedIndex = movies.length - 1;
else
movieList.selectedIndex -= 1;
videoPlayer.source = this.movieList.selectedItem.source.toString();
}

public function onPlay() : void
{
videoPlayer.source = this.movieList.selectedItem.source.toString();
videoPlayer.play();
}

public function onNext() : void
{
if ( movieList.selectedIndex >= ( movies.length - 1 ) )
movieList.selectedIndex = 0;
else
movieList.selectedIndex += 1;
videoPlayer.source = this.movieList.selectedItem.source.toString();
}

public function onChange() : void
{
videoPlayer.source = this.movieList.selectedItem.source.toString();
}
</mx:Script>

<mx:HBox width="100%" paddingLeft="10" paddingTop="10" paddingRight="10">
<mx:VBox>
<mx:VideoDisplay width="400" height="300" id="videoPlayer" complete="onNext()" />
<mx:HBox width="100%" horizontalAlign="center">
<mx:Button label="<<" click="onPrevious()" />
<mx:Button label="Play" click="onPlay()" />
<mx:Button label=">>" click="onNext()" />
</mx:HBox>
</mx:VBox>
<mx:List width="100%" height="340" id="movieList"
dataProvider="{movies}"
change="onChange()"
labelField="title"></mx:List>
</mx:HBox>

</mx:Application>
전과 비교해서 크게 바뀐 부분이 있다면 파일의 상단에 있는 액션 스크립트(ActionScript)인데요, 이 코드로 전체적인 인터페이스를 관리하게 됩니다. 이 액션 스크립트가 하는 일은 먼저 onGetMovies 함수에 있는 HTTPService를 이용해서 movies.php 파일로부터 XML 정보를 읽어들이는 것입니다. HTTPService 클래스는 XML 리스트를 찾게 되면 XML 문서 객체모델(Document Object Model)로 변경하게 되고, 우린 이 문서 객체 모델을 이용해서 첫번째 비디오에 대한 정보를 얻어서 재생할 수가 있습니다. 또 onGetMovies 함수는 movies 라는 변수를 이용해서 페이지에 있는 리스트 박스에 비디오의 이름을 출력하게 됩니다. 나머지 액션 스크립트는 유저가 리스트 박스에 있는 비디오를 선택하거나 "이전", "다음" 버튼을 선택했을 경우를 처리하기 위한 코드입니다.

위 리스트의 제일 아래를 보면 전체 유저 인터페이스를 구성하는 Flex 오브젝트를 볼 수 있습니다. 여기에 이전 비디오와 다음 비디오를 선택할 수 있는 버튼을 배치하고, 오른쪽에는 현재 비디오 리스트를 출력하는 리스트 박스가 배치되어 있습니다.

이제 Flex Builder를 이용해서 위 프로그램을 컴파일하고 실행시키게 되면 [그림 4]와 같은 화면을 볼 수 있습니다.


[그림 4] Flex를 이용해서 구성한 첫 번째 인터페이스

리스트 박스에서 비디오를 선택할 수도 있고, 이전, 다음 버튼을 이용해서 비디오를 선택할 수도 있습니다. 멋있죠? 이제 미리보기 이미지를 제공해 주면 더 멋있어질 것 같네요.

Flex를 이용한 인터페이스 구성 파트 2 – 미리보기 이미지

미 리보기 이미지를 비디오 리스트에 출력하려면 리스트 박스를 비디오의 제목과 미리보기 이미지를 같이 출력할 수 있도록 수정해야 합니다. 다행히도 Flex의 기능을 이용하면 아주 쉽게 수정이 가능합니다. 우선 <List> 태그에 itemRenderer를 추가하도록 하고, 다음 [리스트 8]을 보겠습니다.

[리스트 8] mytube2.mxml
...
<mx:List width="100%" height="340" id="movieList"
dataProvider="{movies}"
change="onChange()"
itemRenderer="MovieItem"></mx:List>
...
여기서 MovieItem이라는 item renderer MXML 컴포넌트를 만들었습니다. 이 컴포넌트를 만들려면 메뉴에서 "New > MXML Component"를 선택하고 [리스트 9]와 같이 컴포넌트를 코드에 넣으면 됩니다.

[리스트 9] MovieItem.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" height="80">
<mx:Image source="{data.thumb}" width="{data.width/3}"
height="{data.height/3}" rotation="5" left="10" top="0" />
<mx:Label text="{data.title}" fontWeight="bold" top="10" left="100" fontSize="18" />
</mx:Canvas>
여기서는 Canvas 라는 컨테이너를 이용했지만, 원한다면 마음에 드는 컨테이너를 선택해서 설정하셔도 괜찮습니다. 그리고 나서 미리보기 이미지 추가를 위해서 <mx:Image> 태그를 사용하고 비디오 제목을 출력하기 위해서 <mx:Label>을 이용하면 됩니다. 좀 더 재밌게 해보기 위해서 미리보기 이미지를 약간 회전시켜 봤습니다. [그림 5]를 보도록 하죠.


[그림 5] 미리보기 이미지를 추가한 리스트 박스

꽤 괜찮은 비디오 플레이어가 됐네요. 여기에 추가적으로 비디오 설명, 재생 시간, 링크, 추천 버튼과 같은 기능을 추가하면 더 좋을 것 같습니다.

저장소와 대역폭

데 이터베이스를 구성하고 비디오 공유 사이트 페이지를 만들어 내는것 자체는 지금까지 잘 해결했는데, 사실 이것말고 한가지 더 고려해야 할 것이 있습니다. 바로 대역폭을 고려해야 합니다. 플래시 비디오 파일 자체가 인코딩이 잘 된다고 해도 역시 비디오 파일이기 때문에 크기가 큰 편에 속하게 됩니다. 그렇기 때문에 중간에 끊김없이 비디오 재생을 얼마나 할 수 있는지 파악하는 것이 무엇보다 중요하게 됩니다.

확실한 방법중 하나는 인터넷 데이터 센타에서 서비스를 하는 것입니다. 다른 방법으로는 비디오 공유 사이트에서는 비디오 자체에 대한 데이터를 가지지 않고 링크만 저장하고 실제 비디오 데이터는 다른 곳에 저장하는 방법입니다. 아마존의 S3 서비스 같은 경우가 좋은예인데요, 저렴한 가격으로 좋은 저장소로 활용할 수가 있고, 어느정도 사이트가 커질때까지는 안정적으로 활용할 수 있습니다.

결론

플래시를 이용한 비디오의 등장과 광대역폭의 보편화로 인해서 이제 적은 예산으로 비디오 공유 사이트를 운영한다는 것이 현실로 다가왔습니다. 바라기는 이 글을 통해서 여러분이 좀 더 멋있는 비디오 공유사이트를 만들어냈으면 하는 것입니다.
2007/12/26 16:16 2007/12/26 16:16
이 글에는 트랙백을 보낼 수 없습니다
New Object Model

PHP 5 에는 새로운 객체 모델이 존재한다. PHP의 객체 조작사항은 더 나은 성능과 보다 많은 특징을 위해 완벽하게 재작성되었다. PHP이전 버전에서 객체는 원시적인 형태로 조작되었다. ( 실례를 들자면 정수나 문자열 같은 것들을 말이다. ). 이 객체 안의 메소드가 가진 결점은 의미론적으로, 어떤 변수가 할당되었거나 파라미터의 값을 메소드로 전달할 때 모든 객체들이 복제된다는 것이었다. 이제 새로운 접근방식에서는 객체가 핸들에 의해 참조되고 값으로 참조되지 않는다. ( 객체식별자와 같은 핸들로 생각할 수 있을 것이다 ).

   많은 PHP 프로그래머들은 심지어는 과거의 객체모델이 멋대로 복제되는 것을 눈치채지 못했고 그랬기때문에 PHP어플리케이션의 대부분은 아주 좁은 틀을 벗어나 동작했을 것이다. 


Private and Protected Members

PHP 5 는 클래스 프로퍼티의 가시성( 可視性 : visibility )을 정의할 수 있게 하는 private 와 protected 멤버 변수를 도입했다.


Example B-4. Private and Protected Members accesibility

Protected 멤버 변수는 확장된 클래스에서 중복 선언되면 접근할 수 있는데 비해, private 멤버 변수는 단지 멤버 변수를 소유한 클래스에서만 접근이 가능하다.

<?php
class MyClass
{
  
private $Hello = "Hello, World!\n"
;
  
protected $Bar = "Hello, Foo!\n"
;
  
protected $Foo = "Hello, Bar!\n"
;

   function
printHello
() {
       print
"MyClass::printHello() " . $this->Hello
;
       print
"MyClass::printHello() " . $this->Bar
;
       print
"MyClass::printHello() " . $this->Foo
;
   }
}

class
MyClass2 extends MyClass
{
  
protected $Foo
;
            
   function
printHello
() {
      
MyClass::printHello();                         
/* Should print */
      
print "MyClass2::printHello() " . $this->Hello;
/* Shouldn't print out anything */
      
print "MyClass2::printHello() " . $this->Bar
/* Shouldn't print (not declared)*/
      
print "MyClass2::printHello() " . $this->Foo
/* Should print */
  
}
}

$obj = new MyClass
();
print
$obj->Hello
/* Shouldn't print out anything */
print $obj->Bar;   
/* Shouldn't print out anything */
print $obj->Foo;   
/* Shouldn't print out anything */
$obj->printHello();
/* Should print */

$obj = new MyClass2
();
print
$obj->Hello
/* Shouldn't print out anything */
print $obj->Bar;   
/* Shouldn't print out anything */
print $obj->Foo;   
/* Shouldn't print out anything */
$obj->printHello
();
?>
 
 

PHP 5에서는 또한 private 와 protected 메소드가 도입되었다.


Example B-5. Protected methods example

<?php
class Foo
{
  
private function aPrivateMethod
() {
       echo
"Foo::aPrivateMethod() called.\n"
;
   }

  
protected function aProtectedMethod
() {
       echo
"Foo::aProtectedMethod() called.\n"
;
      
$this->aPrivateMethod
();
   }
}

class
Bar extends Foo
{
  
public function aPublicMethod
() {
       echo
"Bar::aPublicMethod() called.\n"
;
      
$this->aProtectedMethod
();
   }
}

$o = new Bar
;
$o->aPublicMethod
();
?>

과거의 코드에서는 사용자 정의된 클래스나 함수가 "public", "protected" 또는 "private"를 명기하지 않고 실행했을 것이다.


Abstract Classes and Methods

PHP 5는 또한 추상클래스라는 것과 추상메소드라는 것이 도입되었다. 추상메소드는 단지 메소드의 특징적인 사항을 선언하고 수행사항을 제공하지는 않는다. 다음 예시에서 클래스는 abstract로 선언하는 것을 필요로 하는 추상 메소드를 포함한다.


Example B-6. Abstract class example

<?php
abstract
class AbstractClass
{
  
abstract public function test
();
}

class
ImplementedClass extends AbstractClass
{
  
public function test
() {
       echo
"ImplementedClass::test() called.\n"
;
   }
}

$o = new ImplementedClass
;
$o->test
();
?>

요약클래스는 명시화될 수 없다. 과거의 코드에서는 사용자 정의된 클래스나 함수에 "abstract"를 명기하지 않고 실행했을 것이다.


Interfaces

PHP 5 에서 interface라는 새로운 객체지향 개념이 도입되었다. 클래스는 인터페이스의 임의의 목록을 수단으로 삼을 것이다.


Example B-7. Interface example

<?php
interface Throwable
{
  
public function getMessage
();
}

class
MyException implements Throwable
{
  
public function getMessage
() {
      
// ...
  
}
}
?>

과거에는 사용자정의된 클래스나 함수에 "interface"나 "implements"를 붙이지 않고 실행했을 것이다.


Class Type Hints

 느슨한 유형이 남아있는 PHP5는 클래스 타입 힌트를 사용하여 파라미터로부터 메소드로 값을 전달하는 개체의 요청된 클래스를 선언하는 능력을 도입하였다.


Example B-8. Class type hinting example

<?php
interface Foo
{
   function
a(Foo $foo
);
}

interface Bar
{
   function
b(Bar $bar
);
}

class
FooBar implements Foo, Bar
{
   function
a(Foo $foo
) {
      
// ...
  
}

   function
b(Bar $bar
) {
      
// ...
  
}
}

$a = new FooBar
;
$b = new FooBar
;

$a->a($b
);
$a->b($b
);
?>

이러한 클래스 타입 힌트는 보통 유형화된 언어에서와 같이 컴파일 할 때에는 체크하지 않는다. 그러나 실행 도중에 체크한다. 이것은 다음을 의미한다:

<?php
function foo(ClassName $object
) {
  
// ...
}
?>


는 다음과 같다 :

<?php
function foo($object
) {
   if (!(
$object instanceof ClassName
)) {
       die(
"Argument 1 must be an instance of ClassName"
);
   }
}
?>
 

PHP 5 는 최종 멤버와 메소드를 선언하기 위해 "final" 키워드를 도입하였다. final을 붙인 메소드와 멤버는 하위클레스에 의해 오버라이드 되지 않는다.


Example B-9. final method

<?php
class Foo
{
  
final function bar
() {
      
// ...
  
}
}
?>

이것은 더군다나 최종적인 클래스를 만드는데 가능하다. 이것은 클래스가 특별화 되는 것을 막는다. (다른 클래스에 의해 '절대' 상속될 수 없다.). final 클래스는 자신들의 메소드를 final 로 선언할 필요가 없다.


Example B-10. final class

<?php
final
class Foo
{
  
// class definition
}

// the next line is impossible
// class Bork extends Foo {}
?>

프로퍼티는 final 속성을 가질 수 없다..

과거에는 사용자정의된 클래스나 함수에 "final"을 붙이지 않고 실행했을 것이다.


Objects Cloning

   PHP 4 에서는 객체가 복제되었을 때 복제된 생성자를 실행하기 위한 결정을 사용자가 할 수 없는 그런 방법을 제공했었다. 복제하는 동안에는 PHP 4 에서는 모든 객체의 프로퍼티에 대한 이상적 복제물을 만들기 위해 비트복사를 하는 단역을 수행하였다.  

   전체적으로 복제된 프로퍼티와 함께 복제된 객체를 만드는 것은 항상 원하는 행동이 아니다. 생성자 복제를 위해 필요한 것에 대한 좋은 예는 만약 GTK 윈도우를 묘사하는 객체를 소유하고 있고 객체는 이 객체를 복제할때의 GTK 윈도우의 리소스로 유지될 때, 아마 같은 프로퍼티를 가진 새로운 윈도우를 생성하길 원할것이고 새 윈도우의 리소스를 새 객체가 포함하길 원할 것이다. 다른 예로는 만약 객체가 다른 객체를 사용하는 참조자를 붙들어매고 있고, 개발자는 부모객체를 복제할때, 이 다른 객체의 새로운 인스턴스를 생성하길 원할 것이고 그래서 복제된 개체는 그 자신의 분산된 복제물을 가지고 있을 것이다.

복제되는 객체는 clone 키워드를 사용하여 생성된다. ( 가능하다면 객체의 __clone() 메소드를 호출한다 ). 객체의 __clone() 메소드는 직접적으로 호출될 수는 없다.

개발자들이 객체의 새로운 복제물을 생성하기 위해 요청할때, PHP 5 는 __clone() 메소드가 정의 되었는지 아닌지의 여부를 체크할 것이다. 만약 정의되지 않았다면 모든 객체의 프로퍼티를 복제할 기본적인 __clone() 을 호출할 것이다. __clone() 메소드가 정의되었다면 생성된 객체 안에 필요한 프로퍼티를 정할 의무가 있을 것이다. 편의를 위해 엔진은 소스객체로부터 모든 프로퍼티를 임포팅하는 함수를 공급해서 그것들이 소스 오브젝트의 값에 의한 복제물 과 함께 시작할 수 있도록 할 것이고 변경할 필요가 있는 프로퍼티를 단지 오버라이드 할 것이다.


Example B-11. Objects cloning

<?php
class MyCloneable
{
   static
$id = 0
;

   function
MyCloneable
() {
      
$this->id = self::$id
++;
   }

   function
__clone
() {
      
$this->address = "New York"
;
      
$this->id = self::$id
++;
   }
}

$obj = new MyCloneable
();

$obj->name = "Hello"
;
$obj->address = "Tel-Aviv"
;

print
$obj->id . "\n"
;

$obj_cloned = clone $obj
;

print
$obj_cloned->id . "\n"
;
print
$obj_cloned->name . "\n"
;
print
$obj_cloned->address . "\n"
;
?>
 

PHP 5 는 개발자로 하여름 클래스를 위해 생성자 메소드를 선언할 수 있게 한다. 생성자 메소드를 가진 클래스들은 새롭게 생성된 객체에서 이 메소드를 초기화 하는데 적당하게 호출해서 객체가 사용되기 전에 필요로 하지 않게 할 것이다.

PHP 4 에서 생성자 메소드는 클래스 자신의 이름과 같은 이름을 가진 클래스 메소드였다. 파생된 클래스로부터 부모 생성자를 호출하는 것이 매우 일반적일 때, PHP 4는 거대한 클래스 계층 주변으로 클래스를 옮기는 성가신 부분을 만들어내는 방법을 택해 작업했다. 만약 클래스가 다른 부모클래스 아래로 귀속하기 위해 옮겨졌을 때, 부모클래스 생성자의 잘 바뀌는 이름과 부모클래스 생성자를 호출하는 파생된 클래스의 코드는 수정될 것이다.

PHP 5 는 __construct()라는 이름으로 불리우는 생성자 메소드를 선언하는 표준방법을 도입하였다. 


Example B-12. using new unified constructors

<?php
class BaseClass
{
   function
__construct
() {
       print
"In BaseClass constructor\n"
;
   }
}

class
SubClass extends BaseClass
{
   function
__construct
() {
      
parent::__construct
();
       print
"In SubClass constructor\n"
;
   }
}

$obj = new BaseClass
();
$obj = new SubClass
();
?>

이전 버전과의 호환성을 위해 만약 PHP 5 가 주어진 클래스를 위한 __construct() 함수를 찾지 못한다면 클래스의 이름으로 이루어진 이전 방식의 생성자 함수를 찾을 것이다. 효과적으로 이것은 클래스가 __construct() 라는 이름을 가진 메소드를 가진 경우 이것이 다른 의미론을 위해 쓰일것이라는 의미를 가지고 있는데 호환성 문제를 가진 경우에 한해서만 해당한다.

Destructors

객체를 위해 파괴자를 정의하는 능력을 소유하는 것은 매우 유용할 수 있다. 파괴자는 디버깅을 위해, 데이터베이스의 연결을 끊을 때,기타 다른 여러가지 일을 마무리할 때 로그 메세지를 남길 수 있다. PHP 4에선느 객체 파괴자를 위한 기술이 존재하지 않았지만, PHP가 셧다운을 요청하는 도중에 실행될 등록함수를 위해 이미 지원했다. 

PHP 5 는 자바와 같은 다른 객체지향언어에서와 유사한 개념을 가진 파괴자를 도입하였다. : 객체의 파괴자를 파괴한 객체가 최종적으로 참조되었을때,  어떤 파라미터 값도 받지 않는 __destruct() 라고 이름 붙여진 클래스 메소드는 메모리에서 객체가 해제되기 전에 호출된다.

Example B-13. Destructor

<?php
class MyDestructableClass
{
   function
__construct
() {
       print
"In constructor\n"
;
      
$this->name = "MyDestructableClass"
;
   }

   function
__destruct
() {
       print
"Destroying " . $this->name . "\n"
;
   }
}

$obj = new MyDestructableClass
();
?>

생성자와 같이 부모클래스의 파괴자는 엔진에 의해 명시적으로 호출되지는 않을 것이다. 부모클래스의 파괴자를 실행하기 위해 파생된 클래스에서는 명확하게 파괴자 본문에 parent::__destruct() 를 적어 호출하여야 한다.

Constants

PHP 5 는 완전한 클래스 상수를 도입하였다:

Example B-14. Class constant example

<?php
class Foo
{
   const
constant = "constant"
;
}

echo
"Foo::constant = " . Foo::constant . "\n"
;
?>

과거에는 사용자정의된 클래스나 함수에 "const"를 붙이지 않고 실행했을 것이다.


Exceptions

PHP 4 는 예외사항 조정에 대한 요소가 없었다. PHP 5 에서는 다른 프로그래밍 언어와 유사한 예외모델을 도입하였다. "catch all"을 위해 지원하지만, "finally"조항을 위한 것이 아님을 주의하여라.

Exception 은 catch 블록에서 다시 제시될 수 있다. 또한 다양한 catch 블록에서 소유하고 있는것도 가능하다. 이러한 경우에서 잡힌 exception 은 꼭대기부터 바닥까지의 각각의 catch 블록의 클래스타입과 비교되고, 'instanceof'를 지닌 첫 블록의 매치는 실행될 것이다. catch 블록이 끝날때 실행사항은 마지막 catch 블록까지 지속된다. 만약 어떤 catch 블록도 'instanceof' 매치를 지니고 있지 않은경우, 그 다음 try/catch block이 다음 try/catch 블록이 존재하지 않고 사용가능하지 않을때까지 검색될 것이다. 이러한 경우 exception 은 exception 절을 발견하지 못하고 프로그램은 예외사항을 보여주면서 중단한다.


Example B-15. Exception creation example

<?php
try
{
  
throw new Exception('Hello'
);
}
catch (Exception $exception
) {
   echo
$exception
;
}
?>

과거에는 사용자정의된 클래스나 함수에 "catch","throw" 또는 "try"를 붙이지 않고 실행했을 것이다.

Dereferencing objects returned from functions

PHP 4 에서는 함수에 의해 반환되는 객체들의 값을 부분참조하기란 불가능했고, 더 이상의 메소드를 만드는 것은 이러한 객체를 호출하였다. PHP 5에서는 다음과 같은 것들이 가능하다 :


Example B-16. Dereferencing example

<?php
class Circle
{
   function
draw
() {
       print
"Circle\n"
;
   }
}
    
class
Square
{
   function
draw
() {
       print
"Square\n"
;
   }
}

function
ShapeFactoryMethod($shape
) {
   switch (
$shape
) {
       case
"Circle"
:
           return new
Circle
();
       case
"Square"
:
           return new
Square
();
   }
}

ShapeFactoryMethod("Circle")->draw
();
ShapeFactoryMethod("Square")->draw
();
?>

Static member variables initialization

정적 클래스의 정적 멤버 변수가 이제 초기화될 수 있다.


Example B-17. Static variable initialization example

<?php
class foo
{
   static
$my_static = 5
;
  
public $my_prop = 'bla'
;
}

print
foo::$my_static
;
$obj = new foo
;
print
$obj->my_prop
;
?>
 

PHP 5 는 메소드를 정적으로 선언하기 위해 'static' 키워드를 도입하였다. 그래서 객체의 외부 전후에서 호출할 수 있다.


Example B-18. Static Methods example

<?php
class Foo
{
  
public static function aStaticMethod
() {
      
// ...
  
}
}

Foo::aStaticMethod
();
?>

가상변수 $this 는 static으로 선언된 메소드 안에서는 사용할 수 없다.


instanceof

PHP 5 는 객체가 클래스의 인스턴스건 아니건간에 그것을 조사하고 클래스를 확장하고 인터페이스조건을 제시하게 하기 위한 instanceof  키워드를 도입하였다.


Example B-19. instanceof example

<?php
class baseClass
{ }

$a = new baseClass
;

if (
$a instanceof baseClass
) {
   echo
"Hello World"
;
}
?>
 

Static은 개발자로 하여금 참조의 방식으로 변수의 값을 상수로 전달하도록 하는 컴파일 도중에 다루어진다. 이러한 변화는 또한 그들의 성능을 엄청나게 향상시켰지만 상수로의 우회적 참조가 더이상의 일을 할 수 없음을 의미한다.


Parameters passed by reference

참조에 의해 함수로 전달된 파라미터값은 아마 이제부터 기본값을 가질 수 있을 것이다.


Example B-20.

<?php
function my_function(&$var = null
) {
   if (
$var === null
) {
       die(
"$var needs to have a value"
);
   }
}
?>
 

__autoload() 요격실행 함수는 선언되지 않은 클래스가 명시화되었을 때, 자동적으로 호출될 것이다. 해당 클래스의 이름은 __autoload() 요격실행 함수로 인자처럼 전달될 것이다.


Example B-21. __autoload() example

<?php
function __autoload($className
) {
   include_once
$className . ".php"
;
}

$object = new ClassName
;
?>
 

메소트 호출과 프로퍼티 접근은 __call(), __get() 그리고 __set() 메소드에 의해 오버로드 될 수 있다.


Example B-22. __get() and __set()

<?php
class Setter
{
  
public $n
;
  
public $x = array("a" => 1, "b" => 2, "c" => 3
);

   function
__get($nm
) {
       print
"Getting [$nm]\n"
;

       if (isset(
$this->x[$nm
])) {
          
$r = $this->x[$nm
];
           print
"Returning: $r\n"
;
           return
$r
;
       } else {
           print
"Nothing!\n"
;
       }
   }

   function
__set($nm, $val
) {
       print
"Setting [$nm] to $val\n"
;

       if (isset(
$this->x[$nm
])) {
          
$this->x[$nm] = $val
;
           print
"OK!\n"
;
       } else {
           print
"Not OK!\n"
;
       }
   }
}


$foo = new Setter
();
$foo->n = 1
;
$foo->a = 100
;
$foo->a
++;
$foo->z
++;
var_dump($foo
);
?>

Example B-23. __get() example

<?php
class Caller
{
  
private $x = array(1, 2, 3
);

   function
__call($m, $a
) {
       print
"Method $m called:\n"
;
      
var_dump($a
);
       return
$this->x
;
   }
}

$foo = new Caller
();
$a = $foo->test(1, "2", 3.4, true
);
var_dump($a
);
?>
 

객체는 아마 foreach와 같은 방식을 사용하였을때의 오버로딩하는 방법으로 반복될 수 있을 것이다. 기본적인 행동은 모든 프로퍼티를 반복한다.


Example B-24. Object iteration example

<?php
class Foo
{
  
public $x = 1
;
  
public $y = 2
;
}

$obj = new Foo
;

foreach (
$obj as $prp_name => $prop_value
) {
  
// using the property
}
?>

인스턴스의 각각의 클래스는 Traversable이라는 빈 인터페이스를 실행할 foreach로 반복될 수 있다. 따가서 적합하게 실행되는 몇몇 객체들은 foreach와 합께 사용될 수 있다.

IteratorAggregate 와 Iterator 인터페이스는 PHP 코드에서 반복사용되는 방법을 상술할 수 있도록 한다. 그것들에 있어 첫번째는 Iterator 인터페이스를 이행하거나 반복가능한 내부 클래스에서 명시회되는 배열이나 객체를 반드시 리턴해야 하는 getIterator() 라는 메소드를 포함한다.


Example B-25. Iterator creation example

<?php
class ObjectIterator implements Iterator
{

  
private $obj
;
  
private $num
;

   function
__construct($obj
) {
      
$this->obj = $obj
;
   }
   function
rewind
() {
      
$this->num = 0
;
   }
   function
valid
() {
       return
$this->num < $this->obj->max
;
   }
   function
key
() {
       return
$this->num
;
   }
   function
current
() {
       switch(
$this->num
) {
           case
0: return "1st"
;
           case
1: return "2nd"
;
           case
2: return "3rd"
;
           default: return
$this->num."th"
;
       }
   }
   function
next
() {
      
$this->num
++;
   }
}

class
Object implements IteratorAggregate
{

  
public $max = 3
;

   function
getIterator
() {
       return new
ObjectIterator($this
);
   }
}

$obj = new Object
;

// this foreach ...
foreach($obj as $key => $val
) {
   echo
"$key = $val\n"
;
}

// matches the following 7 lines with the for directive.
$it = $obj->getIterator
();
for(
$it->rewind(); $it->valid(); $it->next
()) {
  
$key = $it->current
();
      
$val = $it->key
();
         echo
"$key = $val\n"
;
}
unset(
$it
);
?>
 

새로운 __METHOD__ 가상 상수는 현재 클래스와 메소드 내부에서 메소드가 사용될 때의 메소드를 보여주고, 클래스 밖에서 사용될때의 함수를 보여준다.


Example B-26. __METHOD__ use example

<?php
class Foo
{
   function
show
() {
       echo
__METHOD__
;
   }
}

class
Bar extends Foo
{
}

Foo::show();
// outputs Foo::show
Bar::show();
// outputs Foo::show either since __METHOD__ is
             // compile-time evaluated token

function test
() {
   echo
__METHOD__
;
}

test();     
// outputs test
?>
 

새로운 __toString() 기술 메소드는 객체를 문자열 변환객체로 오버로드 하도록 한다.


Example B-27. __toString() example

<?php
class Foo
{
   function
__toString
() {
       return
"What ever"
;
   }
}

$obj = new Foo
;

echo
$obj;
// call __toString()
?>
 

PHP 5 는 재설계한 클래스와 인터페이스, 함수와 메소드를 확장요소들과 같은 기능들을 추가한 완벽한 Reflection API 와 함께 출시되었다. 

Reflection API 는 또한 함수와 클래스 그리고 메소드를 위한 도큐먼트 해설을 얻는 방법을 제공한다.

거의 모든 객체지향코드의 외관모습은 개별적으로 상세히 기록된 Reflection API를 사용함에 의해 반영될 수 있다.


Example B-28. Reflection API use example

<?php
class Foo
{
  
public $prop
;
   function
Func($name
) {
       echo
"Hello $name"
;
   }
}

reflectionClass::export('Foo'
);
reflectionObject::export(new Foo
);
reflectionMethod::export('Foo', 'func'
);
reflectionProperty::export('Foo', 'prop'
);
reflectionExtension::export('standard'
);
?>

========================================================================================

2007/05/18 19:25 2007/05/18 19:25
이 글에는 트랙백을 보낼 수 없습니다

PHP에서는 실시한 그래픽 이미지 생성을 위해 PNG나 JPG와 같은 이미지를 생성, 조작, 출력할 수 있는

이미지 함수들을 제공한다. 이러한 함수들은 GD 그래픽 라이브러리가 설치되어 있어야 사용 가능하다.


1.ImageCreate(X ,Y)

가로크기가 X 이고, 세로 크기가  Y인 이미지 파일을 만들 수 있는 가상의 작업 공간을 생성한다.

$im = ImageCreate(300,300)


2.ImageCreateFromGIF(파일명)

지정한 위치에 있는 GIF 파일을 가져와 그 파일과 가로 세로 크기가 같은 새 이미지를 생성한다.

$im= ImageCreateFromGIF("apple.gif")


3.ImageCreateFromPNG(파일명)

지정한 위치에 있는 PNG 파일을 가져와 그 파일과 가로 세로 크기가 같은 새 이미지를 생성한다.

$im = ImageCreateFromPNG("orange.png")


4.ImageCreateFromJPEG(파일명)

지정한 위치에 있는 JPEG 파일을 가져와 그 파일과 가로 세로 크기가 같은 새 이미지를 생성한다.

$im= ImageCreateFromJPEG("melon.jpg")


5.ImageGIF(식별자, 파일명)

ImageCreate() 함수나  ImageCreateFromGIF() 함수를 통해 생성되어 메모리에 올려져 있는 이미지를

브라우저나 파일로 출력한다.


식별자 : ImageCreate() 함수나 ImageCreateFromGIF() 함수로부터 반환된 이미지 식별자

파일명 : 생성될 이미지 파일의 이름

           지정하지 안으면 파일이 생성되지 않고 브라우저에 출력만된다.

           단 브라우저에 출력하려면 함수를 호출하기 전에 Header() 함수를 먼저 호출하여야 한다.


//브라우저 출력

$im = ImageCreate(300,300);

Header("content-type: image/gif");

ImageGIF($im);


//orange.gif 파일로 생성

$im = ImageCreate(300,300);

ImageGIF($im, "orange.gif");


6.ImagePNG(식별자, 파일명)

ImageCreate() 함수나  ImageCreateFromPNG() 함수를 통해 생성되어 메모리에 올려져 있는 이미지를

브라우저나 파일로 출력한다.


7.ImageJPEG(식별자 , 파일명)

ImageCreate() 함수나  ImageCreateFromJPEG() 함수를 통해 생성되어 메모리에 올려져 있는 이미지를

브라우저나 파일로 출력한다.


8.ImageDestroy(식별자)

ImageCreate() 함수에 의해 반환된 이미지 식별자가 점유하고 있던 메모리를 해제한다.


9.ImageColorAllocate(식별자, R, G, B )

지정한 RGB 값으로 해당 식별자가 가리키는 이미지의 배경색이나 문자열의 색깔을 바꾼다.


10.ImageColorDeAllocate(식별자)

ImageColorAllocate() 함수에 의해 할당되었던 색상을 제거한다.


11.ImageRectangle(식별자, 좌측상단X , 좌측상단Y, 우측하단 X , 우측하단 Y, 컬러식별자)

인자로 전달된 네 개의 좌표에 따라 사각형을 지정한 컬러식별자의 색상대로 그린다.


$im=imagecreate(300,300);     //가로300 세로300 이미지 공간을 생성
$gray=imagecolorallocate($im, 0 ,255,0);  //가장 먼저 호출되는 Imagecolorallocate()가 이미지 배경색을 채움
$red=imagecolorallocate($im,255,0,0);        //imagerectangle($im, 180,180,200,200,$red);
imagerectangle($im, 180,180,200,200,$red);   //지정한 색의 테두리를 갖는 사각형 생성

imagepng($im);  //출력


12.ImageFilledRectangle(식별자, 좌측상단X , 좌측상단Y, 우측하단 X , 우측하단 Y, 컬러식별자)
ImageRectangle() 함수는 사각형의 테두리만 색을 채우지만 이 함수는 사각형 내부를 색상으로 채운다.

imagefilledrectangle($im, 180,180,200,200,$red);  


13.ImagePolygon(식별자, 꼭지점좌표, 꼭지점수, 컬러식별자)

지정한 위치와 색깔을 테두리로 갖는 다각형을 그린다.

꼭지점좌표 : (첫번째x, 첫번째y, 두번째x, 두번째y, .....)


$im=imagecreate(400,300);
$gray=imagecolorallocate($im, 0 ,255,0);
$red=imagecolorallocate($im,255,0,0);
$point=array(10,10,150,50,120,180,39,108);
Imagepolygon($im, $point, 4, $red);

Imagepng($im);


14.ImageFilledPolygon(식별자, 꼭지점좌표, 꼭지점수, 컬러식별자)

ImagePolygon() 함수처럼 다각형을 생성하지만 내부가 지정된 색상으로 채워진다.


15.ImageLine(식별자, 시작X좌표, 시작Y좌표, 끝X좌표, 끝Y좌표, 칼라식별자)

이미지 내에 선을 긋는다.

ImageLine($im,10,10,300,10, $red)


16.ImageDashedLine(식별자, 시작X좌표, 시작Y좌표, 끝X좌표, 끝Y좌표, 칼라식별자)

선을 그리되 점선으로 그린다.


17.ImageSetPixel(식별자, X좌표, Y좌표, 칼라식별자)

좌표가 가리키는 위치에 점을 하나 찍는다.


18.ImageString(식별자, 폰트, X좌표, Y좌표, 문자열, 칼라식별자)

좌표가 가리키는 위치에 지정한 색깔로 문자열을 출력한다.

Imagestring($im, 1, 200, 200, "welcome PHP", $red);


19.ImageStringUp(식별자, 폰트, X좌표, Y좌표, 문자열, 칼라식별자)

좌표가 가리키는 위치에 지정한 색깔로 문자열을 출력하되 세로로 출력한다.


20.ImageChar(식별자, 폰트, X좌표, Y좌표, 문자열, 칼라식별자)

ImageString() 함수와 동일하나 단 하나의 문자만을 출력한다.


21.ImageCharUp(식별자, 폰트, X좌표, Y좌표, 문자열, 칼라식별자)

ImageString() 함수와 동일하나 단 하나의 문자만을 출력하되 세로로 출력한다.


22.ImageSX(식별자) / ImageSY(식별자)

이미지의 가로와 세로 크기를 반환한다.


23.GetImageSize(파일명)

GIF나 JPEG, PNG, SWF 이미지 파일의 크기 정보를 반환한다.

$size=GetImageSize("apple.jpg")

$size[0]  : 이미지 가로크기           //300
$size[1]  : 이미지 세로크기           //400
$size[2]  : 파일의 확장자( GIF:1, JPG2, PNG:3)      //2
$size[3]  : 태그안에 사용할 수 있는 형식으로 가로세로 크기값 출력      //width=320 height=400


24.ImageArc(식별자, 중심의X좌표, 중심의Y좌표, 타원너비, 높이, 시작점, 끝점, 컬러식별자)

타원을 그린다.


25.ImageFill(식별자, X좌표, Y좌표, 컬러식별자)

지정한 X, Y 좌표로 점을 찍어 그 점이 속하는 영역의 색을 칠한다.


26.ImageColorTransparent(식별자, 컬러식별자)

식별자가 가리키는 이미지에서  지정한 색깔을 제거해 투명하게 처리한다.


27.ImageCopyResized()

원본 이미지의 일부분을 대상 이미지에 복사한다.


28.ImageCopy()

원본 이미지의 일부분을 복사한다.


29.ImageTTFText()

트루타입 폰트를 이용하여 이미지에 문자열을 출력한다.


30.ImageTTFBBox()

인자로 전달한 문자열이 어느 정도의 자리를 차지하는지를 px 단위의 수치를 담은 배열의 형태로 반환한다.


31.ImageColorAt(식별자, X좌표, Y좌표)

지정한 위치의 픽셀이 가지고 있는 색깔의 인덱스를 얻는다.


32.ImageColorForIndex(식별자, 컬러인덱스)

지정한 클러 인덱스의 RGB 값을 연관 배열의 형태로 반환한다.


33.ImageColorExact(식별자, R, G, B)

특정 색깔의 컬러 인덱스를 반환한다.


34.ImageColorClosest(식별자, R, G, B)

지정한 RGB 성분의 각에 가장 근접하는 컬러 인덱스값을 반환한다.


35.ImageColorSet(식별자, 컬러인덱스, R, G, B)

지정한 컬러 인덱스에 해당하는 색깔을 red, green, blue 인자로 지정한 색깔로 바꾼다.


36.ImageColorResolve(식별자, R, G, B)

인자로 지정한 특정 색깔의 컬러 인덱스를 반환한다.


37.ImageColorsTotal(식별자)

해당 이미지 팔레트에 사용된 총 색상의 수를 반환한다.


38.ImageInterlace(식별자)

식별자가 가리키는 이미지의 interlace 옵션을 설정한다.


39.ImageTypes()

현재 설치되어 있는  PHP가 지원하는 이미지 타입을 반환한다.

2007/01/24 12:48 2007/01/24 12:48
이 글에는 트랙백을 보낼 수 없습니다
Smarty에 내장된 캐시 내용들을 다양한 저장장치에 담을 수 있고, 사이트 내의 컨텐츠들이 업데이트될 때 손쉽게 캐시를 갱신할 수 있다. 이번 호에는 각 상황에 맞는 캐시 사용 방법과 Smarty의 보안 설정 방법에 대해 알아보도록 하겠다.
조한석 |마소 Jr.에 PHP를 연재하던 필자는 최근 Smarty에 흠뻑 빠져 살고 있다. 많은 PHP 프로그래머들과 Smarty를 함께 공유하고 싶은 마음이 간절하며, 지금도 틈틈이 Smarty 매뉴얼을 번역중이고, 최근 들어 학교 프로젝트를 수행하기 위해 파이썬을 공부하는 중이다.

지금까지 템플릿 파일들은 $template_dir에만 위치해 있었고, 이것을 읽어 들이는 방법은 다음과 같았다.

// PHP Script에서
$smarty->display(‘index.tpl’);
{* 템플릿에서 *}
{include file=’home/index.tpl’}

만일 $template_dir에 없는 템플릿들을 불러오기 위해서는 다음과 같이 절대경로를 이용해 템플릿을 가져오면 된다.

// PHP Script에서(Unix)
$smarty->display(‘/home/sizer/template/index.tpl’);
{* 템플릿에서(Windows) *}
{include file=’C:/My Website/template/index.tpl’}

앞의 표현들은 사실 웹 브라우저에서 ‘http://’를 생략하고 URL을 입력하는 것처럼 완전한 것은 아니다. 웹 브라우저들이 프로토콜 타입인 ‘http://’가 생략된 URL에 대해 기본적으로 ‘http://’라고 가정하는 것처럼, Smarty 엔진은 앞에서 생략된 리소스 타입으로 로컬 머신의 파일 시스템에 있는 파일들을 가리키는 리소스 타입인 ‘file’을 가정하고 있다. 그리고 앞의 표현들은 다음과 같이 좀더 길게 타이핑해줄 수도 있다.

$smarty->display(‘file:index.tpl’);
{include file=’file:home/index.tpl’}
$smarty->display(‘file:/home/sizer/template/index.tpl’);
{include file=’file:C:/My Website/template/index.tpl’}

리소스 플러그인 작성하기
Smarty를 사용하는 프로그래머는 파일 시스템이 아닌 데이터베이스나 LDAP, 혹은 공유 메모리 같은 저장장치에 저장할 수 있도록 별도의 리소스 플러그인을 작성하는 것이 가능하다. 그러나 다른 저장장치를 템플릿의 저장소로 사용하는 것은 아주 규모가 큰 카페와 같은 기능을 구현할 때나 고려해 볼 만한 것이고, 일반적인 성격의 웹 사이트에서는 거의 쓰일 일이 없다고 생각된다. 그런 이유로 데이터베이스에서 템플릿을 읽는 리소스 플러그인은 이 글을 다 읽고나서 독자 여러분들이 스스로 해보기를 바라며(Smarty 매뉴얼에 그렇게 실전적이지는 않은 예제가 있으니 참조하기 바란다), 이번 호에는 스킨 기능을 이용하는 웹 애플리케이션에서 필요한 템플릿들을 좀더 편리하게 지정할 수 있도록 리소스 플러그인을 추가하는 예제를 알아보도록 하겠다. <리스트 1>에 나와 있듯이 리소스 플러그인에 필요한 함수는 다른 플러그인과는 달리 4개가 필요하다.

◆ smarty_[resource_name]_template($tpl_name, &$tpl_source, &$smarty) : 템플릿 내용을 &$tpl_source를 통해 반환하는 함수, 지정한 템플릿을 찾는 데 성공하면 true를, 실패하면 false를 반환한다.
◆ smarty_[resource_name]_timestamp($tpl_name, &$tpl_source, &$smarty) : 템플릿이 만들어진 시간을 &$tpl_timestamp를 통해 반환하는 함수, 지정한 템플릿을 찾는 데 성공하면 true를, 실패하면 false를 반환한다.
◆ smarty_[resource_name]_secure($tpl_name, &$smarty) : 해당 리소스 타입이 안전한 것인지를 체크하는 함수(뒤에 나오는 보안과 관련된 함수)
◆ smarty_[resource_name]_trusted($tpl_name, &$smarty) : 해당 리소스 타입이 신뢰할 수 있는 것인지를 체크하는 함수(뒤에 나오는 보안과 관련된 함수)

<리스트 1>은 이와 같은 형식으로 작성된 리소스 플러그인을 plugins 디렉토리에서 자동으로 읽어 들이게 하는 방식이 아니라, 수동으로 register_resource() 함수로 등록시켰는데(이런 경우 플러그인 함수 이름 앞에 ‘smarty_’ 접두어를 붙일 필요가 없다), 일부 특정한 Smarty 자식 클래스에서만 사용하는 플러그인의 경우 이런 식으로 플러그인을 등록하는 방법이 종종 이용되므로 참조하기 바란다. 그리고 스킨을 순수한 템플릿만으로 만드는 것이 아니라 설정파일도 같이 사용하고 싶다면, 스킨 디렉토리의 설정파일을 로드할 수 있는 {skin_config_load} 같은 함수도 만들어 등록해줘야 할 것이다.

기본적인 캐시 사용법
사실 템플릿 리소스들은 컴파일된 이후에는 사용되지 않으므로 아무리 빠른 저장장치(예를 들어, 공유 메모리와 같은)에 저장한다고 해도 웹 사이트에서 얻는 성능상의 이익은 거의 없다고 봐야한다. 실제로 Smarty로 된 웹 애플리케이션의 성능을 개선하기 위해서는 지난 호에 배운 필터와 이번 호의 캐시 기능을 잘 활용해야 한다. 간단하게 Smarty에서 캐시를 활성화시키기 위해서는 다음과 같이 $cache_dir에 웹 서버가 읽기/쓰기가 가능하게 디렉토리의 퍼미션을 줄 필요가 있다.
// ‘/any_cache_path’는 읽기 쓰기가 가능해야 한다.
$smarty->cache_dir = ‘/any_cache_path’;

$smarty->caching을 1이나 2로 설정해주면 된다.

// 캐시가 종료되는 시간을 $cache_lifetime에 설정된 값으로 결정
$smarty->caching = 1;
// 캐시가 종료되는 시간을 캐시가 생성될 때 기록된 cache_lifetime에 의해 결정
$smarty->caching = 2;

또한 $cache_lifetime은 기본적으로 3600초(1시간)로 설정되어 있으며, 0일 경우 항상 캐시를 다시 만들어내고 -1일 경우 명시적으로 캐시를 지우지 않는 이상 영속적으로 사용된다.

$smarty->cache_lifetime = 60; // 캐시 종료시한을 1분으로 결정
$smarty->cache_lifetime = -1; // 캐시 만료시한을 두지 않는다.
$smarty->cache_lifetime = 0; // 캐시를 항상 다시 만들어낸다(테스트할 때 유용).

Smarty는 캐시를 활성화시킨 뒤 템플릿이나 설정파일에 변화가 있을 때마다 새롭게 캐시를 생성하게 되는데 $compile_check를 false로 설정하면 템플릿이나 설정파일이 바뀌어도 이전의 캐시를 그대로 사용하게 되며, 이것은 실제 사이트를 운영할 때 약간의 성능 개선 효과를 준다.

// 템플릿, 설정파일이 바뀌어도 캐시가 갱신되지 않는다.
$smarty->compile_check = false;

그럼 여기서 캐시의 종료시한을 15분으로 설정하고 템플릿과 설정파일의 변화유무를 감지할 수 있도록 설정한 <리스트 2>를 살펴보도록 하자. 얼핏 보면 <리스트 2>에는 별 문제가 없어 보인다. 하지만 이 스크립트는 성능상으로 그다지 캐시의 효과를 얻을 수 없고 사이트의 갱신된 내용을 효과적으로 반영하지도 못하는데, 그 이유는 다음과 같다.

짾 첫째, 만약 $mode가 ‘list’인 상태라면 캐시가 되었든 안되었든 항상 데이터베이스에 접속해서 결과를 가져오는 루틴이 필요하다. 데이터베이스에 저장된 내용의 변화가 없는 상태라면 이런 동작은 할 이유가 전혀 없고, 귀중한 데이터베이스 서버의 리소스만 낭비할 뿐이다.
짿 둘째, 템플릿이나 설정파일의 변화는 캐시에 반영되지만 PHP 스크립트의 변화는 캐시에 반영되지 않으므로 막상 데이터베이스에 변화가 있다고 하더라도 사이트 방문자는 왜 새로운 글이 올라가지 않는지 화를 낼 것이다(운 나쁘면 15분 정도 기다려야 새로운 글이 게시판에 확인할 수 있을 것이다).
스크립트 내에서 캐시 행동 제어하기
먼저 필요 없는 데이터베이스 연결 루틴 부문을 캐시 유무에 따라 수행여부를 결정할 수 있도록 개선해 보자. 특정한 템플릿이 캐시가 되었는지 안되었는지는 is_cached($tpl_name) 메쏘드를 통해 알아낼 수 있다. 다음과 같이 하면 캐시가 된 상태에서는 쓸데없이 데이터베이스에 접속하지 않게 될 것이다.

if (!$smarty->is_cached(‘list.tpl’)) {
// 데이터베이스에 접속해 결과를 가져온다.
}
$smarty->display(‘list.tpl’);

그 다음에 clear_cache() 메쏘드를 이용하면 해당 템플릿의 캐시된 결과를 명시적으로 지울 수 있다. <리스트 3>은 이 두 개의 메쏘드를 이용해서 기존의 캐시를 사용할지 아니면 데이터베이스에 업데이트된 내용을 반영해서 새롭게 캐시를 만들어내야 할지 처리하는 스크립트이다.

템플릿마다 별도의 캐시를 만들어내고 제어하기
<리스트 3>을 보면 $mode가 ‘list’인 경우 리스트가 길어도 그냥 한 페이지에 다 출력한다. 그러나 게시판과 같은 기능을 구현할 때는 리스트를 일정한 길이로 잘라 페이지별로 보여줄 필요가 있다. 이런 경우 $page_num과 같은 별도의 변수에 따라 출력을 달리해서 출력해야 한다.

$smarty->display(‘list.tpl’);

같은 식으로 템플릿을 출력한다면 ‘list.tpl’에 대해 오직 하나의 캐시만을 가지기 때문에 제대로 된 페이지 네비게이션을 구현할 수 없게 된다. 마찬가지로 게시판에서 특정한 글을 읽는 동작 역시 다음과 같이 하면 ‘view.tpl’에 대해 오직 하나의 캐시만을 가지므로 게시판에 접속하는 사용자들은 언제나 같은 글만을 읽게 될 것이다.

$smarty->display(‘view.tpl’);

이것을 해결하는 가장 간단한 방법은 특정한 매개변수에 따라 변동이 심한 페이지 영역에 대해서 캐시 기능을 끄는 것일 테지만, 게시판과 같은 웹 애플리케이션에서 리스트를 보여주는 부분과 글을 읽은 부분에서 캐시 기능을 끄는 것은 사실상 캐시 기능을 사용하지 않겠다는 소리나 마찬가지이다. 지금까지 $smarty->display($tpl_ name)과 같은 형식으로만 템플릿을 읽어 들여 출력했지만, 사실 display() 메쏘드의 완전한 형식은 다음과 같다.

display($tpl_name, $cache_id, $compile_id);

여기서 $cache_id 매개변수를 달리 설정하면 같은 템플릿에 대해 별도의 캐시를 만들어줄 수 있다. ? 과 같은 코드는 같은 ‘list.tpl’에 대해 각각 다른 캐시를 만들어 내는데, ? 와 같이 하면 $page_num에 따라 별도의 캐시들이 생성하게 된다.

$smarty->display(‘list.tpl’, ‘1’); → ?
$smarty->display(‘list.tpl’, ‘2’); → ?
$smarty->display(‘list.tpl’, $page_num); → ?

이렇게 생성된 별도의 캐시들을 지우기 위해서는 clear_cache()를 display()와 같은 형식으로 호출하면 된다.

$smarty->clear_cache(‘list.tpl’, $page_num);

그러나 아쉽게도 이런 방법으로 진행해도 문제는 발생한다. 만약 게시판에 새로운 글이 올라온다면, 리스트와 관련된 모든 캐시를 지워줘야 하는데, 앞과 같이 캐시를 생성했다면 다음과 같은 코드로 캐시를 하나하나 지워줘야 할 것이다.

for ($i=0; $i < $page_total; $i++) {
$smarty->clear_cache(‘list.tpl’, $i);
}

이런 식으로 하면 캐시 제어가 너무 복잡해질 가능성이 있다. 하지만 관련된 페이지들을 묶어서 $cache_id로 표현할 수 있으므로 걱정하지 말기 바란다. 게시판의 예를 계속해서 들어보면, 게시판의 리스트나 글 조회로 인해 생성되는 캐시들은 ‘|’를 이용해서 다음과 같이 그룹핑해주는 것이 가능하다(‘|’로 그룹핑하는 깊이에는 한계가 없다).

$smarty->display(‘list.tpl’, “board|list|$page_num”);
$smarty->display(‘view.tpl’, “board|view|$id”);

만일 특정한 글이 수정되었다면 리스트에는 변동이 없을 테니, “board|view|$id”에 해당하는 캐시만 새롭게 생성해 주면 될 것이다.

$smarty->clear_cache(‘view.tpl’, “board|view|$id”);

그러나 새로운 글이 올라왔다면 리스트 전체에 해당하는 캐시를 갱신해 줄 필요가 있는데, 다음과 같이 “board|list|$page_num”에서 $page_num을 생략한 채 캐시를 clear_cache()를 호출해 주면 자동으로 ‘board|list’에 속하는 모든 캐시들이 만료된다.

$smarty->clear_cache(‘list.tpl’, ‘board|list’);
또한 게시판 전체의 모든 캐시를 깨끗이 지우고 싶다면 clear_all_cache()를 사용해도 어느 정도 비슷한 효과를 낼 수 있겠지만, 그것보다는 다음처럼 $tpl_name을 null로 지정한 채 clear_cache()를 호출하면 list.tpl과 view.tpl과 상관없이 ‘board’에 속하는 모든 하위 캐시들을 만료시키게 된다.

$smarty->clear_cache(null, ‘borad’);

캐시 핸들러 제작과 등록하기
앞에서 리소스들은 아무리 빠른 장치에 저장하더라도 그로부터 발생하는 성능상의 이득은 그렇게 크지 않다고 했다. 하지만 캐시의 경우는 저장하고자 하는 장치가 빠르면 빠를수록 좋다. 여건만 된다면 모든 캐시된 내용들을 메모리에 저장해 보는 것도 생각할 수 있다. 로컬 파일 시스템이 아닌 다른 저장소를 캐시로 이용하기 위해서는 $cache_handler_func에 적당한 캐시 핸들러 함수를 만들어 등록시키면 된다.

$smarty->cache_handler_func = ‘database_cache_handler’;

등록할 캐시 핸들러 함수의 레이아웃은 다음과 비슷한 모습으로 작성하게 된다.

function any_cache_handler($action, &$smarty, &$cache_content,
$tpl_file = null,
$cache_id = null,
$compile_id = null) {
switch ($action) {
case ‘read’: // 캐시로부터 캐시된 내용을 읽는 루틴
case ‘write’: // 캐시에 새로운 캐시 내용을 쓰는 루틴
case ‘clear’: // 캐시 내용을 삭제하는 루틴
default: // ‘read’, ‘write’, ‘clear’이외의 행동은 에러이다.
}
}

<리스트 5>는 Smarty 메뉴얼에 있는 MySQL용 캐시 핸들러 예제인데, 이것은 앞에서 소개한 캐시 그룹핑 기능을 지원하지 못한다. 따라서 앞에서 언급한 대로 캐시들을 하나하나 제거하는 루틴을 구현해 주거나 좀더 기능을 추가할 필요가 있다. $CacheId 이외에 $tpl_file, $cache_id, $compile_id를 나타내는 컬럼을 테이블에 추가한 뒤 그에 맞는 쿼리문을 수행하는 루틴을 핸들러에 삽입하면 될 텐데, 이것은 다음 시간까지 독자 여러분들의 숙제로 남기도록 하겠다(기본 캐시 핸들러의 알고리즘을 살펴보려면 ‘Smarty.class.php’를 참조하면 된다).

Smarty를 안전하게 실행시키기
Smarty는 템플릿 안에 {php}..{/php}나 {include_php}..{/include_ php}를 통해 PHP 코드들이 삽입돼 실행될 수 있다. 그리고 말한 적은 없지만 {if}..{/if} 동적 블럭문이나 변수 변환자에서 일반 PHP 함수를 사용할 수도 있다.
{if count($array) > 1}
..
{/if}
즉, 템플릿 내에서 이와 같은 문장을 사용할 수 있다는 의미인데, 여기서 물론 count는 템플릿 함수가 아닌 PHP 함수 count를 가리킨다. 이런 특징들은 잘만 사용되면 나름대로 편리함을 줄 수도 있겠지만, 편리함을 위해 여러분의 웹 사이트의 안전을 포기할 수는 없는 법이다. Smarty는 보안에 민감한 영향을 줄 수 있는 특징들을 템플릿에서 사용할 수 없도록 하거나, 또 신뢰할 수 있는 위치에 있는 템플릿만을 처리할 수 있도록 멤버 변수들을 설정해 줄 수 있다. 먼저 가장 기본적인 보안 관련 멤버 변수에는 $security가 있는데, 이것을 true로 하면 기본적으로 Smarty 템플릿 엔진은 다음과 같이 행동하게 된다(다음에 나오는 행동들은 $security_setting에 의해 조정될 수 있다).

◆ $secure_dir에 설정된 디렉토리들 밑에 있는 템플릿들만을 사용할 수 있다. (display(), fetch() 메소드와 {include} 템플릿 함수 등에서 이 값을 체크한다)
◆ 만일 $php_handling가 SMARTY_PHP_ALLOW로 설정되어 있으면, 이 값은 묵시적으로 SMARTY_PATH_PATHTHRU로 교체된다.
◆ {php}..{/php} 템플릿 함수는 허용되지 않는다.
◆ {if}..{/if} 동적 블럭문에서 $security_setting에서 허용하는 함수를 제외한 일반 PHP 함수를 사용할 수 없다.
◆ 변수 변환자에서 $security_setting에서 허용하는 함수를 제외한 일반 PHP 함수를 사용할 수 없다.

앞에 나오는 멤버 변수들을 하나하나 살펴보도록 하자. 우선 $secure_dir의 값은 허용할 템플릿 디렉토리를 다음과 같이 설정하면 되는데, 허용할 템플릿 디렉토리가 많다면 배열로 설정해주면 된다.

$smarty->template_dir = ‘/home/sizer/public_html/source/template’;
$smarty->compile_dir = ‘/tmp/site/localhost/compile’;
$smarty->security = true;
$smarty->secure_dir = ‘/home/sizer/public_html/source/template’;
$smarty->display(‘/home/sizer/public_html/source/not_allowed_template/index.tpl’);
$smarty->display(‘/home/sizer/public_html/source/template/index.tpl’);

허용되지 않는 템플릿을 포함하는 부분에서 다음과 같은 메시지를 볼 수 있다.

◆ PHP Warning: Smarty error : (secure mode) accessing “/home/sizer/ public_html/source/not_allowed_template/index.tpl” is not allowed in /usr/local/share/php/smarty/Smarty.class.php on line 595

두 번째로 $php_handling 멤버변수는 템플릿 내에 삽입된 {php}..{/php} 문장을 어떻게 처리할지 결정하는 함수로서 다음과 같이 네 가지 동작을 따른다.

짾 SMARTY_PHP_PASSTHRU : 해당 태그 내용을 있는 그대로 출력한다.
짿 SMARTY_PHP_QUOTE : 해당 태그 내용을 HTML 태그로 감싸 출력한다.
쨁 SMARTY_PHP_REMOVE : 해당 태그 내용을 삭제한다.
쨂 SMARTY_PHP_ALLOW : 태그 안에 있는 PHP 코드를 실행한다.

다음으로 $security_setting 멤버변수는 $security가 true로 설정된 상태에서 보안 수준을 결정할 수 있는 배열로서 다음과 같은 요소들을 가지고 있다.

◆ INCLUDE_ANY : true로 설정하면 $secure_dir에 있는 값을 무시한다. 기본 값은 false이다.
◆ PHP_TAGS : true로 설정하면 템플릿 내에서 {php}..{/php}를 사용할 수 있다. 기본 값은 false이다.
◆ PHP_HANDLING : true로 설정하면 $php_handling에 있는 값을 체크하지 않고 PHP 코드를 항상 실행한다.
◆ IF_FUNCS : {if}..{/if} 문에서 사용할 수 있는 함수들을 설정하며, 기본적으로 허용되는 함수로는 ‘array’, ‘list’, ‘isset’, ‘empty’, ‘count’, ‘sizeof’, ‘in_array’, ‘is_array’가 있다.
◆ MODIFIER_FUNCS : 변수 변환자에서 사용할 수 있는 함수들을 설정하며, 기본적으로 허용되는 함수는 ‘count’이다.

그리고 $trusted_dir이라는 멤버변수가 있는데, 이 변수로 설정한 디렉토리 밑에 있는 템플릿들은 {include_php}를 통해 PHP 코드를 실행할 수 있게 되는데, $secure_dir과 $trusted_dir에 같은 디렉토리가 중복되어 있다면 $secure_dir이 우선권을 가진다.

다음에는 스킨 메모장 제작
이번 호에는 리소스 플러그인과 캐시 제어법, 그리고 보안과 관련된 멤버변수들에 대해 알아보았다. 여러분들은 이제 Smarty 템플릿 엔진에 대해 대부분의 이론적인 지식을 쌓은 셈인데, 막상 Smarty를 이용해서 웹 사이트를 어떻게 구축할 것인가에 대해 고민이 될 것이다. 사실 필자도 아직까지 짙은 안개 속에서 방황하는 감이 없지 않았는데, 아무래도 Smarty를 이용한 실전 코드들이 아직 그렇게 많이 살펴보지 않은 탓이라고 생각한다(Smarty를 이용한 사이트나 웹 애플리케이션은 아직까지 그렇게 많지 않은 편이기도 하다). 약속한 커리큘럼을 따르려면 다음 호에는 Smarty를 이용해서 간단한 스킨 메모장을 만들어 봐야겠지만, 사정이 된다면 PEAR와 Smarty를 이용한 좀 더 큰 규모의 웹 사이트 구축 방법을 소개할지도 모르겠다.

2006/11/01 18:43 2006/11/01 18:43
이 글에는 트랙백을 보낼 수 없습니다
Web_developing/PHP  2006/09/16 22:04
출처 블로그 > 행복이네 집
원본 http://blog.naver.com/prebetty79/100028415343

폼변수 다루기

  폼변수

   PHP 스크립트에서 폼 필드 값은 PHP 변수처럼 접근 할수 있다.

   3가지 방법이 있다.

     ex)

          $tireqty                                  //짦은 스타일

          $_POST['tireqty']                   // 중간 스타일

          $HTTP_POST_VARS['tireqty']  // 긴 스타일

    1. 짧은 스타일 : register_globals를 활성화 시켜야 쓸수 있다. (비추천)

                            지역변수와 혼란을 야기 한다. 4.2.0이후로 비활성화 되어있다.

    2. 중간 스타일 : 추천되는 방식(4.1.0이후에서만 가능)

    3. 긴 스타일 : 지양되어 왔다. 모든 버전에서 사용할수 있어 이식성은 높다.

                        성능에 좋지 않다. registre_long_arays로 비활성화 할수 있다.

식별자(Identifier)

dfe

  - 식별자는 변수의 이름을 말한다.

 - 길이 제한은 없으며 문자,숫자,'_', '$'로 만들 수 있다.

  - '$'는 가변변수때문에 조심해서 사용해야 한다.

  - 숫자는 매 앞에 올수 없다.

  - 대소문자를 구분한다.

변수형

: 변수의 형(type)은 저장된 데이터의 종류에 따라 정해진다.

   기본데이터형

     ■ Integer : 모든 숫자

     ■ Float

     ■ String

     ■ Boolean

     ■ Array

     ■ Object

     이 외에 NULL형과 resource형(외부자원 ex DB연결)이 있다.

형 강도(Type Strength)

PHP는 형 강도가 매우 약한다. 변수에 저장된 값에 따라 형이 결정된다.

     $a = 0;

     $a = 0.00;

       // $a는 처음엔 정수형이였다가 실수형으로 바뀐다.

     $a = 'Hello';  // 이것도 가능하다 이제 $a는 문자열이다

가변 변수(variable varialbes)

:  가변변수를 사용하면 변수의 이름을 동적으로 바꿀수있다.

  ex)

   $varname = 'b';

   $$varname = 5;

 

  위는 $b = 5 와 하는 것과 동일하다.

  

상수

  - 상수는 define 함수를 사용하여 상수를 정의한다.

    ex)

        define('TIREPRICE' , 100);

        define('OILPRICE', 10);

        define('SPARKPRICE', 4);  

  - 상수의 사용

     : 변수는 $를 붙이지만 상수는 상수의이름만 적어주면 된다.

    ex)

      echo TIREPRICE;


변수의 범위(scope) 6개의 범위를 가지고 있다.

- 수퍼글로벌 변수는 스크립트 전역에서 사용할 수 있다.

- 한번 선언된 상수는 스크립트 전역에서 사용할 수 있다. 즉 함수의 안과 밖 모두에서 사용할 수 있다.

- 전역변수는 스크립트 내에서 정의된 변수로 스크립트 내에서 사용할 수 있지만, 함수 안에서는 사용할 수 없다.  

- 함수 안에서 정의된 변수는 함수 내에서만 사용할 수 있다.

- 함수 안에서 전역으로 정의된 변수는 함수 밖에서는 사용할 수 없지만 매 사용 시마다 값이 저장되어 다음에 사용할 수 있다 ???

- 함수 안에서 사용된 변수는 함수가 끝나면 삭제된다.


수퍼글로벌 전체 리스트

  - $GLOBALS

  - $_SERVER

  - $_GET

  - $_POST

  - $COOKIES

  - $_FILES

  - $_ENV

  - $_REQUEST

  - $_SESSION



Operation(연산자)

대부분 C, Java랑 비슷하고 틀린부분만 정리

- 문자열 연산자   '.' : 문자열을 앞뒤로 붙여서 새로운 문자열을 만든다.

  ex)

     $a = "Bob's";

     $b = 'Auto Parts';

     $result = $a.$b;


   결과 $result에 저장된 값은 "Bob's Auto Parts"이다.

  - 산술 연산자

   : 산술 연산자의 operand(피연산자)는 정수와 실수형으로만 쓰일 수 있다. 만약 문자열로 산술연산을 시도한면 문자열을 숫자로 바꾸어서 실행한다. 문자열에 "e"나 "E"가 들어있다면 실수형으로 변화 한다. 그 외에는 정수형으로 변환. PHP는 문자열 처음에서 숫자를 찾아서 그것을 값으로 인식하는데, 만약에 문자열에 숫자가 없다면 문자열의 값은 0이 된다.


 - 참조 연산자(Reference)

   : C의 &연산자와 같음..

    ex) $a = 5

          $b = $a; --> $a, $b 서로 다른 메모리 영역을 가진다.


          $a = 5;

          $b = &a; 

          &b = 7    // $a, $b 서로 같은 메모리영역을 가진다 즉 $a, $b가 7


           unset($a)  : 서로의 참조를 다르게 한다 (관계를 떼어놓을 수 있다)


- 비교연산자(Comparison Operatiors)

     identical operator (===) : 두 피연산자가 값이 같고 같은형일 때만 true를 리턴한다.

     Not Identical (!==)  : != 와는 다르다

     Not Equal (<>) : 같지 않다. (!=) 와 같이 동일한 의미로 쓰인다.

- 에러 억제 연산자(error suppression operator) : @

    : '@'은어떠한 표현식에도 쓸수 있다.

    ex) $a = @(57/0)

     '@'가 없다면 위 문장은 "0으로 나누기"에 의한 에러가 발생하지만 '@'를 앞에 써주어서 에러는 무시하고 넘어간다. 만약 이런 방식으로 억제한다면 에러를 처리하는 코드를 작성해야 한다. 만약 PHP에서 track_error를 설정해 놓았다면 에러메시지를 전역변수인 $PHP_erromsg에 저장한다.


- 실행 연산자(execution operation)

 :  '`' 와 '`'로 이루어진 한 쌍의 연산자로 '`'는 홑따옴표(')와는 다른 키보드 ~아래에 있다.

   PHP에서 서버의 커맨드 라인에서 실행하고 싶은 것이 있다면 `` 사이에 명령어를 쓰면된다.

   그러면 ``의결과값이 표현식의 리턴값이 된다.

   EX)

      유닉스 환경

        @out = `ls -la`;

        echo '<pre>'.$out.'</pre>';

     그러면 시 디렉토리의 파일 리스트가 보이게 된다.


    

- 배열 연산자

   +       |    $a + $b    |  $a와 $b가 가지고 있는 모든값을 반환한다(합집합)

  ==       : $a, $b가 같은 요소를 가지고 있으면 true

  ===     | $a, $b가 같은 요소를 같은 순서로 가지고 있으면 true

  !=

  <>

  !==


변수와 관련된 함수

- 변수의 데이터 형을 검사하고 설정하기

 

      string gettype(mixed var);

         : 'boolean", "integer", "double", "string", "array", "object", "resource", 혹은 NULL을 반환한다. 표준 데이터 형이 아니면 "unknown"을 반환


      bool settype(mixed var, string type);


       ■ is_array()

       ■ is_double(), is_float(), is_real() (모두 같은 함수)

       ■ is_long(), is_int(), is_integer() (모두 같은 함수)

       ■ is_string()

       ■ is_object()

       ■ is_null()

       ■ is_scalar() - 변수가 스칼라 변수인지 확인한다. 즉 정수형, 불리어형, 문자열이나 실수형인지 확인한다.

       ■ is_numeric() - 변수가 숫자나 혹은 숫자 문자열인지 확인한다.

       ■ is_callable() - 변수에 저장된 값이 호출할 수 있는 함수의 이름인지 확인한다.


- 변수 상태 검사

   boolean isset(mixed var);

     : 이 함수는 변수의 이름을 인자로 받아서 만약 이 변수가 존재한다면 true를 반환한다.

      , 로 연결된 변수들을 주면 모든 변수가 존재해야 true를 반환

   boolean unset(mixed var);

    : 인자로 받은 변수의존재 자체를 없애고 true를 반환한다.

  empty(mixed var);

    : 변수가 존재하고, 비어 있지 않으며, 0이 아닌값을 가지고 있다면 true를 리턴

   

 - 변수형 변환

   int intval(mixed var[, int base]);  base :진수 (10, 2, 16)

   float floatval(mixed var);

   string strval(mixed var);

     

== 제어문 ==

 대부분 C와 비슷하지만, 틀린점만 요약하면

 

  1.  else if    -->  elseif  와 같이 붙여서 쓴다   

  2. 루프를 빠져나갈때 'continue', 'break' 이외에 'exit' 라는 제어문이 있다.

     'exit' : 루프를빠져나가 PHP 스크립트를 완전히 끝낸다.

  3. 대체 제어 구조

      { } 로 구역을 정하는 것이 아니라

        '{' 대신에 ':' 를 쓰고,

        '}' 대신에 사용한 제어구조에 따라, endif, endswitch, endwhile, endfor, endforeach를 쓸수있다.

     ex)

      if( $totalqty == 0 )

      {

           echo 'You did not ... ';

           exit;

      }

        를 아래와 같이 쓸수 있다.

      if( $totalqty == 0 ) :

           echo 'You did not ... ';

           exit;

      endif

   4. declare

     declare (directive)

     {

           // block

     }

       이 구조는 코드 블록에서 실행 지침(execution directive)를 설정하기 위해 사용된다.

       단 하나의 실행 지침인 tricks 만이 구현되어있는데 tricks=n이라는 방식으로 지침을 삽입할 수 있다. 코드 블록내에 있는 특정 함수 중 n개의 코드 행을 실행 시킬 수 있어 디버깅에 매우 유용한다.

2006/09/16 22:04 2006/09/16 22:04
이 글에는 트랙백을 보낼 수 없습니다
Web_developing/PHP  2006/09/13 12:21
array_change_key_case -- 모두 대문자나 소문자화된 문자열 키를 갖는 배열로 반환한다
array_chunk -- 배열을 여러 덩어리로 분산시킨다
array_combine --  키를 위한 배열과 값을 위한 배열을 각각 사용하여 배열을 생성한다
array_count_values -- 배열내의 중복된 키값의 개수를 배열로 리턴한다. [배열값]=>중복된갯수
  ::array array_count_values(array input)
array_diff_assoc -- 인덱스 검사와 함께 배열간의 차이를 계산한다
array_diff_uassoc --  Computes the difference of arrays with additional index check which is performed by a user supplied callback function
array_diff -- 배열간의 차이를 계산한다
array_fill -- 배열을 특정값으로 채운다
array_filter --  배열에서 두번째인자로 지정한 함수리턴값(TRUE,FALSE)에 맞는(TRUE)키값을 가진 키와키값을 골라 배열로 리턴.
  ::array array_filter(array input [,mixed callback]) 
array_flip -- 배열안의 모든 키를 각 키의 연관값으로 바꾼다.
array_intersect_assoc -- 인덱스 검사과 함께 배열의 중복을 계산한다
array_intersect -- 배열의 중복을 계산한다
array_key_exists -- 주어진 키와 인덱스가 배열에 존재하는지 확인한다
array_keys -- 배열의 모든 키를 반환한다
array_map --  Applies the callback to the elements of the given arrays
array_merge_recursive -- 두개 이상의 배열을 재귀적으로 병합한다
array_merge -- 인자로 주어진 배열들을 합한 배열을 리턴한다.
  ::array array_merge(array array1, array array2 [,array ..])
array_multisort -- 여러개의 배열 또는 다차원 배열을 정렬한다
array_pad --  설정된 길이만큼 특정 값으로 배열을 채운다
array_pop -- 배열 끝의 요소를 뽑아낸다
  :: mixed array_pop (array array)
array_push --  배열의 끝에 하나 이상의 원소를 넣는다.첫번째 인자인 배열끝에 두번째이후의 인자들을 추가한다.
  :: int array_push (array array, mixed var [, mixed ...]) 
array_rand --  배열안에서 하나 이상의 임의 원소를 뽑아낸다. srand()와 함께 사용하여 난수테이블을 초기화 해주는것이 좋다.
  리턴타입은 두번째 인자가 1일 경우 int 이고 2이상일경우에는 배열이다.
  :: mixed array_rand (array input [, int num_req]) 
array_reduce --  콜백 함수를 사용하여 배열을 반복적으로 단일 값으로 축소시킨다
array_reverse --  배열 원소를 역순으로 반환한다
  :: array array_reverse (array array [, bool preserve_keys])
array_search --  배열에서 주어진 값을 검색하고 성공하면 해당 키를 반환한다.존재하지 않으면 false(널문자)를 돌려준다.
  :: mixed array_search (mixed needle, array haystack [ , bool strict]
  예) $array = array(1,2,3,4,5,6); echo array_search(3, $array) ;
array_shift --  array_pop()과 반대되는 기능을 가지고 있고 배열에서 맨처음값을 삭제하고 삭제한 값을 리턴한다.
  :: mixed array_shift ( array array)
array_slice -- 배열에서 특정부분만 추출한 배열을 리턴한다. 두번째 인자는 시작할 인덱스이고 세번째 인자는 길이이다. 세번째인자가
     음수로 지정될 경우에는 역으로 진행된다. (0부터 시작한다)
  :: array array_slice ( array array, int offset [, int length])
array_splice --  배열의 일부를 삭제하고, 그 위치에 다른 내용을 대체한다
array_sum --  배열내의 값들의 합을 계산한다
  :: mixed array_sum (array arr)
array_udiff_assoc -- Computes the difference of arrays with additional index check. The data is compared by using a callback function.
array_udiff_uassoc -- Computes the difference of arrays with additional index check. The data is compared by using a callback function. The index check is done by a callback function also
array_udiff -- Computes the difference of arrays by using a callback function for data comparison.
array_unique -- 배열에서 중복된 값을 제거한다
array_unshift --  배열의 맨 앞에 하나 이상의 원소를 첨가한다.array_push()와 반대되는 기능을 하는 함수로서,두번째 이하 인자값을 배열에 추가하는데 기존 배열의 키는 뒤로 밀리게 된다.
  :: int array_unshift(array array, mixed var [, mixed ...])
array_values -- 배열의 연관배열을 스칼라 배열로 리턴하는 함수이다. 문자열키나 정수키는 무시되고 0 부터 순서대로 정수 인덱싱됨.
  :: array array_values (array input)
array_walk_recursive --  Apply a user function recursively to every member of an array
array_walk --  배열의 각 키와 값에 대해 두번째 인자로 지정한 함수를 실행케 한다. 세번째 인자는 이때 실해되는 함수의 인자로 쓰인다.
  ::int array_walk( array arr, string func [, mixed userdata])  (예제)
array --  배열을 생성한다
arsort --  배열을 내림차순 정렬하고 인덱스의 상관관계를 유지한다.
  :: void arsort(array array [, int sort_flags]) (예제) 
asort -- 배열을 오름차순 정렬하고 인덱스 상관 관계를 유지한다.즉 배열을 값에 따라 순서대로 정렬시키고 인덱스는 유지.
  :: void  asort(array array [, int sort_flages]) (예제)
compact --  주어진 인자를 변수명으로 갖는 연관배열을 리턴한다.변수명으로 배열변수명을 쓸수도 있다.
  :: array compact (mixed varname[,mixed ..]) (예제)
count -- 변수의 원소 갯수를 구한다
  :: int count(mixed var);
current -- 배열의 현재 원소를 반환한다.배열의 범위를 넘어서면 false를 리턴한다.
  :: mixed current(array array) 
each --  배열에서 현재의 키와 값 쌍을 반환하고 배열 커서를 전진시킨다
  :: array each (array array)
end --  내부 배열 포인터를 마지막 원소를 가리키게 한다
  :: mixed end( array array)
extract --  배열의 현재 심볼 테이블로 변수들을 입력한다
in_array -- 첫번째 이자가 두번째 인자로 주어진 배열의 원소로서 존재하는지 여부를리턴한다. 세번재 인자를 TRUE로 줄경우 데이타타입의 일치 여부까지 검사하게 된다. 리턴값을 false/true로 리턴하지 않고 true일경우 "1"을 false 일경우 널스트링""을 리턴한다.
  :: bool in_array(mixed needle, array haystack [, bool strict])
key -- 연관배열에서 현재 포인터의 키를 꺼낸다 . pos()와 current()는 현재 포인터의 값을 꺼낸다.
  :: mixed key (array array)
krsort -- 역순으로 키에 의해 배열을 정렬한다
  :: int krsort (array array [, int sort-flags]);
ksort -- 키에 의해 배열을 정렬한다
  :: int ksort (array array [, int sort-flags]);
list --  배열처럼 변수들을 지정한다.배열의 각 원소를 인자로 지정한 각 값들을 변수명으로 하는 변수값에 할당.
  :: void list (mixed ...)
  (예) $array = array('공부','노래',미술');  list('a','b','c')= $array;  결과) a=공부,b=노래,c=미술  
natcasesort --  대소문자를 구별하지 않고 "natural order" 알고리즘을 사용하여 배열을 정렬한다
natsort --  "natural order" 알고리즘을 사용하여 배열을 정렬한다.sort()와 비슷하나 sort()가 문자의 등장순으로 순서를 단순비교하여 정렬하는데 비해 의미론적 자연어 정렬을 가능케 해주는 특징이 있다.
  :: void natsort (array array) 
next --  배열의 내부 배열 포인터를 전진시킨다
pos -- 배열에서 현재 원소를 꺼내온다. current()의 alias 이다. 
prev -- 내부 배열 포인터를 앞으로 돌린다
  :: mixed prev (array array)
range --  특정 범위의 원소를 갖는 배열을 생성한다. low~high사이의 정수(또는 알파벳)를 원소로 하는 배열을 리턴한다.
  :: array range(mixed low, mixed high)
  (예) $array= range(5,9);  $array값이 {5,6,7,8,9}이다.
reset --  배열의 내부 포인터가 배열의 첫번째 원소를 가리키게 한다
  :: mixed reset (array array) 
rsort -- 역순으로 배열을 정렬한다.배열원소의 값을 기준으로 역정렬시킨다. 연관배열의 경우 스칼라 배열로 바뀌는 점 유의
  :: mixed rsort( array array [, int sort-flags]) (예제) 
shuffle -- 배열을 뒤섞는다.(주)다른 난수관련 함수들과 마찬가지로 srand()를 이용하여 시드의 초기화를 이뤄줘야한다.
  :: void shuffle( array array) 
sizeof -- count()의 별칭
sort -- 배열을 정렬한다.오름차순(0,1,2,3,4,....)
uasort --  사용자-정의 비교함수로 배열을 정렬하고 인덱스 연관성을 유지한다
uksort --  사용자-정의된 비교함수를 사용하여 키에 의해 배열을 정렬한다
usort --  사용자-정의된 비교함수를 사용하여 값들에 의해 배열을 정렬한다
2006/09/13 12:21 2006/09/13 12:21
이 글에는 트랙백을 보낼 수 없습니다
basename --  경로명에서 파일이름만 반환합니다
   :: string basename( string path [, string suffix])
  예) $path= $PHP_SELF ; echo basename($path);
chgrp -- 파일의 그룹을 변환합니다
chmod -- 파일의 모드 변경하고 성공여부를 리턴한다.

   :: int chmod(string filename, int mode);   첫번째인자는 경로명, 두번째인자는 10진수가 아니라 8진수이다.

chown -- 파일의 소유자 변경
clearstatcache -- 파일의 통계(stat) 캐시를 삭제합니다.
   :: void clearstatcache(void) 
     stat(),lstat(),file_exists() 등등의 statcaching-function을 사용후 다시 쓸일이 없다면 이 함수를 사용하여 리소스를 제거. 
copy -- 파일업로드시 많이 쓰이는 함수로 첫번째인자인 파일을 두번째 인자인 파일명으로 복사하고 성공여부 리턴한다.
   :: int copy( string source, string dest)
delete -- 실제로는 없는 명령
dirname -- 경로의 구성요소중에서 디렉토리 이름만 반환합니다.
   :: string dirname(string path)
disk_free_space -- 인자로 지정한 디렉토리의 남은 용량을 리턴한다. (원도우 버전에 오동작)
   :: float disk_free_space( string directory)
disk_total_space -- 해당 디렉토리의 총용량을 바이트 단위로 리턴한다.
   :: float disk_total_space( string directory) 
diskfreespace -- 디렉토리의 사용가능한 공간을 반환합니다. (리눅스,윈도우 정상동작)
   :: float diskfreespace( string directory)
fclose -- 열려있는 파일 포인터를 닫습니다.
feof -- 파일의 끝이 파일포인터에 있는지 테스트합니다.
fflush -- 출력결과를 파일로 보냅니다.
fgetc -- 파일포인터로부터 문자 가져오기. eof를 만나면 false를 리턴한다.
fgetcsv --  fgets()와 비슷한 용법을 가지나,일반 text파일에서 한라인씩 읽어오는데 반해 CVS파일의 한라인을 읽어서 두번째 인자로
    주어진 구분자를 기준으로 한 배열을 리턴하는데 차이가 있다. 두번째 인자 디폴트는 "." 이다.
   :: array fgetcvs(int fp, int length [, string delimiter]) 
fgets -- 파일 포인터에서 개행문자나 eof를 만날때까지 두번째인자인 byte수 만큼 읽어들인다.
   :: string fgets (int fp [, int length])
fgetss --  파일포인터에서 라인을 가져오고 HTML 태그를 없애기
file_exists -- 파일이 있는지 체크
file_get_contents -- Reads entire file into a string
file_put_contents -- Write a string to a file
file -- 파일전체를 한라인씩 배열로 읽어들임
   :: array file(string filename [, int use_include_path]) 
fileatime -- 최근에 파일에 최종 접근한 시간을 가져옴 (리턴형태는 unix_timestamp이다)
   :: int fileatime(string filename)
filectime -- 파일의 아이노드 변경시간을 가져옵니다 (리턴형태 unix_timestamp)
filegroup -- 파일의 그룹을 가져옵니다
fileinode -- 파일의 아이노드를 가져옵니다
filemtime -- 파일이 수정된 시간을 timestamp 값으로 리턴한다.
fileowner -- 파일의 소유자를 가져옵니다
fileperms -- 파일의 권한을 가져옵니다
filesize -- 파일의 크기를 byte단위로 리턴한다.
   :: int filesize( string filename) 
filetype -- 파일의 형식을 가져옵니다 (파일인지 디텍토리인지 구별하는 용도로 쓰일수 있다)
   :: string filetype (string filename)
flock -- 파일 잠김에 관한 간단한 도움말
fnmatch -- Match filename against a pattern
fopen -- 파일이나 URL을 엽니다
   :: int fopen(string filename, string mode [, int use_include_path])
fpassthru --  파일 포인터에 남아있는 모든 데이타를 출력하고 파일을 닫는다.
   :: int fpassthru(int fp) 
fputs -- 파일 포인터에 기록하기. fwrite()동일하다. 참고바람. 
fread -- 파일을 binary로 읽어온다. 모든내용을 읽고 싶다면 filesize()를 이용.
fscanf -- 형식에 따라서 파일로 부터 분석하여 입력하기
fseek -- 파일포인터를 두번째 인자로 지정한 위치로 옮긴다.
   :: int fseek (int fp, int offset [,int whence]) 
fstat --  오픈 파일 포인터를 사용하는 파일에 대한 정보 가져오기
   :: array fstat (int fp)
ftell -- 파일포인터의 읽기/쓰기 위치값을 리턴한다.
   :: int ftell (int fp) 
ftruncate --  주어진 길이로 잘라내기
fwrite -- Binary-safe 파일 쓰기 . fputs()와 동일하게 사용된다.
   :: int fwrite (int fp, string string [,int length])
glob -- Find pathnames matching a pattern
is_dir -- filename 이 디렉토리인지 아닌지 여부를 리턴한다.
   :: bool is_dir (string filename)
is_executable -- filename이 실행가능한 것인지 아닌지 이야기하기
is_file --  filename이 보통 파일인지 아닌지 이야기하기
is_link --  filename이 심볼릭 링크인지 아닌지 이야기하기
is_readable --  filename이 읽기 가능한 것인지 아닌지 이야기하기
is_uploaded_file -- file이 HTTP POST를 통해 업로드된 것인지 아닌지 이야기하기
is_writable -- filename이 쓰기가능한 것인지 아닌지 이야기하기
is_writeable -- Alias of is_writable()
link -- hard link 만들기
   :: int link(string target , string link) 
linkinfo -- 링크 정보 가져오기
lstat --  파일이나 심볼릭 링크에 관한 정보를 제공
mkdir -- 디렉토리 만들기
   :: int mkdir(string pathname, int mode)
move_uploaded_file -- 업로드된 파일을 다른곳으로 이동하기
parse_ini_file -- ini 확장자를 가진 파일을 열어 각 항목을 첨자로 하는 연관배열을 리턴한다.
   :: array parse_ini_file(string filename [,bool process_sections])
pathinfo -- 인자로 주어진 경로+파일명을 각 요소로 하는 연관배열을 리턴한다.
   :: array pathinfo (string path)
   예) [dirname][basename][extension]이와 같은 연관배열 형태로 출력한다.
pclose -- 진행되는 파일 포인터 닫기
popen -- 진행되는 파일 포인터를 열기
readfile -- 파일을 출력합니다
readlink -- symbolic link의 target 반환
realpath -- 웹경로가 아닌 실제 서버의 로컬경로를 리턴한다.
   :: array pathinfo( string path)
rename -- 파일을 새 이름으로 고치기
rewind -- 파일포인터의 위치를 되돌립니다(rewind).
rmdir -- 디렉토리 제거하기
set_file_buffer --  주어진 파일 포인터에 파일 버퍼링 설정하기
stat -- file에 대한 정보 제공
   :: array stat(string filename)
symlink -- 심볼릭 링크 만들기
tempnam -- 유일한 파일 이름 만들기
tmpfile -- 임시 파일 만들기
touch -- 파일의 수정시간을 설정합니다
umask -- 현재의 umask를 변경하기
unlink -- 파일을 삭제하기
2006/09/12 13:12 2006/09/12 13:12
이 글에는 트랙백을 보낼 수 없습니다
출처 블로그 > 20대의 끝을 잡고
원본 http://blog.naver.com/javancoffee/40003093131

링크 : http://phpschool.com/bbs2/inc_view.html?id=10453&code=tnt2&start=0&mode=search&field=title&search_name=&operator=and&period=last6month&category_id=&s_que=%BD%BA%B8%B6%C6%BC


스마티(Smarty) 템플릿 사용하기

김영진(cogolda@hanmail.net)
이 튜토리얼은 http://www.zend.com/zend/tut/tutorial-cezar.php에 있는
내용은 제가 번역, 추가, 생략했습니다.
소스 코드가 많아서 번역할 내용은 많지 않네요.
질문이나, 의견은 메일이나 코멘트 이용해 주시고,
관심있으신 자료 있으시면, 정리해서 올리겠습니다.
이 자료는 제가 스마티 쓸 때 도움이 되었던 문서이기도 합니다.

대상 독자

이 기사는 PHP templating같은 새로운 웹 개발기술을 적용하고 싶은 PHP 프로그래머와 HTML 디자이너를
위해 작성되었습니다.

Smarty 개요

이론적인 웹 개발 과정은 다음과 같다.
처음에는 디자이너가 유저 인터페이스를 만들고, 그것을 프로그래머를 위해 HTML 조각으로 쪼갠 다음
프로그래머가 HTML안에 PHP 비즈니스 로직을 구현하는 것이다.

그것은 이론적으로는 좋다. 그러나 실질적으로, 내 경험을 빌리자면, 클라이언트는 디자인이나 비즈니스 로직을 변경을 자주 요구한다. 그런 일이 일어날 때, HTML은 변경되고 프로그래머는 HTML 소스 코드를 수정한다.

이런 상황에서 문제는 프로그래머는 디자이너가 레이아웃과 HTML 파일을 완성할떄까지 기다려야 한다는 것이다. 다른 문제는 만약 메인 디자인이 바뀌면, 프로그래머는 새로운 페이지에 적합하기 위해 변경할 것이다. 이것이 바로 내가 스마티(Smarty)를 추천하는 이유이다. 스마티는 PHP를 위한 템플릿 엔진이다.

여러분은 http://smarty.php.net/ 에서 스마티 템플릿을 다운로드 할수 있다. 설치 과정은 매우 단순하다. 문서를 읽고 지시에 따라라.

그래서 스마티가 무엇인가? 스마티는 PHP 스크립트로 템플릿을 컴파일하는 PHP 클래스의 집합이다. 스마티는 템플릿 언어이고 디자이너와 프로그래머에게 매우 유용한 툴이다.
(한국에서 디자이너에게 스마티를 가르치는 것이 가능할까요?)

디자이너를 위한 스마티

디자이너 HTML 파일로 작업한다. 스마티와 작업하기 위해, 여러분은 템플릿 파일로 작업한다. 이런 파일들은 정적인 컨텐츠로 완성했으나, 스마티는 마크업 태그와 함께 결합된다.
(여기서 정적인 컨텐츠라는건 php 코드가 없는 html파일을 애기하는 것입니다.
마크업 태그는 페이지 기술 언어 다시말해 html, sgml, xml이런 걸 애기하는 것입니다.)
모든 템플릿 파일은 확장자가 .tpl이다. 스마티 템플릿 태그는 { and } 구획문자로 감싸진다.

웹 페이지의 기본적인 구조를 생각해 보자. 헤더가 있고, 중간 부분이 있고, 꼬리말(footer)이 있다. 헤더와 꼬리말을 포함하는 파일템플릿 파일 다음과 같다.

{include file="header.tpl"}
<form name="form1">
   Label1 <input type="text" name="text1">
   <input type="submit" value="submit">
</form>
{include file="footer.tpl"}

모든 템플릿은 한 템플릿 디렉토리안에 있어야 한다. 처음에 템플릿을 호출하고 나서, 컴파일된 템플릿은 template_c에 있을 것이다.

스마티 언어는 매우 강력하다. PHP에 모든 변수는 {$Variable_Name}으로 스마티에서 식별된다. 주의할 점은 $ 표시가 앞에 와야 한다. 만약 우리가 PHP에서 $MyName로 호출되는 변수가 있으면, 그 다음에 스마티에서 그것을 출력하기 위해, 우리는 다음과 같이 작성해야 한다.

<html>
   <body>
       Welcome, {$MyName} <br>
   </body>
</html>

스마티의 힘은 유연성에도 있다. 여러분은 템플릿에 IF와 LOOP 삽입할수 있다. IF 문법은 다음과 같다.

{if <condition> }
       html code
{else}
       html code
{/if}

여러분이 링크가 있는 동적인 메뉴를 가지고 있다고 보자. 여러분이 링크를 클릭하면, 여러분은 특정 페이지에 간다. 그래서 여러분은 PHP에서 정수 변수 $Menu가 있다면, 템플릿은 다음과 같다.

{if ($Menu == 1) }
       Option 1
{else}
       <a href=”option1.php”>Option 1</a>
{/if}
{if ($Menu == 2 ) }
       Option 2
{else}
       <a href=”option2.php”>Option 2</a>
{/if}

반복문을 작성하기 위해, 여러분이 PHP에서 다음과 같은 배열을 얻기를 제안한다.
(여기서 얻는다(get)는 표현은 확장자가 php인 파일에 있는 변수나 배열을
템플릿 파일이 가져와야 하기 때문에 이렇게 표현한 것입니다.)

<table>
<tr  
{section name=user loop=$userID}
{if $smarty.section.user.iteration is odd}
       bgcolor=#efefef
{else}
       bgcolor=#ffffff        
{/if}  
>
   <td>    ID = {$userID[user]}  </td>
   <td> Name = {$name[user]}     </td>
   <td> Address = {$address[user]} </td>
</tr>
   {sectionelse}
<tr>
   <td>
       There is no user.
   </td>
</tr>
</section>
</table>

반복자는 스마티를 위한 내부 카운터이다. 그것은 우리에게 섹션의 현제 반복을 알게 해준다. 필자는 만약 현제 반복 변수가 남는지 아닌지 확인으로 인해 테이블에서 다른 열 색깔을 만들기 위해 내부 변수를 사용한다.(뭔 소리를 하는 건지)

LOOPS에 대안은 단일 연관 배열을 반복하기 위해 사용되는 FOREACH이다.

<foreach from=$users item=current_user>
       Name = {$current_user}
<foreachelse}
       No user available.
</foreach>

SECTION과 FOREACH의 중요한 차이는 SECTION은 특정 변수에서 시작할 수 있고, 반복을 위해 스텝을 설정할수 있다. 그에 반해 FOREACH는 모든 변수에 대해 반복할 수 있다.
(뒤에 예제 나오니까 그거 보시면 이해하실수 있을 것입니다.)

프로그래머를 위한 스마티

프로그래머를 위한 장점은 그들은 HTML과 PHP 코드를 분리할 수 있다는 것이다. 좀더 자세히 말하자면, 만약 디자이너가 페이지의 레이아웃을 바꾸면, 프로그래머는 기능적으로 바뀌지 않았다면, 새로운 레이아웃에 적합하게 하기 위해 코드를 바꿀 필요가 없다. 여러분은 여러분의 파일에서 작업하고 화면에 출력되는 모든 변수를 템플릿에 할당하고, 맥주 마시러 나간다.. 디자이너는 레이아웃을 바꾸고 내부적인 에러를 해결하기 위해, 여러분에게 전화 걸고 싶지 않을 것이다.
(쉽게 설명 하자면, 디자이너가 화면 디자인을 살짝 바꾼다음에 프로그래머에게 좀 고쳐달라고 말하지 않아도 됩니다. 여러분이 하는 일은 비즈니스 로직 구현이니까요)

PHP 파일에서 여러분은 스마티 클래스 require ‘Smarty.class.php’를 포함해야 한다.
그리고 $smarty = new Smarty로 인스턴스를 만들어야 합니다.

템플릿에 변수를 할당하기 위해, 여러분은 다음과 같이 해야 한다.
$smarty->assign(‘UserName’, ‘John Doe’).
모두 끝난 다음 여러분은 템플릿 $smarty->display(‘index.tpl)을 보여주기 위해 메소드를 호출한다.

다음과 같은 소스 코드를 보자 (index.php)


<?php
require 'Smarty.class.php';
$smarty = new Smarty;

$smarty->assign('Username', 'John Doe');
$smarty->display('index.tpl');
?>

이런 템플릿(index.tpl)을 보자.


<html>
<body>
       Welcome {$Username}
</body>
</html>

여러분은 역시 PHP에서 템플릿에 그것을 통과하는 배열을 만들수 있다.


$tmp = array ( 'UID'=> '10',  &'Name' => 'John Doe', 'Address'=>'Home address');
$smarty->assign('info', $tmp);

샘플 스크립트 ( 위의 내용은 추상적으로 설명한거고 밑에 내용이 중요합니다.)

이 스크립트는 로컬 데이터베이스에 접속하고 ‘Products’ 테이블에서 모든 제품을 선택(select)한다. 그 때 템플릿에 모든 변수를 통과한다. 그것은 스크린에 그것을 출력한다.


INDEX.PHP

<?php
// 스마티 클래스 파일 포함
require 'Smarty.class.php';
// 스마티 인스턴스 생성
$smarty = new Smarty;
// 디비 설정, 이부분은 각자에 맞게 고치십시오
$hostname = "localhost";
$dbUser = "sqluser";
$dbPass = "sqlpass";
$dbName = "sqldb";
// 데이터베이스에 접속
$conn = mysql_connect($hostname, $dbUser, $dbPass) or die("Cannot connect to the database");
// 디비 선택
mysql_select_db($dbName);
// 질의문 저장
$sql = "SELECT prodID, info FROM products ORDER BY prodID ASC";
// 테이블에서 모든 제품을 선택하라.
$res = mysql_query($sql);
// results를 배열 변수로 선언
$results = array();
$i=0;
while ($r=mysql_fetch_array($res)) {
           $tmp = array(
               'prodID' => $r['prodID'],
               'info'=> $r['info']
           );
           $results[$i++] = $tmp;
}
// 결과를 템플릿에 넘긴다
$smarty->assign('results', $results);
// 템플릿 파일을 로딩load 한다
$smarty->display('index.tpl');
?>


INDEX.TPL

<html>
<body>
Here's a table with the results: <br>
<table cellpadding=1 cellspacing=0 border=0 width=100%>
{section name=nr loop=$results}
   <tr {if $smarty.section.nr.iteration is odd} bgcolor="#efefef"{/if}>
       <td class=fb width=15%>
           <nobr><a href=&#8221;show-product.php?id={$results[nr].prodID}">Press here</a>

       <td class=fb width=29%><a href="show.php?id={$results[nr].prodID}"
       {popup inarray=$smarty.section.nr.iteration}
       >{$results[nr].info}</a></td>
   </tr>

{sectionelse}
<tr><td align="center"><br><b>no product </b> <br> </td></tr>
{/section}
   
</table>

<br>

Here's a select with the results: <br>
<select name="mys">
   {section name=nr loop=$results}
       <option value="{$results[nr].prodID}">{$results[nr].info}</option>
   {/section}
</select>

</body>
</html>


요약

스마티는 디자이너와 개발자 둘 다 에게 멋진 툴이다. 스마티를 사용하면서, 여러분은 사이트 개발과 관리 시간을 줄일 수 있다. 만약 여러분이 개발자라면, 여러분은 더 이상 HTML 코드로 뒤섞인 PHP code가 필요하지 않다. 비즈니스 로직에만 집중하고 디자이너에게 HTML을 떠나라.

번역자에 관하여..
집에서 놀고 있는 백수..

2006/09/08 23:33 2006/09/08 23:33
이 글에는 트랙백을 보낼 수 없습니다
출처 블로그 > What you see is what you get
http://blog.naver.com/etwas0227/60021345880

패턴 문법

패턴 문법 -- PCRE 정규표현식 문법 설명

설명

PCRE 라이브러리는 아주 약간의 차이(아래를 참고)를 제외하고, 펄 5와 동일한 구문과 의미를 사용하여 정규표현식 패턴 매칭을 수행하는 함수의 집합입니다. 현재 수행은 펄 5.005에 대응합니다.

펄과의 차이

여기에서 설명한 차이는 펄 5.005 기준입니다.

  1. PCRE는 다른 문자 집합으로 컴파일할 수 있지만, 기본적으로 공백 문자는 C 라이브러리 함수 isspace()가 인식하는 모든 문자입니다. 보통 isspace()는 스페이스, 폼피드, 줄바꿈, 캐리지 리턴, 수평 탭, 수직 탭을 인식합니다. 펄 5는 공백 문자에 수직 탭을 포함하지 않습니다. 오랜 기간동안 펄 문서의 \v 이스케이프는 사실상 인정되지 않았습니다. 그러나 문자 자체는 적어도 5.002까지 공백으로 취급되었으며, 5.004와 5.005는 \s에서 인식하지 않습니다.

  2. PCRE는 lookahead 단정에서 반복 횟수를 허용하지 않습니다. 펄은 허용하지만, 생각하는 그대로의 의미를 갖지 않습니다. 예를 들어, (?!a){3}는 다음 세 문자가 "a"가 아닌 것을 의미하지 않습니다. 단지, 다음 문자가 "a"가 아니라는 것을 세번 확인할 뿐입니다.

  3. 부정 lookahead 단정 안에서 일어나는 서브패턴 검출을 카운트를 하지만, 시작 위치 벡터에 그 엔트리를 설정하지는 않습니다. 펄은 부정 lookahead 단정이 단 하나의 브랜치를 가지고 있을 경우에 한하여, 그 단정이 매치에 실패(결과적으로 성공)하기 전에 매치한 어떠한 패턴에 대해서만 그에 대한 숫자 변수를 설정합니다.

  4. 바이너리 제로 문자는 목표 문자열에서는 지원하지만, 패턴 문자열에서는 허용하지 않습니다. 패턴은 제로로 종료하는 보통의 C 문자열로 처리하기 때문입니다. 패턴에서 바이너리 제로를 표현하기 위해서는 이스케이프 시퀀스 "\\x00"로 사용할 수 있습니다.

  5. 다음의 펄 이스케이프 시퀀스는 지원하지 않습니다: \l, \u, \L, \U, \E, \Q. 사실, 이들은 펄의 일반 문자열 핸들링이며, 패턴 매칭 엔진의 부분이 아닙니다.

  6. 펄의 \G는 싱글 패턴 매치에 적절하지 않기 때문에 지원하지 않습니다.

  7. 당연하게도, PCRE는 (?{code}) 구조를 지원하지 않습니다.

  8. 패턴의 일부가 반복될 때, 잡아낸 문자열의 설정에 관해서, 펄 5.005_02에서 일부 이상한 동작이 존재합니다. 예를 들어, "aba"에 대해서 패턴 /^(a(b)?)+$/를 매칭하면 $2를 "b" 값으로 설정하지만, "aabbaa"에 대해서 /^(aa(bb)?)+$/를 매칭하면 $2를 설정하지 않습니다. 하지만 패턴을 /^(aa(b(b))?)+$/로 변경하면 $2(와 $3)를 설정합니다. 펄 5.004에서는 $2를 두 경우 모두 설정했으며, PCRE에서도 TRUE입니다. 앞으로 펄이 이 차이를 일관성 있게 변경한다면, PCRE는 그 변경에 따를 것입니다.

  9. 또다른 해결되지 않은 모순점은 펄 5.005_02가 패턴 /^(a)?(?(1)a|b)+$/를 문자열 "a"에 매치하지만, PCRE는 하지 않습니다. 그러나 펄과 PCRE 모두 /^(a)?a/를 "a"에 매치하고 $1을 설정하지 않습니다.

  10. PCRE는 펄 정규표현식 기능의 몇가지 확장을 지원합니다:

    1. lookbehind 단정은 고정 길이 문자열에만 매치해야하지만, 양자 택일의 lookbehind 단정에서는 다른 길이의 문자열을 매치할 수 있습니다. 펄 5.005에서는 모두 같은 길이를 가질 것을 요구합니다.

    2. PCRE_DOLLAR_ENDONLY를 설정하고 PCRE_MULTILINE를 설정하지 않으면 $ 메타 문자는 문자열의 가장 마지막에만 매치합니다.

    3. PCRE_EXTRA를 설정하면, 백슬래쉬 뒤에 특별한 의미를 가지지 않는 문자의 사용은 실패하게 됩니다.

    4. PCRE_UNGREEDY를 설정하면, 반복 수량어의 greediness가 뒤집어져서, 기본값으로 greedy하지 않게 됩니다. 하지만 뒤에 물음표가 붙으면 greedy하게 됩니다.

정규표현식 상세

소개

아래 설명은 PCRE가 지원하는 정규표현식의 문법과 의미입니다. 정규표현식은 펄 문서 및 많은 책들에 설명이 있으며, 그 중 일부에는 풍부한 예제를 가지고 있습니다. O'Reilly에서 출판한 Jeffrey Friedl의 "Mastering Regular Expressions"(ISBN 1-56592-257-3)는 예제들을 매우 자세하게 다루고 있습니다. 여기의 설명은 레퍼런스 문서에 따릅니다.

정규표현식은 주어진 문자열에 대하여 왼쪽에서 오른쪽으로 매치하는 패턴입니다. 문자열은 패턴으로 준비하고, 목표에서 대응하는 문자열에 매치합니다. 간단한 예로, 패턴 The quick brown fox는 목표 문자열의 동일한 부분에 매치합니다.

메타 문자

정규표현식이 강력한 이유는 패턴에 선택과 반복을 포함할 수 있다는 점입니다. 이는 특별한 방법으로 해석하는 메타 문자를 사용하여 패턴에 넣습니다.

메타 문자는 두가지 종류가 존재합니다: 대괄호 안을 제외하고 패턴의 어디에서라도 작동하는 종류와, 대괄호 안에서만 작동하는 종류입니다. 다음은 대괄호 밖에서 사용하는 메타 문자들입니다.

\

여러가지로 사용하는 일반적인 이스케이프 문자

^

목표의 처음 (멀티라인 모드에서는 줄의 처음)

$

목표의 마지막 (멀티라인 모드에서는 줄의 끝)

.

(기본값으로) 줄바꿈을 제외한 아무 문자

[

클래스 정의 시작 문자

]

클래스 정의 끝 문자

|

선택 브랜치 시작

(

서브패턴 시작

)

서브패턴 끝

?

( 의미 확장, 또는 0회나 1회, 또는 수량어 minimizer

*

0회 이상의 횟수

+

1회 이상의 횟수

{

최소/최대 횟수 시작

}

최소/최대 횟수 끝

대괄호 안쪽의 패턴은 "문자 클래스"라고 부릅니다. 다음은 문자 클래스에서 사용하는 메타 문자들입니다:
\

일반적인 이스케이프 문자

^

처음 문자로 올 때, 부정 클래스로 설정

-

문자 범위 지정

]

문자 클래스 종료

다음 섹션은 각 메타 문자의 사용을 설명합니다.

백슬래쉬

백슬래쉬 문자는 여러가지 사용법을 가집니다. 먼저, 뒤에 영숫자가 아닌 문자가 붙는다면, 그 문자가 가지고 있는 특별한 의미가 사라집니다. 이러한 이스케이프 문자로 백슬래쉬를 사용하는 것은 문자 클래스 안과 밖 양쪽에 모두 적용됩니다.

예를 들어, "*" 문자를 매치하길 원한다면, 패턴에는 "\*"로 써야합니다. 이는 따라오는 문자가 메타 문자이던 아니던간에 관계 없이 적용하기 떄문에, 영숫자가 아닌 문자에 그 자체를 사용하기 위해 "\"를 붙이는 것이 항상 안전합니다. 특히, 백슬래쉬를 매치하고자 한다면, "\\"로 써야합니다.

패턴에 PCRE_EXTENDED 옵션을 사용하면, 패턴에 존재하는 (문자 클래스 안이 아닌) 공백, 그리고 문자 클래스 밖의 "#"사이의 문자와 바로 뒤의 줄바꿈 문자를 무시합니다. 이스케이프하는 백슬래쉬를 공백이나 "#"문자를 패턴에 넣기 위해 사용할 수 있습니다.

백슬래쉬의 두번째 사용법은 패턴에서 출력할 수 없는 문자를 보여지게 인코딩하는 방법을 제공합니다. 바이너리 제로가 패턴 종료를 의미하는걸 제외하면, 출력할 수 없는 문자가 나타나는 제한은 존재하지 않습니다. 그러나 패턴을 텍스트 편집으로 준비할 때는, 다음의 이스케이프 시퀀스를 사용하는 편이 바이너리 문자를 직접 표현하는 것보다 간편합니다:

\a

알람, BEL 문자(hex 07)

\cx

"control-x", x는 임의의 문자

\e

이스케이프 (hex 1B)

\f

폼피드 (hex 0C)

\n

줄바꿈 (hex 0A)

\r

캐리지 리턴 (hex 0D)

\t

탭 (hex 09)

\xhh

16진 코드 hh 문자

\ddd

8진 코드 ddd 문자, 혹은 역참조

"\cx"의 효과는 다음과 같이 계산합니다: "x"가 소문자라면, 대문자로 변환합니다. 그 후, 문자의 6번째 비트(hex 40)가 뒤집어집니다. 즉 "\cz"은 hex 1A가 되고, "\c{"은 hex 3B, 그리고 "\c;"은 hex 7B가 됩니다.

"\x" 뒤에, 두개의 16진 숫자를 읽습니다. (대소문자는 구별하지 않습니다)

"\0"은 다음의 두자리의 8진수를 읽습니다. 양쪽 모두, 두자리가 되지 않을 경우, 그 표현을 그대로 사용합니다. 즉 "\0\x\07" 시퀀스는 두개의 바이너리 제로에 이어지는 BEL 문자를 정의합니다. 바로 뒤에 8진수로 인식되는 문자가 이어질 경우에는 처음의 제로 뒤에 두자리 수를 써야한다는 것을 잊지 마십시오.

백슬래쉬 뒤에 0이 아닌 수가 올 경우에 혼동할 수 있습니다. 문자 클래스 밖에서, PCRE는 그것과 따라오는 수를 10진수로 읽습니다. 수가 10보다 작거나, 표현식에서 수 이상의 묶음을 잡아냈다면, 이 시퀀스는 역참조가 됩니다. 이 작동에 관해서는 아래에, 묶음 서브패턴에 설명이 있습니다.

문자 클래스 안이나, 10진수 9 이상이 없고 서브패턴이 그만큼 존재하지 않을 경우, PCRE는 백슬래쉬 뒤의 세자리 8진수로 다시 읽어들여, 해당하는 8비트 값으로 하나의 바이트를 생성합니다. 어떠한 수라도 사용할 수 있습니다. 예를 들면:

\040

스페이스의 다른 표현 방법

\40

40개 미만의 서브 패턴을 검출하였을때, 동일한 의미

\7

항상 역참조

\11

역참조, 혹은 탭의 다른 표현 방법

\011

항상 탭

\0113

문자 "3"이 따라오는 탭

\113

8진 코드 113 문자 (역참조는 99까지입니다)

\377

1비트만을 제외한 바이트

\81

역참조이거나 "8"과 "1"의 두 문자가 붙는 바이너리 제로

100이상의 8진 값은 앞에 제로가 붙지 않아야만 합니다. 세자리를 넘어가는 8진 값은 읽지 않습니다.

하나의 바이트값을 정의하는 모든 시퀀스는 문자 클래스 내외, 어디에서도 사용할 수 있습니다. 추가로, 문자 클래스 안에서 "\b" 시퀀스는 백스페이스 문자(hex 08)로 해석합니다. 문자 클래스 밖에서는 다른 의미를 가집니다. (아래를 참고)

백슬래쉬의 세번째 사용법은 일반적인 문자 타입의 지정입니다:

\d

임의의 10진 숫자

\D

10진 숫자가 아닌 임의의 문자

\s

임의의 공백 문자

\S

공백이 아닌 임의의 문자

\w

임의의 "word" 문자

\W

임의의 "non-word" 문자

각 이스케이프 시퀀스 조합은 완전한 문자 세트를 두개의 개별 세트로 분리합니다. 주어진 문자는 각 조합의 한쪽에만 매치합니다.

"word" 문자는 어떠한 문자나 숫자, 혹은 언더스코어(_)입니다. 즉, 펄의 "word"에 해당하는 어떠한 문자입니다. 문자와 숫자의 정의는 PCRE의 문자 테이블이 제어하고, 로케일 특정 매칭이 존재할 경우에는 다양할 수 있습니다. (위쪽의 "로케일 지원" 참고) 예를 들어, "fr"(프랑스어) 로케일에서는, 128 이상의 몇몇 코드를 엑센트 문자를 나타내는데 사용하며, 이들은 \w에 매치합니다.

문자형 시퀀스는 문자 클래스 안과 밖에서 모두 사용할 수 있습니다. 각각 해당하는 형의 한 문자에 매치합니다. 현재 매칭 위치가 목표 문자열의 마지막이라면, 전부 실패하고, 어떠한 문자도 매치하지 않습니다.

백슬래쉬의 네번째 사용법은 간단한 단정입니다. 단정은 조건이 목표 문자열에서 다른 부분에 매치하지 않고, 특정한 위치에만 매치하도록 지정합니다. 복잡한 단정을 위한 서브패턴의 사용법은 아래에 설명이 있습니다. 백슬래쉬 단정은 다음과 같습니다.

\b

word 경계

\B

word 경계가 아님

\A

목표의 처음 (멀티라인 모드와 무관)

\Z

목표의 마지막이나 마지막에서 줄바꿈 (멀티라인 모드와 무관)

\z

목표의 마지막 (멀티라인 모드와 무관)

단정은 문자 클래스 안에서 사용할 수 없습니다. ("\b"가 문자 클래스 안에서는 백스페이스 문자를 나타내는 점에 주의하십시오)

word 경계는 현재 문자와 이전 문자가 둘 다 \w에 매치하지 않거나 둘 다 \W에 매치하지 않는 (즉, 하나는 \w에 매치하고 다른 하나는 \W에 매치) 목표 문자열의 위치이거나, 처음이나 마지막 문자가 \w에 매치할 경우는 문자열의 처음이나 마지막입니다.

\A, \Z, \z 단정은 전통적인 circumflex와 달러와는 달리 옵션과 관계 없이 목표 문자열의 가장 처음이나 가장 마지막에만 매치합니다. 이들은 PCRE_MULTILINE이나 PCRE_DOLLAR_ENDONLU 옵션에 영향을 받지 않습니다. \Z\z의 차이는, \Z가 문자열의 마지막뿐만 아니라 문자열 마지막 문자가 줄바꿈일 경우에는 바로 앞에도 매치하지만, \z는 마지막에만 매치합니다.





출처: http://www.php.net/manual/kr/pcre.pattern.syntax.php



-------------------------------------------------------------------------------






array preg_grep ( string pattern, array input [, int flags])

preg_grep()은 주어진 pattern에 매치되는 input 배열의 요소를 포함하는 배열을 반환합니다.


EXAMPLE:
$food = array('apple', 'banana', 'squid', 'pear');
$fruits = preg_grep("/squid/", $food, PREG_GREP_INVERT);
echo "Food  "; print_r($food);
echo "Fruit "; print_r($fruits);

RESULTS IN:
Food  Array
(
  [0] => apple
  [1] => banana
  [2] => squid
  [3] => pear
)
Fruit Array
(
  [0] => apple
  [1] => banana
  [3] => pear
)

출처: http://www.php.net/manual/kr/function.preg-grep.php



-------------------------------------------------------------------




preg_match -- 정규표현식 매치를 수행합니다.


예 1. 문자열 "php" 찾기

<?php
// 패턴 구분자 뒤의 "i"는 대소문자를 구별하지 않게 합니다.
if (preg_match("/php/i", "PHP is the web scripting language of choice."
)) {
  echo
"발견하였습니다."
;
} else {
  echo
"발견하지 못했습니다."
;
}
?>

예 2. 단어 "Web" 찾기

<?php
/* 패턴에서 \b는 단어를 지시합니다. 단어 "web"만 매치하고,
* "webbing"이나 "cobweb" 등의 부분적인 경우에는 매치하지 않습니다. */
if (preg_match("/\bweb\b/i", "PHP is the web scripting language of choice."
)) {
  echo
"발견하였습니다."
;
} else {
  echo
"발견하지 못했습니다."
;
}

if (
preg_match("/\bweb\b/i", "PHP is the website scripting language of choice."
)) {
  echo
"발견하였습니다."
;
} else {
  echo
"발견하지 못했습니다."
;
}
?>

예 3. URL에서 도메인 이름 얻기

<?php
// URL에서 호스트 이름 얻기
preg_match("/^(http:\/\/)?([^\/]+)/i"
,
 
"http://www.php.net/index.html", $matches
);
$host = $matches[2
];

// 호스트 이름에서 마지막 두 세그멘트 얻기
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches
);
echo
"도메인 이름은: {$matches[0]}\n"
;
?>

이 예제의 결과:

도메인 이름은: php.net



출처: http://www.php.net/manual/kr/function.preg-match.php



------------------------------------------------------------------------






< 참고 >





-----------------------------------------------------------------------------









1. ereg(string pattern, string string, array [regs])

   해당 문자열에서 주어진 정규 표현식 패턴과의 일치 되는 문자열을 검색합니다.

2. ereg_replace(string pattern, string replacement, string string)

   해당 문자열에서 주어진 정규 표현식 패턴과의 일치 되는 문자열을 검색하고 바꿀 문자열로 대체합니다.


3. eregi(string pattern, string string, array [regs])

   ereg() 함수와 동일하나 검색을 할 때 대, 소 문자를 구분하지 않습니다.


4. eregi_replace(string pattern, string replacement, string string)

   ereg_replace()와 동일하나 검색을 할 때 대, 소 문자를 구분하지 않습니다.

                                                       
5. split(string pattern, string string, int [limit])

   지정한 패턴과 일치하는 문자열을 경계로 해당 문자열을 나누고 배열에 저장합니다.


 
정규 표현식 패턴의 종류

                                                                        

정규 표현식은 주로 게시판의 입력 사항에서 사용 되어 집니다. 가령 비밀번호나 기타 이름 등을 입력할 때

주어진 조건에 맞게 입력하게끔 하는 것입니다.

   " . " - 이 표현은 c.y처럼 표현하기도 하고 .cy로 하기도 합니다.
             즉, 전자는 c로 시작 하면서 y로 끝나는 문자를 나타냅니다.
             (cry , cay , cat) 물론 여기서 . 은 한 문자만을 가리키는 것입니다.
             후자는 문자열이 cy로 끝나는 문자열을 나타냅니다(xcy, xcy). 잘못된 표현은 전자의 경우
             csdy, cfgy , cy입니다. " . " 은 한문자 만을 나타냅니다.

   " ? " - ?앞의 문자가 있거나 없음을 나타냅니다. 즉, sc?y 는 sy , scy , scyf , frsy …와 일치합니다.               

   " + " - +는 앞의 문자를 가리키며 최소 하나 이상의 문자임을 나타냅니다.
             즉, c+ry는 cry, ccry, cccry, cryhj … 와 일치합니다.

   " * " - * 는 앞의 문자가 없거나 하나 이상의 문자임을 나타냅니다.
             즉, c*ry 는 ry, cry, cccry … 과 일치합니다. 또 cry* 는 y가 없거나 하나 이상 문자임을 나타냅니다.
             cr, cry, cry, cryyy …. 와 일치합니다.

   " $ " - $는 해당 문자열의 마지막 부분을 가리킵니다. 즉, c?ry$ 는 ry로 끝나는 문자열에서 앞의 문자가 c가
             있거나 없는 문자열을 나타냅니다.
             cry , ry , skycry …와 일치합니다. c?r+$ 는 앞의 문자 c 가 있거나 없는 문자이며 r로 적어도 하나이상
             끝나는 문자열을 나타냅니다. r , cr , crr , crrr … 와 일치합니다.
                                                                                          
   " ^ " - ^ 는 뒤 문자열로 시작되는 모든 문자열을 나타냅니다.
             즉, ^cry 는 cry is good, cry is very good, crypdf … 와 일치합니다.
             또 ^cry?df는 y가 있거나 없는 crydf , crdf로 시작하는 모든 문자열을 나타냅니다.
             crydf is good, crdfgg …와 일치합니다.


   이렇게 이 기호들은 상호 같이 사용해서 문자열을 표현합니다.

                                                                                               
   " [ ] " - [ ] 는 이 안의 문자 중에 하나의 문자를 표현합니다. 그리고 [ ] 안의 문자의 표현은
            "-" 를 사용해서 합니다.
            즉, [a-z] 는 영문의 소문자 한글자를 포함하는 모든 문자열을 나타냅니다.
            A2sdr , skycry , cry , zzzz …. 와 일치합니다.
            또 [a-zA-Z0-9] 는 영문 대,소문자 와 십진수 한자를 포함하는 모든 문자열을 나타냅니다.
            a4df, Cry44 is passw , 4ded … 등과 일치합니다. 
            [cC][yY] 는 cy , cY , Cy , CY 를 포함하는 문자열을 나타냅니다. Cycap , Cyclub … 등과 일치합니다.
            만약 해당하는 문자를 제외한 문자열과의 일치를 나타내려면 ^기호를 [] 안에 사용합니다.
            [^a-z]는 영문 소문자를 제외한 한글자를 포함하는 문자열을 나타냅니다.
            Cry44, skycryGood, 444 is passw … 와 일치합니다.
            물론 영문 자체의 입력을 하지 못하게 하려면 [^a-zA-Z]로 표현할 수 있습니다.
            [ ] 는 일정한 문자의 표현은 간단하게 표현할 수도 있습니다. 클래스화된 방법을 사용합니다.
            즉, [[:space:]]는 공백 문자를 나타냅니다 ( ) 와 일치합니다.
            [[:digit:]]는 숫자 하나를 나타냅니다. [0-9]와 일치합니다.
            [[:alpha:]]는 영문 알파벳 하나를 나타냅니다. [a-zA-Z] , [a-Z]와 일치합니다.
            [[:alnum:]]는 영문 알파벳 문자와 숫자 중 하나를 나타냅니다. [a-zA-Z0-9]와 일치합니다.

                                                                                                                                                
   " { } " - { }는 {숫자}로 표현하며 중괄호 안의 숫자는 앞의 문자의 개수를 나타냅니다.
            C{4}ry는 C가 ry 앞에 4개 존재하는 문자열을 나타냅니다.
            CCCCry를 나타냅니다. C{4,}ry는 C가 ry 앞에 적어도 4개 이상인 문자열을 나타냅니다.
            CCCCry , CCCCCry , CCCCCCry … 와 일치합니다.
            C{1,4}ry 는 C 가 ry 앞에 1 ~ 4개 존재하는 문자열을 나타냅니다.
            Cry , CCry , CCCry , CCCCry 와 일치합니다.

   " ( ) " - ( ) 는 이 안의 문자를 그룹화합니다.
            sky(cry)* 는 sky 뒤에 cry 가 하나 이상 있거나 없는 문자열을 나타냅니다.
            sky , skycry is good , skycrycrydd …. 와 일치합니다.

   " | " - | 는 OR 연산을 나타내 줍니다.
            sky|cry 는 sky 나 cry 를 나타내는 문자열을 나타냅니다. sky is good , cry is good..와 일치합니다.
            sky(cry|g)* 는 sky 뒤에 cry 나 g 가 없거나 하나 이상 존재하는 문자열을 나타냅니다.
            sky , skycry , sky is good , skygjjh … 등과 일치합니다.

                                      
   특수 기호 패턴에 비교하기 -
            특수 기호 " ^  .  [ ]  $  ( ) |  *  +  ?  { }  \ " 앞에 \를 붙여 표현합니다.
            하지만 [ ] 안에서 특수 기호를 사용할 경우 \를 붙이지 않고 그냥 표현합니다.
            \$+ 는 문자열 앞에 $ 기호가 하나 이상 포함된 문자열을 나타냅니다.
            $cry , $$$sky … 등과 일치합니다.
            [^.[]?*{}/\] 는 문자열 중에 "^" , " ." , " [" , " ]" , "? " , " * " , " { " ,
            " } " , "/ " , "\"문자가 포함된 문자열을 나타냅니다. Hi? , {cry} , … 등과 일치합니다.



출처: http://www.junjaewoo.com/kldp/ApacheMySQLPHP_Guide-KLDP-html/ApacheMySQLPHP_Guide-KLDP-8.html#ss8.1







-------------------------------------------------------------------------------








< 테스트 예제 >

위 내용들을 적용한 테스트 소스~ 문의는 http://blog.naver.com/etwas0227.do 에게루~


<?
  // ex) php 에서 해당 페이지 접속한 client ip 구하기 //
  $ip = $_SERVER['REMOTE_ADDR'];
  $fullhost = gethostbyaddr($ip);
 
  echo ("Client IP : $ip <br>");
  echo ("Fullhost  : $fullhost <br>"); 
  echo ("Server IP : $ServerIP <br><br>");
 
  
  // ex) php 에서 아이피 추출하기 //
  // preg_match 함수적용
  echo ("preg_match - Fullhost Sample : 123.10.101.102 <br>");   
 
  preg_match("/^([^\.]+)+\.([^\.]+)/i", "123.10.101.102", $matches);   //1,2 단계 아이피 추출
  echo ("1,2 단계 아이피 : $matches[0] <br>");  
 
  preg_match("/[^\.\/]+\.[^\.\/]+$/", "123.10.101.102", $matches);   //3,4 단계 아이피 추출
  echo ("3,4 단계 아이피 : $matches[0] <br>");
 
  preg_match("/^([^\.]+)+\.([^\.]+)+\.([^\.]+)/i", "123.10.101.102", $matches);  //1,2,3 단계 아이피 추출
  echo ("1,2,3 단계 아이피 : $matches[0] <br><br>");  //결과 : 123.10.101


  // preg_replace 함수적용
  echo ("preg_replace - Fullhost Sample : 123.10.101.102 <br>");
  $fullhost = "123.10.101.102";
  //$host = preg_replace("/*./", "*.*.", $fullhost);
  //$fullhost = preg_replace("/^[^\.]+\.[^\.]+/", "*", $fullhost);
  $fullhost = preg_replace("/^([^\.]+)+\.([^\.]+)/", "*.*", $fullhost);
  echo ("Fullhost 해당 패턴 변형 : $fullhost <br>");
 
?>


<br>


<?

  // 특정 아이피 접속자만 해당 페이지 보여주기
   $ip = $_SERVER['REMOTE_ADDR'];
   $client_ip = gethostbyaddr($ip);    //사용자 접속아이피
preg_match("/^([^\.]+)+\.([^\.]+)/i", $client_ip, $matches);   //두 단계 아이피를 추출
$match_ip = $matches[0]; 

if ($match_ip == "12.34.56.78") {   //추출한 아이피와 접속가능 아이피 비교
 echo ("Match IP : $matches[0] <br>");  //해당페이지 내용보여줌

else
 exit;   //해당페이지 내용보여주지 않음
?>

<br>

2006/09/08 16:23 2006/09/08 16:23
이 글에는 트랙백을 보낼 수 없습니다
웅쓰:웅자의 상상플러스
웅자의 상상플러스
전체 (379)
게임 (5)
영화 (2)
기타 (23)
맛집 (5)
영어 (2)
대수학 (3)
형태소 (5)
Hacking (9)
Linux (112)
HTML (48)
Application_developing (48)
Web_developing (102)
Window (11)
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
  1. 2016/01 (1)
  2. 2015/12 (3)
  3. 2015/10 (3)
  4. 2015/03 (2)
  5. 2015/01 (4)