홈으로 홈으로 | 무료회원가입 | 아이디/비번찾기 | 즐겨찾기
추천음악방송메인홈1대1상담음악방송청취
뽕짝아가씨(무료음악채널)
okTrot(무료음악채널)
전통가요(무료음악채널)

온라이브스토어(앱다운로드)
온라이브(방송등록및청취)

환상의뽕짝파티 무료음악
명작트로트메들리 무료음악
트로트메들리관광 무료음악
동영상노래방
가사검색

POP Player
신나는 고스톱
컴퓨터 오목
작은 음악다방
자동러시 웹플레이어신청

보안∵서버∵쿠키
윈도우∵프레임
이미지∵배경
시간∵달력∵계산
상태바∵타이틀바
음악∵영상
폼∵전송∵테이블
키보드∵마우스
효과∵링크∵메뉴
Script∵php
기타
PHP 강좌
윈도우관련팁
웹관련팁
홈페이지제작팁
기본강좌
레지스트리
윈도우서버
리눅스서버
Android
php로 웹상의 파일 읽기(html 소스 읽기)
5년 전
이 글은 http://www.php-mysql-tutorial.com/wikis/php-tutorial/reading-a-remote-file-using-php.aspx  에 있는 글을 번역한 것입니다

——————————————————–

php로 웹상(원격)에 있는 파일을 읽는 방법으로는 아래의 4가지가 가능하다

1. fopen() 함수 사용

2. file_get_contents() 함수 사용

3. CURL

4. php 소켓 함수를 활용하여 직접 가져오는 법



1번과 2번 방법을 사용하기 위해서는 fopen wrapper 가 사용가능해야한다. 이 fopen wrapper 파라미터는 php.ini에 정의되어 있으나, ini_set()을 사용해서 실행시간에 바꿀수는 없다.

이 두 방법을 쓸수 있는지의 여부는 아래 코드로 확인할수 있다
if (ini_get('allow_url_fopen') == '1') {
   // fopen() 이나 file_get_contents() 사용
} else {
   // curl 이나 함수 직접 작성
}


1. fopen() 함수 사용

fopen()을 사용하는 법은 local 파일을 읽는것 만큼 쉽다. 유일하게 다른점은 fopen()함수 내에 파일명 대신 URL을 적는다는 것이다

아래 예제를 보자
// 원격 파일을 사용하기 전에 성공적으로 open 되었는지 확인
if ($fp = fopen('http://www.google.com/', 'r')) {
   $content = '';
   // 전부 읽을때까지 계속 읽음
   while ($line = fread($fp, 1024)) {
      $content .= $line;
   }

   // content 사용
   // ...
} else {
   // 파일 open시 에러 발생
}

위 코드중 while 반복문의 fread() 함수는 한 루프 안에서 1024 바이트의 데이터를 읽기 위해 사용된다. 이 코드는 아래와 같이 쓸수도 있다
// 원격 파일을 사용하기 전에 성공적으로 open 되었는지 확인
if ($fp = fopen('http://www.google.com/', 'r')) {
   $content = '';
   // 전부 읽을때까지 계속 읽음
   while ($line = fgets($fp, 1024)) {
      $content .= $line;
   }

   // content 사용
   // ...
} else {
   // 파일 open시 에러 발생
}

fread() 대신에 최대 1024바이트의 라인 한줄을 읽는 fgets()를 사용했다. 첫번째 코드가 두번째보다 좀더 선호되는 방식이다

원격에 있는 파일이 300줄 짜리 50KB 파일이라고 생각해보면, 첫번째 코드는 루프가 15번 정도 돌테지만 두번째 코드는 300번의 루프가 실행되야 한다

만약 함수호출 비용과 시간을 고려중이라면 첫번째 방법이 확실히 나은 방법이다



2. file_get_contents() 함수 사용

가장 간단해서 내가 가장 선호하는 방법이다. 단지 파라메터를 url로 주고 함수를 호출하기만 하면 된다. 한가지 기억해야할 점은 리턴받은 값을 사용하기 전에 error가 리턴 됬는지 확인 먼저 해야한다는 것.
$content = file_get_contents('http://www.google.com/');
if ($content !== false) {
   // content 사용
} else {
   // error 발생
}

3. CURL

위의 두 방법과는 다르게 CURL을 쓰는 방법은 딱 부러지게 설명하기 힘들다. 이 라이브러리는 (http뿐만 아니라) 다른 프로토콜 간의 연결과 통신하는 데에 매우 유용하기 쓰이긴 하지만 배우는데 시간을 좀 들여야 한다. 또다른 문제는 모든 web host 들이 이 php 라이브러리를 설치하지는 않았다는것. 따라서 이 방법을 쓰기 전에 해당 라이브러리가 설치되어 있는지 먼저 확인 해야한다

다음은 원격 파일을 여는 간단한 예제
// curl이 설치 되었는지 확인
if (function_exists('curl_init')) {
   // curl 리소스를 초기화
   $ch = curl_init();

   // url을 설정
   curl_setopt($ch, CURLOPT_URL, 'http://www.google.com');

   // 헤더는 제외하고 content 만 받음
   curl_setopt($ch, CURLOPT_HEADER, 0);

   // 응답 값을 브라우저에 표시하지 말고 값을 리턴
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

   // 브라우저처럼 보이기 위해 user agent 사용
   curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0');

   $content = curl_exec($ch);

   // 리소스 해제를 위해 세션 연결 닫음
   curl_close($ch);
} else {
   // curl 라이브러리가 설치 되지 않음. 다른 방법 알아볼 것
}

몇가지 경우에는 file_get_contents()나 fopen() 을 쓰는것보다 CURL이 더 빠르다. 이것은 CURL이 기본적으로 압축 프로토콜을 사용하기 때문이다 (예를들면 gzip).

크고 작은 많은 사이트에서 bandwidth를 줄이기 위해 그들 페이지에서 gzip 압축을 사용한다. 이 사이트도 gzip 압축을 사용했고, bandwidth가 절반으로 줄었다. 만약 기다리기 싫어하는 타입이라면 CURL이 가장 적당할것이다



4. 함수 직접 작성

최악의 경우에는 서버의 fopen wrapper 옵션도 꺼져있고, CURL 라이브러리도 인스톨 되지 않았을수도 있다. 이 슬픈 상황에서는 우리가 쓸 함수를 직접 만들어야 한다.

우리의 함수는 대상 파일의 url 파라미터 한개를 갖는 getRemoteFile() 함수로 명명했다. 대략적인 뼈대는 아래와 같다
function getRemoteFile($url)
{
   // 1. host name과 url path 값을 획득

   // 2. 원격 서버에 접속

   // 3. 파일을 얻기위해 필요한 헤더들을 전송

   // 4. 원격 서버로부터 응답 받음

   // 5. header 부분 걷어냄

   // 6. 파일 content 리턴
}

url에서 host name과 url path 를 추출하기위해서는 parse_url() 함수를 이용하면 된다. 이  함수에 넘겨진 url은 다음 항목들로 분리될 것이다
•scheme
•host
•port
•user
•pass
•path
•query
•fragment



예를들면, http://www.php-mysql-tutorial.com/somepage.php 은 아래와 같이 리턴된다
Array
(
    [scheme] => http
    [host] => www.php-mysql-tutorial.com
    [path] => /somepage.php
)

만약 http://myusername:mypassword@www.php-mysql-tutorial.com/somepage.php?q=whatsthis#ouch 라면 아래와 같이 리턴된다
Array
(
    [scheme] => http
    [host] => www.php-mysql-tutorial.com
    [user] => myusername
    [pass] => mypassword
    [path] => /somepage.php
    [query] => q=whatsthis
    [fragment] => ouch
)

우리가 관심있는것은 host, port, path, query 값 뿐이다

원격 서버와의 connection을 생성하기는 위해서 fsockopen()을 사용한다. 이 함수는 [hostname, port number, error number 포인터, error message 포인터, 시간제한] 5개의 인자를 가지고 있다
function getRemoteFile($url)
{
   // host name 과 url path 값을 획득
   $parsedUrl = parse_url($url);
   $host = $parsedUrl['host'];
   if (isset($parsedUrl['path'])) {
      $path = $parsedUrl['path'];
   } else {
      // url이 http://www.mysite.com 같은 형식이라면
      $path = '/';
   }

   if (isset($parsedUrl['query'])) {
      $path .= '?' . $parsedUrl['query'];
   }

   if (isset($parsedUrl['port'])) {
      $port = $parsedUrl['port'];
   } else {
      // 대부분의 사이트들은 80포트를 사용
      $port = '80';
   }

   $timeout = 10;
   $response = '';
   // 원격 서버에 접속한다
   $fp = @fsockopen($host, $port, $errno, $errstr, $timeout );

   if( !$fp ) {
      echo "Cannot retrieve $url";
   } else {
      // 필요한 헤더들 전송
      fputs($fp, "GET $path HTTP/1.0\r\n" .
                 "Host: $host\r\n" .
                 "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3\r\n" .
                 "Accept: */*\r\n" .
                 "Accept-Language: en-us,en;q=0.5\r\n" .
                 "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" .
                 "Keep-Alive: 300\r\n" .
                 "Connection: keep-alive\r\n" .
                 "Referer: http://$host\r\n\r\n");

      // 원격 서버로부터 response 받음
      while ( $line = fread( $fp, 4096 ) ) {
         $response .= $line;
      }

      fclose( $fp );

      // header 부분 걷어냄
      $pos      = strpos($response, "\r\n\r\n");
      $response = substr($response, $pos + 4);
   }

   // 파일의 content 리턴
   return $response;
}

위의 코드에서는 9줄의 헤더 정보를 보내지만 사실 처음 2줄만 필수사항이다. 따라서 이렇게만 보내도 된다
fputs($fp, "GET $path HTTP/1.0\r\n" .
           "Host: $host\r\n\r\n");

아마 잘동작할것이다. 하지만 항상 잘 동작하는것은 아니다. 열고자 하는 파일들은 원격 서버에 저장되어 있기때문에, 원격 서버가 request에 response 하는지 안하는지에 달려있다

몇몇 서버는 request 헤더에 referer 항목이 없다면 block 할것이고, 몇몇은 특정 user agent 만 받아들일 것이다. 또 어떤 것들은 cookie가 설정되어 있는 header만 받을 것이다

특정 원격 파일을 여는데에 어떤 헤더가 보내져야 하는지 알고 싶다면 파이어폭스와  live http headers plugin 툴을 사용해 보라. 작고 강한 툴이다
추천추천 : 314 추천 목록
번호 제목
3,015
 iframe 높이 100% 맞추기
3,014
 curl 함수를 이용한 HTTP REFERER 변경
3,013
 윈도우10 시스템 파일 및 Dism 검사
3,012
 텍스트 줄바꿈, 글자자르기 CSS
3,011
 jQuery Mobile에서 유용한 코드 10가지.
3,010
 [PHP] dirname()함수와 $_SERVER 관련 상수들
3,009
 [PHP] 파일 크기, 사이즈 불러오는 함수, filesize()
3,008
 [jQuery] jQuery Quick API
3,007
 [ transition ] 링크 hover 색상 변화 속도 조절
3,006
 PHP 5.3.0 에서 사라진 함수들 대체
3,005
 어떤 파일들이 include 나 require 되었는지 확인하는 함수(get_included_files)
3,004
 PHP 날짜 형식 및 계산하기(날짜 더하고 빼기)
3,003
 jQuery Mobile에서 유용한 코드 10가지.
3,002
 값이 배열 안에 존재하는지 확인하는 in_array함수
3,001
 사용자가 웹브라우저에서 뒤로가기를 했을때 감지하는 방법
3,000
 [jQuery]버튼 활성화, 비활성화
2,999
 jQuery show() / hide() / toggle() 사용법
2,998
 jquery 여러가지 이벤트
2,997
 border-radius 속성
2,996
 네이버 오픈API 음성합성 API 사용하는 PHP 샘플코드
2,995
 UTF8 한글 자르기..
2,994
 iconv 에러 발생시 계속 처리하기 옵션
2,993
 [PHP] 현재 페이지의 도메인 , URL 정보 알아내기.
2,992
 [PHP] 막강 기능 배열..
2,991
 [CSS] - Input clear `X ` 버튼 제거 ( IE, Chrome, Firefox )
2,990
 [Mobile] - 모바일웹 Href 태그속성들
2,989
 [JqueryMobile] - 현재화면의 가로세로 사이즈 구하기
2,988
 [JqueryMobile] - 화면의 가로, 세로 사이즈 구하는 방법
2,987
 jquery로 가로 넓이(width), 세로 높이(height) 자동 조절
2,986
 iframe 높이 jquery로 자동조절하기
2,985
 jQuery 오른쪽 영역의 높이를 왼쪽 영역의 높이와 동일하게 하기
2,984
 jquery에서 테이블 짝수, 홀수 번째 TR 배경색 변경하기
2,983
 jquery에서 테이블에 마우스 오버시 해당 행의 배경색상 변경하기
2,982
 jquery 스크립트내 특정값 확인하기 (디버깅)
2,981
 jquery cookie (jquery.cookie.js)
목록
인기절정뽕짝파티
트로트재생목록
인기트로트모음
지루박디스코메들리
밤무대애창곡
전자올겐경음악
종합성인가요방
못잊을옛날노래
카바레 음악
트롯디스코팡팡
관광 메들리
트롯카페
가요감상실
추억의옛노래
스페셜가요광장
BillBoard Free
추천가요모음
경음악.전자올겐
스페셜음악여행
WOLRD POPs
K-POP\BillBoard
JP\CN
POP TOP BEST
K.R.노래방

추천가요\인기
F뮤직 인기\발라드
F뮤직 애창\트로트
트로트성인가요
인기가요
프리미엄 POP
경음악\기타
프리미엄 최신가요
프리미엄 성인가요
가요축제\트롯1번지
댄스\메들리\리믹스
카페\명상\경음악\기타
뮤직트로트 부산광역시부산진구 가야동 ㅣ 개인정보취급방침
Copyright (C) musictrot All rights reserved.