Saturday, February 27, 2016

IIS Settings for PHP on Windows 10

웹호스팅 업체에서 최신 PHP 버전1)을 지원하지 않거나, MySQL 데이터베이스 타입을 MyISAM2)으로 제한하는 등의 문제가 있을 때 테스트 용으로 간단히 운영하기에는 역시 Windows의 IIS( 인터넷정보서비스) 서버가 편하다.0)  localhost(127.0.0.1이나, 공유기를 쓰는 경우 192.168.XXX.YYY 등)로 접속해서 간단히 쓰기 좋다.

IIS는 최근의 Windows(아마도 7 이상)에는 기본 포함되어서, 제어판의 Windows 기능에서 추가해 주기만 하면 바로 쓸 수 있다. Express 버전이 아닌 IIS이므로 기능면에서 Visual Studio나 WebMatrix에 내장된 것보다 낫다.

흔히 APM (Apache + PHP + MySQL)을 웹 개발에서 많이 쓰는데, Windows 환경에서는 굳이 Apache까지 설치할 필요는 없는 것 같다. 옵션 설정도 나름 복잡하고, 테스트 용으로 쓰기에는 시간이 너무 많이 든다.

PHP 설치

그냥 PHP 홈페이지에서 zip 파일을 받아서 아무 폴더에나 풀면 된다. C:\Program Files 밑에 두기를 원하는 사람도 있을 수 있고, C:\ 밑에 두기를 원하는 사람도 있을 것이다.

IIS 설치

  1. Windows 기능 켜기/끄기에서 '인터넷 정보 서비스'에 체크하면 IIS 자체는 설치하기로 결정된 것이다. 확인을 누르면 설치가 되겠지만, 그 전에 체크할 게 하나 더 있다:
  2. 대개 웹 서버의 목표는 동적인 콘텐츠를 보여주는 것이므로 CGI도 사용 가능하게 설정해야 하는데, 안타깝게도 IIS 체크 시 동시에 활성화되지 않는다.

    • World Wide Web 서비스 >> 응용 프로그램 개발 기능 >> CGI로 가서 수동으로 체크해 주어야 한다.
    • http로 탐색했을 때 자동으로 https로 넘어가게 하려면, WWW 서비스 >> 일반적인 HTTP 기능 >> HTTP 리디렉션에도 체크해야 한다.
확인을 누르면 IIS가 설치되고, 웹 서버가 실행된다.

  • 경우에 따라서는 제대로 설치되지 않을 수도 있는데, Windows를 재시작한 후 다른 응용 프로그램이 실행되지 않는 상태(증권사 HTS나 백신 프로그램 등의 문제로 추정한다)에서 다시 시도하면 되기도 한다.


PHP를 CGI로 등록

위에서 비록 CGI까지 활성화해 두었지만, 기본 처리기로 PHP를 등록해 주지는 않는다. 이것도 수동으로 만들어 주어야 하는데, 그러기 위해서는 일단 IIS 설정 프로그램을 열어 보자.
제어판에서 'IIS(인터넷 정보 서비스) 관리자'를 찾아 가든지, 시작 메뉴에서 'iis'를 쳐서 나오는 아이콘을 실행하면 된다.
왼쪽 패널에는 사이트 맵, 오른쪽 패널에는 설정 항목 아이콘들이 나오는데, 아이콘들 일부는 홈에도 나오고 사이트 별로도 나온다. 홈에서 설정한 것을 이어받아(inherit) 쓰든지, 사이트 별로 쓰든지 선택할 수 있는 것이다. 여기서 아이콘들 중 선택할 것은 처리기 매핑이다.
클릭해 보면 OPTIONSVerbHandler 외 3개가 이미 추가돼 있는데, 여기에 PHP 처리기를 추가할 것이다. 가장 오른쪽 패널 ('작업')에서 '모듈 매핑 추가'를 누르고 추가하면 된다.
모듈 매핑 추가 대화상자가 뜨면,
요청 경로를 *.php, 모듈을 FastCgiModule, 실행 파일은 php-cgi.exe가 설치된 경로로 선택한다.
이름은 적당히 지어 주면 된다. 참고한 동영상에서는 PHP_via_fastCGI로 지었다.3)

  • 주의: 1) php.exe가 아니라 php-cgi.exe이다. 2) 탐색(browse, ...) 버튼을 누르면 처음에 확장자가 exe가 아니고 dll로 돼 있다. exe로 바꿔 주어야 php-cgi.exe를 찾을 수 있을 것이다.
  • 그냥 C# 인터프리터 같은 거 하나 만들어서 여기 등록하면 지긋지긋한 PHP를 버릴 수 있는 부분!!??

PHP 설정 - php.ini

  1. PHP를 설치(라기보다는 zip 압축 해제...)한 직후에는 php.ini 파일이 없다. php.ini-development 파일을 복사본을 만든 후 php.ini로 이름을 바꾼다. 그리고 메모장으로 편집한다.
    • 주의: C:\나 C:\Program Files 같은 시스템 폴더의 하위 폴더에 설치한 경우에는 이 파일을 편집하기 위해서 메모장을 관리자 권한으로 열어야 한다. 그냥 연 경우에는 저장이 안 된다.
  2. 다음을 주석 해제한다
    • extension_dir="ext"를 주석 해제
    • php_mysql.dllphp_mysqli.dll 주석 해제. 대부분 MySQL은 쓰니까 해제하는 것이 좋을 것이다.
      PDO를 쓴다면 extension=php_pdo_mysql.dll 이 부분도 주석 해제한다.
    • PHP 5.6이라면 always_populate_raw_post_data = -1 이 부분은 반드시 주석 해제해야 한다.4)
    • date.timezone 주석 해제하고, date.timezone = Asia/Seoul (또는 서버 시간대에 맞는 적절한 위치)로 설정한다. 5)
    • 파일 업로드를 위해서 파일 업로드 용 임시 폴더를 지정하는 upload_tmp_dir 주석 해제하고 
      • upload_tmp_dir = c:\inetpub\wwwroot\some_temp_folder 와 같이 쓴다.
      • 이 폴더는 탐색기 -> 속성 -> 보안에서 IIS_USRS의 쓰기, 수정 권한을 주어야 한다.
      • 마찬가지로 최종적으로 파일이 저장될 폴더도 IIS_USRS에게 권한을 주어야 한다.
  3. 수정한 ini가 효과를 내려면 (뭔가를) 재시작해야 하는데, PHP는 재시작할 수가 없으니까6) IIS를 재시작한다. IIS 제어판에서 하면 된다.



-----------------------
0) Vmware에 CentOS 설치했다가 패키지 버전 꼬여서 쓰는 글이다. rpm, yum, ...응?
1) 5.6부터 암호에도 써도 괜찮은 해싱을 지원한다. 암호는 구 버전의 md5 같은 걸로 저장하면 안 된다. 5.3 미만에서는 associative array 처리에도 최신 버전과 차이가 있다.
2) InnoDB만 transaction을 지원한다.
3) 동영상에서는 보안을 위해 요청 제한을 열고 "요청이 다음에 매핑되는 경우에만 처리기 호출"에 체크하라고 하는데, Windows 10에서는 기본값으로 체크돼 있다. 아마도 Windows 7 이후 minor update인 듯.
4) 버그는 아니고 의도된 거라고 하는데, 요약하자면 그냥 -1이 낫다. 이것을 설정하지 않으면, JSON 인코딩(이나 urlencoding이 아닌 모든 인코딩)으로 텍스트를 보낼 때 warning을 내게 돼 있다. Warning 자체를 꺼 버린다면 문제가 안 될 수도 있지만 지금은 테스트용 서버를 만드는 것이므로 디버깅을 위해 켜 둔다고 가정하면, 이것 때문에 header와 연관되는 setcookie, session_start, session_destroy 등의 여러 함수가 제대로 작동하지 않게 된다.
PHP 7에서는 이 옵션 자체가 삭제된다고 하는데, PHP 7에서는 이를 어떻게 해결할 지 궁금하다. 이 옵션을 못 쓴다면 고쳐야 할 코드가 너무 많은데...
5) 흔히 PHP 테스트 용으로 phpinfo()를 호출하는데, 제대로 나오지 않고 warning이 뜬다. http://php.net/date.timezone 따르면 이것은 환경 변수 TZ 없어서 나타나는 오류라 한다. TZ 설정하거나 ini에서 주석 처리돼 있는 date.timezone = 부분을 수정하면 된다고 하는데, 환경 변수를 설정하기 귀찮으므로 date.timezone = Asia/Seoul 두었다.

6) 웹서버의 요청에 따라 호출되니까




Tuesday, February 9, 2016

맥용 카톡 > PC용 카톡

1. 움짤(GIF)도 바로 보여준다.

2. 이모티콘 해상도가 더 높다.


ㅇㄱㄹㅇ ㅂㅂㅂㄱ


창 핸들을 만드는 동안 오류가 발생했습니다

System.ComponentModel.Win32Exception was unhandled   MyForm w = new MyForm IntPtr handle = wnd.Handle;   // Exception occurs here class MyFo...