뭐, 그다지 훌륭한 내용 아닙니다. 그러니 그냥 대충 읽어보고 가시면 됩니다.
행복한고니님께서 댓글로 몇가지 조언을 주셨습니다. 조언에 따라,, 내용을 일부 수정했습니다.
내용 정말 별내용 아니니,, 그냥 편하게 읽고가세요 ^^
// 팁 1 -------------------------------------------------------------------- // function_exists 와 eval 을 이용한 능동적인 코딩지향,
function_exists() : 해당 함수가 존재하는지 확인하는 함수. eval() : 문자열을 코딩소스로 바꾸어 파싱하는 함수. ( 아래 예제에서는 eval 함수는 사용하지 않아도 된다고 합니다. ) ( 방금 태스트 해본결과 함수호출은 정말 eval 함수를 사용하지 않아도 되네요 ^^ )
아무튼~~ 코딩된 문서를 혼자 사용할것이라면 정형화시켜서 코딩해도 문제가 안될겁니다만, 어느정도는 능동적으로 코딩을 해 두는게 나중을 위해서 혹은 다른환경에서 같은 코딩소스를 돌릴때를 위해 처음부터 이식성좋게 코딩하는 것이 좋은방법일겁니다.
gd 관련함수를 보겠습니다.
이미지를 불러서 썸네일을 만들어 저장하려고 한다면
jpeg 파일인 경우는 ImageCreatefromjpeg() 함수로 읽어서.. Imagejpeg() 함수로 출력해야겠지요..
혹은 Gif 파일이라면 ImageCreatefromgif() 함수로 읽어서.. Imagegif() 함수로 출력해야겠지요..
혹은 Png 파일이라면 ImageCreatefrompng() 함수로 읽어서.. Imagepng() 함수로 출력해야겠지요..
위내용을 대충.. 소스로 표현하면 아래처럼 될겁니다. <? $file = 파일이름; $ext = 확장자;
siwth( $ext ) { case 'gif': $source = ImageCreatefromgif( $file ); break; case 'jpeg': $source = ImageCreatefromjpeg( $file ); break; case 'png': break; $source = ImageCreatefrompng( $file ); }
$thumb = 기타 줄이기 작업;
siwth( $ext ) { case 'gif': $source = Imagegif( $thumb ); break; case 'jpeg': $source = Imagejpeg( $thumb ); break; case 'png': $source = Imagepng( $thumb ); break; default : echo "지원되지 않는 포멧입니다"; } ?>
물론 가독성은 좋습니다. 그리고 퍼포먼스차원으로도 위 처럼 하는것이 좋습니다만...
이미지 파일이 gif, jpeg, png 3종류만 있는건 아니죠.. gif, jpeg, png, psd, bmp, tiff, jpc, jp2, jpx, jb2, wbmp, xbm 등등.. 많은 종류의 이미지 파일이 있을 수 있고,
gd 나 php 가 버전업이 되면서 아직은 지원이 되지않는 ImageCreatefromtiff() 같은 함수가 생길 수도 있을겁니다.
그때 되서 다시 소스코딩을 추가하거나 고치는것도 좋겠지만, 처음부터 능동적으로 동작이 될 수 있도록 아래처럼 코딩하는 것도 좋은 방법이라 할 수 있습니다. ( 완벽하진 않겠지만, 그리고 오동작의 소지도 염두해 두어야 겠지만 )
<? $file = 파일이름; $ext = 확장자;
if( function_exists( "ImageCreatefrom$ext" ) ) {
$Func = 'ImageCreatefrom' . $ext; $source = $Func('$file'); // eval() $thumb = 기타 줄이기 작업; $Func = 'Imagegif' . $ext; $Func( $thumb ); } else { echo "지원되지 않는 포멧입니다"; } ?>
어떤가요 ? 가독성은 좀 떨어질수 있겠지만, 오히려 소스는 짧아지고 꽤나 능동적인 함수가 만들어 졌습니다.
속도요 ? 당연히 조금 느려집니다만, 함수명 파서하는 시간이 잠깐 걸리는것 뿐이고 전체적인 속도는 지장이 없습니다.
이유는 함수명 파서시간이 문제가 아니라 이미지 데이타 로딩시간이 어차피 수백 ~ 수천배 느리기 때문이죠~
이처럼, function_exists를 적극 ? 활용하면 gd 관련뿐 아니라 다른 부분의 많은 코딩에서도 꽤 융통성있는 동적 코딩이 이루어 진다고 생각하고 있습니다.
// 팁 2 -------------------------------------------------------------------- // 문자열 구분자는 특수문자로..
배열값을 조립하고 풀어낼때 사용하는 예를 들어봅니다. <? $res = emplode( "|", 배열 ); ... $배열 = explode( "|", $res ); ?>
explode, implode 함수는 배열에서 거의 필수로 사용하는 함수들이죠..
보통 구분자로 많이 사용하는문자는 |, @, ~ 등등을 사용할겁니다만,, 만약에 배열값 자체에 '구분자'의 문자가 석여있다면 오작동을 하게 됩니다.
가령, <? $test[] = '123'; $test[] = '4|56';
$res = emplode( "|", $test ); ... $test = explode( "|", $res ); ?>
위처럼 작성된 소스는 오작동을 일으키게 됩니다.
그래서, 저는 문자열의 구분자는 '키보드로칠 수 없는' 특수문자를 사용합니다.
이런식이죠. <? $_TAB = "x1b";
$res = emplode( $_TAB, 배열 ); ... $배열 = explode( $_TAB, $res ); ?>
참고로 x1b 문자는 아스키값 27인, 키보드의 'ESC'문자에 해당합니다. 'ESC'문자는 문서에 입력할 수 없는 문자가 됩니다.
혹은, 바운더리 개념으로 아래처럼 해도 되겠구요.. <? $_TAB = "아무거나중복안되는긴문자열";
$res = emplode( $_TAB, 배열 ); ... $배열 = explode( $_TAB, $res ); ?>
물론 처음처럼 그냥 |, @ 등을 구문자로 사용하는것도 좋습니다. 하지만, 만에 하나 우연히 구문자로 사용한 문자가 value 로 사용되어 오동작을 읽으키게 된다면
디버그할때 고생꽤나 할 수도 있습니다.
처음부터 어떤 value 가 넘어오더라도 구분자와 value가 석이지 않도록 구분자를 unique 하게 만드는 습관이 좋을듯 합니다.
// 팁 3 -------------------------------------------------------------------- // 전역변수 선언시 변수 이름은 규칙있게..
<? $a = 10; $c;
function() { global $a, $c; $b = 20; $c = ( $a * $b ); } ?>
위처럼 전역변수를 선언할때는 가급적 규칙성있는 이름이 필요합니다. 소스동작에는 전혀 문제가 없겠지만, 나중에 가독성을 생각해야 합니다.
전역변수를 몇가지 특성으로 구분해서
가령, '전역상수', '전역변수' 로 구분을 하여 변수이름에 규칙을 둡니다. 보통은 대문자와 '_'언더바를 많이 사용합니다.
<? $_A_ = 10; $_C;
function() { global $_A_, $_C; $b = 20; $_C = ( $_A_ * $b ); } ?>
위와같이 변수명지정에 대문자와 언더바 구분을 두면 ? 그리고 나중에 소스가 비대해지고 복잡해졌을 경우 아래같은 소스를 보면..
<? .........
if( $_INCLUDE_ME == 'ok' ) $buff = 'php_date1';
$_COMMON = $newFunc;
switch( $arc ) { case $_DEF_A01_ : .... case $_DEF_A02_ : .... } ?>
소스를 부분적으로만 봐도 어느게 전역변수인지 어느게 전역상수인지 알게됩니다. 가독성 높은 코딩습관이 중요하다고 할 수 있습니다.
// 팁 4 -------------------------------------------------------------------- // form 객체 이름을 정의할 때..
( 태그속성 예시에서 따옴표가 없었습니다. 따옴표 추가로 고칩니다.. )
흔히 게시판보드 코딩중에 document 부분을 아래처럼 하겠죠...
<form name='board' .. > <input type='text' name='subject' value=''> <input type='text' name='memo' value=''> ... </form>
<? if( !$subject ) .... if( !$memo ) .... ?>
문제는,, 위에서 사용한 폼객체의 이름을 subject, memo 등을 사용하였는데. 다른문서에서도 너무 흔하게 사용될 수 있는 이름이죠..
include 된 다른문서에서 중복으로 사용될 소지가 많습니다.
그래서 중복되지 않고 ( 중복될 가능성이 적고 ) 이해하기 쉬운 방법으로 객체이름을 생성합니다.
배열객체를 이용하면 쉽게 해결됩니다.
<form name='board' .. > <input type='text' name='MYBOARD[subject]' value=''> <input type='text' name='MYBOARD[memo]' value=''> ... </form>
<? extract( $MYBOARD );
if( !$subject ) .... if( !$memo ) .... ?>
위처럼 해 두는게 실수를 막아줄수 있는 방법이라 하겠습니다.
// 팁 5 -------------------------------------------------------------------- // 파라메터에 포인트지시자 '&' 의 사용
( 레퍼런스 관련설명에서 오류가 좀 있었습니다. ) ( 예제코드와 설명을 다소 고쳤습니다 )
예제1 <? $str = 'ABCDEFG';
fonction chg( $str ) { $str{0} = 'a'; return $str; } echo chg( $str ); ?>
예제2 <? $str = 'ABCDEFG';
fonction chg( &$str ) { $str{0} = 'a'; return $str; } echo chg( $str ); ?>
함수에서 $str의 전달자(파라메터)를 예제1은 그냥 보통으로 지정했고, 예제2에서는 포인터를 지정했습니다.
위 두가지 예제에서 틀린점이 무엇일까요 ?
무엇이 틀려질까요 ?
함수에 일반적인 방법으로 파라메터로 어느 변수를 주어주면 메모리의 DS( data Segment ) 에 전달받은 변수의 값을 복사하는 과정이 생깁니다. ( 데이터가 수정이 이루어 지지 않으면 DS 생성이 안되고 참조만 한다는 ... 그건.. 제가 잘 모르겠습니다. 암튼, 위 예제처럼 데이타에 수정을 가하는 경우라면 DS 를 복사하게 됩니다. )
결국,
원래의 $str = '1234567890'; 외에도
함수 CS( Code Segment ) 에 의해 함수가 전용으로 사용할 또하나의 DS 를 만들게 됩니다.
예제 1에서의 방법을 표현을 해보면 이런식이 됩니다.
<? $str = 'ABCDEFG';
fonction chg( $str ) { // 자체적으로 또하나의 (복사본) DS 생성 : $str = 'ABCDEFG'; $str{0} = 'a'; //생성된DS의$str값에서작업 return $str }
echo chg( $str ); ?>
즉, 원래의 전역변수인 $str = 'ABCDEFG'; 외에 함수 속에서 또하나의 $str = 'ABCDEFG'; 변수를 만든 후 $str = 'aBCDEFG'; 로 바꾸어서 리턴시키게 됩니다.
$str 변수가 지시하는 DS 값을 함수에서 사용하기위해 하나 더 복사를 한 것입니다.
예제 2에서의 방법은 아래와 같습니다. <? $str = 'ABCDEFG';
fonction chg( &$str ) { $str{0} = 'a'; //원래의$str값에서작업 ); }
echo chg( $str ); ?>
이 방법에서는 $str 데이터를 복사하지 않았습니다. 원래의 전역변수 그자리에서 $str = 'aBCDEFG'; 로 값을 바꾸었습니다. 물론 이런 경우에는 return문 자체가 의미가 없습니다. 아래처럼 해도 원래의 전역변수인 $str 값이 원하는데로 바뀝니다. <? $str = 'ABCDEFG';
fonction chg( &$str ) { $str{0} = 'a'; }
chg( $str ); echo $str; ?>
이런것들의 차이점이 무엇일까요 ?
그것은 바로 메모리 리소스에 있습니다.
예제1 에서는 함수가 호출되는 동시 또하나의 데이터가 메모리에 복사되어야 하기때문에 데이터가 크다면 메모리 DS영역을 그많큼 많이 차지하게 됩니다.
속도차이를 검사하려고 루프테스트를 했는데..
호출된 함수속에서 어떤 작업을 하느냐에 따라, 그리고 데이터의 크기에 따라, 서로 상이한 결과가 나서... 어떤조건이 빨라지는 조건인지 잘 못찾았습니다. 속도태스트는 검증된 내용이 나오면 다시 알려드리겠습니다
암튼, 속도를 개의치 않는다면, 파라메터를 포인터로 주고 받는것이 메모리 리소스 확보차원에서는 훨씬 좋다고 말할 수 있습니다.
//-------------------------------------------------------------------- // 이상이구요,
그다지 팁이라고 할수도 없는내용을 적었습니다 ^^
그냥 참고만 하시고, 제가 틀리게 설명한 부분이 있을수도 있으니 절대적으로 믿지는 마시기 바랍니다 ~~
|