PHP 다운로드 download.php 파일을 통해 파일 다운로드 할 때 아래 사진과 같이 이 파일 형식은 지원되지 않는 것 같습니다. 라는 오류가 발생 할 때 여러 방법을 통해 해 봤지만 안됐습니다.

그러던 중 ob_clean() 코드 한 줄 넣고 성공 했습니다.

 

전체 코드 입니다.

$file = "";//전체 경로
if (file_exists($file)) {
     $filename = basename($file);
     $mime = mime_content_type($file);
     header('Content-Type: ' . $mime);
     header('Content-Disposition: attachment; filename="' . $filename . '"');
     header('Content-Length: ' . filesize($file));
     ob_clean();
     readfile($file);
     exit;
 } else {
     exit('파일이 존재하지 않습니다.');
 }

 

'프로그래밍 > PHP' 카테고리의 다른 글

[PHP] 달력 만들기  (0) 2024.02.16
[PHP] Excel 업로드  (1) 2024.01.13

첫째 주, 마지막 주에 비는 날짜는 저번 달, 다음 달 날짜로 채워야 하는 PHP 달력 코드 입니다.

 

<div>
    <div>
        <div>
            <div>
                <h4>달력</h4>
                <h3>Program</h3>
            </div>
        </div>
        <div class="calendar">
            <dl>
                <dt class="sun">일</dt>
                <dt>월</dt>
                <dt>화</dt>
                <dt>수</dt>
                <dt>목</dt>
                <dt>금</dt>
                <dt class="sat">토</dt>
            </dl>
            <?
            $year = date('Y');
            $month = date("m");
            //$month = date("m",strtotime('2024-06-01')); 테스트 코드

            $firstDayOfMonth = 1;//첫 날
            $lastDayOfMonth = date("t",strtotime("$year-$month"));//마지막 날

            $firstDayOfWeek = date('w',strtotime("$year-$month-01"));//첫날 요일(0~6)
            $lastDayOfWeek = date('w',strtotime("$year-$month-$lastDayOfMonth"));//마지막 날 요일(0~6)

            $lastDiff = 6-$lastDayOfWeek; //다음 달 날짜 표시 해야 될 수
            $prev_last_day=date('t',strtotime("-1 month",strtotime("$year-$month-01")));//지난달 마지막 날

            $prev_count = $prev_last_day - $firstDayOfWeek+1; //첫째 주 저번 달 날짜 표시
            $totalCnt = $firstDayOfWeek+$lastDayOfMonth+$lastDiff;//첫째 주 표시 해야 할 수 + 이번 달 표시 해야 될 수 + 마지막 주 표시 해야 할 수
            $day=1; // 이번 달 날짜 표시
            $last_cnt = 1; //마지막 주 다음 달 날짜 표시
            for($i=1;$i<=$totalCnt;$i++){
                if($i<=$firstDayOfWeek){
                    if($i==1){
                        echo "<dl class=\"body\">";
                    }
                    echo "<dd class=\"block\"><em>{$prev_count}</em></dd>";
                    $prev_count++;
                }else if($i>$lastDayOfMonth+$firstDayOfWeek){
                    echo "<dd class=\"block\"><em>{$last_cnt}</em></dd>";
                    $last_cnt++;
                    if($i==$totalCnt){
                        echo "</dl>";
                    }
                }
                else{
                    if(date("w", strtotime("$year-$month-$day")) == 0){//주 시작(일요일)
                        echo "<dl class=\"body\">";
                    }
                    echo "<dd><em>{$day}</em></dd>";

                    if(date("w", strtotime("$year-$month-$day")) == 6){// 주 종료(토요일)
                        echo "</dl>";
                    }

                    $day++;
                }
            }
            ?>
        </div>
    </div>
</div>

 

 

'프로그래밍 > PHP' 카테고리의 다른 글

[PHP] 파일 다운로드 오류  (0) 2024.04.03
[PHP] Excel 업로드  (1) 2024.01.13

1.프로젝트 생성 [생략]

https://console.cloud.google.com/

 

Google 클라우드 플랫폼

로그인 Google 클라우드 플랫폼으로 이동

accounts.google.com

 

2.OAuth 동의 하기

OAuth 동의 화면

 

위의 사진 처럼 프로젝트를 선택 후 왼쪽 메뉴 탭을 펼쳐서 OAuth 동의 화면을 클릭 한다.

OAuth 동의 화면2

프로젝트에 맞게 내부, 외부를 선택 후 만들기 클릭

 

2-1.앱 등록 하기.

 

항목에 맞게 써주는데 홈페이지 URL은 이때 안 써도 된다.

 

 

범위 추가 또는 삭제 버튼을 클릭 해서 필요한 범위를 체크 해준다.

 

테스트를 할 사용자의 계정을 추가 해준다.

 

 

추가 후 OAuth 동의 화면 메뉴를 클릭 후 앱 게시 버튼을 클릭 해준다.

 

3.OAuth 클라이언트 ID를 생성

 

 

 

사용자 인증 정보 메뉴 클릭 -> +사용자 인증 정보 만들기 클릭 -> OAuth 클라이언트 ID 클릭

 

 

웹 어플리케이션으로 선택 후 이름, URL, 리다이렉트 URL을 설정해준다.

 

4.코드

php 코드

<?php
$google_redirect_url = "등록한 리다이렉트 주소(파일명 제거)";
$client_id = '발급한 클라이언트 ID';
$client_secret = '발급한 시크릿 키';
$scope = 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile';

function curl($url,$parameters){
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
    curl_setopt($ch,CURLOPT_POSTFIELDS,$parameters);
    $data = curl_exec($ch);
    return $data;
}

function getCallbackUrl(){
    global $google_redirect_url;
    return urlencode($google_redirect_url.'login_google.php?google=callback');
}

function getLoginUrl(){
    global $client_id,$scope;
    return "https://accounts.google.com/o/oauth2/auth?response_type=code&redirect_uri=".getCallbackUrl()."&client_id=".$client_id."&scope=".$scope;
}

function getAccessToken(){
    global $client_id,$client_secret;

    if(isset($_GET['code'])){
        // get access token from authorization code
        $url = "https://accounts.google.com/o/oauth2/token";
        $parameters="code=".$_GET['code']."&client_id=".$client_id."&client_secret=".$client_secret."&redirect_uri=".getCallbackUrl()."&grant_type=authorization_code";
        return json_decode(curl($url,$parameters),true)['access_token'];

    }else if(isset($_SESSION['access_token'])){
        // get access token from session
        return $_SESSION['access_token'];

    }else{
        // redirect to login url
        header("Location: ".getLoginUrl());
        exit;

    }
}

function getUserInfo(){

    // get user info from google api
    $url="https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=".getAccessToken();
    return json_decode(file_get_contents($url),true);

}

if(isset($_GET['google']) && $_GET['google']=='callback'){

    // store access token in session
    $_SESSION['access_token']=getAccessToken();

    // redirect to index page
    header("Location: ".$google_redirect_url."login_google.php");

}else{
    $res = getUserInfo();
    //여기서 로그인된 정보를 갖고 회원 가입 및 로그인 연동
    exit;
}

 

redirect_url 변수 사용하는 곳을 보면 파일명을 따로 쓰기 때문에 처음 선언시 파일명을 제외한 URL로 입력 시켜야 한다.

또한 getcallbackUrl() 함수를 보면 ?google=callback 이렇게 파라미터를 보내기 때문에 애플리케이션 설정 페이지에서

redirect url을 저장시 기존 파일명에 ?google=callback 파라미터를 보내는 url도 저장시켜야 한다.

예를 들면 저장 시켜야 하는 URL은 2개이다.

-https://localhost:8080/API/login_google.php

-https://localhost:8080/API/ login_google.php?goole=callback 

위의 2개를 저장 시켜야 한다.

 

프론트에서 코드

<a href="/API/login_google.php">구글 로그인</a>

 

'프로그래밍 > API' 카테고리의 다른 글

[API] 네이버 로그인 API 연동  (0) 2024.01.24
YouTube 간단히 연동하기  (0) 2019.06.27

참고 URL :https://developers.naver.com/products/login/api/api.md

 

네이버 로그인 - INTRO

환영합니다 네이버 로그인의 올바른 적용방법을 알아볼까요? 네이버 로그인을 통해 신규 회원을 늘리고, 기존 회원은 간편하게 로그인하게 하려면 제대로 적용하는 것이 중요합니다! 이에 올바

developers.naver.com

 

1. 위의 사이트에 접속 후 애플리케이션을 등록 해준다. (어렵지 않기 때문에 생략)

 

2.프론트

<?
  //네이버 로그인 접근토큰 요청 예제
  $client_id = "YOUR_CLIENT_ID";
  $redirectURI = urlencode("YOUR_CALLBACK_URL");
  $state = "RAMDOM_STATE";
  $apiURL = "https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=".$client_id."&redirect_uri=".$redirectURI."&state=".$state;
 ?>
  
  <!-- html -->
  <a href="<?=$apiURL?>">네이버 로그인</a>

 

 

이때 callback url은 1번에서 등록한 URL과 동일 해야 한다.(www제거)

 

3.PHP(위에서 적은 콜백 URL 파일)

<?php
  // 네이버 로그인 콜백 예제
  $client_id = "YOUR_CLIENT_ID";
  $client_secret = "YOUR_CLIENT_SECRET";
  $code = $_GET["code"];;
  $state = $_GET["state"];;
  $redirectURI = urlencode("YOUR_CALLBACK_URL");
  $url = "https://nid.naver.com/oauth2.0/token?grant_type=authorization_code&client_id=".$client_id."&client_secret=".$client_secret."&redirect_uri=".$redirectURI."&code=".$code."&state=".$state;
  $is_post = false;
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_POST, $is_post);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $headers = array();
  $response = curl_exec ($ch);
  $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  
  if($status_code == 200) {//로그인 성공
    $responseArr = json_decode($response, true);
    //회원프로필 조회
    $token = $responseArr['access_token'];
    $header = "Bearer ".$token;
    $url = "https://openapi.naver.com/v1/nid/me";
    $is_post = false;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, $is_post);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $headers = array();
    $headers[] = "Authorization: ".$header;
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec ($ch);
    $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close ($ch);
    if($status_code == 200) {
    	//여기서 받은 데이터 조회 후 회원 등록 또는 회원 가입 페이지로 이동 시키면 된다.
        echo $response;
    } else {
        echo "Error 내용:".$response;
    }
} else {
    echo "Error 내용:".$response;
}
?>

 

'프로그래밍 > API' 카테고리의 다른 글

[API]구글 로그인 API  (0) 2024.01.26
YouTube 간단히 연동하기  (0) 2019.06.27

-PHPExcel

PHP 엑셀 업로드 및 다운로드에 필요한 라이브러리

다운로드 주소 : https://github.com/PHPOffice/PHPExcel

 

GitHub - PHPOffice/PHPExcel: ARCHIVED

ARCHIVED. Contribute to PHPOffice/PHPExcel development by creating an account on GitHub.

github.com

 

HTML

<div id="uploadModal">
	<button id="closeBtn" onclick="closeUploadModal()">닫기</button>
    <h2>엑셀 업로드</h2>
    <form id="uploadForm" enctype="multipart/form-data" action="excel_read.php" method="post">
    	<input type="file" name="excelFile" accept=".xls, .xlsx" required>
        <br><br>
        <input type="submit" value="업로드">
    </form>
 </div>
 
 <script type="text/javascript">
    function openUploadModal() {
        document.getElementById('uploadModal').style.display = 'block';
    }

    function closeUploadModal() {
        document.getElementById('uploadModal').style.display = 'none';
    }
 </script>

 

PHP

require_once "../common/PHPExcel-1.8/Classes/PHPExcel.php";
require_once "../common/PHPExcel-1.8/Classes/PHPExcel/IOFactory.php";

if (!$_FILES['excelFile']['name']) {
    echo "<script>alert('엑셀파일을 확인해주세요.')</script>";
    exit;
}

$objPHPExcel = new PHPExcel();
try {
    // 업로드한 PHP 파일을 읽어온다.
    $objPHPExcel = PHPExcel_IOFactory::load($_FILES['excelFile']['tmp_name']);
    $objPHPExcel -> setActiveSheetIndex(0);//첫번째 시트를 선택
    $sheet = $objPHPExcel->getActiveSheet();
    $rows = $sheet->getRowIterator();
    foreach ($rows as $row) { // 모든 행에 대해서
        $cellIterator = $row->getCellIterator();
        $cellIterator->setIterateOnlyExistingCells(false);
    }
    $maxRow = $sheet->getHighestRow();
    for ($i = 0 ; $i <= $maxRow ; $i++) {
        $A = $sheet->getCell('A' . $i)->getValue(); // A열
        $B = $sheet->getCell('B' . $i)->getValue(); // B열
        $C = $sheet->getCell('C' . $i)->getValue(); // C열
        $D = $sheet->getCell('D' . $i)->getValue(); // D열
        $F = $sheet->getCell('E' . $i)->getValue(); // E열
        $G = $sheet->getCell('F' . $i)->getValue(); // F열
        $H = $sheet->getCell('H' . $i)->getValue(); // H열
        $I = $sheet->getCell('I' . $i)->getValue(); // I열
    }
}catch(exception $e) {
    echo $e;
}

 

만약 시트가 여러개인 경우 아래 코드 참고.

$sheetsCount = $objPHPExcel -> getSheetCount();
// 시트Sheet별로 읽기
for($i = 0; $i < $sheetsCount; $i++) {
    $objPHPExcel -> setActiveSheetIndex($i);
    $sheet = $objPHPExcel -> getActiveSheet();
    $highestRow = $sheet -> getHighestRow();   		// 마지막 행
    $highestColumn = $sheet -> getHighestColumn();	// 마지막 컬럼

    // 한줄읽기
    for($row = $start_row; $row <= $highestRow+$start_row-1; $row++) {
        // $rowData가 한줄의 데이터를 셀별로 배열처리 된다.
        $rowData = $sheet -> rangeToArray("A" . $row . ":" . $highestColumn . $row, NULL, TRUE, FALSE);

        // $rowData에 들어가는 값은 계속 초기화 되기때문에 값을 담을 새로운 배열을 선안하고 담는다.
        $allData[$row] = $rowData[0];
    }
}

 

'프로그래밍 > PHP' 카테고리의 다른 글

[PHP] 파일 다운로드 오류  (0) 2024.04.03
[PHP] 달력 만들기  (0) 2024.02.16

요약

1. 선언

var - 중복 선언 가능

let, const - 중복 선언 불가능

2. 초기화

var, let - 초기화를 안 해도 된다.

const - 선언과 동시에 초기화를 해야 한다.

3. 재할당

var, let - 재할당 가능

const - 재할당 불가능

4. 호이스팅

var - 호이스팅 O

let, const - 호이스팅 X

5.스코프(참조 가능한 영역)

var - function

let, const - 블럭{}

 

1. 선언  및 초기화

var v; //초기화를 안해도 된다.
var v = 'var'; //중복선언 가능

let l; //초기화를 안해도 된다.
let l = 'let'; //중복선언 불가능(Uncaught SyntaxError: Identifier 'l' has already been declared)

const c; //Error(Uncaught SyntaxError: Missing initializer in const declaration)
const c = 'const'; //중복선언 불가능(Uncaught SyntaxError: Identifier 'c' has already been declared)

2. 재할당

var v = 'var';
console.log(v); //output : var
v='var2';
console.log(v); //output : var2

let l = 'let';
console.log(l); //output : let
l = 'let2';
console.log(l); //output : let2

const c = 'const';
c= 'const2'; //Error(Uncaught TypeError: Assignment to constant variable.)

3. 호이스팅

호이스팅이란?

javascript 엔진이 작동할 때(실행 컨텍스트 단계) var, function 등 선언 한 변수, 함수 등을 메모리에 저장하는 걸 의미합니다.

 

아래의 코드를 예를 들어보겠습니다.

 example();

function example() {
	console.log('Test');
}

한 줄씩 차례대로 진행하면 위와 같은 코드는 오류가 발생해야 정상이지만 호이스팅이 발생하면서 example 함수를 메모리에 저장했기 때문에 오류가 발생하지 않습니다.

 

var와 let, const 호이스팅 차이

아래의 코드를 보면 var는 에러가 안 나고 let, const는 Uncaught ReferenceError가 발생하는 걸 확인할 수 있습니다.

console.log(v)
var v = 'var';
//output : undefined

console.log(l)
let l = 'let';
//output : Uncaught ReferenceError: Cannot access 'l' before initialization

console.log(c)
const c = 'const';
//output : Uncaught ReferenceError: c is not defined

변수는 선언, 초기화, 할당의 단계를 걸쳐 선언되는데 이때 var와 let, const 차이가 발생합니다.

var의 경우 선언 시 선언과 초기화를 동시에 진행하고 (이때 undefined로 초기화 됩니다)

let, const의 경우 선언 시에 선언 단계만 진행합니다.(선언 단계에만 있을 때 TDZ 영역에 있다고 말합니다)

(※TDZ란? 초기화되지 않은 변수가 있는 영역)

 

호이스팅이 발생할때 TDZ에 있는 영역을 제외 하고 발생하기 때문에 위와 같은 차이가 발생합니다.

(※참고로 let, const, class는 TDZ에 영향을 받습니다.)

호이스팅 참고 URL : https://developer.mozilla.org/en-US/docs/Glossary/Hoisting

 

Hoisting - MDN Web Docs Glossary: Definitions of Web-related terms | MDN

JavaScript Hoisting refers to the process whereby the compiler allocates memory for variable and function declarations prior to execution of the code. Declarations that are made using var are initialized with a default value of undefined. Declarations made

developer.mozilla.org

 

4. 스코프

스코프란 변수, 함수, 클래스의 유효 범위를 의미합니다.

스코프는 선언된 위치에 따라 전역 스코프, 지역 스코프로 구분합니다.

전역 스코프 - 어디서든 참조 가능

지역 스코프 - 선언한 지역 범위에서 참조 가능

let g = 1; // 전역 스코프
function print() { 
	let l = 1; //지역 스코프
}
//변수 g는 어디서든 접근이 가능하지만 변수 l은 print 함수 안에서만 접근이 가능합니다.
//만약 변수 l을 print 함수 밖에서 접근시 ReferenceError가 발생합니다.

 

-var : function 스코프

-let, const : 블럭{} 스코프

if(true) {
	var v = "var";
}
console.log(v);
//output : var

if(true) {
	let l = "let";
}
console.log(l);
//output : Uncaught ReferenceError: l is not defined

if(true) {
	const c = "const";
	console.log("{} scope :"+c)
}
console.log("function scope"+c);
//output : 
//{} scope :const
//Uncaught ReferenceError: c is not defined

위의 코드를 보면 var는 function 스코프 let, const는 {}스코프 단위로 변수에 참조할 수 있단 걸 알 수 있습니다.

 

이렇게 var, let, const 차이를 알아보았습니다.

var 변수로 선언된 변수는 for문 같은 반복문이 끝나고도 접근이 가능하기고 중복 선언 등과 같은 문제점이 있기 때문에  let, const를 사용하시는 걸 추천드립니다.

console.time()

 

-사용 방법

console.time('time');
for(var i=0; i<50000; i++){}
console.timeEnd('time');

-결과

time: 0.971923828125 ms

 

-참고 URL : https://developer.mozilla.org/en-US/docs/Web/API/console/time

 

console.time() - Web APIs | MDN

The console.time() method starts a timer you can use to track how long an operation takes. You give each timer a unique name, and may have up to 10,000 timers running on a given page. When you call console.timeEnd() with the same name, the browser will out

developer.mozilla.org

 

Performance.now()

 

-사용방법

var time0 = performance.now();
for(var i=0; i<50000; i++){}
var time1 = performance.now();
console.log("time: " + (time1 - time0) + ' ms');

-결과

time: 0.7999999523162842 ms

-참고 URL : https://developer.mozilla.org/en-US/docs/Web/API/Performance

 

Performance - Web APIs | MDN

The Performance interface provides access to performance-related information for the current page. It's part of the High Resolution Time API, but is enhanced by the Performance Timeline API, the Navigation Timing API, the User Timing API, and the Resource

developer.mozilla.org

 

console.time() , performance.now() 비교

console.time('console.time()');
for(var i=0; i<50000; i++){}
console.timeEnd('console.time()');

var time0 = performance.now();
for(var i=0; i<50000; i++){}
var time1 = performance.now();
console.log("performance.now(): " + (time1 - time0) + ' ms');
console.time(): 0.965087890625 ms
performance.now(): 0.7999999523162842 ms

결과를 보면 performance.now()이 더 정확하게 나오는 걸 확인이 가능합니다.

대신 간단하게 쓸 수 있는 건 console.time()입니다.

 

performance은 .mark() , .measure() 등등 많은 기능이 있으니 참고 URL에서 확인하고 사용하시면 됩니다.

IWebHostEnvironment 인터페이스를 사용하면 파일의 경로를 얻을 수 있습니다.

WebRootPath, ContentRootPath 2개의 경로를 얻을 수 있습니다.

 

두 경로의 차이는 아래와 같습니다.

WebRootPath - www 파일의 경로

ContentRootPath - 최상위의 경로

 

WebRootPath 와 ContentRootPath  차이

 

사용법

using Microsoft.AspNetCore.Hosting;

namespace HostEnvironmentSample.Controllers
{
	public class HomeController : Controller
	{
		private IWebHostEnvironment _hostEnvironment;

		public HomeController(IWebHostEnvironment hostEnvironment)
		{
			_hostEnvironment = hostEnvironment;
		}

		public string Index()
		{
			string wwwPath = _hostEnvironment.WebRootPath;
			string contentPath = _hostEnvironment.ContentRootPath;
			return "WebRootPath :"+wwwPath + "\n\nContentRootPath " + contentPath;
		}
	}
}

 

ASP.NET 2.0에선 IHostingEnvironment 인터페이스 입니다.

IHostingEnvironment 인터페이스는 더 이상 지원하지 않는다고 합니다.

+ Recent posts