WebApp/PHP2010. 10. 21. 01:33
PHP를 통해 폼으로 파일을 업로드하는 방법을 알아보겠다.

폼 작성 방식은 다른 폼과 크게 차이가 없으나 중요한 점이 하나 있다. 다음 코드를 살펴보자.
<form enctype='multipart/form-data' action='test.php' method='post'>
    <p>
        <label>File: </label><input type='file' name='file' /><br />
        <input type='submit' name='upload' />
    </p>
</form>

위 코드에서 가장 중요한 부분은 form태그 바로 옆에 있는 enctype='multipart/form-data'부분이다.
이 부분이 없으면, $_POST 변수로 파일명만 넘어가게 된다.
만약 $_FILES변수가 NULL값이고, $_POST변수에 업로드한 파일명이 나타난다면, enctype 설정이 잘못된 경우이다.
만약 고쳤는데도 불구하고 계속 이러한 현상이 발생한다면, 페이지에 재접속하여 파일을 업로드해보기 바란다.

업로드가 정상적으로 이루어졌다면 print_r()함수를 통해서 다음과 같은 결과를 얻을 수 있다.
Array
(
    [file] => Array
        (
            [name] => test.gif
            [type] => image/gif
            [tmp_name] => /tmp/phpmTiHI4
            [error] => 0
            [size] => 1596
        )
)

이 파일은 tmp_name이라는 경로로 임시 저장이 되는데, 이 파일을 영구저장하기 위해서는 move_uploaded_file()함수를 사용하여 별도의 경로에 저장을 하여야 한다.

$path = $_SERVER['DOCUMENT_ROOT'].$_FILES['file']['name'];
move_uploaded_file($_FILES['file']['tmp_name'], $path);
첫 번째 인수가 임시 파일의 경로, 두 번째 인수가 파일을 영구 저장할 경로이다.

위와 같이 지정하면 사이트 루트에 파일이 저장된다.

'WebApp > PHP' 카테고리의 다른 글

PHP를 이용한 Header 페이지 이동(리다이렉트Redirect)  (0) 2010.08.13
foreach 배열 반복  (0) 2010.08.12
다차원배열의 구성  (0) 2010.06.26
array_merge()  (0) 2010.06.25
Form과 Input 태그로 배열 넘기기  (0) 2010.06.24
Posted by 마이클
WebApp/PHP2010. 8. 13. 15:38
브라우저에 헤더 메시지를 보냄으로써 페이지 이동을 할 수 도 있다.

이 전에 헤더 메시지에 대한 소량의 설명을 하도록 하겠다.
헤더 메시지는 서버와 클라이언트간 본격적으로 송수신하기 전에 있어서 필요한 정보들을 사전에 나누는 것이다.
클라이언트의 브라우저 정보(Firefox, IE 등), 서버의 웹 서버 정보(IIS, Apache 등), 본격적으로 주고받을 데이터의 MIME Type등을 그 내용으로 보낸다.
또한 헤더 메시지로 리다이렉트 정보 또한 전송할 수 있다.
헤더 메시지는 본격적으로 데이터를 주고 받기 전에 보내는 사전 작업이기 때문에 HTML 코드 등의 데이터를 전송한 다음에 헤더 메시지를 보내게 되면 상호간에 오류가 나므로 주의해야 한다.

PHP에서는 header() 함수를 활용하여 헤더 정보를 보낼 수가 있으며, 페이지 이동을 위한 코드는 다음과 같다.
header('Location: http://www.example.com/');
Location을 콜론(:) 이후의 주소로 이동하라는 헤더 메시지이다. 여기에서는 http://www.example.com/이 되겠다.

만약 일정 시간 후에 페이지 이동을 하도록 하려면, sleep() 함수를 이용하면 된다.
sleep(5);
header('Location: http://www.example.com/');
위와 같이 작성하면 5초 후에 페이지 이동이 되지만, 5초 동안 사용자는 공백의 화면을 보고 있어야 한다. 만약 페이지를 이동하기 전에 사용자에게 로딩, 경고 및 안내 화면을 보여주고자 한다면 HTML의 메타 태그를 이용한 방법이나, 자바스크립트를 이용한 페이지 이동 방법을 사용하기 바란다. (포스트 하단에 링크 첨부하였다.)

앞서 말했지만 데이터 전송 전에 보내도록 되어있는 헤더 메시지의 특성 때문에, 페이지를 로드하고 일정 시간 뒤에 다른 페이지로 이동하는 방법은 구현할 수가 없다.(클라이언트가 로드할 데이터가 주어지기도 전에 헤더 메시지가 먼저 주어지기 때문이다.)

---
HTML 페이지 이동(http://studio2b.tistory.com/32)
Javascript 페이지 이동(http://studio2b.tistory.com/33)
PHP를 이용한 Header 페이지 이동(http://studio2b.tistory.com/34)

'WebApp > PHP' 카테고리의 다른 글

Post방식을 통한 파일 업로드File Upload  (0) 2010.10.21
foreach 배열 반복  (0) 2010.08.12
다차원배열의 구성  (0) 2010.06.26
array_merge()  (0) 2010.06.25
Form과 Input 태그로 배열 넘기기  (0) 2010.06.24
Posted by 마이클
WebApp/PHP2010. 6. 26. 02:15
데이터베이스를 통해 자료를 사용하다보면, 어떠한 방식으로 자료를 배열에 저장해야 좋을까 고민하게 된다.
데이터베이스를 다루는 프로그램의 진행 구조를 살펴보면, 이러한 고민에 부딪치는 까닭을 알 수 있다.

프로그램은 사용자의 요구에 따라(Input) 데이터베이스에 있는 정보를 꺼내어 배열에 저장하고(Process)
그 값을 화면 구성에 알맞게 적절하게 뿌리도록 프로그램을 작성한다.(Output)

우리는 처리Process 절차 - 데이터베이스에 있는 정보를 변수에 저장하는 단계를 위해서 이를 고민하고 있는 것이다. 그렇다면, 배열 구성 방식에 관한 문제는 어떠한 방법이 출력Output 단계에서 효율적인지만을 확인하면 되는 것이다.

게시판 프로그램을 작성한다는 가정 하에 이 문제를 풀어보도록 하자.
현재 나타나고 있는 게시판은 다음과 같다.
 제목 내용  작성자 
 php입문 php는 <?php로 시작해서 ?>로 끝납니다. php.net
 html입문 html은 <html>로 시작해서 </html>로 끝납니다. w3c.org

이 게시판의 HTML코드는 다음과 같다.
<table>
<tr>
<th>제목</th>
<th>내용</th>
<th>작성자</th>
</tr>
<tr>
<td>php입문</td>
<td>php는 &lt;?php로 시작해서 ?&gt;로 끝납니다.</td>
<td>php.net</td>
</tr>
<tr>
<td>html입문</td>
<td>html은 &lt;html&gt;로 시작해서 &lt;/html&gt;로 끝납니다.</td>
<td>w3c.org</td>
</tr>
</table>
또한 SQL 테이블 구조는 다음과 같다 .
table : `board`
columns: `subject`, `description`, `author`

다음은 위의 내용을 담기 위한 제 1의 배열 방법이다. 위의 표에서 가로축에 해당하는 것을 1차 배열로 놓는 경우이다.
$board => Array
(
[subject] => Array
(
[0] => php입문
[1] => html입문
)
[description] => Array
(
[0] => php는 <?php로 시작해서 ?>로 끝납니다.
[1] => html은 <html>로 시작해서 </html>로 끝납니다.
)
[author] => Array
(
[0] => php.net
[1] => w3c.org
)
)

제 2의 방법은 다음과 같다. 위의 표에서 세로축에 해당되는 것을 1차 배열로 놓는 경우이다.
$board => Array
(
[0] => Array
(
[subject] => php입문
[description] => php는 <?php로 시작해서 ?>로 끝납니다.
[author] => php.net
)
[1] => Array
(
[subject] => html입문
[description] => phtml은 <html>로 시작해서 </html>로 끝납니다.
[author] => w3c.org
)
)

어느것이 효율적인 저장방법일까? 다음의 예제들을 통해서 확인해보자.

첫째는 위의 배열들을 게시물에 뿌리는 방법이다.
제1의 방법을 통한 예제를 먼저 보겠다.
echo "<table>";
echo "<tr>";
echo "<th>제목</th>";
echo "<th>내용</th>";
echo "<th>작성자</th>";
echo "</tr>";
$counter = count($board[subject]);
for($i=0; $i<$counter; $i++) {
echo "<tr>";
echo "<td>".$board[subject][$i]."</td>";
echo "<td>".$board[description][$i]."</td>";
echo "<td>".$board[author][$i]."</td>";
echo "</tr>";
}
echo "</table>";
코드를 보면, 일단 for 반복문의 반복 횟수를 결정하는 문제부터 막힌다.
위에서 제시한 표만 처리하는 코드이기 때문에 여기서는 카운터 횟수를 쉽게 결정했지만,
좀더 유연한 코드를 작성하고자 한다면 처리하기가 매우 어려울 것이다.
한 가지 예를 들자면 다음처럼 몇몇 값이 비어있는 채로 넘어오는 경우이다.
$board => Array
(
[subject] => Array
(
[1] => html입문
)
[description] => Array
(
[0] => php는 <?php로 시작해서 ?>로 끝납니다.
)
[author] => Array
(
[0] => php.net
[1] => w3c.org
)
)
위와 같은 경우는 우리가 원하는 결과를 얻지 못하게 되는 것이다.

그렇다면, 제2의 방법은 어떠할까?
echo "<table>";
echo "<tr>";
echo "<th>제목</th>";
echo "<th>내용</th>";
echo "<th>작성자</th>";
echo "</tr>";
foreach($board as $value) {
echo "<tr>";
echo "<td>".$value[subject]."</td>";
echo "<td>".$value[description]."</td>";
echo "<td>".$value[author]."</td>";
echo "</tr>";
}
echo "</table>";
눈에 띄게 차이가 나지는 않지만, 위의 코드보다 더 간단하다.
반복문의 반복 횟수를 결정하기 위해 고민할 필요도 없이 foreach문만으로도 작성이 가능하다.
또한 제1의 방법과 달리 아래처럼 몇몇 요소가 빠지더라도 반복 횟수에는 문제가 없다.
$board => Array
(
[0] => Array
(
[description] => php는 <?php로 시작해서 ?>로 끝납니다.
[author] => php.net
)
[1] => Array
(
[subject] => html입문
[author] => w3c.org
)
)
얻을 수 있는 것은 이것 뿐만이 아니다. 안의 변수구성도 간단해졌다.
변수에 $i같은 군더더기 요소가 사라짐으로써, 바이트를 좀 더 줄였다.
PHP와 같은 스크립트 프로그램의 경우에는 파일의 용량이 줄어들수록 처리 엔진의 부하가 줄어들기 때문에 더 효과적이다.

둘째는 데이터베이스에서 자료를 꺼내는 것이 아니라 저장하는 경우이다.
제1의 방법을 보자.(execute_query() 함수에 관련해서는 본 블로그에서 검색해보기 바란다.)
$counter = count($board[subject]);
for($i=0; $i<$counter; $i++) {
unset($keys, $values);
foreach($board as $key => $value) {
if($keys==NULL) {
$keys = "`".$key."`";
$values = "'".$value[$i]."'";
} else {
$keys .= ",`".$key."`";
$values .= ",'".$value[$i]."'";
}
}
$query = "INSERT INTO `board` ($keys) VALUES ($values)";
$result = execute_query($query);
}
앞서 말했던 반복 횟수에 대한 비효율이 계속 나타난다.
또 한 가지 주목해야 할 사항은 NULL값에 대한 비효율문제이다.
만약 배열의 값이 다음과 같이 구성이 되어 있다고 하자.
$board => Array
(
[subject] => Array
(
[1] => html입문
)
[description] => Array
(
[0] => php는 <?php로 시작해서 ?>로 끝납니다.
)
[author] => Array
(
[0] => php.net
[1] => w3c.org
)
)
위의 코드와 같은 경우는 다음과 같은 쿼리문을 만들어낼 것이다.
INSERT INTO `board` (`subject`, `description`, `author`) VALUES ('', 'php는 <?php로 시작해서 ?>로 끝납니다.', 'php.net')
INSERT INTO `board` (`subject`, `description`, `author`) VALUES ('html입문', '', 'w3c.org')
이와 같은 쿼리문은 쓸데 없이 NULL값을 데이터베이스에 입력하게 된다.
이에 대한 유일한 대안인 제2의 방법을 살펴보자.
foreach($board as $item) {
unset($keys, $values);
foreach($item as $key => $value) {
if($keys==NULL) {
$keys = "`".$key."`";
$values = "'".$value."'";
} else {
$keys .= ",`".$key."`";
$values .= ",'".$value."'";
}
}
$query = "INSERT INTO `board` ($keys) VALUES ($values)";
$result = execute_query($query);
}
코드는 $i가 빠졌다거나 하는 소소한 차이일 뿐 거의 달라진 것이 없다.
하지만 한 가지 분명한 것은 NULL값 입력과 같은 비효율적 현상은 나타나지 않는다.
만약 배열의 구성이 다음과 같다고 하자.
$board => Array
(
[0] => Array
(
[description] => php는 <?php로 시작해서 ?>로 끝납니다.
[author] => php.net
)
[1] => Array
(
[subject] => html입문
[author] => w3c.org
)
)
이러한 경우 이 코드는 다음과 같은 쿼리문을 만들어 낸다.
INSERT INTO `board` (`description`, `author`) VALUES ('php는 <?php로 시작해서 ?>로 끝납니다.','php.net')
INSERT INTO `board` (`subject`, `author`) VALUES ('html입문','w3c.org')
군더더기 없이 깔끔한 모습이다.

지금까지 더 효율적인 다차원 배열 구성을 찾기 위해 몇 가지 예를 살펴보았다.
for 루프문의 구성이나 그것을 통한 출력물에 있어서, $변수[항목][숫자]의 형태보다 $변수[숫자][항목] 형태의 구성이 더 효율적임을 입증하였다.
앞으로 이러한 배열 형태를 기반으로 하는 많은 알고리즘들을 생겨났으면 한다.
Posted by 마이클
WebApp/PHP2010. 6. 25. 16:08
PHP에는 배열을 합칠 수 있는 array_merge()함수가 있다.
인자는 두 개의 배열로써 호출할 때는 다음과 같이 호출한다.
$array = array_merge($array1, $array2);

$array1에 $array2에 내용을 끼워 넣어 결과 값을 리턴한다.
그렇기 때문에, 다음 코드를 실행하게 되면
$array[0] = array(1, 2, 3);
$array[1] = array("a", "b", "c");
for($i=0; $i<count($array); $i++) {
$return = array_merge($array[$i], $return);
}
print_r($return);

$array[1]에 $array[0]을 끼워넣는 것이 되므로, 다음과 같이 아래 위가 뒤집힌 값이 나타난다.
Array
(
[0] => a
[1] => b
[2] => c
[3] => 1
[4] => 2
[5] => 3
)
이를 바로잡기 위해서는 함수 인자들의 위치를 신경 써주어야 하겠다.

또한, array_merge함수의 다른 한 가지 특징은 해당 숫자 배열이 존재하는 경우 그 배열명을 피해서 저장한다는 점에 있다.
눈치가 빠른 사람들은 위의 예제에서 눈치 챘겠지만, 위의 예제에서 사용한 배열 두 개의 값은 다음과 같다.
Array
(
[0] => 1
[1] => 2
[2] => 3
)
Array
{
[0] => a
[1] => b
[2] => c
)
이렇게 중복되는 배열명이 존재하는 경우 그것을 자동적으로 피해서 저장하는 것이다.

하지만 문자 배열의 경우에는 신경을 쓸 필요가 있다. 다음 예제를 살펴보자.
$array1 = array("id" => "identification");
$array2 = array("id" => "i.d.");
$result = array_merge($array1, $array2);
print_r($result);
이것을 실행하게 되면 다음과 같은 결과 값이 나타난다.
Array
(
[id] => Array
(
[0] => identification
[1] => i.d.
)
)
배열이 아니었던 배열명 id의 값을 배열로 저장하고 있는 것이다.

array_merge는 다차원배열도 물론 지원한다.
$array1 = array("member" => array("id"=>"identification"));
$array2 = array("member" => array("pw" => "password"));
$result = array_merge($array1, $array2);
print_r($result);
위의 코드를 실행시키면 , 다음과 같은 결과 값이 나타난다.
Array
(
[member] => Array
(
[id] => identification
[pw] => password
)
)

하지만 1차 배열명이 숫자인 경우에는 문제가 좀 달라진다.
$array1 = array(array("id"=>"identification"));
$array2 = array(array("pw" => "password"));
$result = array_merge($array1, $array2);
print_r($result);
혹시 다음과 같은 결과 값을 예상하고 있지는 않은가?
Array
(
[0] => Array
(
[id] => identification
[pw] => password
)
)
하지만 array_merge()함수는 이처럼 작동하지 않는다.
해당 배열명이 숫자 그리고 그 배열명에 해당하는 값이 NULL이 아닌경우,
NULL값인 숫자 배열명이 나타날때까지 찾아서 그곳에 값을 입력한다.
위의 코드를 통해 말하자면, 현재 [0]은 NULL이 아니므로, 다음 숫자 배열명인 [1]에 값을 저장하게 되는 것이다.
그러므로 위 코드의 결과 값은 다음과 같이 나타난다.
Array
(
[0] => Array
(
[id] = identification
)
[1] => Array
(
[pw] = password
)
)

문자 배열이나 숫자 배열이나 일관된 방법으로 배열을 저장하는 함수를 개발 중이므로,
개발이 완료되면 공개하도록 하겠다.

'WebApp > PHP' 카테고리의 다른 글

foreach 배열 반복  (0) 2010.08.12
다차원배열의 구성  (0) 2010.06.26
Form과 Input 태그로 배열 넘기기  (0) 2010.06.24
파일 경로 숨긴 채로 전송 및 다운로드하기  (0) 2010.06.07
파일 읽기 함수  (0) 2010.05.30
Posted by 마이클
WebApp/PHP2010. 6. 24. 01:08
form과 input 태그를 통해서 배열을 넘기는 것을 의외로 간단하다.
input 태그에 있는 name 속성에 변수명 및 대괄호[]를 이용해서 작성한다.
다음 예제를 통해서 확인하자.
<form action='http://www.example.com/' method='post'>
<p>
<label>array[0]</label>
<input type='text' name='array[]' value='hello' />
<br />
<label>array[1]</label>
<input type='text' name='array[]' value='world' />
<br />
<label>array[2]</label>
<input type='text' name='array[]' value='!' />
<br />
<input type='submit' value='Submit' />
</p>
</form>

위의 예제를 통해서 값을 전송하게 되면, PHP와 같은 경우 위의 값을 다음 코드를 통해 출력할 수 있다.
print_r($array);
또는
print_r($_POST['array']);
의 두 가지 방법 모두 가능하다. 하지만 Form태그의 Method 값이 GET인 경우는 배열을 넘길 수가 없으니 $_GET은 무용지물임을 명심하기 바란다.

상단 코드의 실행 값은 다음과 같다,
Array ( [0] => hello [1] => world [2] => ! )

숫자를 이용한 자동 배열 뿐만 아니라 문자로 지정한 배열명도 사용이 가능하다.
<form action='http://www.example.com' method=''>
<p>
<label>Identification</label>
<input type='text' name='user[id]' value='hello' />
<br />
<label>Password</label>
<input type='password' name='user[pw]' value='world' />
<br />
<input type='submit' name='Sign-in' />
</p>
</form>
위와 같이 제출 폼을 작성하면 print_r함수로 다음과 같은 값을 얻을 수 있다.
Array ( [user] => Array ( [id] => hello [pw] => world ) )

'WebApp > PHP' 카테고리의 다른 글

다차원배열의 구성  (0) 2010.06.26
array_merge()  (0) 2010.06.25
파일 경로 숨긴 채로 전송 및 다운로드하기  (0) 2010.06.07
파일 읽기 함수  (0) 2010.05.30
PHP 자바스크립트 경고 함수  (0) 2010.05.30
Posted by 마이클
WebApp/PHP2010. 5. 30. 13:29
function load_file ($filepath) {
$data = implode("", file($filepath));

return $data;
}

파일의 내용을 리턴합니다.

Implode와 file함수를 엮어쓰기 귀찮은 분들을 위한 최적의 함수

'WebApp > PHP' 카테고리의 다른 글

다차원배열의 구성  (0) 2010.06.26
array_merge()  (0) 2010.06.25
Form과 Input 태그로 배열 넘기기  (0) 2010.06.24
파일 경로 숨긴 채로 전송 및 다운로드하기  (0) 2010.06.07
PHP 자바스크립트 경고 함수  (0) 2010.05.30
Posted by 마이클
WebApp/PHP2010. 5. 30. 12:58
function alert($message) {
echo "<script type='text/javascript'>\n";
echo "<!--\n";
    echo "alert('$message');\n";
    echo "// -->\n";
echo "</script>\n";
return 0;
}

자바스크립트 경고 창으로 메시지를 띄우는 함수입니다.

'WebApp > PHP' 카테고리의 다른 글

다차원배열의 구성  (0) 2010.06.26
array_merge()  (0) 2010.06.25
Form과 Input 태그로 배열 넘기기  (0) 2010.06.24
파일 경로 숨긴 채로 전송 및 다운로드하기  (0) 2010.06.07
파일 읽기 함수  (0) 2010.05.30
Posted by 마이클