php 개발 관련 아주 초보적인 질문입니다.

canuyes의 이미지

안녕하세요.
요즘 php를 공부하는 학생입니다.
보통 홈페이지에 있는 기능들을
하나하나 뜯어서 구현해보는 중에 궁금한 것이 생겨질문 올립니다.

우선 구현하려는 것은 '쿠키를 이용한 카운터' 입니다.
1. 방문자의 수를 visitor.txt에 저장하고,
2. 브라우저를 종료 후 다시 들어올때만 카운트해줍니다.(새로고침 등의 영향을 받지 않습니다.)

예제 수준에서 자주 등장하는 문제이기에 별 걱정 없이 풀었는데, 아래의 부분이 영 이해가 안갑니다.

if(!isset($_COOKIE['IP'] )){          		
	setcookie( "IP", $_SERVER["REMOTE_ADDR"]); 
	$visitor++;	              			         
}

보시다시피 방문자에게 쿠키가 있는지를 확인하는 코드입니다.

전 이코드역시 새로고침을 하면 첫줄부터 다시 실행되서 if state 안이 실행 될 것이라고 생각했습니다.
그런데, 처음부터 실행되는 것이 아닌지 잘 돌아가더군요.(브라우저 종료후 재접속시만 카운트 됨)

반면,

if(!$ip){
        setcookie("ip",$REMOTE_ADDR);
        visitor++;
}

라고 앞서 적은 코드와 별반 다름 없이 작성을 하면 새로고침을 할때마다 카운트가 올라갑니다.

요약하면 질문은 이렇습니다.

1. 상단의 코드가 작동하는 원리가 무었인가요?
-새로고침을 하여도 ip의 값은 유지가 되나요?, ip라는 쿠키는 접속자의 컴퓨터에 생성 되는것인가요?
2. 하단의 코드와 상단의 코드에 차이가 없어 보이는데, 하나는 새로고침에 독립적이고 하나는 종속적인 이유는 무엇인가요?

겸손한 마음으로 답변 기다립니다.
좋은 하루되세요 ^^

peecky의 이미지

1.
새로고침을 하면 첫 줄부터 다시 실행되는게 맞습니다.
setcookie() 함수를 호출하면 그 다음에 접속할 때 부터는 if문의 조건이 거짓이 되므로 $visitor++;가 실행되지 않습니다.

$_SERVER["REMOTE_ADDR"]는 접속자의 컴퓨터의 IP 주소입니다. 유동 IP거나 무선 환경이면 IP가 변할 수도 있습니다.

쿠키가 저장되는 위치는 접속자의 웹 브라우저입니다.

2.
$ip 변수에는 어떤 값이 저장되어 있는지 확인해보셨나요? var_dump($ip); 이런 식으로 변수의 타입과 값을 화면에 출력해볼 수 있습니다.

김정균의 이미지

두 코드간에는 큰 차이가 있습니다. 바로 register_global 이라는 기능인데 GET/POST/COOKIE/PHP server 변수를 어떻게 사용할지에 대한 결정을 하게 됩니다.

예를 들어 php의 경우 get parameter를 PHP에서 사용을 하려면 $_GET 이라는 전역 변수를 사용해야 합니다. 하지만 register_global을 On으로 할 경우 $_GET 대신에 parameter 이름을 그대로 전역 변수로 사용할 수 있습니다. 다음의 예를 보시죠.

URI: /path/file.php?a=4

register_global Off 일 경우

<?php
isset($_GET['a']);  // true
isset($a);          // false
?>

register_global On 일 경우

<?php
isset($_GET['a']);  // true
isset($a);          // true
?>

즉, Post, Get parameter나 cookie 변수를 그냥 사용하기 위해서는 register_global이 On 이어야 하는데, 님의 코드에서 차이가 발생하는 것으로 보아서는 register_global이 off로 되어 있기 때문에 두 코드간의 차이가 발생합니다.

그래서 위의 두 차이를 없애려면 register_global을 On으로 해 놓으면 되는데, 문제는 register_global이 보안상의 이슈로 php 5.3부터는 deprecated 되었고, 5.4 부터는 아예 기능이 없어졌습니다. 그러므로, 쿠키를 사용하기 위해서는 $_COOKIE['ip'] 로 코드를 만드셔야 합니다. 즉 님이 제시하셨던 두번째 방법을 사용하려면, 해당 코드에 아래의 코드가 선행 되어야 합니다.

<?php
$ip = &$_COOKIE['ip'];
if(!$ip){
        setcookie("ip",$REMOTE_ADDR);
        visitor++;
}
?>

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.