Copyright © 1997 - 2009 by the PHP Documentation Group. 이 저작물은 Creative Commons Attribution 3.0 이상의 사용허가 조항 및 제약에 따를 경우에 배포할 수 있습니다. Creative Commons Attribution 3.0 라이센스 사본은 매뉴얼과 함께 배포됩니다. 최신 버전은 » http://creativecommons.org/licenses/by/3.0/에서 확인할 수 있습니다.
변경 여부에 관계 없이, 이 문서의 전체나 부분에 대한 재배포나 출판에 관심이 있을 경우 저작권자(» doc-license@lists.php.net)에게 문의하십시오. 주의: 이 주소는 공개적으로 기록되는 메일링 리스트입니다.
PHP는 하이퍼텍스트 전처리기("PHP: Hypertext Preprocessor")를 의미하며, 널리 쓰이는 오픈 소스 일반 스크립트 언어입니다. 특히 웹 개발에 적합하고 HTML에 삽입할 수 있습니다. 문법은 C, Java, Perl과 흡사하여 배우기 쉽습니다. 주 목표는 웹 개발자가 동적으로 생성되는 웹 페이지를 빠르게 개발할 수 있게 하는 것이지만, PHP로 할 수 있는 일은 훨씬 많습니다.
이 메뉴얼은 본래 함수 레퍼런스이지만, 문법 레퍼런스 및 PHP의 주요 기능과 기타 추가 정보를 수록하고 있습니다.
다양한 형태의 매뉴얼을 » http://www.php.net/download-docs.php에서 받을 수 있습니다. 부록 메뉴얼에 관하여에서 매뉴얼이 어떻게 개발되는지 찾아 볼 수 있습니다. PHP의 역사에 관심이 있으면, 해당 부록을 참고하십시오.
현재 가장 활발한 사람을 매뉴얼 첫 페이지에 표시하지만, 그 외에도 현재 작업을 돕는, 또는 과거에 프로젝트에 많은 양의 도움을 준 공헌자들이 많이 있습니다. 많은 수의 이름이 남지 않은 매뉴얼 페이지의 사용자 노트는 계속하여 참조되어지고, 매우 고마운 일입니다. 아래의 모든 목록은 알파벳 순입니다.
다음 공헌자들은 매뉴얼에 많은 콘텐트를 추가한 영향을 인정합니다: Bill Abt, Jouni Ahto, Alexander Aulbach, Daniel Beckham, Stig Bakken, Jesus M. Castagnetto, Ron Chmara, Sean Coates, John Coggeshall, Simone Cortesi, Markus Fischer, Wez Furlong, Sara Golemon, Rui Hirokawa, Brad House, Pierre-Alain Joye, Etienne Kneuss, Moriyoshi Koizumi, Rasmus Lerdorf, Andrew Lindeman, Stanislav Malyshev, Rafael Martinez, Rick McGuire, Yasuo Ohgaki, Derick Rethans, Rob Richards, Sander Roobol, Egon Schmid, Thomas Schoefbeck, Sascha Schumann, Dan Scott, Masahiro Takagi, Michael Wallner, Lars Torben Wilson, Jim Winstead, Jeroen van Wolffelaar 그리고 Andrei Zmievski.
다음 공헌자들은 매뉴얼 편집에 많은 도움을 주었습니다: Stig Bakken, Gabor Hojtsy, Hartmut Holzgraefe 그리고 Egon Schmid.
현재 가장 활동중인 관리자: Daniel Brown, Nuno Lopes, Felipe Pena, Thiago Pojda 그리고 Maciek Sokolewicz.
이 사람들은 사용자 노트 관리에 많은 노력을 했습니다: Mehdi Achour, Daniel Beckham, Friedhelm Betz, Victor Boivie, Jesus M. Castagnetto, Nicolas Chaillan, Ron Chmara, Sean Coates, James Cox, Vincent Gevers, Sara Golemon, Zak Greant, Szabolcs Heilig, Oliver Hinckel, Hartmut Holzgraefe, Etienne Kneuss, Rasmus Lerdorf, Matthew Li, Andrew Lindeman, Aidan Lister, Hannes Magnusson, Maxim Maletsky, Bobby Matthis, James Moore, Philip Olson, Sebastian Picklum, Derick Rethans, Sander Roobol, Damien Seguy, Jason Sheets, Tom Sommer, Jani Taskinen, Yasuo Ohgaki, Jakub Vrana, Lars Torben Wilson, Jim Winstead, Jared Wyles 그리고 Jeroen van Wolffelaar.
PHP(정식 명칭 "PHP: Hypertext Preprocessor")는 범용성을 지닌 널리 사용되는 오픈 소스 스크립트 언어입니다. 특히, 웹 개발 및 HTML에 포함하기에 적합합니다.
좋습니다, 그려면 어떤 의미일까요? 다음 예제를 봅시다:
Example #1 소개용 예제
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>예제</title>
</head>
<body>
<?php
echo "안녕, 나는 PHP 스크립트야!";
?>
</body>
</html>
(C나 펄처럼) HTML을 출력하기 위해서 많은 명령을 쓰는 대신, PHP 페이지는
"무언가"(여기서는, "안녕, 나는 PHP 스크립트야!"를 출력)를 하는 추가적인
코드를 가진 HTML입니다. PHP 코드는 "PHP 모드"로 들어가는 특수한 프로세싱 시말 지시
<?와 ?> 사이에 들어가 있습니다.
PHP가 클라이언트측 자바스크립트 등과 구별되는 점은 이 코드는 서버에서 실행하여, HTML 생성하여 전송하는 점입니다. 클라이언트는 스크립트 실행 결과만을 받게 되고, 그 코드의 모양은 알 수 없습니다. 웹 서버를 설정하여 모든 HTML 파일을 PHP가 처리하게 할 수 있으며, 그러면 사용자가 무엇으로 처리하는 지 알 방법은 없습니다.
PHP를 사용하는 가장 큰 이득은 초보에게는 매우 쉽고, 전문가에게는 많은 고급 기능을 제공한다는 점입니다. PHP 기능의 긴 리스트를 읽는 것을 두려워하지 마십시오. 그저 시작해 보면 짧은 시간 안에 간단한 스크립트를 작성할 수 있을 것입니다.
PHP의 개발은 서버측 스크립팅에 초점이 맞추어져 있지만, 그보다 더 많은 것들을 할 수 있습니다. PHP로 할 수 있는 것들 섹션을 참고하거나, 웹 프로그래밍에만 관심이 있다면 간단한 튜토리얼로 넘어가십시오.
PHP로 무엇이든지 할 수 있습니다. PHP는 서버측 스크립팅에 중점을 두고 있어, 다른 종류의 CGI 프로그램이 하는 모든 것을 할 수 있습니다. 예를 들면, 폼 데이터를 수집하거나, 동적인 페이지 콘텐츠를 만들거나 쿠키를 보내고 받을 수 있습니다. 그리고 PHP는 더 많은 것들을 할 수 있습니다.
PHP 스크립트가 사용되는 세가지 중점적인 영역이 있습니다.
PHP는 리눅스, 많은 유닉스 계열 (HP-UX, Solaris와 OpenBSD를 포함), 마이크로소프트 윈도우, 맥 OS X, RISC OS 등과 같은 모든 유명한 OS에서 사용할 수 있습니다. 또한, PHP는 오늘날의 대부분의 웹 서버를 지원합니다. 이것에는 아파치, Microsoft Internet Information Server, Personal Web Server, Netscape and iPlanet servers, Oreilly, Website Pro server, Caudium, Xitami, OmniHTTPd, 그 외의 많은 서버들을 포함합니다. 유명한 서버에 대해서는 PHP 모듈이 있으며, 다른 것에 대해서는 CGI 표준을 지원한다면, PHP는 CGI 프로세서로 동작할 수 있습니다.
그러므로 PHP라면, OS와 웹서버를 선택하는 것에서 자유로워 질 수 있습니다. 추가로, 함수 지향형이나 객체 지향형, 또는 그 둘을 섞은 형태로 프로그램을 할 수 있습니다. 비록 PHP 4는 모든 표준 OOP 기능을 포함하고 있지 않지만, 많은 코드 라이브러리와 커다란 애플리케이션들(PEAR 라이브러리를 포함하여)이 OOP 코드만을 이용하여 작성되고 있습니다. PHP 5는 PHP 4에서의 객체 관련 취약점을 보완하고, 완전한 객체 모델을 지원하고 있습니다.
PHP는 HTML을 출력하는 것에만 제한되지 않습니다. PHP의 능력은 이미지, PDF 파일, 심지어 플래시 무비(libswf와 Ming를 사용하여)까지 만들어서 출력할 수 있습니다. 또한 XHTML이나 다른 종류의 XML 파일과 같은 어떠한 텍스트 파일이라도 쉽게 출력할 수 있습니다. PHP로 출력을 하는 대신, 자동적으로 만들어진 파일들을 파일 시스템에 저장하여 동적 컨텐츠에 대한 서버측 캐시를 구현할 수도 있습니다.
PHP의 가장 강력하고 인상적인 기능 중 하나는 넓은 범위의 데이터베이스에 대한 지원입니다. 데이터베이스를 이용하는 웹 페이지를 작성하는것은 매우 간단합니다. 현재 다음과 같은 데이터베이스를 지원하고 있습니다:
또한 데이터베이스 추상 확장(이름은 PDO)은 이 확장이 지원하는 어떠한 데이터베이스라도 투명하게 사용할 수 있게 합니다. 추가로 PHP는 공개 데이터베이스 접속 표준(ODBC)을 지원하기 때문에, 이 세계 표준을 지원하는 어떤 데이터베이스라도 연결할 수 있습니다.
- Adabas D
- dBase
- Empress
- FilePro (read-only)
- Hyperwave
- IBM DB2
- Informix
- Ingres
- InterBase
- FrontBase
- mSQL
- Direct MS-SQL
- MySQL
- ODBC
- Oracle (OCI7 and OCI8)
- Ovrimos
- PostgreSQL
- SQLite
- Solid
- Sybase
- Velocis
- Unix dbm
또한 PHP는 LDAP, IMAP, SNMP, NNTP, POP3, HTTP, COM (윈도우에서), 그리고 셀 수 없는 여러가지 프로토콜들을 이용해서 다른 서비스와 연계할 수 있도록 지원합니다. 또한 비어있는 네트워크 소켓을 열수도 있기에 어떤 프로토콜과도 연계해서 실행할 수 있습니다. PHP는 WDDX complex data exchange between virtually all Web programming languages를 지원합니다. 이를 통한 연계로, PHP는 자바 객체를 그대로 PHP 객체로 옮겨서 이용할 수 있습니다. 또한 원거리 객체 접근을 위해 CORBA 익스텐션을 이용할 수도 있습니다.
PHP는 극도로 유용한 텍스트 처리 기능을 가지고 있습니다. POSIX 확장 정규표현식이나 펄 정규표현식을 가지고 있고, XML 문서 처리를 위하여 PHP 4는 SAX와 DOM 표준을 지원하고, XML 문서를 변형하기 위해 XSLT 확장을 사용할 수 있습니다. PHP 5는 모든 XML 확장을 libxml2의 튼튼한 기반 위에 표준화하고, SimpleXML과 XMLReader 지원을 추가하여 기능을 확장하였습니다.
마지막으로, 하지만 적지 않게 (At last but not least), 많은 또다른 재미있는 확장들이 있습니다. mnoGoSearch 검색 엔진 함수, IRC 게이트웨이 함수, 많은 압축 유틸리티 (gzip, bz2, zip), 달력 변환, 번역...
이 페이지만을 보는 것으로는 PHP가 제공할 수 있는 모든 기능과 이득을 알기에는 충분하지 않습니다. PHP 설치하기 섹션을 읽어보고, 이곳에 언급된 확장들에 대한 함수 레퍼런스를 참고하십시오.
짧고 간단한 튜토리얼로 PHP의 가장 기초가 되는 부분을 보여드립니다. PHP는 웹페이지를 만들 때만 사용하는 것은 아니지만, 여기서는 PHP로 동적 웹페이지를 만드는 내용에 대해서만 다룹니다. PHP로 할 수 있는 것들 섹션에서 더 많은 정보를 얻을 수 있습니다.
PHP를 포함한 웹 페이지는 보통의 HTML 페이지와 같이 취급합니다. 그러므로, 보통의 HTML 페이지를 만드는 것과 같은 방법으로 작성할 수 있습니다.
이 튜토리얼은 서버가 PHP를 지원하고, .php 확장자를 가지는 모든 파일을 PHP로 다루고 있다고 가정합니다. 대부분의 서버에서 이는 PHP의 기본 확장자입니다만, 확인하기 위해서 서버 관리자에게 문의해보십시오. 서버가 PHP를 지원하고 있다면, 더 이상 준비할 것은 없습니다. 단순히 .php 파일을 만들어서 웹 디렉토리에 넣으면, 서버가 자동적으로 처리합니다. 컴파일할 필요도 없고, 별도의 툴을 설치할 필요도 없습니다. PHP를 포함한 파일을, 모든 일을 할 수 있는 마법의 태그를 가진 단순한 HTML 파일이라고 생각하십시오. 대부분의 웹 호스트는 PHP를 지원하지만, 지원하지 않을 경우에는 » PHP 링크 섹션에서 PHP를 지원하는 웹 호스트에 대한 정보를 얻을 수 있습니다.
대역폭을 보존하기 위해 로컬 영역에서 개발하고 싶을 수도 있습니다. 이 경우에는, » 아파치 등의 웹 서버와 함께 » PHP를 설치할 수 있습니다. 원한다면 » MySQL 등의 데이터베이스를 설치할 수도 있습니다.
이들은 개별적으로 설치하거나, 보다 간단한 방법을 이용할 수 있습니다. 매뉴얼에는 PHP 설치 안내(이미 설치한 몇몇 웹 서버를 따라서)가 있습니다. 이 경우, PHP 설치시에 문제가 있다면, » 설치 메일링 리스트를 통하여 질문을 할 수 있습니다. 보다 간단한 길을 간다면, 사용하는 OS를 위한 » 미리 설정된 패키지를 사용하여, 이 모든 것을 간단한 마우스 클릭만으로 설치할 수 있습니다. MacOSX, 리눅스, 윈도우를 포함하여, 어떠한 운영 체제 아래에서도 간단히 PHP를 지원하는 웹 서버를 설정합니다. 리눅스에서는, » rpmfind와 » PBone이 RPM을 찾을 때 유용합니다. » apt-get에서 데비안 패키지를 찾을 수 있습니다.
다음에 쓰여진 내용으로 hello.php를 만들고, 웹서버의 루트 디렉토리(DOCUMENT_ROOT)에 놓습니다.
Example #1 첫번째 PHP 스크립트: hello.php
<html>
<head>
<title>PHP 테스트</title>
</head>
<body>
<?php echo '<p>Hello World</p>'; ?>
</body>
</html>
웹 브라우저를 이용해서 "/hello.php"에 접근합니다. 로컬에서 개발한다면 URL은 보통 http://localhost/hello.php이나 http://127.0.0.1/hello.php일 것이지만, 이는 웹 서버 설정에 따라 달리집니다. 모두 제대로 되었다면, 이 파일은 PHP에 의해 처리되어 다음 출력을 브라우저로 전송합니다:
<html> <head> <title>PHP 테스트</title> </head> <body> <p>Hello World</p> </body> </html>
이 프로그램은 매우 간단해서, 실제로 이런 페이지를 만들기 위해서 PHP를 사용할 필요는 없습니다. 이 프로그램은 Hello World를 PHP echo() 표현으로 보여주기만 할 뿐입니다. 파일에 실행 권한을 줄 필요도 없고, 어떠한 특별한 처리를 할 필요도 없습니다. 서버는 ".php" 확장을 사용하였기 때문에, 이 파일을 PHP를 통해 처리해야 한다고 인식합니다. 이를 많은 일들을 가능하게 하는 특별한 태그를 가진 일반적인 HTML 파일로 생각하십시오.
이 예제를 실행했을 때, 아무것도 출력하지 않거나, 다운로드 할 것인지 묻거나, 모든 내용이 텍스트 문서처럼 보였다면, 그 서버에서 PHP가 작동하지 않거나 제대로 설정되지 않은 것입니다. 서버 관리자에게 매뉴얼의 설치 장을 참고하여 PHP를 사용할 수 있게 해달라고 요청하십시오. http를 통하여, 서버가 출력을 제공하도록 접근하고 있는지 확인하십시오. 단순히 파일 시스템에서 읽어들인다면, PHP를 통하여 처리되지 않습니다. 문제가 계속된다면, 망설이지 말고 » PHP 지원을 이용하십시오.
예제의 초점은 특별한 PHP 태그를 보여주는 것입니다. 이 예제에서 <?php가 PHP 태그의 시작을 알립니다. 그러면 PHP 상태로 돌입하게 되고, 종료 태그인 ?>에 의해 PHP 모드를 떠나게 됩니다. HTML 파일 어디에서라도 이런 방법으로 PHP 모드로 들어가고, 나올 수 있습니다. 더 자세한 내용은 매뉴얼에서 기본 PHP 문법 섹션을 읽어보십시오.
Note: 줄바꿈에 대한 주의
HTML에서 줄바꿈은 약간의 의미를 가지지만, 줄바꿈을 넣어서 HTML을 깔끔하게 보이게 하는 건 좋은 생각입니다. ?> 바로 뒤에 따라오는 줄바꿈은 PHP가 제거합니다. 이는 많은 PHP 블록을 쓰거나, 아무것도 출력하지 않는 PHP 파일을 포함할 때 매우 유용합니다. 반면, 약간 혼동할 수도 있습니다. ?>로 닫은 뒤에 공백을 하나 둠으로써, 공백과 줄바꿈을 출력하게 하거나, PHP 블록 안에서 마지막 echo/print에 명시적으로 줄바꿈을 넣을 수 있습니다.
Note: 텍스트 편집기에 대한 참고
PHP를 만들고, 수정하고, 관리할 수 있는 많은 텍스트 편집기와 IDE가 있습니다. 이러한 도구에 대한 부분적인 목록은 » PHP 편집기 목록에서 관리하고 있습니다. 편집기를 추천하려면, 위 페이지를 방문해서 페이지 관리자에게 그 편집기를 목록에 추가해달라고 하십시오. 구문 하이라이팅이 있는 편집기는 도움이 될 것입니다.
Note: 워드 프로세서에 대한 주의
StarOffice Writer, Microsoft Word, Abiword 등의 워드 프로세서는 PHP 파일을 수정하는데에는 최적화되어 있지 않습니다. 이들을 텍스트 스크립트에 이용하기 위해서는, 꼭 plain text로 저장해야만 하며, 그렇지 않으면 PHP는 그 스크립트를 읽을 수가 없고 실행할 수 없습니다.
Note: 윈도우 메모장에 대한 주의
PHP 스크립트를 윈도우 메모장을 이용해서 작성할때는, 파일이 .php 확장자를 가지도록 주의해야합니다. (메모장은 다음과 같은 절차를 거치지 않으면 자동적으로 .txt 확장자를 붙입니다) 파일을 저장할 때, 파일 이름을 묻는 부분에서 파일 이름을 따옴표로 감싸줘야 합니다. (예: "hello.php") 또는, '저장' 창에서 '텍스트 문서' 드롭다운 메뉴를 클릭해서 "모든 파일"로 설정을 바꿀 수 있습니다. 이 경우에는 따옴표를 쓰지 않아도 됩니다.
작동하는 PHP 스크립트를 성공적으로 만들었다면, 가장 유명한 PHP 스크립트를 작성할 차례입니다! phpinfo() 함수를 호출하여, 사용 가능한 예약 정의 변수, 불러진 PHP 모듈들, 설정 등 시스템과 설정에 관련한 수많은 유용한 정보를 볼 수 있습니다. 잠깐의 시간을 들여서 중요한 정보들을 확인해보십시오.
Example #2 PHP에서 시스템 정보 얻기
<?php phpinfo(); ?>
이제 더 유용한 무언가를 해봅시다. 방문자가 사용하는 브라우저의 종류를 확인할 것입니다. 이를 위해서, 브라우저가 HTTP 요청의 부분으로 보내는 user agent 문자열을 확인합니다. 이 정보는 변수에 기록되어 있습니다. PHP에서 변수는 항상 달러표시($)로 시작합니다. 여기서 다룰 변수는 $_SERVER['HTTP_USER_AGENT']입니다.
Note: $_SERVER는 모든 웹 서버 정보를 포함하기 위해 특별히 예약된 PHP 변수입니다. 이것은 자동전역이라고 부릅니다. 더 많은 정보는 자동전역과 관련한 매뉴얼 페이지를 참고하십시오. 이 특별한 변수들은 PHP » 4.1.0에서 소개되었습니다. 이전에는 $HTTP_SERVER_VARS 등의 $HTTP_*_VARS 배열을 이용하였습니다. 배제되었지만, 이 구형의 변수들은 아직 존재합니다. (예전의 코드에 관한 노트를 참고하십시오)
이 변수를 표시하기 위해서는, 간단히 다음과 같이 하면 됩니다:
Example #1 변수 출력하기 (배열 원소)
<?php
echo $_SERVER['HTTP_USER_AGENT'];
?>
이 스크립트의 출력 예제는 다음과 같습니다:
PHP에는 많은 변수의 형이 존재합니다. 위 예제에서는 배열 원소를 출력했습니다. 배열은 매우 유용합니다.
$_SERVER는 PHP가 자동적으로 생성하는 변수 중의 하나에 불과합니다. 매뉴얼의 예약 정의 변수를 보거나, 이전 섹션의 예제에서 사용한 phpinfo() 함수의 출력에서 전체 목록을 얻을 수 있습니다.
PHP 태그 안쪽으로 하나의 echo뿐이 아닌 여러개의 PHP문을 넣어서 작은 코드 블럭을 만들 수 있습니다. 예를 들면, Internet Explorer를 체크하고 싶다면 다음과 같이 할 수 있습니다:
<?php
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE) {
echo 'Internet Explorer를 사용하고 있습니다.<br />';
}
?>
이 스크립트의 출력 예제:
Internet Explorer를 사용하고 있습니다.<br />
여기서 두가지 새로운 컨셉을 소개합니다. PHP에는 if문이 있습니다. C 언어에서 사용하는 기본 문법에 친숙하다면, 이것은 매우 논리적으로 보일 것입니다. 그렇지 않으면, PHP 소개서를 구해서 첫부분을 읽어보거나, 매뉴얼의 언어 레퍼런스 부분을 읽어보십시오.
두번째 컨셉은 strpos() 함수 호출입니다. strpos()는 하나의 문자열을 다른 문자열에서 찾아내는 PHP 내장 함수입니다. 여기서는 $_SERVER['HTTP_USER_AGENT'](haystack이라고 합니다) 안에서 'MSIE'(needle이라고 합니다)를 찾아봅시다. haystack 안에서 needle을 발견하면, 이 함수는 haystack의 첫번째 문자로부터 needle의 위치를 반환합니다. 발견하지 못했다면 FALSE를 반환합니다. FALSE를 반환하지 않았다면, if문은 TRUE로 판단하고 {중괄호} 안에 있는 코드를 실행합니다. 그렇지 않으면, 코드를 실행하지 않습니다. if, else, 그리고 strtoupper()나 strlen() 등의 함수를 사용하는 비슷한 예제도 쉽게 작성할 수 있습니다. 관련된 매뉴얼 페이지들은 예제를 포함하고 있습니다. 어떻게 함수를 사용하는지를 모르겠다면, 매뉴얼의 함수 정의를 읽는 방법과 PHP 함수 섹션을 읽어보십시오.
한걸음 더 나아가서, PHP 블록 안에서 어떻게 PHP 모드를 드나드는지 알아봅시다:
Example #3 HTML과 PHP 모드 섞기
<?php
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE) {
?>
<h3>strpos()는 false가 아닌 것을 반환했습니다.</h3>
<p>Internet Explorer를 사용하고 있습니다.</p>
<?php
} else {
?>
<h3>strpos()는 false를 반환했습니다.</h3>
<p>Internet Explorer를 사용하고 있지 않습니다.</p>
<?php
}
?>
이 스크립트의 출력 예제:
<h3>strpos()는 false가 아닌 것을 반환했습니다.</h3> <p>Internet Explorer를 사용하고 있습니다.</p>
PHP echo문을 이용한 출력 방법 대신, PHP 모드를 빠져나가서 직접 HTML을 전송할 수 있습니다. 여기서 주의해야할 중요하고 강력한 점은 스크립트의 논리적 흐름이 유지되고 있는 점입니다. strpos()의 결과값에 따라서 오직 하나의 HTML 블록만이 보여지게 됩니다. 즉, MSIE의 발견 여부에 따르게 됩니다.
PHP의 매우 강력한 기능의 하나는 HTML 폼을 다루는 방법입니다. 이를 이해하는데에 중요한 기본적인 컨셉은 어떤 폼 요소라도 자동적으로 PHP 스크립트에서 사용 가능하다는 점입니다. PHP로 폼을 이용하는 많은 정보와 예제를 위해서 매뉴얼의 외부 변수 섹션을 읽어보십시오. 다음은 HTML 폼의 예제입니다:
Example #1 간단한 HTML 폼
<form action="action.php" method="post"> <p>이름: <input type="text" name="name" /></p> <p>연령: <input type="text" name="age" /></p> <p><input type="submit" /></p> </form>
이 폼에는 특별한 것은 아무것도 없습니다. 어떠한 특별한 태그도 가지지 않는 단순한 HTML 폼입니다. 유저가 이 폼을 채우고 submit 버튼을 누르면, action.php 페이지가 호출됩니다. 이 파일은 다음처럼 작성할 수 있습니다:
Example #2 폼에서 온 데이터 출력하기
<?php echo htmlspecialchars($_POST['name']); ?>씨 안녕하세요.
당신은 <?php echo (int)$_POST['age']; ?>세입니다.
이 스크립트의 출력 예제:
홍길동씨 안녕하세요. 당신은 22세입니다.
htmlspecialchars()와 (int) 부분을 제외하면, 이 소스가 어떤 일을 하는지는 명백합니다. htmlspecialchars()는 HTML에서 특별한 의미를 가지는 문자들을 정확히 인코딩하게 하여, HTML 태그나 자바스크립트를 페이지에 삽입할 수 없도록 합니다. age 필드에 대해서는, 숫자이여야 함을 알고 있으므로 간단히 integer로 변환하여 다른 문자들을 제거합니다. 이러한 작업은 필터 확장을 이용하여 PHP가 자동으로 하도록 할 수 있습니다. $_POST['name']와 $_POST['age'] 변수는 PHP가 자동적으로 사용할수 있도록 설정합니다. 위에서 자동전역 $_SERVER를 사용했듯이, 이번에는 모든 POST 데이터를 포함하는 $_POST 자동전역을 소개합니다. 폼에서 method를 POST로 설정한 점에 주의하십시오. 폼에서 GET method로 지정하면, 폼 정보는 $_GET 자동전역이 가집니다. 요청한 데이터가 어떤 소스인지를 신경쓰지 않을 때는 $_REQUEST 자동전역을 사용할 수 있습니다. 이는 GET, POST, COOKIE 데이터를 포함합니다. import_request_variables() 함수를 참고하십시오.
한동안은 잘 지원되는 HTML 폼에 만족할 수도 있지만, PHP에서는 XForms 입력을 다룰 수도 있습니다. XForms로 작업하는 것은 초보자를 위한 것은 아니지만, 흥미를 가질 것입니다. 기능 섹션에서 XForms로 받은 데이터를 다루는 짧은 안내를 참고하십시오.
PHP는 유명한 스크립트 언어로 성장했고, 재사용 할 수 있는 많은 양의 저장소와 라이브러리 코드 자원이 존재합니다. PHP 개발자는 하위 호환을 유지하기 위해 많이 노력했기 때문에, 이전 버전에서 작성한 스크립트라도 아무런 변경 없이 새버전의 PHP에서 (완벽하게) 작동합니다. 그렇지만, 실제 상황에선 몇가지 변경이 필요할 수도 있습니다.
예전의 코드에 영향을 주는 최근의 중요한 두가지 변경점:
이 변화에 대한 자세한 내용은 예약 정의 변수 섹션과 그 안의 링크들을 참고하십시오.
새로운 지식으로 매뉴얼과 예제 아카이브의 수많은 예제 스크립트의 대부분을 이해할 수 있을 것입니다. php.net 사이트의 또다른 예제들을 다음 링크 섹션에서 찾아볼 수 있습니다: » http://www.php.net/links.php.
PHP로 할 수 있는 많은 일들에 대한 다양한 슬라이드 프리젠테이션을 PHP 컨퍼런스 자료 사이트를 참고하십시오: » http://talks.php.net/
설치하기에 앞서, 먼저 PHP를 무엇에 사용해야 할지를 알아야 합니다. PHP로 할 수 있는 것들 섹션에 PHP를 사용하여 할수 있는것들이 설명되어 있습니다.:
이를 위한 첫번째와 대부분의 일반적인 형식으로, 3가지가 필요 합니다.: PHP 그자체와, 웹서버와 웹브라우저가 필요합니다. 아마도 당신은 당신의 운영체제에 의존하는 웹브라우저를 이미 가지고 있을것이며, 어쩌면 웹서버 또한 가지고 있을지도 모릅니다. (e.g. Linux상의 Apache 와 MacOS X; Window상의 IIS). 웹호스팅 회사로부터 웹호스팅을 받고 있을지도 모릅니다. 이경우에는 아무것도 설치할 필요가 없으며, 그냥 PHP 스크립트를 작성하여 웹호스팅을 받고 있는 서버에 업로드 하고, 그 결과를 웹브라우저로 확인만 하면 됩니다.
PHP와 웹서버를 직접 설치하는 경우라면 PHP를 웹서버에 연결하는데에는 두가지 방법을 선택할 수 있습니다. 많은 웹서버들은 다이렉트 모듈 인터페이스를 지원하고 있습니다.(SAPI라고 부르는). Apache, Microsoft Internet Information Server, Netscape and iPlanet server 가 이에 속합니다. 그 외의 많은 웹서버들은 ISAPI를 비롯하여, Microsoft module interface 를 지원합니다. (예를 들어 OmniHTTPd). 웹서버가 PHP모듈을 지원하지 못한다면, 언제든지 CGI나 FastCGI 프로세서를 사용할 수 있습니다. 이것은 서버상의 모든 PHP 파일 요청을 처리하기 위해 웹서버는 PHP CGI 가 실행될수 있도록 설치할 수 있음을 의미합니다.
PHP를 커맨드라인 스크립팅에 사용하는것에 관심이 있다면 (e.g. 오프라인 상태에서 어떤 이미지를 생성하는 스크립트 라던가 어떤 인수를 넘겨받아 텍스트 파일을 조작하는것과 같은), 커맨드 라인 실행기가 필요할 것입니다. 더 많은 정보를 원한다면 커맨드 라인에서 PHP 사용하기 섹션을 읽어보기 바랍니다. 이 경우에는 웹서버와 웹브라우저가 필요하지 않습니다.
PHP-GTK 확장을 사용하면 PHP로 데스크탑 GUI어플리케이션을 작성할 수 있습니다. 이것은 웹페이지를 작성하는것과는 완전히 틀린방식이며, 어떤 HTML도 생성해 낼수 없지만, 대신에 윈도우와 오브젝트들을 관리해야 합니다. PHP-GTK에 대한 더 많은 정보를 원한다면, » 이 확장을 위한 독립적인 사이트에 방문해 보시기 바랍니다. PHP-GTK 는 공식적인 PHP 배포판에는 포함되지 않습니다.
지금부터, 이 섹션은 유닉스나 윈도우상의 웹서버에 PHP를 서버 모듈 인터페이스와 CGI 실행방식으로 설치하는 방법을 다룰것입니다. 또한 다음 섹션에서 커맨드 라인 실행방식에 대한 정보도 찾을 수 있을 것입니다.
PHP 소스코드와 윈도우 바이너리 배포판들은 » http://www.php.net/downloads.php 에서 찾을 수 있습니다. 배포판을 다운로드 하기 위해서 가까운 » mirror 사이트를 사용할 것을 권장합니다.
이 섹션은 유닉스 시스템에 대한 PHP의 일반적인 설정과 설치에 대해서 안내합니다. 진행하기 전에 플래폼 및 웹서버의 사양을 확인하십시오.
일반적인 설치 고려 장에서 나온 매뉴얼 아웃라인에 따라, 이 장에서는 주로 PHP를 웹 중심으로 설정을 합니다. 물론, 명령줄 사용을 위한 PHP 설정도 포함하고 있습니다.
유닉스 플래폼에 PHP를 설치하는 방법은 여러가지가 있습니다. configure 및 컴파일 프로세스를 거치거나, 미리 작성된 패키지 방법 등이 있습니다. 이 문서는 주로 configure와 컴파일을 통한 작업에 맞추어져 있습니다. 많은 유닉스 호환 시스템은 몇몇 패키지 설치 시스템을 갖추고 있습니다. 이는 일반적인 설정에는 도움을 줄 수 있지만, 다른 기능을 필요로 할 경우에는 (보안 서버나, 다른 데이터베이스 드라이버 등), PHP와 웹 서버를 빌드할 필요가 있습니다. 소프트웨어의 컴파일과 빌드에 익숙하지 않다면, 필요한 기능이 들어있는 PHP 패키지를 찾아보는 것도 좋을 것입니다.
컴파일을 위해 필요한 지식과 소프트웨어:
PHP 설정의 첫 작업은 configure 스크립트의 명령줄 옵션을 통해서 조정합니다. 사용할 수 있는 옵션 목록과 그에 대한 짧은 설명은 ./configure --help를 실행하여 얻을 수 있습니다. 매뉴얼은 여러 옵션을 나누어 다루고 있습니다. 부록에서 코어 옵션을 볼 수 있고, 홧장 전용 옵션은 레퍼런스 페이지에 설명이 있습니다.
PHP가 설정되면, 바로 모듈과 확장을 빌드할 수 있습니다. make 명령이 이를 수행합니다. 이 명령이 실패하고, 원인을 찾을 수 없다면, 문제 장을 참고하십시오.
This section contains notes and hints specific to Apache installs of PHP on Unix platforms. We also have instructions and notes for Apache 2 on a separate page.
You can select arguments to add to the configure on line 10 below from the list of core configure options and from extension specific options described at the respective places in the manual. The version numbers have been omitted here, to ensure the instructions are not incorrect. You will need to replace the 'xxx' here with the correct values from your files.
Example #1 Installation Instructions (Apache Shared Module Version) for PHP
1. gunzip apache_xxx.tar.gz
2. tar -xvf apache_xxx.tar
3. gunzip php-xxx.tar.gz
4. tar -xvf php-xxx.tar
5. cd apache_xxx
6. ./configure --prefix=/www --enable-module=so
7. make
8. make install
9. cd ../php-xxx
10. Now, configure your PHP. This is where you customize your PHP
with various options, like which extensions will be enabled. Do a
./configure --help for a list of available options. In our example
we'll do a simple configure with Apache 1 and MySQL support. Your
path to apxs may differ from our example.
./configure --with-mysql --with-apxs=/www/bin/apxs
11. make
12. make install
If you decide to change your configure options after installation,
you only need to repeat the last three steps. You only need to
restart apache for the new module to take effect. A recompile of
Apache is not needed.
Note that unless told otherwise, 'make install' will also install PEAR,
various PHP tools such as phpize, install the PHP CLI, and more.
13. Setup your php.ini file:
cp php.ini-dist /usr/local/lib/php.ini
You may edit your .ini file to set PHP options. If you prefer your
php.ini in another location, use --with-config-file-path=/some/path in
step 10.
If you instead choose php.ini-recommended, be certain to read the list
of changes within, as they affect how PHP behaves.
14. Edit your httpd.conf to load the PHP module. The path on the right hand
side of the LoadModule statement must point to the path of the PHP
module on your system. The make install from above may have already
added this for you, but be sure to check.
For PHP 4:
LoadModule php4_module libexec/libphp4.so
For PHP 5:
LoadModule php5_module libexec/libphp5.so
15. And in the AddModule section of httpd.conf, somewhere under the
ClearModuleList, add this:
For PHP 4:
AddModule mod_php4.c
For PHP 5:
AddModule mod_php5.c
16. Tell Apache to parse certain extensions as PHP. For example,
let's have Apache parse the .php extension as PHP. You could
have any extension(s) parse as PHP by simply adding more, with
each separated by a space. We'll add .phtml to demonstrate.
AddType application/x-httpd-php .php .phtml
It's also common to setup the .phps extension to show highlighted PHP
source, this can be done with:
AddType application/x-httpd-php-source .phps
17. Use your normal procedure for starting the Apache server. (You must
stop and restart the server, not just cause the server to reload by
using a HUP or USR1 signal.)
Alternatively, to install PHP as a static object:
Example #2 Installation Instructions (Static Module Installation for Apache) for PHP
1. gunzip -c apache_1.3.x.tar.gz | tar xf -
2. cd apache_1.3.x
3. ./configure
4. cd ..
5. gunzip -c php-5.x.y.tar.gz | tar xf -
6. cd php-5.x.y
7. ./configure --with-mysql --with-apache=../apache_1.3.x
8. make
9. make install
10. cd ../apache_1.3.x
11. ./configure --prefix=/www --activate-module=src/modules/php5/libphp5.a
(The above line is correct! Yes, we know libphp5.a does not exist at this
stage. It isn't supposed to. It will be created.)
12. make
(you should now have an httpd binary which you can copy to your Apache bin dir if
it is your first install then you need to "make install" as well)
13. cd ../php-5.x.y
14. cp php.ini-dist /usr/local/lib/php.ini
15. You can edit /usr/local/lib/php.ini file to set PHP options.
Edit your httpd.conf or srm.conf file and add:
AddType application/x-httpd-php .php
Note: Replace php-5 by php-4 and php5 by php4 in PHP 4.
Depending on your Apache install and Unix variant, there are many possible ways to stop and restart the server. Below are some typical lines used in restarting the server, for different apache/unix installations. You should replace /path/to/ with the path to these applications on your systems.
Example #3 Example commands for restarting Apache
1. Several Linux and SysV variants: /etc/rc.d/init.d/httpd restart 2. Using apachectl scripts: /path/to/apachectl stop /path/to/apachectl start 3. httpdctl and httpsdctl (Using OpenSSL), similar to apachectl: /path/to/httpsdctl stop /path/to/httpsdctl start 4. Using mod_ssl, or another SSL server, you may want to manually stop and start: /path/to/apachectl stop /path/to/apachectl startssl
The locations of the apachectl and http(s)dctl binaries often vary. If your system has locate or whereis or which commands, these can assist you in finding your server control programs.
Different examples of compiling PHP for apache are as follows:
./configure --with-apxs --with-pgsql
This will create a libphp5.so (or libphp4.so in PHP 4) shared library that is loaded into Apache using a LoadModule line in Apache's httpd.conf file. The PostgreSQL support is embedded into this library.
./configure --with-apxs --with-pgsql=shared
This will create a libphp4.so shared library for Apache, but it will also create a pgsql.so shared library that is loaded into PHP either by using the extension directive in php.ini file or by loading it explicitly in a script using the dl() function.
./configure --with-apache=/path/to/apache_source --with-pgsql
This will create a libmodphp5.a library, a mod_php5.c and some accompanying files and copy this into the src/modules/php5 directory in the Apache source tree. Then you compile Apache using --activate-module=src/modules/php5/libphp5.a and the Apache build system will create libphp5.a and link it statically into the httpd binary (replace php5 by php4 in PHP 4). The PostgreSQL support is included directly into this httpd binary, so the final result here is a single httpd binary that includes all of Apache and all of PHP.
./configure --with-apache=/path/to/apache_source --with-pgsql=shared
Same as before, except instead of including PostgreSQL support directly into the final httpd you will get a pgsql.so shared library that you can load into PHP from either the php.ini file or directly using dl().
When choosing to build PHP in different ways, you should consider the advantages and drawbacks of each method. Building as a shared object will mean that you can compile apache separately, and don't have to recompile everything as you add to, or change, PHP. Building PHP into apache (static method) means that PHP will load and run faster. For more information, see the Apache » web page on DSO support.
Note: Apache's default httpd.conf currently ships with a section that looks like this:
User nobody Group "#-1"Unless you change that to "Group nogroup" or something like that ("Group daemon" is also very common) PHP will not be able to open files.
Note: Make sure you specify the installed version of apxs when using --with-apxs=/path/to/apxs. You must NOT use the apxs version that is in the apache sources but the one that is actually installed on your system.
이 섹션은 유닉스 시스템 아파치 2.0에 특화된 PHP 설치에 관한 정보와 힌트를 담고 있습니다.
제품 환경에서 아파치 2 쓰레드 MPM 사용을 권하지 않습니다. prefork MPM을 사용하거나, Apache 1을 사용하십시오. 이유는 관련 FAQ 아파치2 쓰레드 MPM 사용하기를 읽어보십시오.
아파치 2.0 서버에 대한 이해를 위하여 » 아파치 문서를 살펴보길 권합니다.
Note: PHP와 아파치 2.0.x 호환 노트
다음 버전의 PHP가 최신 버전의 아파치 2.0.x에서 작동합니다:
- » http://www.php.net/downloads.php에서 받을 수 있는 PHP 4.3.0 이후.
- 최신 안정 개발 버전. 소스 코드를 » http://snaps.php.net/php5-latest.tar.gz에서 얻거나 윈도우 바이너리를 » http://snaps.php.net/win32/php5-win32-latest.zip에서 얻을 수 있습니다.
- 릴리즈 예정 버전을 » http://qa.php.net/에서 받을 수 있습니다.
- 언제든지 » 익명 CVS를 통해서 PHP를 받을 수 있습니다.
위 PHP 버전은 아파치 2.0.40 이후에 호환됩니다.
아파치 2.0 SAPI 지원은 PHP 4.2.0부터 시작했습니다. PHP 4.2.3은 아파치 2.0.39에서 작동하며, PHP 4.2.3과 다른 아파치 버전을 사용하지 마십시오. 그러나, 권장하는 설정은 최신 버전의 아파치2와 PHP 4.3.0 이후를 사용하는 것입니다.
언급한 모든 PHP 버전은 아파치 1.3.x에서 잘 동작합니다.
최신 버전의 » 아파치 2.0과 위에서 언급한 위치에서 적합한 PHP 버전을 내려받습니다. 이 빠른 가이드는 아파치 2.0과 PHP를 시작하는 기본적인 내용만 다루고 있습니다. 자세한 정보는 » 아파치 문서를 읽으십시오. 지시가 틀리지 않기 위해서, 여기에서 버전 번호는 제거했습니다. 'NN'을 적합한 값으로 변경해야 합니다.
Example #1 설치 안내 (아파치 2 공유 모듈 버전)
1. gzip -d httpd-2_0_NN.tar.gz
2. tar xvf httpd-2_0_NN.tar
3. gunzip php-NN.tar.gz
4. tar -xvf php-NN.tar
5. cd httpd-2_0_NN
6. ./configure --enable-so
7. make
8. make install
이제 /usr/local/apache2 아래 모듈 적재 지원과 표준 MPM
prefork로 설정한 아파치 2.0.NN이 존재합니다.
설치를 테스트하려면 일반적인 아파치 서버 시작 절차를
사용합니다. 즉:
/usr/local/apache2/bin/apachectl start
그리고 PHP 설정을 위하여 서버를 중단합니다:
/usr/local/apache2/bin/apachectl stop.
9. cd ../php-NN
10. 이제, PHP를 설정합니다. 여기에서 확장을 활성화 하는 등,
PHP를 다양한 다양한 옵션으로 커스터마이즈합니다.
./configure --help 를 실행하여 가능한 옵션 목록을 확인할 수 있습니다.
예제에서는 아파치 2와 MySQL 지원으로 간단히 설정합니다. 실제 apxs
경로는 다를 수 있습니다. 시스템에 따라서 apxs2로 존재하는 경우도
있습니다.
./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql
11. make
12. make install
설치 후에 설정 옵션을 바꾸려면, 마지막 세 단계만
반복하면 됩니다. 그리고 새 모듈이 효과를 발휘하도록
아파치를 재시작하면 됩니다. 아파치를 다시 컴파일할
필요는 없습니다.
특별히 언급이 없는 한, 'make install'은 PEAR, phpize 같은 다양한
PHP 도구, PHP CLI 등을 함께 설치합니다.
13. php.ini 설치
cp php.ini-dist /usr/local/lib/php.ini
PHP 옵션을 설정하기 위하여 .ini 파일을 수정할 수 있습니다. php.ini를
다른 위치에 놓으려면, 10번째 단계에서 --with-config-file-paht=/some/path
를 사용합니다.
php.ini-recommended를 선택한다면, 안에서 변경 목록을 읽어서,
어떤 PHP 행동에 영향을 주는지 확인하십시오.
14. httpd.conf를 수정하여 PHP 모듈을 적재합니다. LoadModule
구문 우측에서는 시스템의 PHP 모듈 경로를 가르켜야 합니다.
위에서 make install이 이미 이를 추가했을 수도 있지만,
꼭 확인해보십시오.
For PHP 4:
LoadModule php4_module modules/libphp4.so
For PHP 5:
LoadModule php5_module modules/libphp5.so
15. 어떠한 확장자를 PHP로 해석할지 아파치에 알려줍니다. 예를 들어,
아파치가 .php 파일을 PHP로 해석하게 합시다. 단순히 아파치
AddType 지시어를 사용하는 대신, exploit.php.jpg 등의 파일이
업로드되어 PHP로 실행되는 것을 막습니다. 이 예제를 사용하여,
PHP로 해석할 어떠한 확장자라도 단순히 추가할 수 있습니다.
예시를 위해 .phtml을 추가하겠습니다.
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
또는, .php, .php2, .php3, .php4, .php6, .phtml 파일을 PHP로 실행하게
할 수 있습니다. 이렇게 하면 됩니다:
<FilesMatch "\.ph(p[2-6]?|tml)$">
SetHandler application/x-httpd-php
</FilesMatch>
.phps 파일을 PHP 소스 파일로 실행하려면, 다음을 추가합니다:
<FilesMatch "\.phps$">
SetHandler application/x-httpd-php-source
</FilesMatch>
16. 아파치 서버를 시작하는 정상 절차를 사용합니다, 즉:
/usr/local/apache2/bin/apachectl start
- 또는 -
service httpd restart
위 단계를 따라하면 아파치2 웹 서버를 PHP SAPI 모듈로 실행하게 됩니다. 물론, 아파치와 PHP에는 많은 설정 옵션이 존재합니다. 자세한 정보는 해당 소스 트리에서 ./configuration --help를 쳐 보십시오. 멀티쓰레드 버전의 아파치2를 빌드하려면, 표준 MPM 모듈 prefork를 worker나 perchild로 덮어써야 합니다. 이를 위해서는 위의 6번째 단계에서 --with-mpm=worker나 --with-mpm=perchild 옵션을 추가해야 합니다. 이를 하기 전에, 최소한 이 일이 어떻게 작동하는지와 장단점을 파악하십시오. 자세한 정보는 » MPM 모듈에 관한 아파치 문서를 읽어보십시오.
Note: 내용 협상을 사용하려면, 아파치 MultiViews FAQ를 읽어보십시오.
Note: 아파치 멀티쓰레드 버전을 빌드하려면, 시스템이 쓰레드를 지원해야 합니다. 이 경우 PHP를 실험적인 Zend Thread Safety (ZTS)로 빌드하게 합니다. 그러므로 모든 확장을 사용할 수 없습니다. 권장하는 설치는 아파치를 표준 prefork MPM 모듈로 빌드하는 것입니다.
This section contains notes and hints specific to Lighttpd 1.4 installs of PHP on Unix systems.
Please use the » Lighttpd trac to learn how to install Lighttpd properly before continuing.
Fastcgi is the preferred SAPI to connect PHP and Lighttpd. Fastcgi is automagically enabled in php-cgi in PHP 5.3, but for older versions configure PHP with --enable-fastcgi. To confirm that PHP has fastcgi enabled, php -v should contain PHP 5.2.5 (cgi-fcgi) Before PHP 5.2.3, fastcgi was enabled on the php binary (there was no php-cgi).
To configure Lighttpd to connect to php and spawn fastcgi processes, edit lighttpd.conf. Sockets are preferred to connect to fastcgi processes on the local system.
Example #1 Partial lighttpd.conf
server.modules += ( "mod_fastcgi" )
fastcgi.server = ( ".php" =>
((
"socket" => "/tmp/php.socket",
"bin-path" => "/usr/local/bin/php-cgi",
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "16",
"PHP_FCGI_MAX_REQUESTS" => "10000"
),
"min-procs" => 1,
"max-procs" => 1,
"idle-timeout" => 20
))
)
The bin-path directive allows lighttpd to spawn fastcgi processes dynamically. PHP will spawn children according to the PHP_FCGI_CHILDREN environment variable. The "bin-environment" directive sets the environment for the spawned processes. PHP will kill a child process after the number of requests specified by PHP_FCGI_MAX_REQUESTS is reached. The directives "min-procs" and "max-procs" should generally be avoided with PHP. PHP manages its own children and opcode caches like APC will only share among children managed by PHP. If "min-procs" is set to something greater than 1, the total number of php responders will be multiplied PHP_FCGI_CHILDREN (2 min-procs * 16 children gives 32 responders).
Lighttpd provides a program called spawn-fcgi to ease the process of spawning fastcgi processes easier.
It is possible to spawn processes without spawn-fcgi, though a bit of heavy-lifting is required. Setting the PHP_FCGI_CHILDREN environment var controls how many children PHP will spawn to handle incoming requests. Setting PHP_FCGI_MAX_REQUESTS will determine how long (in requests) each child will live. Here's a simple bash script to help spawn php responders.
Example #2 Spawning FastCGI Responders
#!/bin/sh
# Location of the php-cgi binary
PHP=/usr/local/bin/php-cgi
# PID File location
PHP_PID=/tmp/php.pid
# Binding to an address
#FCGI_BIND_ADDRESS=10.0.1.1:10000
# Binding to a domain socket
FCGI_BIND_ADDRESS=/tmp/php.sock
PHP_FCGI_CHILDREN=16
PHP_FCGI_MAX_REQUESTS=10000
env -i PHP_FCGI_CHILDREN=$PHP_FCGI_CHILDREN \
PHP_FCGI_MAX_REQUESTS=$PHP_FCGI_MAX_REQUESTS \
$PHP -b $FCGI_BIND_ADDRESS &
echo $! > "$PHP_PID"
Fastcgi instances can be spawned on multiple remote machines in order to scale applications.
Example #3 Connecting to remote php-fastcgi instances
fastcgi.server = ( ".php" =>
(( "host" => "10.0.0.2", "port" => 1030 ),
( "host" => "10.0.0.3", "port" => 1030 ))
)
PHP can be built as a Pike module for the » Caudium webserver. Follow the simple instructions below to install PHP for Caudium.
Example #1 Caudium Installation Instructions
1. Make sure you have Caudium installed prior to attempting to
install PHP 4. For PHP 4 to work correctly, you will need Pike
7.0.268 or newer. For the sake of this example we assume that
Caudium is installed in /opt/caudium/server/.
2. Change directory to php-x.y.z (where x.y.z is the version number).
3. ./configure --with-caudium=/opt/caudium/server
4. make
5. make install
6. Restart Caudium if it's currently running.
7. Log into the graphical configuration interface and go to the
virtual server where you want to add PHP 4 support.
8. Click Add Module and locate and then add the PHP 4 Script Support module.
9. If the documentation says that the 'PHP 4 interpreter isn't
available', make sure that you restarted the server. If you did
check /opt/caudium/logs/debug/default.1 for any errors related to
PHP4.so. Also make sure that
caudium/server/lib/[pike-version]/PHP4.so
is present.
10. Configure the PHP Script Support module if needed.
You can of course compile your Caudium module with support for the various extensions available in PHP 4. See the reference pages for extension specific configure options.
Note: When compiling PHP 4 with MySQL support you must make sure that the normal MySQL client code is used. Otherwise there might be conflicts if your Pike already has MySQL support. You do this by specifying a MySQL install directory the --with-mysql option.
PHP를 fttpd 모듈로 빌드하려면, fttpd 소스 기반 디렉토리를 지정하고 "Build as an fhttpd module?"에 "yes"로 답하십시오. (configure에 --with-fhttpd=DIR 옵션을 줍니다) 기본 디렉토리는 /usr/local/src/fhttpd입니다. fhttpd를 사용한다면, PHP를 모듈로 빌드하는 것이 더욱 좋은 퍼포먼스와 많은 조작, 원격 실행을 가능하게 합니다.
Note: PHP 4.3.0부터 fhttpd를 지원하지 않습니다.
This section contains notes and hints specific to Sun Java System Web Server, Sun ONE Web Server, iPlanet and Netscape server installs of PHP on Sun Solaris.
From PHP 4.3.3 on you can use PHP scripts with the NSAPI module to generate custom directory listings and error pages. Additional functions for Apache compatibility are also available. For support in current web servers read the note about subrequests.
You can find more information about setting up PHP for the Netscape Enterprise Server (NES) here: » http://benoit.noss.free.fr/php/install-php4.html
To build PHP with Sun JSWS/Sun ONE WS/iPlanet/Netscape web servers, enter the proper install directory for the --with-nsapi=[DIR] option. The default directory is usually /opt/netscape/suitespot/. Please also read /php-xxx-version/sapi/nsapi/nsapi-readme.txt.
Install the following packages from » http://www.sunfreeware.com/ or another download site:
export PATH
.
gunzip php-x.x.x.tar.gz
(if you have a .gz dist,
otherwise go to 4).
tar xvf php-x.x.x.tar
cd ../php-x.x.x
For the following step, make sure /opt/netscape/suitespot/ is where your netscape server is installed. Otherwise, change to the correct path and run:
./configure --with-mysql=/usr/local/mysql \ --with-nsapi=/opt/netscape/suitespot/ \ --enable-libgcc
After performing the base install and reading the appropriate readme file, you may need to perform some additional configuration steps.
Firstly you may need to add some paths to the LD_LIBRARY_PATH environment for the server to find all the shared libs. This can best done in the start script for your web server. The start script is often located in: /path/to/server/https-servername/start. You may also need to edit the configuration files that are located in: /path/to/server/https-servername/config/.
Add the following line to mime.types (you can do that by the administration server):
type=magnus-internal/x-httpd-php exts=php
Edit magnus.conf (for servers >= 6) or obj.conf (for servers < 6) and add the following, shlib will vary depending on your system, it will be something like /opt/netscape/suitespot/bin/libphp4.so. You should place the following lines after mime types init.
Init fn="load-modules" funcs="php4_init,php4_execute,php4_auth_trans" shlib="/opt/netscape/suitespot/bin/libphp4.so" Init fn="php4_init" LateInit="yes" errorString="Failed to initialize PHP!" [php_ini="/path/to/php.ini"]
(PHP >= 4.3.3) The php_ini parameter is optional but with it you can place your php.ini in your web server config directory.
Configure the default object in obj.conf (for virtual server classes [version 6.0+] in their vserver.obj.conf):
<Object name="default"> . . . .#NOTE this next line should happen after all 'ObjectType' and before all 'AddLog' lines Service fn="php4_execute" type="magnus-internal/x-httpd-php" [inikey=value inikey=value ...] . . </Object>
(PHP >= 4.3.3) As additional parameters you can add some special php.ini-values, for example you can set a docroot="/path/to/docroot" specific to the context php4_execute is called. For boolean ini-keys please use 0/1 as value, not "On","Off",... (this will not work correctly), e.g. zlib.output_compression=1 instead of zlib.output_compression="On"
This is only needed if you want to configure a directory that only consists of PHP scripts (same like a cgi-bin directory):
<Object name="x-httpd-php"> ObjectType fn="force-type" type="magnus-internal/x-httpd-php" Service fn=php4_execute [inikey=value inikey=value ...] </Object>
After that you can configure a directory in the Administration server and assign it the style x-httpd-php. All files in it will get executed as PHP. This is nice to hide PHP usage by renaming files to .html.
Setup of authentication: PHP authentication cannot be used with any other authentication. ALL AUTHENTICATION IS PASSED TO YOUR PHP SCRIPT. To configure PHP Authentication for the entire server, add the following line to your default object:
<Object name="default"> AuthTrans fn=php4_auth_trans . . . </Object>
To use PHP Authentication on a single directory, add the following:
<Object ppath="d:\path\to\authenticated\dir\*"> AuthTrans fn=php4_auth_trans </Object>
Note: The stacksize that PHP uses depends on the configuration of the web server. If you get crashes with very large PHP scripts, it is recommended to raise it with the Admin Server (in the section "MAGNUS EDITOR").
Important when writing PHP scripts is the fact that Sun JSWS/Sun ONE WS/iPlanet/Netscape is a multithreaded web server. Because of that all requests are running in the same process space (the space of the web server itself) and this space has only one environment. If you want to get CGI variables like PATH_INFO, HTTP_HOST etc. it is not the correct way to try this in the old PHP way with getenv() or a similar way (register globals to environment, $_ENV). You would only get the environment of the running web server without any valid CGI variables!
Note: Why are there (invalid) CGI variables in the environment?
Answer: This is because you started the web server process from the admin server which runs the startup script of the web server, you wanted to start, as a CGI script (a CGI script inside of the admin server!). This is why the environment of the started web server has some CGI environment variables in it. You can test this by starting the web server not from the administration server. Use the command line as root user and start it manually - you will see there are no CGI-like environment variables.
Simply change your scripts to get CGI variables in the correct way for PHP 4.x by using the superglobal $_SERVER. If you have older scripts which use $HTTP_HOST, etc., you should turn on register_globals in php.ini and change the variable order too (important: remove "E" from it, because you do not need the environment here):
variables_order = "GPCS" register_globals = On
You can use PHP to generate the error pages for "404 Not Found" or similar. Add the following line to the object in obj.conf for every error page you want to overwrite:
Error fn="php4_execute" code=XXX script="/path/to/script.php" [inikey=value inikey=value...]
where XXX is the HTTP error code. Please delete any other Error directives which could interfere with yours. If you want to place a page for all errors that could exist, leave the code parameter out. Your script can get the HTTP status code with $_SERVER['ERROR_TYPE'].
Another possibility is to generate self-made directory listings. Just create a PHP script which displays a directory listing and replace the corresponding default Service line for type="magnus-internal/directory" in obj.conf with the following:
Service fn="php4_execute" type="magnus-internal/directory" script="/path/to/script.php" [inikey=value inikey=value...]
For both error and directory listing pages the original URI and translated URI are in the variables $_SERVER['PATH_INFO'] and $_SERVER['PATH_TRANSLATED'].
The NSAPI module now supports the nsapi_virtual() function (alias: virtual()) to make subrequests on the web server and insert the result in the web page. This function uses some undocumented features from the NSAPI library. On Unix the module automatically looks for the needed functions and uses them if available. If not, nsapi_virtual() is disabled.
Note: But be warned: Support for nsapi_virtual() is EXPERIMENTAL!!!
The default is to build PHP as a CGI program. This creates a command line interpreter, which can be used for CGI processing, or for non-web-related PHP scripting. If you are running a web server PHP has module support for, you should generally go for that solution for performance reasons. However, the CGI version enables users to run different PHP-enabled pages under different user-ids.
CGI 설정을 사용할 때, 서버가 여러 공격에 노출됩니다. 그러한 공격을 막기 위해 CGI 보안 섹션을 읽어보십시오.
As of PHP 4.3.0, some important additions have happened to PHP. A new SAPI named CLI also exists and it has the same name as the CGI binary. What is installed at {PREFIX}/bin/php depends on your configure line and this is described in detail in the manual section named Using PHP from the command line. For further details please read that section of the manual.
If you have built PHP as a CGI program, you may test your build by typing make test. It is always a good idea to test your build. This way you may catch a problem with PHP on your platform early instead of having to struggle with it later.
Some server supplied environment variables are not defined in the current » CGI/1.1 specification. Only the following variables are defined there: AUTH_TYPE, CONTENT_LENGTH, CONTENT_TYPE, GATEWAY_INTERFACE, PATH_INFO, PATH_TRANSLATED, QUERY_STRING, REMOTE_ADDR, REMOTE_HOST, REMOTE_IDENT, REMOTE_USER, REQUEST_METHOD, SCRIPT_NAME, SERVER_NAME, SERVER_PORT, SERVER_PROTOCOL, and SERVER_SOFTWARE. Everything else should be treated as 'vendor extensions'.
This section contains notes and hints specific to installing PHP on HP-UX systems.
There are two main options for installing PHP on HP-UX systems. Either compile it, or install a pre-compiled binary.
Official pre-compiled packages are located here: » http://software.hp.com/
Until this manual section is rewritten, the documentation about compiling PHP (and related extensions) on HP-UX systems has been removed. For now, consider reading the following external resource: » Building Apache and PHP on HP-UX 11.11
This section contains notes and hints specific to installing PHP on » OpenBSD 3.6.
Using binary packages to install PHP on OpenBSD is the recommended and simplest method. The core package has been separated from the various modules, and each can be installed and removed independently from the others. The files you need can be found on your OpenBSD CD or on the FTP site.
The main package you need to install is php4-core-4.3.8.tgz, which contains the basic engine (plus gettext and iconv). Next, take a look at the module packages, such as php4-mysql-4.3.8.tgz or php4-imap-4.3.8.tgz. You need to use the phpxs command to activate and deactivate these modules in your php.ini.
Example #1 OpenBSD Package Install Example
# pkg_add php4-core-4.3.8.tgz # /usr/local/sbin/phpxs -s # cp /usr/local/share/doc/php4/php.ini-recommended /var/www/conf/php.ini (add in mysql) # pkg_add php4-mysql-4.3.8.tgz # /usr/local/sbin/phpxs -a mysql (add in imap) # pkg_add php4-imap-4.3.8.tgz # /usr/local/sbin/phpxs -a imap (remove mysql as a test) # pkg_delete php4-mysql-4.3.8 # /usr/local/sbin/phpxs -r mysql (install the PEAR libraries) # pkg_add php4-pear-4.3.8.tgz
Read the » packages(7) manual page for more information about binary packages on OpenBSD.
You can also compile up PHP from source using the » ports tree. However, this is only recommended for users familiar with OpenBSD. The PHP 4 port is split into two sub-directories: core and extensions. The extensions directory generates sub-packages for all of the supported PHP modules. If you find you do not want to create some of these modules, use the no_* FLAVOR. For example, to skip building the imap module, set the FLAVOR to no_imap.
Older releases of OpenBSD used the FLAVORS system to compile up a statically linked PHP. Since it is hard to generate binary packages using this method, it is now deprecated. You can still use the old stable ports trees if you wish, but they are unsupported by the OpenBSD team. If you have any comments about this, the current maintainer for the port is Anil Madhavapeddy (avsm at openbsd dot org).
This section contains notes and hints specific to installing PHP on Solaris systems.
Solaris installs often lack C compilers and their related tools. Read this FAQ for information on why using GNU versions for some of these tools is necessary. The required software is as follows:
In addition, you will need to install (and possibly compile) any additional software specific to your configuration, such as Oracle or MySQL.
You can simplify the Solaris install process by using pkgadd to install most of your needed components.
This section contains notes and hints specific to installing PHP on » Debian GNU/Linux.
While the instructions for building PHP on Unix apply to Debian as well, this manual page contains specific information for other options, such as using either the apt-get or aptitude commands. This manual page uses these two commands interchangeably.
First, note that other related packages may be desired like libapache2-mod-php5 to integrate with Apache 2, and php-pear for PEAR.
Second, before installing a package, it's wise to ensure the package list is up to date. Typically, this is done by running the command apt-get update.
Example #1 Debian Install Example with Apache 2
# apt-get install php5-common libapache2-mod-php5 php5-cli
APT will automatically install the PHP 5 module for Apache 2 and all of its dependencies, and then activate it. Apache should be restarted in order for the changes take place. For example:
Example #2 Stopping and starting Apache once PHP is installed
# /etc/init.d/apache2 stop # /etc/init.d/apache2 start
In the last section, PHP was installed with only core modules. It's very likely that additional modules will be desired, such as MySQL, cURL, GD, etc. These may also be installed via the apt-get command.
Example #3 Methods for listing additional PHP 5 packages
# apt-cache search php5 # aptitude search php5 # aptitude search php5 |grep -i mysql
The examples will show a lot of packages including several PHP specific ones like php5-cgi, php5-cli and php5-dev. Determine which are needed and install them like any other with either apt-get or aptitude. And because Debian performs dependency checks, it'll prompt for those so for example to install MySQL and cURL:
Example #4 Install PHP with MySQL, cURL
# apt-get install php5-mysql php5-curl
APT will automatically add the appropriate lines to the different php.ini related files like /etc/php5/apache2/php.ini, /etc/php5/conf.d/pdo.ini, etc. and depending on the extension will add entries similar to extension=foo.so. However, restarting the web server (like Apache) is required before these changes take affect.
이 장은 Mac OS X에 PHP를 설치하기 위해 필요한 정보와 힌트를 포함하고 있습니다. Mac OS X에는 클라이언트와 서버의 두가지 다른 버전이 존재합니다만, 매뉴얼은 양쪽의 시스템을 모두 다룹니다. MacOS 9 이전 버전에서는 PHP를 사용할 수 없는 점에 주의하십시오.
Mac OS X를 위해 미리 컴파일 하여 패키지 된 몇몇 PHP 버전이 존재합니다. 이는 일반적인 설정으로 간편하게 설치할 수 있지만, 특별한 기능(보안 서버나 특정 데이터베이스 드라이버)이 필요할 경우에는 직접 PHP를 빌드해야 합니다. 소프트웨어를 컴파일하고 빌드하는 작업에 익숙하지 않다면, 누군가가 필요한 기능을 포함한 PHP 버전을 패키지로 만들어 두었는지 확인해 보는 것도 좋습니다.
PHP를 MacOS에 쉽게 설치할 수 있는 패키지와 컴파일된 바이너리입니다:
PHP has come standard with Macs since OS X version 10.0.0. Enabling PHP with the default web server requires uncommenting a few lines in the Apache configuration file httpd.conf whereas the CGI and/or CLI are enabled by default (easily accessible via the Terminal program).
Enabling PHP using the instructions below is meant for quickly setting up a local development environment. It's highly recommended to always upgrade PHP to the newest version. Like most live software, newer versions are created to fix bugs and add features and PHP being is no different. See the appropriate MAC OS X installation documentation for further details. The following instructions are geared towards a beginner with details provided for getting a default setup to work. All users are encouraged to compile, or install a new packaged version.
The standard installation type is using mod_php, and enabling the bundled mod_php on Mac OS X for the Apache web server (the default web server, that is accessible via System Preferences) involves the following steps:
Note: One way to open this is by using a Unix based text editor in the Terminal, for example nano, and because the file is owned by root we'll use the sudo command to open it (as root) so for example type the following into the Terminal Application (after, it will prompt for a password): sudo nano /private/etc/apache2/httpd.conf Noteworthy nano commands: ^w (search), ^o (save), and ^x (exit) where ^ represents the Ctrl key.
Note: Versions of Mac OS X prior to 10.5 were bundled with older versions of PHP and Apache. As such, the Apache configuration file on legacy machines may be /etc/httpd/httpd.conf.
With a text editor, uncomment the lines (by removing the #) that look similar to the following (these two lines are often not together, locate them both in the file):
# LoadModule php5_module libexec/httpd/libphp5.so # AddModule mod_php5.c
Be sure the desired extensions will parse as PHP (examples: .php .html and .inc)
Due to the following statement already existing in httpd.conf (as of Mac Panther), once PHP is enabled the .php files will automatically parse as PHP.
<IfModule mod_php5.c>
# If php is turned on, we respect .php and .phps files.
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
# Since most users will want index.php to work we
# also automatically enable index.php
<IfModule mod_dir.c>
DirectoryIndex index.html index.php
</IfModule>
</IfModule>
Note: Before OS X 10.5 (Leopard), PHP 4 was bundled instead of PHP 5 in which case the above instructions will differ slightly by changing 5's to 4's.
The phpinfo() function will display information about PHP. Consider creating a file in the DocumentRoot with the following PHP code:
<?php phpinfo(); ?>
The CLI (or CGI in older versions) is appropriately named php and likely exists as /usr/bin/php. Open up the terminal, read the command line section of the PHP manual, and execute php -v to check the PHP version of this PHP binary. A call to phpinfo() will also reveal this information.
Untar them, and run the configure program on Apache like so.
./configure --exec-prefix=/usr \ --localstatedir=/var \ --mandir=/usr/share/man \ --libexecdir=/System/Library/Apache/Modules \ --iconsdir=/System/Library/Apache/Icons \ --includedir=/System/Library/Frameworks/Apache.framework/Versions/1.3/Headers \ --enable-shared=max \ --enable-module=most \ --target=apache
If you want the compiler to do some optimization, you may also want to add this line:
setenv OPTIM=-O2
Next, go to the PHP 4 source directory and configure it.
./configure --prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var \
--mandir=/usr/share/man \
--with-xml \
--with-apache=/src/apache_1.3.12
If you have any other additions (MySQL, GD, etc.), be sure to add them here. For the --with-apache string, put in the path to your apache source directory, for example /src/apache_1.3.12.
Now, reconfigure Apache to build in PHP 4.
./configure --exec-prefix=/usr \ --localstatedir=/var \ --mandir=/usr/share/man \ --libexecdir=/System/Library/Apache/Modules \ --iconsdir=/System/Library/Apache/Icons \ --includedir=/System/Library/Frameworks/Apache.framework/Versions/1.3/Headers \ --enable-shared=max \ --enable-module=most \ --target=apache \ --activate-module=src/modules/php4/libphp4.a
You may get a message telling you that libmodphp4.a is out of date. If so, go to the src/modules/php4 directory inside your Apache source directory and run this command: ranlib libmodphp4.a. Then go back to the root of the Apache source directory and run the above configure command again. That'll bring the link table up to date. Run make and make install again.
cp php.ini-dist /usr/local/bin/php.ini
or (if your don't have a local directory)
cp php.ini-dist /usr/bin/php.ini
.
The following instructions will help you install a PHP module for the Apache web server included in MacOS X using the MacOS GUI. This version includes MySQL, PostgreSQL, and iODBC database support, cURL, GD, PDFLib, LDAP, and more. These instructions are graciously provided by » Marc Liyanage.
Be sure you know what you're doing before advancing beyond this point! You can cause irreparable harm to your Apache installation otherwise.
Note: These instructions will only work with the original Apache web server as shipped by Apple. If you re-built or upgraded your Apache, you will have to build your own PHP module.
To install:
http://www2.entropy.ch/download/entropy-php-5.2.4-1.tar.gz
wget
http://www2.entropy.ch/download/entropy-php-5.2.4-1-apache2.tar.gz
That's all! PHP should now be up and running. You can test it by dropping a file named test.php into your Sites folder in your home directory. Into that file, write this line: <?php phpinfo() ?>.
Now open up 127.0.0.1/~your_username/test.php in your web browser. You should see a status table with information about the PHP module.
본 섹션은 윈도우 98/Me와 윈도우 NT/2000/XP/2003에 해당합니다. PHP는 윈도우 3.1 같은 16비트 플랫폼상에서는 동작하지 않고 때때로 지원되는 윈도우 플랫폼이 Win32에 의존합니다. 윈도우 95는 PHP 4.3.0과 같은것은 더이상 지원되지 않습니다.
Note: PHP 5.3.0부터 윈도우 98/ME/NT4를 지원하지 않습니다.
Note: PHP 4.3.0부터 윈도우 95를 지원하지 않습니다.
윈도우에 PHP를 인스톨하는데에는 크게 두가지 방법이 있습니다. 수동설치 를 하거나 설치관리자 를 사용하는 것입니다.
Microsoft Visual Studio 를 가지고 있다면, 원본 소스코드로 부터 PHP를 빌드 할 수가 있습니다.
일단 PHP를 설치 했다면, 기능을 추가시키기 위해 몇가지 확장모듈을 적재 하기를 원할수도 있을 것입니다.
인터넷에 몇가지의 올인원(all-in-one) 설치관리자가 나돌지만, 어떤것도 PHP.net으로부터 승인된 것은 없으며, » http://www.php.net/downloads.php 으로부터 제공되는 공식 윈도우 패키지를 사용하는것이 시스템을 안전하고 최적화되게 하는 최선의 선택이라고 생각합니다.
The Windows PHP installer is available from the downloads page at » http://www.php.net/downloads.php. This installs the CGI version of PHP and for IIS, PWS, and Xitami, it configures the web server as well. The installer does not include any extra external PHP extensions (php_*.dll) as you'll only find those in the Windows Zip Package and PECL downloads.
Note: While the Windows installer is an easy way to make PHP work, it is restricted in many aspects as, for example, the automatic setup of extensions is not supported. Use of the installer isn't the preferred method for installing PHP.
First, install your selected HTTP (web) server on your system, and make sure that it works.
Run the executable installer and follow the instructions provided by the installation wizard. Two types of installation are supported - standard, which provides sensible defaults for all the settings it can, and advanced, which asks questions as it goes along.
The installation wizard gathers enough information to set up the php.ini file, and configure certain web servers to use PHP. One of the web servers the PHP installer does not configure for is Apache, so you'll need to configure it manually.
Once the installation has completed, the installer will inform you if you need to restart your system, restart the server, or just start using PHP.
Be aware, that this setup of PHP is not secure. If you would like to have a secure PHP setup, you'd better go on the manual way, and set every option carefully. This automatically working setup gives you an instantly working PHP installation, but it is not meant to be used on online servers.
The Windows PHP installer for later versions of PHP is built using MSI technology using the Wix Toolkit (» http://wix.sourceforge.net/). It will install and configure PHP and all the built-in and PECL extensions, as well as configure many of the popular web servers such as IIS, Apache, and Xitami.
First, install your selected HTTP (web) server on your system, and make sure that it works. Then proceed with one of the following install types.
Run the MSI installer and follow the instructions provided by the installation wizard. You will be prompted to select the Web Server you wish to configure first, along with any configuration details needed.
You will then be prompted to select which features and extensions you wish to install and enable. By selecting "Will be installed on local hard drive" in the drop-down menu for each item you can trigger whether to install the feature or not. By selecting "Entire feature will be installed on local hard drive", you will be able to install all sub-features of the included feature ( for example by selecting this options for the feature "PDO" you will install all PDO Drivers ).
It is not recommended to install all extensions by default, since many other them require dependencies from outside PHP in order to function properly. Instead, use the Installation Repair Mode that can be triggered thru the 'Add/Remove Programs' control panel to enable or disable extensions and features after installation.
The installer then sets up PHP to be used in Windows and the php.ini file, and configures certain web servers to use PHP. The installer will currently configure IIS, Apache, Xitami, and Sambar Server; if you are using a different web server you'll need to configure it manually.
The installer also supports a silent mode, which is helpful for Systems Administrators to deploy PHP easily. To use silent mode:
msiexec.exe /i php-VERSION-win32-install.msi /q
You can control the install directory by passing it as a parameter to the install. For example, to install to e:\php:
msiexec.exe /i php-VERSION-win32-install.msi /q INSTALLDIR=e:\php
You can also specify what features to install. For example, to install the mysqli extension and the CGI executable:
msiexec.exe /i php-VERSION-win32-install.msi /q ADDLOCAL=cgi,ext_php_mysqli
The current list of Features to install is as follows:
MainExecutable - php.exe executable ScriptExecutable - php-win.exe executable ext_php_* - the various extensions ( for example: ext_php_mysql for MySQL ) apache13 - Apache 1.3 module apache20 - Apache 2.0 module apache22 - Apache 2,2 module apacheCGI - Apache CGI executable iis4ISAPI - IIS ISAPI module iis4CGI - IIS CGI executable iis4FastCGI - IIS CGI executable NSAPI - Sun/iPlanet/Netscape server module netserve - NetServe Web Server CGI executable Xitami - Xitami CGI executable Sambar - Sambar Server ISAPI module CGI - php-cgi.exe executable PEAR - PEAR installer Manual - PHP Manual in CHM Format
For more information on installing MSI installers from the command line, visit » http://msdn.microsoft.com/en-us/library/aa367988.aspx
To upgrade, run the installer either graphically or from the command line as normal. The installer will read your current install options, remove your old installation, and reinstall PHP with the same options as before. It is recommended that you use this method of keeping PHP updated instead of manually replacing the files in the installation directory.
This install guide will help you manually install and configure PHP with a web server on Microsoft Windows. To get started you'll need to download the zip binary distribution from the downloads page at » http://www.php.net/downloads.php.
Although there are many all-in-one installation kits, and we also distribute a PHP installer for Microsoft Windows, we recommend you take the time to setup PHP yourself as this will provide you with a better understanding of the system, and enables you to install PHP extensions easily when needed.
Note: Upgrading from a previous PHP version
Previous editions of the manual suggest moving various ini and DLL files into your SYSTEM (i.e. C:\WINDOWS) folder and while this simplifies the installation procedure it makes upgrading difficult. We advise you remove all of these files (like php.ini and PHP related DLLs from the Windows SYSTEM folder) before moving on with a new PHP installation. Be sure to backup these files as you might break the entire system. The old php.ini might be useful in setting up the new PHP as well. And as you'll soon learn, the preferred method for installing PHP is to keep all PHP related files in one directory and have this directory available to your systems PATH.
Note: MDAC requirements
If you use Microsoft Windows 98/NT4 download the latest version of the Microsoft Data Access Components (MDAC) for your platform. MDAC is available at » http://msdn.microsoft.com/data/. This requirement exists because ODBC is built into the distributed Windows binaries.
The following steps should be completed on all installations before any server specific instructions are performed:
Extract the distribution file into a directory of your choice. If you are installing PHP 4, extract to C:\, as the zip file expands to a foldername like php-4.3.7-Win32. If you are installing PHP 5, extract to C:\php as the zip file doesn't expand as in PHP 4. You may choose a different location but do not have spaces in the path (like C:\Program Files\PHP) as some web servers will crash if you do.
The directory structure extracted from the zip is different for PHP versions 4 and 5 and look like as follows:
Example #1 PHP 4 package structure
c:\php | +--cli | | | |-php.exe -- CLI executable - ONLY for command line scripting | +--dlls -- support DLLs required by some extensions | | | |-expat.dll | | | |-fdftk.dll | | | |-... | +--extensions -- extension DLLs for PHP | | | |-php_bz2.dll | | | |-php_cpdf.dll | | | |-... | +--mibs -- support files for SNMP | +--openssl -- support files for Openssl | +--pdf-related -- support files for PDF | +--sapi -- SAPI (server module support) DLLs | | | |-php4apache.dll | | | |-php4apache2.dll | | | |-... | +--PEAR -- initial copy of PEAR | | |-go-pear.bat -- PEAR setup script | |-... | |-php.exe -- CGI executable | |-... | |-php.ini-dist -- default php.ini settings | |-php.ini-recommended -- recommended php.ini settings | |-php4ts.dll -- core PHP DLL | |-...
Or:
Example #2 PHP 5 package structure
c:\php | +--dev | | | |-php5ts.lib | +--ext -- extension DLLs for PHP | | | |-php_bz2.dll | | | |-php_cpdf.dll | | | |-... | +--extras | | | +--mibs -- support files for SNMP | | | +--openssl -- support files for Openssl | | | +--pdf-related -- support files for PDF | | | |-mime.magic | +--pear -- initial copy of PEAR | | |-go-pear.bat -- PEAR setup script | |-fdftk.dll | |-... | |-php-cgi.exe -- CGI executable | |-php-win.exe -- executes scripts without an opened command prompt | |-php.exe -- CLI executable - ONLY for command line scripting | |-... | |-php.ini-dist -- default php.ini settings | |-php.ini-recommended -- recommended php.ini settings | |-php5activescript.dll | |-php5apache.dll | |-php5apache2.dll | |-... | |-php5ts.dll -- core PHP DLL | |-...
Notice the differences and similarities. Both PHP 4 and PHP 5 have a CGI executable, a CLI executable, and server modules, but they are located in different folders and/or have different names. While PHP 4 packages have the server modules in the sapi folder, PHP 5 distributions have no such directory and instead they're in the PHP folder root. The supporting DLLs for the PHP 5 extensions are also not in a seperate directory.
Note: In PHP 4, you should move all files located in the dll and sapi folders to the main folder (e.g. C:\php).
Here is a list of server modules shipped with PHP 4 and PHP 5:
sapi/php4activescript.dll (php5activescript.dll) - ActiveScript engine, allowing you to embed PHP in your Windows applications.
sapi/php4apache.dll (php5apache.dll) - Apache 1.3.x module.
sapi/php4apache2.dll (php5apache2.dll) - Apache 2.0.x module.
sapi/php5apache2_2.dll - Apache 2.2.x module.
sapi/php4isapi.dll (php5isapi.dll) - ISAPI Module for ISAPI compliant web servers like IIS 4.0/PWS 4.0 or newer.
sapi/php4nsapi.dll (php5nsapi.dll) - Sun/iPlanet/Netscape server module.
sapi/php4pi3web.dll (no equivalent in PHP 5) - Pi3Web server module.
Server modules provide significantly better performance and additional functionality compared to the CGI binary. The CLI version is designed to let you use PHP for command line scripting. More information about CLI is available in the chapter about using PHP from the command line.
The SAPI modules have been significantly improved as of the 4.1 release, however, in older systems you may encounter server errors or other server modules failing, such as ASP.
The CGI and CLI binaries, and the web server modules all require the php4ts.dll (php5ts.dll) file to be available to them. You have to make sure that this file can be found by your PHP installation. The search order for this DLL is as follows:
The same directory from where php.exe is called, or in case you use a SAPI module, the web server's directory (e.g. C:\Program Files\Apache Group\Apache2\bin).
Any directory in your Windows PATH environment variable.
To make php4ts.dll / php5ts.dll available you have three options: copy the file to the Windows system directory, copy the file to the web server's directory, or add your PHP directory, C:\php to the PATH. For better maintenance, we advise you to follow the last option, add C:\php to the PATH, because it will be simpler to upgrade PHP in the future. Read more about how to add your PHP directory to PATH in the corresponding FAQ entry (and then don't forget to restart the computer - logoff isn't enough).
The next step is to set up a valid configuration file for PHP, php.ini. There are two ini files distributed in the zip file, php.ini-dist and php.ini-recommended. We advise you to use php.ini-recommended, because we optimized the default settings in this file for performance, and security. Read this well documented file carefully because it has changes from php.ini-dist that will drastically affect your setup. Some examples are display_errors being off and magic_quotes_gpc being off. In addition to reading these, study the ini settings and set every element manually yourself. If you would like to achieve the best security, then this is the way for you, although PHP works fine with these default ini files. Copy your chosen ini-file to a directory that PHP is able to find and rename it to php.ini. PHP searches for php.ini in the locations described in 설정 파일 section.
If you are running Apache 2, the simpler option is to use the PHPIniDir directive (read the installation on Apache 2 page), otherwise your best option is to set the PHPRC environment variable. This process is explained in the following FAQ entry.
Note: If you're using NTFS on Windows NT, 2000, XP or 2003, make sure that the user running the web server has read permissions to your php.ini (e.g. make it readable by Everyone).
The following steps are optional:
Edit your new php.ini file. If you plan to use OmniHTTPd, do not follow the next step. Set the doc_root to point to your web servers document_root. For example:
doc_root = c:\inetpub\wwwroot // for IIS/PWS doc_root = c:\apache\htdocs // for Apache
PHP is now setup on your system. The next step is to choose a web server, and enable it to run PHP. Choose a web server from the table of contents.
This section contains notes specific to the ActiveScript installation.
ActiveScript is a Windows only SAPI that enables you to use PHP script in any ActiveScript compliant host, like Windows Script Host, ASP/ASP.NET, Windows Script Components or Microsoft Scriptlet control.
As of PHP 5.0.1, ActiveScript has been moved to the » PECL repository. 이 PECL 확장에 대한 DLL은 현재 사용할 수 없습니다. 윈도우에서 빌드하기 섹션을 참고하십시오.
Note: You should read the manual installation steps first!
After installing PHP, you should download the ActiveScript DLL (php5activescript.dll) and place it in the main PHP folder (e.g. C:\php).
After having all the files needed, you must register the DLL on your system. To achieve this, open a Command Prompt window (located in the Start Menu). Then go to your PHP directory by typing something like cd C:\php. To register the DLL just type regsvr32 php5activescript.dll.
To test if ActiveScript is working, create a new file, named test.wsf (the extension is very important) and type:
<job id="test">
<script language="PHPScript">
$WScript->Echo("Hello World!");
</script>
</job>
Save and double-click on the file. If you receive a little window saying "Hello World!" you're done.
Note: In PHP 4, the engine was named 'ActivePHP', so if you are using PHP 4, you should replace 'PHPScript' with 'ActivePHP' in the above example.
Note: ActiveScript doesn't use the default php.ini file. Instead, it will look only in the same directory as the .exe that caused it to load. You should create php-activescript.ini and place it in that folder, if you wish to load extensions, etc.
This section contains notes and hints specific to IIS (Microsoft Internet Information Server).
CGI 설정을 사용할 때, 서버가 여러 공격에 노출됩니다. 그러한 공격을 막기 위해 CGI 보안 섹션을 읽어보십시오.
PHP may be installed as a CGI binary, or with the ISAPI module. In either case, you need to start the Microsoft Management Console (may appear as 'Internet Services Manager', either in your Windows NT 4.0 Option Pack branch or the Control Panel=>Administrative Tools under Windows 2000/XP). Then right click on your Web server node (this will most probably appear as 'Default Web Server'), and select 'Properties'.
If you want to use the CGI binary, do the following:
To use the ISAPI module, do the following:
With IIS 6 (2003 Server), open up the IIS Manager, go to Web Service Extensions, choose "Add a new Web service extension", enter in a name such as PHP, choose the Add button and for the value browse to either the ISAPI file (php4isapi.dll or php5isapi.dll) or CGI (php.exe or php-cgi.exe) then check "Set extension status to Allowed" and click OK.
In order to use index.php as a default content page, do the following: From within the Documents tab, choose Add. Type in index.php and click OK. Adjust the order by choosing Move Up or Move Down. This is similar to setting DirectoryIndex with Apache.
The steps above must be repeated for each extension that is to be associated with PHP scripts. .php is the most common although .php3 may be required for legacy applications.
If you experience 100% CPU usage after some time, turn off the IIS setting Cache ISAPI Application.
PWS 4 does not support ISAPI, only PHP CGI should be used.
The recommended method for configuring these servers is to use the REG file included with the distribution (pws-php4cgi.reg in the SAPI folder for PHP 4, or pws-php5cgi.reg in the main folder for PHP 5). You may want to edit this file and make sure the extensions and PHP install directories match your configuration. Or you can follow the steps below to do it manually.
These steps involve working directly with the Windows registry. One error here can leave your system in an unstable state. We highly recommend that you back up your registry first. The PHP Development team will not be held responsible if you damage your registry.
The following steps do not affect the web server installation and only apply if you want your PHP scripts to be executed when they are run from the command line (ex. run C:\myscripts\test.php) or by double clicking on them in a directory viewer window. You may wish to skip these steps as you might prefer the PHP files to load into a text editor when you double click on them.
PWS and IIS 3 users now have a fully operational system. IIS 3 users can use a nifty » tool from Steven Genusa to configure their script maps.
This section contains notes and hints specific to Apache 1.3.x installs of PHP on Microsoft Windows systems. There are also instructions and notes for Apache 2 on a separate page.
Note: Please read the manual installation steps first!
There are two ways to set up PHP to work with Apache 1.3.x on Windows. One is to use the CGI binary (php.exe for PHP 4 and php-cgi.exe for PHP 5), the other is to use the Apache Module DLL. In either case you need to edit your httpd.conf to configure Apache to work with PHP, and then restart the server.
It is worth noting here that now the SAPI module has been made more stable under Windows, we recommend it's use above the CGI binary, since it is more transparent and secure.
Although there can be a few variations of configuring PHP under Apache, these are simple enough to be used by the newcomer. Please consult the Apache Documentation for further configuration directives.
After changing the configuration file, remember to restart the server, for example, NET STOP APACHE followed by NET START APACHE, if you run Apache as a Windows Service, or use your regular shortcuts.
Note: 윈도우 상에서 아파치 설정 파일에 경로값을 추가할 때는 다음과 같이 모든 백슬래시를 슬래시로 바꿔야 합니다: c:\directory\file.ext을 c:/directory/file.ext로 바꿉니다. 디렉토리에는 마지막에 슬래시를 붙여줘야 합니다.
You should add the following lines to your Apache httpd.conf file:
Example #1 PHP as an Apache 1.3.x module
This assumes PHP is installed to c:\php. Adjust the path if this is not the case.
For PHP 4:
# Add to the end of the LoadModule section # Don't forget to copy this file from the sapi directory! LoadModule php4_module "C:/php/php4apache.dll" # Add to the end of the AddModule section AddModule mod_php4.c
For PHP 5:
# Add to the end of the LoadModule section LoadModule php5_module "C:/php/php5apache.dll" # Add to the end of the AddModule section AddModule mod_php5.c
For both:
# Add this line inside the <IfModule mod_mime.c> conditional brace AddType application/x-httpd-php .php # For syntax highlighted .phps files, also add AddType application/x-httpd-php-source .phps
If you unzipped the PHP package to C:\php\ as described in the Manual Installation Steps section, you need to insert these lines to your Apache configuration file to set up the CGI binary:
Example #2 PHP and Apache 1.3.x as CGI
ScriptAlias /php/ "c:/php/" AddType application/x-httpd-php .php # For PHP 4 Action application/x-httpd-php "/php/php.exe" # For PHP 5 Action application/x-httpd-php "/php/php-cgi.exe" # specify the directory where php.ini is SetEnv PHPRC C:/php
Note that the second line in the list above can be found in the actual versions of httpd.conf, but it is commented out. Remember also to substitute the c:/php/ for your actual path to PHP.
CGI 설정을 사용할 때, 서버가 여러 공격에 노출됩니다. 그러한 공격을 막기 위해 CGI 보안 섹션을 읽어보십시오.
If you would like to present PHP source files syntax highlighted, there is no such convenient option as with the module version of PHP. If you chose to configure Apache to use PHP as a CGI binary, you will need to use the highlight_file() function. To do this simply create a PHP script file and add this code: <?php highlight_file('some_php_script.php'); ?>.
이 섹션은 마이크로소프트 윈도우 시스템에서 아파치 2.0.x에 PHP 설치에 관한 정보와 힌트를 가지고 있습니다. 아파치 1.3.x 사용자를 위한 지시와 정보는 별도 페이지에 존재합니다.
Note: 수동 설치 단계를 먼저 읽어야 합니다!
Note: 아파치 2.2.x 지원
아파치 2.2.x 사용자는 해당하는 DLL 파일이 php5apache2_2.dll이고, PHP 5.2.0부터 존재한다는 점을 생각하고 아래 문서를 사용해야 합니다. » http://snaps.php.net/를 참고하십시오.
제품 환경에서 아파치 2 쓰레드 MPM 사용을 권하지 않습니다. prefork MPM을 사용하거나, Apache 1을 사용하십시오. 이유는 관련 FAQ 아파치2 쓰레드 MPM 사용하기를 읽어보십시오.
아파치 2.0.x 서버에 대한 이해를 위하여 » 아파치 문서를 읽기를 권합니다. 또한, 아파치 2.0.x에 대한 » 윈도우 특정 노트도 읽어보십시오.
Note: PHP와 아파치 2.0.x 호환 노트
다음 버전의 PHP가 최신 버전의 아파치 2.0.x에서 작동합니다:
- » http://www.php.net/downloads.php에서 받을 수 있는 PHP 4.3.0 이후.
- 최신 안정 개발 버전. 소스 코드를 » http://snaps.php.net/php5-latest.tar.gz에서 얻거나 윈도우 바이너리를 » http://snaps.php.net/win32/php5-win32-latest.zip에서 얻을 수 있습니다.
- 릴리즈 예정 버전을 » http://qa.php.net/에서 받을 수 있습니다.
- 언제든지 » 익명 CVS를 통해서 PHP를 받을 수 있습니다.
위 PHP 버전은 아파치 2.0.40 이후에 호환됩니다.
아파치 2.0 SAPI 지원은 PHP 4.2.0부터 시작했습니다. PHP 4.2.3은 아파치 2.0.39에서 작동하며, PHP 4.2.3과 다른 아파치 버전을 사용하지 마십시오. 그러나, 권장하는 설정은 최신 버전의 아파치2와 PHP 4.3.0 이후를 사용하는 것입니다.
언급한 모든 PHP 버전은 아파치 1.3.x에서 잘 동작합니다.
아파치 2.0.x는 윈도우 NT 4.0, 윈도우 2000, 윈도우 XP에서 실행하도록 설계되었습니다. 현 시점에서, 윈도우 9x 지원은 미완성입니다. 아파치 2.0.x는 아직 이러한 플랫폼에서 작동한다는 보장이 없습니다.
가장 최신 버전의 » 아파치 2.0.x와 적합한 PHP 버전을 받으십시오. 수동 설치 단계에 따르고 PHP와 아파치 통합을 진행하십시오.
윈도우에서 아파치 2.0.x에 PHP를 설치하는 방법은 두 가지가 있습니다. 하나는 CGI 바이너리이고, 다른 하나는 아파치 모듈 DLL입니다. 두 방법 모두 httpd.conf를 수정하여 아파치에서 PHP를 작동하도록 하고 서버를 재시작 해야 합니다.
Note: 윈도우 상에서 아파치 설정 파일에 경로값을 추가할 때는 다음과 같이 모든 백슬래시를 슬래시로 바꿔야 합니다: c:\directory\file.ext을 c:/directory/file.ext로 바꿉니다. 디렉토리에는 마지막에 슬래시를 붙여줘야 합니다.
CGI 바이너리로 설치하려면 아래 세 줄을 아파치 httpd.conf 설정 파일에 넣어야 합니다:
Example #1 CGI로 PHP와 아파치 2.0
ScriptAlias /php/ "c:/php/" AddType application/x-httpd-php .php # For PHP 4 Action application/x-httpd-php "/php/php.exe" # For PHP 5 Action application/x-httpd-php "/php/php-cgi.exe"
CGI 설정을 사용할 때, 서버가 여러 공격에 노출됩니다. 그러한 공격을 막기 위해 CGI 보안 섹션을 읽어보십시오.
아파치 2.0에 PHP 모듈을 설치하려면 아래 두 줄을 아파치 httpd.conf 설정 파일에 넣어야 합니다:
Example #2 모듈로 PHP와 Apache 2.0
# For PHP 4 do something like this: LoadModule php4_module "c:/php/php4apache2.dll" # Don't forget to copy the php4apache2.dll file from the sapi directory! AddType application/x-httpd-php .php # For PHP 5 do something like this: LoadModule php5_module "c:/php/php5apache2.dll" AddType application/x-httpd-php .php # configure the path to php.ini PHPIniDir "C:/php"
Note: 위 예제에서 c:/php/을 실제 PHP 경로로 변경하십시오. LoadModule 지시어에 php4apache2.dll이나 php5apache2.dll을 사용하는 점에 주의하십시오. php4apache.dll이나 php5apache.dll이 아닙니다. 이들은 아파치 1.3.x에 사용하도록 설계되었습니다.
Note: 내용 협상을 사용하려면, 관련 FAQ를 읽어보십시오.
DLL 파일을 다른 PHP 버전과 섞지 마십시오. DLL 사용과 확장을 모두 내려받은 PHP 버전에서 사용해야 합니다.
This section contains notes and hints specific to Sun Java System Web Server, Sun ONE Web Server, iPlanet and Netscape server installs of PHP on Windows.
From PHP 4.3.3 on you can use PHP scripts with the NSAPI module to generate custom directory listings and error pages. Additional functions for Apache compatibility are also available. For support in current web servers read the note about subrequests.
To install PHP as a CGI handler, do the following:
Make a file association from the command line. Type the following two lines:
assoc .php=PHPScript ftype PHPScript=c:\php\php.exe %1 %*
More details about setting up PHP as a CGI executable can be found here: » http://benoit.noss.free.fr/php/install-php.html
To install PHP with NSAPI, do the following:
Make a file association from the command line. Type the following two lines:
assoc .php=PHPScript ftype PHPScript=c:\php\php.exe %1 %*
Edit magnus.conf (for servers >= 6) or obj.conf (for servers < 6) and add the following: You should place the lines after mime types init.
Init fn="load-modules" funcs="php4_init,php4_execute,php4_auth_trans" shlib="c:/php/sapi/php4nsapi.dll" Init fn="php4_init" LateInit="yes" errorString="Failed to initialise PHP!" [php_ini="c:/path/to/php.ini"]
(PHP >= 4.3.3) The php_ini parameter is optional but with it you can place your php.ini in your web server configuration directory.
Configure the default object in obj.conf (for virtual server classes [Sun Web Server 6.0+] in their vserver.obj.conf): In the <Object name="default"> section, place this line necessarily after all 'ObjectType' and before all 'AddLog' lines:
Service fn="php4_execute" type="magnus-internal/x-httpd-php" [inikey=value inikey=value ...]
(PHP >= 4.3.3) As additional parameters you can add some special php.ini-values, for example you can set a docroot="/path/to/docroot" specific to the context php4_execute is called. For boolean ini-keys please use 0/1 as value, not "On","Off",... (this will not work correctly), e.g. zlib.output_compression=1 instead of zlib.output_compression="On"
This is only needed if you want to configure a directory that only consists of PHP scripts (same like a cgi-bin directory):
<Object name="x-httpd-php"> ObjectType fn="force-type" type="magnus-internal/x-httpd-php" Service fn=php4_execute [inikey=value inikey=value ...] </Object>
After that you can configure a directory in the Administration server and assign it the style x-httpd-php. All files in it will get executed as PHP. This is nice to hide PHP usage by renaming files to .html.
Note: More details about setting up PHP as an NSAPI filter can be found here: » http://benoit.noss.free.fr/php/install-php4.html
Note: The stacksize that PHP uses depends on the configuration of the web server. If you get crashes with very large PHP scripts, it is recommended to raise it with the Admin Server (in the section "MAGNUS EDITOR").
Important when writing PHP scripts is the fact that Sun JSWS/Sun ONE WS/iPlanet/Netscape is a multithreaded web server. Because of that all requests are running in the same process space (the space of the web server itself) and this space has only one environment. If you want to get CGI variables like PATH_INFO, HTTP_HOST etc. it is not the correct way to try this in the old PHP way with getenv() or a similar way (register globals to environment, $_ENV). You would only get the environment of the running web server without any valid CGI variables!
Note: Why are there (invalid) CGI variables in the environment?
Answer: This is because you started the web server process from the admin server which runs the startup script of the web server, you wanted to start, as a CGI script (a CGI script inside of the admin server!). This is why the environment of the started web server has some CGI environment variables in it. You can test this by starting the web server not from the administration server. Use the command line as root user and start it manually - you will see there are no CGI-like environment variables.
Simply change your scripts to get CGI variables in the correct way for PHP 4.x by using the superglobal $_SERVER. If you have older scripts which use $HTTP_HOST, etc., you should turn on register_globals in php.ini and change the variable order too (important: remove "E" from it, because you do not need the environment here):
variables_order = "GPCS" register_globals = On
You can use PHP to generate the error pages for "404 Not Found" or similar. Add the following line to the object in obj.conf for every error page you want to overwrite:
Error fn="php4_execute" code=XXX script="/path/to/script.php" [inikey=value inikey=value...]
where XXX is the HTTP error code. Please delete any other Error directives which could interfere with yours. If you want to place a page for all errors that could exist, leave the code parameter out. Your script can get the HTTP status code with $_SERVER['ERROR_TYPE'].
Another possibility is to generate self-made directory listings. Just create a PHP script which displays a directory listing and replace the corresponding default Service line for type="magnus-internal/directory" in obj.conf with the following:
Service fn="php4_execute" type="magnus-internal/directory" script="/path/to/script.php" [inikey=value inikey=value...]
For both error and directory listing pages the original URI and translated URI are in the variables $_SERVER['PATH_INFO'] and $_SERVER['PATH_TRANSLATED'].
The NSAPI module now supports the nsapi_virtual() function (alias: virtual()) to make subrequests on the web server and insert the result in the web page. The problem is, that this function uses some undocumented features from the NSAPI library.
Under Unix this is not a problem, because the module automatically looks for the needed functions and uses them if available. If not, nsapi_virtual() is disabled.
Under Windows limitations in the DLL handling need the use of a automatic detection of the most recent ns-httpdXX.dll file. This is tested for servers till version 6.1. If a newer version of the Sun server is used, the detection fails and nsapi_virtual() is disabled.
If this is the case, try the following: Add the following parameter to php4_init in magnus.conf/obj.conf:
Init fn=php4_init ... server_lib="ns-httpdXX.dll"
where XX is the correct DLL version number. To get it, look in the server-root for the correct DLL name. The DLL with the biggest filesize is the right one.
You can check the status by using the phpinfo() function.
Note: But be warned: Support for nsapi_virtual() is EXPERIMENTAL!!!
This section contains notes and hints specific to » OmniHTTPd on Windows.
Note: You should read the manual installation steps first!
CGI 설정을 사용할 때, 서버가 여러 공격에 노출됩니다. 그러한 공격을 막기 위해 CGI 보안 섹션을 읽어보십시오.
You need to complete the following steps to make PHP work with OmniHTTPd. This is a CGI executable setup. SAPI is supported by OmniHTTPd, but some tests have shown that it is not so stable to use PHP as an ISAPI module.
Note: Important for CGI users
Read the faq on cgi.force_redirect for important details. This directive needs to be set to 0.
Install OmniHTTPd server.
Right click on the blue OmniHTTPd icon in the system tray and select Properties
Click on Web Server Global Settings
On the 'External' tab, enter: virtual = .php | actual = c:\php\php.exe (use php-cgi.exe if installing PHP 5), and use the Add button.
On the Mime tab, enter: virtual = wwwserver/stdcgi | actual = .php, and use the Add button.
Click OK
Repeat steps 2 - 6 for each extension you want to associate with PHP.
Note: Some OmniHTTPd packages come with built in PHP support. You can choose at setup time to do a custom setup, and uncheck the PHP component. We recommend you to use the latest PHP binaries. Some OmniHTTPd servers come with PHP 4 beta distributions, so you should choose not to set up the built in support, but install your own. If the server is already on your machine, use the Replace button in Step 4 and 5 to set the new, correct information.
This section contains notes and hints specific to the » Sambar Server for Windows.
Note: You should read the manual installation steps first!
This list describes how to set up the ISAPI module to work with the Sambar server on Windows.
Find the file called mappings.ini (in the config directory) in the Sambar install directory.
Open mappings.ini and add the following line under [ISAPI]:
Example #1 ISAPI configuration of Sambar
#for PHP 4 *.php = c:\php\php4isapi.dll #for PHP 5 *.php = c:\php\php5isapi.dll
(This line assumes that PHP was installed in c:\php.)
Now restart the Sambar server for the changes to take effect.
Note: If you intend to use PHP to communicate with resources which are held on a different computer on your network, then you will need to alter the account used by the Sambar Server Service. The default account used for the Sambar Server Service is LocalSystem which will not have access to remote resources. The account can be amended by using the Services option from within the Windows Control Panel Administation Tools.
This section contains notes and hints specific to » Xitami on Windows.
Note: You should read the manual installation steps first!
This list describes how to set up the PHP CGI binary to work with Xitami on Windows.
Note: Important for CGI users
Read the faq on cgi.force_redirect for important details. This directive needs to be set to 0. If you want to use $_SERVER['PHP_SELF'] you have to enable the cgi.fix_pathinfo directive.
CGI 설정을 사용할 때, 서버가 여러 공격에 노출됩니다. 그러한 공격을 막기 위해 CGI 보안 섹션을 읽어보십시오.
Make sure the web server is running, and point your browser to xitamis admin console (usually http://127.0.0.1/admin), and click on Configuration.
Navigate to the Filters, and put the extension which PHP should parse (i.e. .php) into the field File extensions (.xxx).
In Filter command or script put the path and name of your PHP CGI executable i.e. C:\php\php.exe for PHP 4, or C:\php\php-cgi.exe for PHP 5.
Press the 'Save' icon.
Restart the server to reflect changes.
This chapter teaches how to compile PHP from sources on windows, using Microsoft's tools. To compile PHP with cygwin, please refer to 유닉스 시스템에 설치.
This chapter is outdated therefore it's temporarily been removed from the manual. For now, consider the following:
After installing PHP and a web server on Windows, you will probably want to install some extensions for added functionality. You can choose which extensions you would like to load when PHP starts by modifying your php.ini. You can also load a module dynamically in your script using dl().
The DLLs for PHP extensions are prefixed with php_.
Many extensions are built into the Windows version of PHP. This means additional DLL files, and the extension directive, are not used to load these extensions. The Windows PHP Extensions table lists extensions that require, or used to require, additional PHP DLL files. Here's a list of built in extensions:
In PHP 4 (updated PHP 4.3.11): BCMath, Caledar, COM, Ctype, FTP, MySQL, ODBC, Overload, PCRE, Session, Tokenizer, WDDX, XML 그리고 Zlib
In PHP 5 (updated PHP 5.0.4), the following changes exist. Built in: DOM, LibXML, Iconv, SimpleXML, SPL 그리고 SQLite. And the following are no longer built in: MySQL and Overload.
The default location PHP searches for extensions is C:\php4\extensions in PHP 4 and C:\php5 in PHP 5. To change this setting to reflect your setup of PHP edit your php.ini file:
You will need to change the extension_dir setting to point to the directory where your extensions lives, or where you have placed your php_*.dll files. For example:
extension_dir = C:\php\extensions
Enable the extension(s) in php.ini you want to use by uncommenting the extension=php_*.dll lines in php.ini. This is done by deleting the leading ; from the extension you want to load.
Example #1 Enable Bzip2 extension for PHP-Windows
// change the following line from ... ;extension=php_bz2.dll // ... to extension=php_bz2.dll
Some of the extensions need extra DLLs to work. Couple of them can be found in the distribution package, in the C:\php\dlls\ folder in PHP 4 or in the main folder in PHP 5, but some, for example Oracle (php_oci8.dll) require DLLs which are not bundled with the distribution package. If you are installing PHP 4, copy the bundled DLLs from C:\php\dlls folder to the main C:\php folder. Don't forget to include C:\php in the system PATH (this process is explained in a separate FAQ entry).
Some of these DLLs are not bundled with the PHP distribution. See each extensions documentation page for details. Also, read the manual section titled Installation of PECL extensions for details on PECL. An increasingly large number of PHP extensions are found in PECL, and these extensions require a separate download.
Note: If you are running a server module version of PHP remember to restart your web server to reflect your changes to php.ini.
The following table describes some of the extensions available and required additional dlls.
| Extension | Description | Notes |
|---|---|---|
| php_bz2.dll | bzip2 compression functions | None |
| php_calendar.dll | Calendar conversion functions | Built in since PHP 4.0.3 |
| php_crack.dll | Crack functions | None |
| php_ctype.dll | ctype family functions | Built in since PHP 4.3.0 |
| php_curl.dll | CURL, Client URL library functions | Requires: libeay32.dll, ssleay32.dll (bundled) |
| php_dba.dll | DBA: DataBase (dbm-style) Abstraction layer functions | None |
| php_dbase.dll | dBase functions | None |
| php_dbx.dll | dbx functions | |
| php_domxml.dll | DOM XML functions | PHP <= 4.2.0 requires: libxml2.dll (bundled) PHP >= 4.3.0 requires: iconv.dll (bundled) |
| php_dotnet.dll | .NET functions | PHP <= 4.1.1 |
| php_exif.dll | EXIF functions | php_mbstring.dll. And, php_exif.dll must be loaded after php_mbstring.dll in php.ini. |
| php_fbsql.dll | FrontBase functions | PHP <= 4.2.0 |
| php_fdf.dll | FDF: Forms Data Format functions. | Requires: fdftk.dll (bundled) |
| php_filepro.dll | filePro functions | Read-only access |
| php_ftp.dll | FTP functions | Built-in since PHP 4.0.3 |
| php_gd.dll | GD library image functions | Removed in PHP 4.3.2. Also note that truecolor functions are not available in GD1, instead, use php_gd2.dll. |
| php_gd2.dll | GD library image functions | GD2 |
| php_gettext.dll | Gettext functions | PHP <= 4.2.0 requires gnu_gettext.dll (bundled), PHP >= 4.2.3 requires libintl-1.dll, iconv.dll (bundled). |
| php_hyperwave.dll | HyperWave functions | None |
| php_iconv.dll | ICONV characterset conversion | Requires: iconv-1.3.dll (bundled), PHP >=4.2.1 iconv.dll |
| php_ifx.dll | Informix functions | Requires: Informix libraries |
| php_iisfunc.dll | IIS management functions | None |
| php_imap.dll | IMAP POP3 and NNTP functions | None |
| php_ingres.dll | Ingres functions | Requires: Ingres libraries |
| php_interbase.dll | InterBase functions | Requires: gds32.dll (bundled) |
| php_java.dll | Java functions | PHP <= 4.0.6 requires: jvm.dll (bundled) |
| php_ldap.dll | LDAP functions | PHP <= 4.2.0 requires libsasl.dll (bundled), PHP >= 4.3.0 requires libeay32.dll, ssleay32.dll (bundled) |
| php_mbstring.dll | Multi-Byte String functions | None |
| php_mcrypt.dll | Mcrypt Encryption functions | Requires: libmcrypt.dll |
| php_mhash.dll | Mhash functions | PHP >= 4.3.0 requires: libmhash.dll (bundled) |
| php_mime_magic.dll | Mimetype functions | Requires: magic.mime (bundled) |
| php_ming.dll | Ming functions for Flash | None |
| php_msql.dll | mSQL functions | Requires: msql.dll (bundled) |
| php_mssql.dll | MSSQL functions | Requires: ntwdblib.dll (bundled) |
| php_mysql.dll | MySQL functions | PHP >= 5.0.0, requires libmysql.dll (bundled) |
| php_mysqli.dll | MySQLi functions | PHP >= 5.0.0, requires libmysql.dll (libmysqli.dll in PHP <= 5.0.2) (bundled) |
| php_oci8.dll | Oracle 8 functions | Requires: Oracle 8.1+ client libraries |
| php_openssl.dll | OpenSSL functions | Requires: libeay32.dll (bundled) |
| php_overload.dll | Object overloading functions | Built in since PHP 4.3.0 |
| php_pdf.dll | PDF functions | None |
| php_pgsql.dll | PostgreSQL functions | None |
| php_printer.dll | Printer functions | None |
| php_shmop.dll | Shared Memory functions | None |
| php_snmp.dll | SNMP get and walk functions | NT only! |
| php_soap.dll | SOAP functions | PHP >= 5.0.0 |
| php_sockets.dll | Socket functions | None |
| php_sybase_ct.dll | Sybase functions | Requires: Sybase client libraries |
| php_tidy.dll | Tidy functions | PHP >= 5.0.0 |
| php_tokenizer.dll | Tokenizer functions | Built in since PHP 4.3.0 |
| php_w32api.dll | W32api functions | None |
| php_xmlrpc.dll | XML-RPC functions | PHP >= 4.2.1 requires: iconv.dll (bundled) |
| php_xslt.dll | XSLT functions | PHP <= 4.2.0 requires sablot.dll, expat.dll (bundled). PHP >= 4.2.1 requires sablot.dll, expat.dll, iconv.dll (bundled). |
| php_yaz.dll | YAZ functions | Requires: yaz.dll (bundled) |
| php_zip.dll | Zip File functions | Read only access |
| php_zlib.dll | ZLib compression functions | Built in since PHP 4.3.0 |
» PECL 은 PHP 확장의 저장소(repository)이며 » PEAR 패키징 시스템을 통하여 이용할 수가 있습니다. 본 섹션은 PECL을 구하여 설치하는것을 설명하기 위해 마련 되었습니다.
이 지침들은 /your/phpsrcdir/ 은 PHP 소스가 위치하는 경로이고, extname 은 PECL 확장의 이름인것으로 가정 합니다. 적절히 조절하시기 바랍니다. 또한 이 지침들은 » pear command 에 친숙한것을 가정합니다. pear 명령에 대한 PEAR 매뉴얼의 정보는 또한 pecl 명령에도 적용됩니다.
이 기능을 사용하기 위해서는, 확장모듈을 빌드하고, 설치하고, 로드해야 합니다. 확장모듈을 어떻게 빌드하고 설치할것인지에 대해 아래에서 다양한 지침과 함께 그 방법들이 설명되지만, 하지만 그것만으론 모듈을 자동으로 로드할 수는 없습니다. 확장모듈은 php.ini 파일에 extension 디렉티브를 추가하든지, dl() 함수를 사용하여 로드할 수 있습니다.
PHP 모듈을 빌드할때는, 적절한 버전의 필수 툴을 사용하는것이 중요합니다 (autoconf, automake, libtool, 등등.). 필수 툴과 그 버전에 대한 자세한 내용은 » Anonymous CVS 지침 을 보십시오.
PECL 확장모듈을 다운로드 하는데에는 몇가지 방법이 있습니다. 다음과 같습니다:
윈도우에서, PHP 확장을 적재하는 두가지 방법이 있습니다: PHP 안에 컴파일하거나, DLL을 적재. 미리 컴파일된 확장을 적재하는 것이 쉽고 편한 방법입니다.
확장을 적재하려면, 시스템에 해당하는 ".dll" 파일이 있어야 합니다. 모든 확장은 자동으로 주기적으로 PHP 그룹에서 컴파일합니다. (내려받기는 다음 섹션을 참고하십시오)
확장을 PHP 안에 컴파일하려면, 소스에서 빌드하기 문서를 확인하십시오.
독립 확장(DLL 파일)을 컴파일하려면, 소스에서 빌드하기 문서를 확인하십시오. DLL 파일이 PHP 배포판이나 PECL에 존재하지 않는다면, 그 확장을 사용하기 전에 컴파일해야 합니다.
PHP 확장은 일반적으로 "php_*.dll"(별은 확장 이름)로 불리고, "PHP\ext"(PHP 4에서는 "PHP\extensions") 폴더에 위치하고 있습니다.
PHP는 대다수의 개발자에게 가장 유용한 확장을 포함하고 있습니다. 이들은 "핵심" 확장이라고 불립니다.
그러나, 핵심 확장에서 지원하지 않는 기능이 필요하면, PECL에서 찾을 수 있습니다. PHP Extension Community Library (PECL)는 PHP 확장의 저장고로, 알려진 모든 알려진 확장의 디렉토리를 제공하고, PHP 확장 개발과 내려받기에 필요한 기능을 지원합니다.
스스로 사용할 확장을 개발했다면, PECL에 올려서 같은 요구를 가진 다른 사람들에게 혜택을 제공할 수 있습니다. 좋은 추가 효과로 다른 사람들의 피드백, 감사, 버그 보고와 심지어 픽스/패치를 받을 수 있습니다. PECL에 확장을 제공하기 전에, http://pecl.php.net/package-new.php를 읽어보십시오.
많은 경우에, 각 DLL의 여러 버전을 찾을 수 있습니다:
확장 설정이 사용하는 PHP 실행 설정과 일치해야만 합니다. 다음 PHP 스크립트가 모든 PHP 설정을 알려줍니다:
<?php phpinfo(); ?>
또는 명령줄에서, 실행:
drive:\\path\to\php\executable\php.exe -i
PHP 확장을 적재하는 가장 일반적인 방법은 php.ini 설정 파일에 포함하는 것입니다. 많은 확장이 이미 php.ini에 존재하고, 세미콜론을 제거하면 바로 활성화됩니다.
;extension=php_extname.dll
extension=php_extname.dll
그러나, 일부 웹서버는 PHP 실행에 놓여있는 php.ini를 사용하지 않아서 혼동을 가져옵니다. 정확한 php.ini의 위치를 확인하려면, phpinfo()에서 경로를 찾아보십시오:
Configuration File (php.ini) Path C:\WINDOWS
Loaded Configuration File C:\Program Files\PHP\5.2\php.ini
확장을 활성화한 후, php.ini을 저장, 웹서버를 재시작하고 phpinfo()를 다시 확인하십시오. 새 확장이 자신의 섹션을 가지고 있어야 합니다.
확장이 phpinfo()에 나타나지 않으면, 어디서 문제가 발생하였는지 로그를 확인해야 합니다.
PHP를 명령줄(CLI)에서 사용한다면, 확장 적재 오류를 화면에서 바로 읽을 수 있습니다.
PHP를 웹서버에서 사용하면, 로그의 위치와 형식은 웹서버 소프트웨어에 의존합니다. 웹서버 문서에서 로그 위치를 찾아서 읽어보십시오. PHP 자체로는 아무것도 하지 않습니다.
일반적인 문제는 DLL 위치입니다. php.ini 안의 "extension_dir" 값이 컴파일시 설정과 일치하지 않아서 발생합니다.
문제가 컴파일시 설정이 일치하지 않는 것이라면, 아마도 옮은 DLL을 내려받지 않았을 것입니다. 적합한 설정을 가진 확장을 다시 내려받아 보십시오. 다시 말하지만, phpinfo()가 큰 도움이 될 것입니다.
PECL은 공유 PHP 확장모듈을 만들기 쉽게 합니다. » pecl command 을 사용하려면, 다음을 따라하십시오.:
이 명령은 extname 소스를 다운받아 컴파일 하고, extname.so 를 extension_dir 에 설치할 것입니다. extname.so는 php.ini를 통해 로드될 것입니다.
기본적으로 pecl은 alpha나 beta 상태로 마크되어 있는 패키지는 설치하지 않을 것입니다. 만약에 stable 패키지가 없다면, 다음 명령을 사용해 beta 패키지를 설치 할수 있습니다.:
다음과 같이 변형하면 특정버전을 설치할수 있을것입니다.
Note: php.ini 에 확장모듈을 사용가능하도록 한 뒤에는, 그것이 반영되기 위해 웹서비스를 다시 시작해야 합니다.
가끔은, pecl 인스톨러를 사용하는것이 선택사항이 아닐수 있습니다. 방화벽뒤에 있거나, CVS의 릴리즈되지 않은 확장 모듈처럼 설치할 PECL 호환패키지가 없는것이 이유가 될 것입니다. 이런 확장모듈을 빌드할 필요가 있을 경우, 좀더 하위 레벨의 빌드툴을 사용하여 직접 빌드할수가 있습니다.
phpize 명령은 PHP 확장모듈을 위한 빌드환경을 만들기 위해 사용합니다. 아래의 샘플코드에는 확장모듈의 소스가 extname 이름의 디렉터리 안에 있습니다.:
$ cd extname $ phpize $ ./configure $ make # make install
성공적으로 인스톨되었다면 extname.so 이 생성될것이고, 그것을 PHP의 확장모듈 디렉터리 안에 위치시킬 것입니다. 확장 모듈을 사용하기전에 php.ini 에 extension=extname.so 라인의 추가가 필요할 것입니다.
만약에 시스템이 phpize 명령을 찾지 못하고, 미리컴파일된 패키지(RPM 같은)를 사용하고 있다면, 적절한 버전의 PHP devel 패키지를 설치하도록 합니다. 그것들은 대체로 phpize 명령 이외에 PHP와 확장모듈을 빌드할 적절한 헤더파일을 포함합니다.
phpize --help 를 실행하면 추가적인 사용법 정보를 볼수가 있습니다.
아마도 필요한 PECL 확장모듈을 PHP 바이너리 안에 정적으로 빌드하는 방법을 찾을 것입니다. 이것을 위해서는, 확장모듈 소스를 php-src/ext/ 디렉터리 아래에 위치시키고, PHP 빌드 시스템에 설정(configure) 스크립트를 다시 만들라고 말해줄 필요가 있습니다.
$ cd /your/phpsrcdir/ext $ pecl download extname $ gzip -d < extname.tgz | tar -xvf - $ mv extname-x.x.x extname
이 스크립트는 아래의 디렉터리를 만들어 냅니다.:
여기에서, 강제로 PHP 설정 스크립트를 리빌드 한다음, 통상적인 방법으로 PHP를 빌드하십시오:
Note: 'buildconf' 스크립트를 실행하기 위해서는 autoconf 2.13 버전과 automake 1.4+ 의 버전이 필요합니다. (새로운 버전의 autoconf는 동작할지도 모르나 지원되지 않을수도 있습니다.)
--enable-extname 이든 --with-extname 이든 그것들은 확장모듈 의존성을 위해 사용됩니다. 일반적으로 외부 라이브러리를 필요로하지 않는 확장모듈은 --enable 을 사용합니다. 확인을 위해 다음의 buildconf를 실행하십시오.:
아직도 문제에 봉착해 있다면, PHP 설치 메일링 리스트의 누군가는 도움을 줄수 있을 것입니다. 누군가 당신과 같은 문제를 가지고 있거나 답변이 없는지 제일 먼저 아카이브를 체크해야만 합니다. 아카이브는 » http://www.php.net/support.php의 서포트 페이지에서 제공 합니다. PHP 설치 메일링 리스트를 구독하기 위해서는, 빈(empty) 메일을 » php-install-subscribe@lists.php.net로 보내시기 바랍니다. 메일링 리스트 주소는 » php-install@lists.php.net 입니다.
메일링 리스트로부터 도움을 얻길 원한다면, 필요한 세부 환경( 어떤 운영체제 인지, PHP 버전이 무엇인지, 무슨 웹서버 인지, PHP를 돌리고 있다면 CGI방식인지 웹서버 모듈 방식인지, 안전 모드, 등등)과 함께, 되도록이면 다른 사람들이 문제를 재현하고 테스트 할수 있도록 충분한 코드를 명확하게 알려주시기 바랍니다.
PHP에서 버그를 찾은것 같다면, 그것을 보고해 주시기 바랍니다. PHP 개발자들은 그것에 관해 모를수도 있으며, 그것을 보고 하기 전에는, 충분히 그럴 가능성이 있습니다. » http://bugs.php.net/의 버그 트랙킹(bug-tracking) 시스템을 사용하여 버그를 보고 할 수 있습니다. 버그 보고를 메일링 리스트나 개인적인 편지로 보내지 마시기 바랍니다. 버그 시스템은 또한 기능요청을 제출 하기에 적합합니다.
어떤 버그를 보고하기 전에 » 버그를 보고하는 방법 을 읽어 보시기 바랍니다.
설정 파일(php.ini)은 PHP를 시작할 때 읽습니다. PHP 서버 모듈 버전은 웹 서버가 시작할 때 한번만 일어납니다. CGI와 CLI 버전에서는 매번 일어납니다.
php.ini는 세 위치에서 찾아집니다 (순서대로):
SAPI 모듈 지정 위치 (아파치 2에서 PHPIniDir 지시어, CGI와 CLI에서 -c 명령줄 옵션, NSAPI에서 php_ini 인수, THTTPD에서 PHP_INI_PATH 환경 변수)
PHPRC 환경 변수. PHP 5.2.0 이전에는 아래 언급한 레지스트리 키 이후에 확인했습니다.
PHP 5.2.0부터, 다음 레지스트리 위치가 순서대로 찾아집니다: HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x.y.z\IniFilePath, HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x.y\IniFilePath, HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x\IniFilePath. x, y, z는 PHP 메이저, 마이너, 릴리즈 버전을 의미합니다.
HKEY_LOCAL_MACHINE\SOFTWARE\PHP\IniFilePath (윈도우 레지스트리 위치)
현재 작업 디렉토리 (CLI 제외)
웹 서버 디렉토리(SAPI 모듈의 경우)나 PHP 디렉토리(윈도우 제외)
윈도우 디렉토리(C:\windows나 C:\winnt)(윈도우)나 --with-config-file-path 컴파일 시 옵션
php-SAPI.ini이 존재하면(SAPI는 사용하는 SAPI, 그러므로 파일명은 php-cli.ini, php-apache.ini 등), php.ini 대신 사용합니다. SAPI 이름은 php_sapi_name()으로 확인할 수 있습니다.
Note: 아파치 웹 서버는 시작할 때 디렉토리를 루트로 변경하므로, PHP는 루트 파일시스템에 php.ini가 존재할 경우 이를 읽으려고 시도합니다.
확장에 의해 다뤄지는 php.ini 지시어는 각 확장 페이지에 문서가 있습니다. 핵심 지시어 목록은 부록에 있습니다. 모든 PHP 지시어가 매뉴얼에 나와있지 않을 수 있습니다. PHP 버전에 따른 완전한 지시어 목록은, php.ini 파일을 읽어보십시오. 또는, CVS에서 » 최신 php.ini를 찾아볼 수 있습니다.
Example #1 php.ini 예제
; any text on a line after an unquoted semicolon (;) is ignored [php] ; section markers (text within square brackets) are also ignored ; Boolean values can be set to either: ; true, on, yes ; or false, off, no, none register_globals = off track_errors = yes ; you can enclose strings in double-quotes include_path = ".:/usr/local/lib/php" ; backslashes are treated the same as any other character include_path = ".;c:\php\lib"
PHP 5.1.0부터, .ini 파일 안에서 이미 존재하는 .ini 변수를 참조할 수 있습니다. 예: open_basedir = ${open_basedir} ":/new/dir".
이 모드는 PHP 지시어를 언제, 어디서 설정할 수 있는지 결정하고, 매뉴얼의 각 지시어는 이 모드를 참조합니다. 예를 들어, 몇몇 설정은 PHP 스크립트 안에서 ini_set()으로 설정할 수 있지만, 어떤 설정은 php.ini나 httpd.conf를 요구합니다.
예를 들어, output_buffering 설정은 PHP_INI_PERDIR이므로 ini_set()으로 설정할 수 없습니다. 그러나, display_errors 지시어는 PHP_INI_ALL이므로 ini_set()을 포함하여 어디에서라도 설정할 수 있습니다.
| 모드 | 의미 |
|---|---|
| PHP_INI_USER | 사용자 스크립트(ini_set() 등)나 윈도우 레지스트리에서 설정할 수 있습니다 |
| PHP_INI_PERDIR | php.ini, .htaccess, httpd.conf에서 설정할 수 있습니다 |
| PHP_INI_SYSTEM | php.ini나 httpd.conf에서 설정할 수 있습니다 |
| PHP_INI_ALL | 어디에서라도 설정할 수 있습니다 |
PHP를 아파치 모듈로 사용할 때, 아파치 설정 파일(즉 httpd.conf)과 .htaccess 파일에서 설정을 변경할 수 있습니다. 이를 위해서는 "AllowOverride Options"나 "AllowOverride All" 권한이 필요합니다.
몇몇 아파치 지시어는 PHP 설정을 아파치 설정 파일에서 바꿀 수 있게 합니다. 어떤 지시어가 PHP_INI_ALL, PHP_INI_PERDIR, PHP_INI_SYSTEM인지는, php.ini 지시어 목록 부록을 참고하십시오.
php_value
name
value
지정한 지시어의 값을 설정합니다. PHP_INI_ALL과 PHP_INI_PERDIR 형식 지시어에만 사용할 수 있습니다. 이전 설정 값을 지우려면 값에 none을 사용합니다.
Note:
php_value로 논리 값을 설정하지 마십시오. 대신php_flag(아래 참고)를 사용해야 합니다.
php_flag
name
on|off
논리값 지시어를 설정합니다. PHP_INI_ALL과 PHP_INI_PERDIR 형식 지시어에만 사용할 수 있습니다.
php_admin_value
name
value
지정한 지시어의 값을 설정합니다. .htaccess 파일에서 사용할
수 없습니다. php_admin_value
로 설정하는 지시어
형식은 .htaccess나 ini_set()으로 덮어쓸 수
없습니다. 이전 설정 값을 지우려면 값에 none을
사용합니다.
php_admin_flag
name
on|off
논리값 지시어를 설정합니다. .htaccess 파일에서 사용할
수 없습니다. php_admin_flag
로 설정하는 지시어
형식은 .htaccess로 덮어쓸 수 없습니다.
Example #1 아파치 설정 예제
<IfModule mod_php5.c> php_value include_path ".:/usr/local/lib/php" php_admin_flag safe_mode on </IfModule> <IfModule mod_php4.c> php_value include_path ".:/usr/local/lib/php" php_admin_flag safe_mode on </IfModule>
PHP 상수는 PHP 밖에 존재하지 않습니다. 예를 들어, httpd.conf에서 E_ALL나 E_NOTICE 등의 PHP 상수를 사용할 수 없습니다. error_reporting 지시어에 이런 설정을 하면, 아무런 의미를 가지지 않고 0으로 평가됩니다. 대신 할당된 비트마스크 값을 사용하십시오. 이런 상수는 php.ini에서는 사용할 수 있습니다.
PHP를 윈도우에서 실행할 때, 설정값은 윈도우 레지스트리를 사용하여 디렉토리 기반으로 변경할 수 있습니다. 설정값은 레지스트리 키 HKLM\SOFTWARE\PHP\Per Directory Values에 저장되며, 보조키는 경로명에 해당합니다. 예를 들어, c:\inetpub\wwwroot 디렉토리를 위한 설정값은 HKLM\SOFTWARE\PHP\Per Directory Values\c\inetpub\wwwroot 키에 저장됩니다. 디렉토리 설정은 이 디렉토리와 그 밑의 서브디렉토리에서 실행하는 모든 스크립트에 적용됩니다. 키 아래 값은 PHP 설정 지시어 이름을 가지고 문자열 값이여야 합니다. 값에 사용하는 PHP 상수는 해석되지 않습니다. 그러나, PHP_INI_USER로 바꿀 수 있는 설정값만 이 방법을 사용할 수 있습니다. PHP_INI_PERDIR 값은 사용할 수 없습니다.
PHP를 어떻게 실행하는가에 관계 없이, ini_set()으로 몇몇 값을 실행시에 변경할 수 있습니다. 자세한 정보는 ini_set() 페이지 문서를 참고하십시오.
시스템의 모든 설정 목록과 현재 값을 얻고 싶다면, phpinfo()를 실행하여 결과 페이지를 살펴보십시오. 각 설정 지시어의 값은 실행시에 ini_get()이나 get_cfg_var()를 사용하여 접근할 수 있습니다.
PHP가 파일을 해석할 때, PHP가 사이에 있는 코드를 해석하라고 하는 시작과 끝 태그를 찾습니다. 이런 방법의 해석은, 시작과 끝 태그 밖에 있는 부분은 PHP 해석기가 무시하게 됨으로써, php가 어떠한 종료의 문서에도 포함될 수 있도록 합니다. 대부분의 경우 다음 예제와 같이 php가 포함된 HTML 문서를 보게 될 것입니다.
<p>이 부분은 무시합니다.</p>
<?php echo '이 부분은 해석합니다.'; ?>
<p>이 부분도 무시합니다.</p>
좀 더 복잡한 구조도 사용할 수 있습니다:
Example #1 복잡한 벗어나기
<?php
if ($expression) {
?>
<strong>This is true.</strong>
<?php
} else {
?>
<strong>This is false.</strong>
<?php
}
?>
예상한 대로 작동합니다. PHP가 ?> 닫기 태그를 만나면, 그것이 무엇이던간에 다른 시작 태그를 만나기 전까지 단순히 출력하기 때문입니다. (바로 따라오는 줄바꿈 제외 - 명령 구분 참고) 물론, 여기서 주어진 예제는 부자연스럽지만 큰 텍스트 블록을 출력할 경우에는 PHP 해석 모드를 벗어나는 것이 모든 텍스트를 echo()나 print()를 통하여 전송하는 것보다 효율적입니다.
php에서 사용할 수 있는 네가지 형태의 시작과 끝 태그가 있습니다. 그 중 두가지, <?php ?>와 <script language="php"> </script>는 항상 사용할 수 있습니다. 두가지 짧은 태그와 ASP 형식 태그는 php.ini 설정 파일에서 끄거나 켤 수 있습니다. 그러므로, 몇몇 사람들에겐 짧은 태그나 ASP 형식 태그가 편할지는 몰라도, 이식성이 부족하므로 일반적으로 권하지 않습니다.
Note: PHP를 XML이나 XHTML에 넣을 경우 <?php ?> 태그를 사용해야 표준과 호환을 유지할 수 있습니다.
Example #2 PHP 시작과 끝 태그
1. <?php echo 'XHTML나 XML 문서와 호환시키려면, 이렇게 쓰세요'; ?>
2. <script language="php">
echo '어떤 에디터 (프론트페이지같은)는
처리 명령을 좋아하지 않습니다';
</script>
3. <? echo '이런 형태가 제일 간단한 SGML 처리명령입니다'; ?>
<?= expression ?>은 "<? echo expression ?>"을 간단히 쓴 모양입니다
4. <% echo ("ASP스타일 태그를 쓸 수도 있습니다"); %>
<%= $variable; # 이것은 "<% echo . . ." %>을 간단히 쓴 모양입니다
예제에서 볼 수 있는 태그 중 첫번째와 두번째는 항상 사용할 수 있지만, 둘 중 첫번째 예제가 가장 보편적으로 사용되며, 권장됩니다.
짧은 태그(예제 3)은 php.ini 설정 파일 지시어 short_open_tag를 활성화하거나, php를 --enable-short-tags 옵션으로 설정하였을 경우에만 사용할 수 있습니다.
ASP 형식 태그(예제 4)는 php.ini 설정 파일 지시어 asp_tags를 활성화 했을 경우에만 사용할 수 있습니다.
Note: 프로그램이나 재사용을 위한 라이브러리를 개발할때, 또는 통제밖의 PHP서버에 배치시킬때는 짧은 형 태그를 쓰는것은 피해야 한다. 왜냐하면 짧은 형 태그는 목표하는 서버에서 지원되지 않을수도 있기 때문이다. 이식성을 위해서, 재사용 코드는 짧은 형 태그로 쓰지 않도록 한다.
C나 펄처럼, PHP는 각 명령 구문 끝을 세미콜론으로 종료해야 합니다. PHP 코드 블록을 종료하면 자동으로 세미콜론을 적용합니다; PHP 블록의 마지막 줄에는 세미콜론 종료를 하지 않아도 됩니다. 블록의 닫기 태그는 바로 뒤에 따라올 수 있는 줄바꿈도 포함합니다.
<?php
echo 'This is a test';
?>
<?php echo 'This is a test' ?>
<?php echo '마지막 닫기 태그를 생략합니다';
Note: 파일의 마지막에서 PHP 블록의 닫기 태그를 생략할 수 있으며, 때로는 유용합니다. include()나 require()를 사용할 경우, 원하지 않은 공백이 파일 마지막에 들어가지 않게 함으로써, 나중에 추가 응답 헤더를 추가할 수 있습니다. 또한 출력 버퍼링을 사용할 경우에도 포함한 파일들에 의해서 각 파트의 마지막에 원하지 않은 공백을 피할 수 있으므로 도움이 됩니다.
PHP는 'C', 'C++', Unix 쉘 형식(펄 형식)의 주석(comment)형태를 지원한다. 예를 들면:
<?php
echo 'This is a test'; // 한줄짜리 c++ 스타일 주석
/* 여러줄의 주석
이줄까지 주석처리 된다 */
echo 'This is yet another test';
echo 'One Final Test'; # 쉘 형식의 한줄짜리 주석
?>
"한 줄" 주석 형식은 줄의 끝까지나 PHP 코드의 현재 블록까지 중, 먼저 오는 부분까지만 주석으로 처리합니다. 이는 // ... ?>나 # ... ?> 뒤에 오는 HTML 코드가 출력됨을 의미합니다: ?>는 PHP 모드를 종료하고 HTML 모드로 돌아가게 하므로, //나 #은 영향을 주지 않습니다. asp_tags 설정 지시어가 켜져 있으면, // %>나 # %>에도 동일하게 적용됩니다. 그러나, </script> 태그는 한 줄 주석에서 PHP 모드를 종료하지 않습니다.
<h1>This is an <?php # echo 'simple';?> example.</h1>
<p>The header above will say 'This is an example'.</p>
'C' 형식 주석은 첫 */에서 종료합니다. 그러므로 'C' 형식 주석을 중첩하지 않아야 합니다. 이는 큰 코드 블럭을 주석처리 하려고 할 경우에 자주 발생하는 실수입니다.
<?php
/*
echo 'This is a test'; /* 이 주석은 문제가 발생합니다 */
*/
?>
PHP는 여덟가지 기본 자료형을 지원합니다.
네가지 스칼라형:
두가지 복합형:
마지막으로 두가지 특별형:
이 매뉴얼에는 설명을 위해서 몇가지 모의형을 사용합니다:
그리고 모의 변수 $...
매뉴얼의 몇몇 레퍼런스에 "double" 형이 남아 있습니다. double은 float와 같다고 생각하십시오; 두 이름은 단지 역사적인 이유로 남아 있습니다.
변수의 자료형은 보통 프로그래머가 설정하지 않습니다; 대신, PHP가 변수가 사용되는 지점에 따라서 실행시에 자동으로 결정합니다.
Note: 표현에 따른 자료형과 값을 확인하려면, var_dump() 함수를 사용하십시오. 디버깅을 위해 자료형을 쉽게 읽을 수 있는 형태를 얻으려면, gettype() 함수를 사용하십시오. 특정한 자료형을 확인하려면 gettype()을 사용하지 말고 is_type 함수를 사용하십시오. 예를 들면:
<?php
$a_bool = TRUE; // 논리
$a_str = "foo"; // 문자열
$a_str = 'foo'; // 문자열
$an_int = 12; // 정수
echo gettype($a_bool); // 출력: boolean
echo gettype($a_str); // 출력: string
// 정수라면, 4 증가
if (is_int($an_int)) {
$an_int += 4;
}
// $bool이 문자열이라면, 출력
// (아무것도 출력하지 않음)
if (is_string($a_bool)) {
echo "문자열: $a_bool";
}
?>
변수를 강제로 특정 자료형으로 변환하려면, 변수를 형변환하거나 settype() 함수를 사용하십시오.
변수는 어떤 상황이냐에 따라서, 그 시점에 어떠한 자료형을 요구하냐에 따라서 다른 자료형으로 평가될 수 있습니다. 자세한 정보는 자료형 조절 섹션을 참고하십시오. 자료형 비교표도 유용합니다. 다양한 자료형 관련 비교 예제를 볼 수 있습니다.
This is the simplest type. A boolean expresses a truth value. It can be either TRUE or FALSE.
Note: The boolean type was introduced in PHP 4.
To specify a boolean literal, use the keywords TRUE or FALSE. Both are case-insensitive.
<?php
$foo = True; // assign the value TRUE to $foo
?>
Typically, some kind of operator which returns a boolean value, and the value is passed on to a control structure.
<?php
// == is an operator which test
// equality and returns a boolean
if ($action == "show_version") {
echo "The version is 1.23";
}
// this is not necessary...
if ($show_separators == TRUE) {
echo "<hr>\n";
}
// ...because instead, this can be used:
if ($show_separators) {
echo "<hr>\n";
}
?>
To explicitly convert a value to boolean, use the (bool) or (boolean) casts. However, in most cases the cast is unncecessary, since a value will be automatically converted if an operator, function or control structure requires a boolean argument.
See also Type Juggling.
When converting to boolean, the following values are considered FALSE:
Every other value is considered TRUE (including any resource).
-1 is considered TRUE, like any other non-zero (whether negative or positive) number!
<?php
var_dump((bool) ""); // bool(false)
var_dump((bool) 1); // bool(true)
var_dump((bool) -2); // bool(true)
var_dump((bool) "foo"); // bool(true)
var_dump((bool) 2.3e5); // bool(true)
var_dump((bool) array(12)); // bool(true)
var_dump((bool) array()); // bool(false)
var_dump((bool) "false"); // bool(true)
?>
An integer is a number of the set Z = {..., -2, -1, 0, 1, 2, ...}.
See also:
Integers can be specified in decimal (base 10), hexadecimal (base 16), or octal (base 8) notation, optionally preceded by a sign (- or +).
To use octal notation, precede the number with a 0 (zero). To use hexadecimal notation precede the number with 0x.
Example #1 Integer literals
<?php
$a = 1234; // decimal number
$a = -123; // a negative number
$a = 0123; // octal number (equivalent to 83 decimal)
$a = 0x1A; // hexadecimal number (equivalent to 26 decimal)
?>
Formally, the structure for integer literals is:
decimal : [1-9][0-9]*
| 0
hexadecimal : 0[xX][0-9a-fA-F]+
octal : 0[0-7]+
integer : [+-]?decimal
| [+-]?hexadecimal
| [+-]?octal
The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). PHP does not support unsigned integers. Integer size can be determined using the constant PHP_INT_SIZE, and maximum value using the constant PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5.
If an invalid digit is given in an octal integer (i.e. 8 or 9), the rest of the number is ignored.
Example #2 Octal weirdness
<?php
var_dump(01090); // 010 octal = 8 decimal
?>
If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead. Also, an operation which results in a number beyond the bounds of the integer type will return a float instead.
<?php
$large_number = 2147483647;
var_dump($large_number);
// output: int(2147483647)
$large_number = 2147483648;
var_dump($large_number);
// output: float(2147483648)
// it's true also for hexadecimal specified integers between 2^31 and 2^32-1:
var_dump( 0xffffffff );
// output: float(4294967295)
// this doesn't go for hexadecimal specified integers above 2^32-1:
var_dump( 0x100000000 );
// output: int(2147483647)
$million = 1000000;
$large_number = 50000 * $million;
var_dump($large_number);
// output: float(50000000000)
?>
Unfortunately, there was a bug in PHP which caused this to not always work correctly when negative numbers were involved. For example, the result of -50000 * $million is -429496728. However, when both operands were positive, there was no problem.
This was fixed in PHP 4.1.0.
There is no integer division operator in PHP. 1/2 yields the float 0.5. The value can be casted to an integer to round it downwards, or the round() function provides finer control over rounding.
<?php
var_dump(25/7); // float(3.5714285714286)
var_dump((int) (25/7)); // int(3)
var_dump(round(25/7)); // float(4)
?>
To explicitly convert a value to integer, use either the (int) or (integer) casts. However, in most cases the cast is not needed, since a value will be automatically converted if an operator, function or control structure requires an integer argument. A value can also be converted to integer with the intval() function.
See also: type-juggling.
FALSE will yield 0 (zero), and TRUE will yield 1 (one).
When converting from float to integer, the number will be rounded towards zero.
If the float is beyond the boundaries of integer (usually +/- 2.15e+9 = 2^31), the result is undefined, since the float doesn't have enough precision to give an exact integer result. No warning, not even a notice will be issued when this happens!
Never cast an unknown fraction to integer, as this can sometimes lead to unexpected results.
<?php
echo (int) ( (0.1+0.7) * 10 ); // echoes 7!
?>
See also the warning about float precision.
The behaviour of converting to integer is undefined for other types. Do not rely on any observed behaviour, as it can change without notice.
Floating point numbers (also known as "floats", "doubles", or "real numbers") can be specified using any of the following syntaxes:
<?php
$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
?>
Formally:
LNUM [0-9]+
DNUM ([0-9]*[\.]{LNUM}) | ({LNUM}[\.][0-9]*)
EXPONENT_DNUM [+-]?(({LNUM} | {DNUM}) [eE][+-]? {LNUM})
The size of a float is platform-dependent, although a maximum of ~1.8e308 with a precision of roughly 14 decimal digits is a common value (the 64 bit IEEE format).
It is typical that simple decimal fractions like 0.1 or 0.7 cannot be converted into their internal binary counterparts without a small loss of precision. This can lead to confusing results: for example, floor((0.1+0.7)*10) will usually return 7 instead of the expected 8, since the internal representation will be something like 7.9.
This is due to the fact that it is impossible to express some fractions in decimal notation with a finite number of digits. For instance, 1/3 in decimal form becomes 0.3.
So never trust floating number results to the last digit, and never compare floating point numbers for equality. If higher precision is necessary, the arbitrary precision math functions and gmp functions are available.
For information on converting strings to float, see String conversion to numbers. For values of other types, the conversion is performed by converting the value to integer first and then to float. See Converting to integer for more information. As of PHP 5, a notice is thrown if an object is converted to float.
A string is series of characters. Before PHP 6, a character is the same as a byte. That is, there are exactly 256 different characters possible. This also implies that PHP has no native support of Unicode. See utf8_encode() and utf8_decode() for some basic Unicode functionality.
Note: It is no problem for a string to become very large. PHP imposes no boundary on the size of a string; the only limit is the available memory of the computer on which PHP is running.
A string literal can be specified in four different ways:
The simplest way to specify a string is to enclose it in single quotes (the character ').
To specify a literal single quote, escape it with a backslash (\). To specify a literal backslash before a single quote, or at the end of the string, double it (\\). Note that attempting to escape any other character will print the backslash too.
Note: Unlike the two other syntaxes, variables and escape sequences for special characters will not be expanded when they occur in single quoted strings.
<?php
echo 'this is a simple string';
echo 'You can also have embedded newlines in
strings this way as it is
okay to do';
// Outputs: Arnold once said: "I'll be back"
echo 'Arnold once said: "I\'ll be back"';
// Outputs: You deleted C:\*.*?
echo 'You deleted C:\\*.*?';
// Outputs: You deleted C:\*.*?
echo 'You deleted C:\*.*?';
// Outputs: This will not expand: \n a newline
echo 'This will not expand: \n a newline';
// Outputs: Variables do not $expand $either
echo 'Variables do not $expand $either';
?>
If the string is enclosed in double-quotes ("), PHP will interpret more escape sequences for special characters:
| Sequence | Meaning |
|---|---|
| \n | linefeed (LF or 0x0A (10) in ASCII) |
| \r | carriage return (CR or 0x0D (13) in ASCII) |
| \t | horizontal tab (HT or 0x09 (9) in ASCII) |
| \v | vertical tab (VT or 0x0B (11) in ASCII) (since PHP 5.2.5) |
| \f | form feed (FF or 0x0C (12) in ASCII) (since PHP 5.2.5) |
| \\ | backslash |
| \$ | dollar sign |
| \" | double-quote |
| \[0-7]{1,3} | the sequence of characters matching the regular expression is a character in octal notation |
| \x[0-9A-Fa-f]{1,2} | the sequence of characters matching the regular expression is a character in hexadecimal notation |
As in single quoted strings, escaping any other character will result in the backslash being printed too. Before PHP 5.1.1, the backslash in \{$var} had not been printed.
The most important feature of double-quoted strings is the fact that variable names will be expanded. See string parsing for details.
A third way to delimit strings is the heredoc syntax: <<<. After this operator, an identifier is provided, then a newline. The string itself follows, and then the same identifier again to close the quotation.
The closing identifier must begin in the first column of the line. Also, the identifier must follow the same naming rules as any other label in PHP: it must contain only alphanumeric characters and underscores, and must start with a non-digit character or underscore.
It is very important to note that the line with the closing identifier must contain no other characters, except possibly a semicolon (;). That means especially that the identifier may not be indented, and there may not be any spaces or tabs before or after the semicolon. It's also important to realize that the first character before the closing identifier must be a newline as defined by the local operating system. This is \n on UNIX systems, including Mac OS X. The closing delimiter (possibly followed by a semicolon) must also be followed by a newline.
If this rule is broken and the closing identifier is not "clean", it will not be considered a closing identifier, and PHP will continue looking for one. If a proper closing identifier is not found before the end of the current file, a parse error will result at the last line.
Heredocs can not be used for initializing class members. Since PHP 5.3, this limitation is valid only for heredocs containing variables.
Example #1 Invalid example
<?php
class foo {
public $bar = <<<EOT
bar
EOT;
}
?>
Heredoc text behaves just like a double-quoted string, without the double quotes. This means that quotes in a heredoc do not need to be escaped, but the escape codes listed above can still be used. Variables are expanded, but the same care must be taken when expressing complex variables inside a heredoc as with strings.
Example #2 Heredoc string quoting example
<?php
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;
/* More complex example, with variables. */
class foo
{
var $foo;
var $bar;
function foo()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'MyName';
echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;
?>
위 예제의 출력:
My name is "MyName". I am printing some Foo. Now, I am printing some Bar2. This should print a capital 'A': A
It is also possible to use the Heredoc syntax to pass data to function arguments:
Example #3 Heredoc in arguments example
<?php
var_dump(array(<<<EOD
foobar!
EOD
));
?>
As of PHP 5.3.0, its possible to initialize static variables and class members/constants using the Heredoc syntax:
Example #4 Using Heredoc to initialize static values
<?php
// Static variables
function foo()
{
static $bar = <<<LABEL
Nothing in here...
LABEL;
}
// Class members/constants
class foo
{
const BAR = <<<FOOBAR
Constant example
FOOBAR;
public $baz = <<<FOOBAR
Property example
FOOBAR;
}
?>
PHP 5.3.0 also introduces the possibility for Heredoc's to use double quotes in declarings:
Example #5 Using double quotes in Heredoc
<?php
echo <<<"FOOBAR"
Hello World!
FOOBAR;
?>
Note: Heredoc support was added in PHP 4.
Nowdocs are to single-quoted strings what heredocs are to double-quoted strings. A nowdoc is specified similarly to a heredoc, but no parsing is done inside a nowdoc. The construct is ideal for embedding PHP code or other large blocks of text without the need for escaping. It shares some features in common with the SGML <![CDATA[ ]]> construct, in that it declares a block of text which is not for parsing.
A nowdoc is identified with the same <<< seqeuence used for heredocs, but the identifier which follows is enclosed in single quotes, e.g. <<<'EOT'. All the rules for heredoc identifiers also apply to nowdoc identifiers, especially those regarding the appearance of the closing identifier.
Example #6 Nowdoc string quoting example
<?php
$str = <<<'EOD'
Example of string
spanning multiple lines
using nowdoc syntax.
EOD;
/* More complex example, with variables. */
class foo
{
public $foo;
public $bar;
function foo()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'MyName';
echo <<<'EOT'
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41
EOT;
?>
위 예제의 출력:
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41Note: Unlike heredocs, nowdocs can be used in any static data context. The typical example is initializing class members or constants:
Example #7 Static data example
<?php
class foo {
public $bar = <<<'EOT'
bar
EOT;
}
?>
Note: Nowdoc support was added in PHP 5.3.0.
When a string is specified in double quotes or with heredoc, variables are parsed within it.
There are two types of syntax: a simple one and a complex one. The simple syntax is the most common and convenient. It provides a way to embed a variable, an array value, or an object property in a string with a minimum of effort.
The complex syntax was introduced in PHP 4, and can be recognised by the curly braces surrounding the expression.
If a dollar sign ($) is encountered, the parser will greedily take as many tokens as possible to form a valid variable name. Enclose the variable name in curly braces to explicitly specify the end of the name.
<?php
$beer = 'Heineken';
echo "$beer's taste is great"; // works; "'" is an invalid character for variable names
echo "He drank some $beers"; // won't work; 's' is a valid character for variable names but the variable is "$beer"
echo "He drank some ${beer}s"; // works
echo "He drank some {$beer}s"; // works
?>
Similarly, an array index or an object property can be parsed. With array indices, the closing square bracket (]) marks the end of the index. The same rules apply to object properties as to simple variables.
<?php
// These examples are specific to using arrays inside of strings.
// When outside of a string, always quote array string keys and do not use
// {braces}.
// Show all errors
error_reporting(E_ALL);
$fruits = array('strawberry' => 'red', 'banana' => 'yellow');
// Works, but note that this works differently outside a string
echo "A banana is $fruits[banana].";
// Works
echo "A banana is {$fruits['banana']}.";
// Works, but PHP looks for a constant named banana first, as described below.
echo "A banana is {$fruits[banana]}.";
// Won't work, use braces. This results in a parse error.
echo "A banana is $fruits['banana'].";
// Works
echo "A banana is " . $fruits['banana'] . ".";
// Works
echo "This square is $square->width meters broad.";
// Won't work. For a solution, see the complex syntax.
echo "This square is $square->width00 centimeters broad.";
?>
For anything more complex, you should use the complex syntax.
This isn't called complex because the syntax is complex, but because it allows for the use of complex expressions.
In fact, any value in the namespace can be included in a string with this syntax. Simply write the expression the same way as it would have appeared outside the string, and then wrap it in { and }. Since { can not be escaped, this syntax will only be recognised when the $ immediately follows the {. Use {\$ to get a literal {$. Some examples to make it clear:
<?php
// Show all errors
error_reporting(E_ALL);
$great = 'fantastic';
// Won't work, outputs: This is { fantastic}
echo "This is { $great}";
// Works, outputs: This is fantastic
echo "This is {$great}";
echo "This is ${great}";
// Works
echo "This square is {$square->width}00 centimeters broad.";
// Works
echo "This works: {$arr[4][3]}";
// This is wrong for the same reason as $foo[bar] is wrong outside a string.
// In other words, it will still work, but only because PHP first looks for a
// constant named foo; an error of level E_NOTICE (undefined constant) will be
// thrown.
echo "This is wrong: {$arr[foo][3]}";
// Works. When using multi-dimensional arrays, always use braces around arrays
// when inside of strings
echo "This works: {$arr['foo'][3]}";
// Works.
echo "This works: " . $arr['foo'][3];
echo "This works too: {$obj->values[3]->name}";
echo "This is the value of the var named $name: {${$name}}";
echo "This is the value of the var named by the return value of getName(): {${getName()}}";
echo "This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}";
?>
Note: Functions and method calls inside {$} work since PHP 5.
Characters within strings may be accessed and modified by specifying the zero-based offset of the desired character after the string using square array brackets, as in $str[42]. Think of a string as an array of characters for this purpose.
Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose. However, this syntax is deprecated as of PHP 6. Use square brackets instead.
Writing to an out of range offset pads the string with spaces. Non-integer types are converted to integer. Illegal offset type emits E_NOTICE. Negative offset emits E_NOTICE in write but reads empty string. Only the first character of an assigned string is used. Assigning empty string assigns NUL byte.
Example #8 Some string examples
<?php
// Get the first character of a string
$str = 'This is a test.';
$first = $str[0];
// Get the third character of a string
$third = $str[2];
// Get the last character of a string.
$str = 'This is still a test.';
$last = $str[strlen($str)-1];
// Modify the last character of a string
$str = 'Look at the sea';
$str[strlen($str)-1] = 'e';
?>
Note: Accessing variables of other types using [] or {} silently returns NULL.
Strings may be concatenated using the '.' (dot) operator. Note that the '+' (addition) operator will not work for this. See String operators for more information.
There are a number of useful functions for string manipulation.
See the string functions section for general functions, and the regular expression functions or the Perl-compatible regular expression functions for advanced find & replace functionality.
There are also functions for URL strings, and functions to encrypt/decrypt strings (mcrypt and mhash).
Finally, see also the character type functions.
A value can be converted to a string using the (string) cast or the strval() function. String conversion is automatically done in the scope of an expression where a string is needed. This happens when using the echo() or print() functions, or when a variable is compared to a string. The sections on Types and Type Juggling will make the following clearer. See also the settype() function.
A boolean TRUE value is converted to the string "1". Boolean FALSE is converted to "" (the empty string). This allows conversion back and forth between boolean and string values.
An integer or float is converted to a string representing the number textually (including the exponent part for floats). Floating point numbers can be converted using exponential notation (4.1E+6).
Note: The decimal point character is defined in the script's locale (category LC_NUMERIC). See the setlocale() function.
Arrays are always converted to the string "Array"; because of this, echo() and print() can not by themselves show the contents of an array. To view a single element, use a construction such as echo $arr['foo']. See below for tips on viewing the entire contents.
Objects in PHP 4 are always converted to the string "Object". To print the values of object members for debugging reasons, read the paragraphs below. To get an object's class name, use the get_class() function. As of PHP 5, the __toString method is used when applicable.
Resources are always converted to strings with the structure "Resource id #1", where 1 is the unique number assigned to the resource by PHP at runtime. Do not rely upon this structure; it is subject to change. To get a resource's type, use the get_resource_type() function.
NULL is always converted to an empty string.
As stated above, directly converting an array, object, or resource to a string does not provide any useful information about the value beyond its type. See the functions print_r() and var_dump() for more effective means of inspecting the contents of these types.
Most PHP values can also be converted to strings for permanent storage. This method is called serialization, and is performed by the serialize() function. If the PHP engine was built with WDDX support, PHP values can also be serialized as well-formed XML text.
When a string is evaluated in a numeric context, the resulting value and type are determined as follows.
If the string does not contain any of the characters '.', 'e', or 'E' and the numeric value fits into integer type limits (as defined by PHP_INT_MAX), the string will be evaluated as an integer. In all other cases it will be evaluated as a float.
The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an 'e' or 'E' followed by one or more digits.
<?php
$foo = 1 + "10.5"; // $foo is float (11.5)
$foo = 1 + "-1.3e3"; // $foo is float (-1299)
$foo = 1 + "bob-1.3e3"; // $foo is integer (1)
$foo = 1 + "bob3"; // $foo is integer (1)
$foo = 1 + "10 Small Pigs"; // $foo is integer (11)
$foo = 4 + "10.2 Little Piggies"; // $foo is float (14.2)
$foo = "10.0 pigs " + 1; // $foo is float (11)
$foo = "10.0 pigs " + 1.0; // $foo is float (11)
?>
For more information on this conversion, see the Unix manual page for strtod(3).
To test any of the examples in this section, cut and paste the examples and insert the following line to see what's going on:
<?php
echo "\$foo==$foo; type is " . gettype ($foo) . "<br />\n";
?>
Do not expect to get the code of one character by converting it to integer, as is done in C. Use the ord() and chr() functions to convert between ASCII codes and characters.
An array in PHP is actually an ordered map. A map is a type that associates values to keys. This type is optimized for several different uses; it can be treated as an array, list (vector), hash table (an implementation of a map), dictionary, collection, stack, queue, and probably more. As array values can be other arrays, trees and multidimensional arrays are also possible.
Explanation of those data structures is beyond the scope of this manual, but at least one example is provided for each of them. For more information, look towards the considerable literature that exists about this broad topic.
An array can be created by the array() language construct. It takes as parameters any number of comma-separated key => value pairs.
array( key => value , ... ) // key may only be an integer or string // value may be any value of any type
<?php
$arr = array("foo" => "bar", 12 => true);
echo $arr["foo"]; // bar
echo $arr[12]; // 1
?>
A key may be either an integer or a string. If a key is the standard representation of an integer, it will be interpreted as such (i.e. "8" will be interpreted as 8, while "08" will be interpreted as "08"). Floats in key are truncated to integer. The indexed and associative array types are the same type in PHP, which can both contain integer and string indices.
A value can be any PHP type.
<?php
$arr = array("somearray" => array(6 => 5, 13 => 9, "a" => 42));
echo $arr["somearray"][6]; // 5
echo $arr["somearray"][13]; // 9
echo $arr["somearray"]["a"]; // 42
?>
If a key is not specified for a value, the maximum of the integer indices is taken and the new key will be that value plus 1. If a key that already has an assigned value is specified, that value will be overwritten.
<?php
// This array is the same as ...
array(5 => 43, 32, 56, "b" => 12);
// ...this array
array(5 => 43, 6 => 32, 7 => 56, "b" => 12);
?>
Before PHP 4.3.0, appending to an array in which the current maximum key was negative would create a new key as described above. Since PHP 4.3.0, the new key will be 0.
Using TRUE as key will evaluate to integer 1 as a key. Using FALSE as key will evaluate to integer 0 as a key. Using NULL as a key will evaluate to the empty string. Using the empty string as a key will create (or overwrite) a key with the empty string and its value; it is not the same as using empty brackets.
Arrays and objects can not be used as keys. Doing so will result in a warning: Illegal offset type.
An existing array can be modified by explicitly setting values in it.
This is done by assigning values to the array, specifying the key in brackets. The key can also be omitted, resulting in an empty pair of brackets ([]).
$arr[key] = value; $arr[] = value; // key may be an integer or string // value may be any value of any type
If $arr doesn't exist yet, it will be created, so this is also an alternative way to create an array. To change a certain value, assign a new value to that element using its key. To remove a key/value pair, call the unset() function on it.
<?php
$arr = array(5 => 1, 12 => 2);
$arr[] = 56; // This is the same as $arr[13] = 56;
// at this point of the script
$arr["x"] = 42; // This adds a new element to
// the array with key "x"
unset($arr[5]); // This removes the element from the array
unset($arr); // This deletes the whole array
?>
Note: As mentioned above, if no key is specified, the maximum of the existing integer indices is taken, and the new key will be that maximum value plus 1. If no integer indices exist yet, the key will be 0 (zero).
Note that the maximum integer key used for this need not currently exist in the array. It need only have existed in the array at some time since the last time the array was re-indexed. The following example illustrates:
<?php
// Create a simple array.
$array = array(1, 2, 3, 4, 5);
print_r($array);
// Now delete every item, but leave the array itself intact:
foreach ($array as $i => $value) {
unset($array[$i]);
}
print_r($array);
// Append an item (note that the new key is 5, instead of 0).
$array[] = 6;
print_r($array);
// Re-index:
$array = array_values($array);
$array[] = 7;
print_r($array);
?>위 예제의 출력:
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 ) Array ( ) Array ( [5] => 6 ) Array ( [0] => 6 [1] => 7 )
There are quite a few useful functions for working with arrays. See the array functions section.
Note: The unset() function allows removing keys from an array. Be aware that the array will not be reindexed. If a true "remove and shift" behavior is desired, the array can be reindexed using the array_values() function.
<?php
$a = array(1 => 'one', 2 => 'two', 3 => 'three');
unset($a[2]);
/* will produce an array that would have been defined as
$a = array(1 => 'one', 3 => 'three');
and NOT
$a = array(1 => 'one', 2 =>'three');
*/
$b = array_values($a);
// Now $b is array(0 => 'one', 1 =>'three')
?>
The foreach control structure exists specifically for arrays. It provides an easy way to traverse an array.
Always use quotes around a string literal array index. For example, $foo['bar'] is correct, while $foo[bar] is not. But why? It is common to encounter this kind of syntax in old scripts:
<?php
$foo[bar] = 'enemy';
echo $foo[bar];
// etc
?>
This is wrong, but it works. The reason is that this code has an undefined constant (bar) rather than a string ('bar' - notice the quotes). PHP may in future define constants which, unfortunately for such code, have the same name. It works because PHP automatically converts a bare string (an unquoted string which does not correspond to any known symbol) into a string which contains the bare string. For instance, if there is no defined constant named bar, then PHP will substitute in the string 'bar' and use that.
Note: This does not mean to always quote the key. Do not quote keys which are constants or variables, as this will prevent PHP from interpreting them.
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('html_errors', false);
// Simple array:
$array = array(1, 2);
$count = count($array);
for ($i = 0; $i < $count; $i++) {
echo "\nChecking $i: \n";
echo "Bad: " . $array['$i'] . "\n";
echo "Good: " . $array[$i] . "\n";
echo "Bad: {$array['$i']}\n";
echo "Good: {$array[$i]}\n";
}
?>위 예제의 출력:
Checking 0: Notice: Undefined index: $i in /path/to/script.html on line 9 Bad: Good: 1 Notice: Undefined index: $i in /path/to/script.html on line 11 Bad: Good: 1 Checking 1: Notice: Undefined index: $i in /path/to/script.html on line 9 Bad: Good: 2 Notice: Undefined index: $i in /path/to/script.html on line 11 Bad: Good: 2
More examples to demonstrate this behaviour:
<?php
// Show all errors
error_reporting(E_ALL);
$arr = array('fruit' => 'apple', 'veggie' => 'carrot');
// Correct
print $arr['fruit']; // apple
print $arr['veggie']; // carrot
// Incorrect. This works but also throws a PHP error of level E_NOTICE because
// of an undefined constant named fruit
//
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit]; // apple
// This defines a constant to demonstrate what's going on. The value 'veggie'
// is assigned to a constant named fruit.
define('fruit', 'veggie');
// Notice the difference now
print $arr['fruit']; // apple
print $arr[fruit]; // carrot
// The following is okay, as it's inside a string. Constants are not looked for
// within strings, so no E_NOTICE occurs here
print "Hello $arr[fruit]"; // Hello apple
// With one exception: braces surrounding arrays within strings allows constants
// to be interpreted
print "Hello {$arr[fruit]}"; // Hello carrot
print "Hello {$arr['fruit']}"; // Hello apple
// This will not work, and will result in a parse error, such as:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// This of course applies to using superglobals in strings as well
print "Hello $arr['fruit']";
print "Hello $_GET['foo']";
// Concatenation is another option
print "Hello " . $arr['fruit']; // Hello apple
?>
When error_reporting is set to show E_NOTICE level errors (by setting it to E_ALL, for example), such uses will become immediately visible. By default, error_reporting is set not to show notices.
As stated in the syntax section, what's inside the square brackets ('[' and ']') must be an expression. This means that code like this works:
<?php
echo $arr[somefunc($bar)];
?>
This is an example of using a function return value as the array index. PHP also knows about constants:
<?php
$error_descriptions[E_ERROR] = "A fatal error has occured";
$error_descriptions[E_WARNING] = "PHP issued a warning";
$error_descriptions[E_NOTICE] = "This is just an informal notice";
?>
Note that E_ERROR is also a valid identifier, just like bar in the first example. But the last example is in fact the same as writing:
<?php
$error_descriptions[1] = "A fatal error has occured";
$error_descriptions[2] = "PHP issued a warning";
$error_descriptions[8] = "This is just an informal notice";
?>
because E_ERROR equals 1, etc.
At some point in the future, the PHP team might want to add another constant or keyword, or a constant in other code may interfere. For example, it is already wrong to use the words empty and default this way, since they are reserved keywords.
Note: To reiterate, inside a double-quoted string, it's valid to not surround array indexes with quotes so "$foo[bar]" is valid. See the above examples for details on why as well as the section on variable parsing in strings.
For any of the types: integer, float, string, boolean and resource, converting a value to an array results in an array with a single element with index zero and the value of the scalar which was converted. In other words, (array)$scalarValue is exactly the same as array($scalarValue).
If an object is converted to an array, the result is an array whose elements are the object's properties. The keys are the member variable names, with a few notable exceptions: integer properties are unaccessible; private variables have the class name prepended to the variable name; protected variables have a '*' prepended to the variable name. These prepended values have null bytes on either side. This can result in some unexpected behaviour:
<?php
class A {
private $A; // This will become '\0A\0A'
}
class B extends A {
private $A; // This will become '\0B\0A'
public $AA; // This will become 'AA'
}
var_dump((array) new B());
?>
The above will appear to have two keys named 'AA', although one of them is actually named '\0A\0A'.
It is possible to compare arrays with the array_diff() function and with array operators.
The array type in PHP is very versatile. Here are some examples:
<?php
// This:
$a = array( 'color' => 'red',
'taste' => 'sweet',
'shape' => 'round',
'name' => 'apple',
4 // key will be 0
);
$b = array('a', 'b', 'c');
// . . .is completely equivalent with this:
$a = array();
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name'] = 'apple';
$a[] = 4; // key will be 0
$b = array();
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// After the above code is executed, $a will be the array
// array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round',
// 'name' => 'apple', 0 => 4), and $b will be the array
// array(0 => 'a', 1 => 'b', 2 => 'c'), or simply array('a', 'b', 'c').
?>
Example #1 Using array()
<?php
// Array as (property-)map
$map = array( 'version' => 4,
'OS' => 'Linux',
'lang' => 'english',
'short_tags' => true
);
// strictly numerical keys
$array = array( 7,
8,
0,
156,
-10
);
// this is the same as array(0 => 7, 1 => 8, ...)
$switching = array( 10, // key = 0
5 => 6,
3 => 7,
'a' => 4,
11, // key = 6 (maximum of integer-indices was 5)
'8' => 2, // key = 8 (integer!)
'02' => 77, // key = '02'
0 => 12 // the value 10 will be overwritten by 12
);
// empty array
$empty = array();
?>
Example #2 Collection
<?php
$colors = array('red', 'blue', 'green', 'yellow');
foreach ($colors as $color) {
echo "Do you like $color?\n";
}
?>
위 예제의 출력:
Do you like red? Do you like blue? Do you like green? Do you like yellow?
Changing the values of the array directly is possible since PHP 5 by passing them by reference. Before that, a workaround is necessary:
Example #3 Collection
<?php
// PHP 5
foreach ($colors as &$color) {
$color = strtoupper($color);
}
unset($color); /* ensure that following writes to
$color will not modify the last array element */
// Workaround for older versions
foreach ($colors as $key => $color) {
$colors[$key] = strtoupper($color);
}
print_r($colors);
?>
위 예제의 출력:
Array
(
[0] => RED
[1] => BLUE
[2] => GREEN
[3] => YELLOW
)
This example creates a one-based array.
Example #4 One-based index
<?php
$firstquarter = array(1 => 'January', 'February', 'March');
print_r($firstquarter);
?>
위 예제의 출력:
Array
(
[1] => 'January'
[2] => 'February'
[3] => 'March'
)
Example #5 Filling an array
<?php
// fill an array with all items from a directory
$handle = opendir('.');
while (false !== ($file = readdir($handle))) {
$files[] = $file;
}
closedir($handle);
?>
Arrays are ordered. The order can be changed using various sorting functions. See the array functions section for more information. The count() function can be used to count the number of items in an array.
Example #6 Sorting an array
<?php
sort($files);
print_r($files);
?>
Because the value of an array can be anything, it can also be another array. This enables the creation of recursive and multi-dimensional arrays.
Example #7 Recursive and multi-dimensional arrays
<?php
$fruits = array ( "fruits" => array ( "a" => "orange",
"b" => "banana",
"c" => "apple"
),
"numbers" => array ( 1,
2,
3,
4,
5,
6
),
"holes" => array ( "first",
5 => "second",
"third"
)
);
// Some examples to address values in the array above
echo $fruits["holes"][5]; // prints "second"
echo $fruits["fruits"]["a"]; // prints "orange"
unset($fruits["holes"][0]); // remove "first"
// Create a new multi-dimensional array
$juices["apple"]["green"] = "good";
?>
Array assignment always involves value copying. Use the reference operator to copy an array by reference.
<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 is changed,
// $arr1 is still array(2, 3)
$arr3 = &$arr1;
$arr3[] = 4; // now $arr1 and $arr3 are the same
?>
To create a new object, use the new statement to instantiate a class:
<?php
class foo
{
function do_foo()
{
echo "Doing foo.";
}
}
$bar = new foo;
$bar->do_foo();
?>
For a full discussion, see the Classes and Objects chapter.
If an object is converted to an object, it is not modified. If a value of any other type is converted to an object, a new instance of the stdClass built-in class is created. If the value was NULL, the new instance will be empty. Arrays convert to an object with properties named by keys, and corresponding values. For any other value, a member variable named scalar will contain the value.
<?php
$obj = (object) 'ciao';
echo $obj->scalar; // outputs 'ciao'
?>
A resource is a special variable, holding a reference to an external resource. Resources are created and used by special functions. See the appendix for a listing of all these functions and the corresponding resource types.
Note: The resource type was introduced in PHP 4
See also the get_resource_type() function.
As resource variables hold special handlers to opened files, database connections, image canvas areas and the like, converting to a resource makes no sense.
Thanks to the reference-counting system introduced with PHP 4's Zend Engine, a resource with no more references to it is detected automatically, and it is freed by the garbage collector. For this reason, it is rarely necessary to free the memory manually.
Note: Persistent database links are an exception to this rule. They are not destroyed by the garbage collector. See the persistent connections section for more information.
The special NULL value represents a variable with no value. NULL is the only possible value of type NULL.
Note: The null type was introduced in PHP 4.
A variable is considered to be null if:
it has been assigned the constant NULL.
it has not been set to any value yet.
it has been unset().
There is only one value of type null, and that is the case-insensitive keyword NULL.
<?php
$var = NULL;
?>
Casting a variable to null will remove the variable and unset its value.
mixed indicates that a parameter may accept multiple (but not necessarily all) types.
gettype() for example will accept all PHP types, while str_replace() will accept strings and arrays.
Some functions like call_user_func() or usort() accept user-defined callback functions as a parameter. Callback functions can not only be simple functions, but also object methods, including static class methods.
A PHP function is passed by its name as a string. Any built-in or user-defined function can be used, except language constructs such as: array(), echo(), empty(), eval(), exit(), isset(), list(), print() or unset().
A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1.
Static class methods can also be passed without instantiating an object of that class by passing the class name instead of an object at index 0.
Apart from common user-defined function, create_function() can also be used to create an anonymous callback function. As of PHP 5.3.0 its possible to also pass a closure to a callback parameter.
Example #1 Callback function examples
<?php
// An example callback function
function my_callback_function() {
echo 'hello world!';
}
// An example callback method
class MyClass {
static function myCallbackMethod() {
echo 'Hello World!';
}
}
// Type 1: Simple callback
call_user_func('my_callback_function');
// Type 2: Static class method call
call_user_func(array('MyClass', 'myCallbackMethod'));
// Type 3: Object method call
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));
// Type 4: Static class method call (As of PHP 5.2.3)
call_user_func('MyClass::myCallbackMethod');
// Type 5: Relative static class method call (As of PHP 5.3.0)
class A {
public static function who() {
echo "A\n";
}
}
class B extends A {
public static function who() {
echo "B\n";
}
}
call_user_func(array('B', 'parent::who')); // A
?>
Example #2 Callback example using a Closure
<?php
// Our closure
$double = function($a) {
return $a * 2;
};
// This is our range of numbers
$numbers = range(1, 5);
// Use the closure as a callback here to
// double the size of each element in our
// range
$new_numbers = array_map($double, $numbers);
print implode(' ', $new_numbers);
?>
위 예제의 출력:
2 4 6 8 10
Note: In PHP4, it was necessary to use a reference to create a callback that points to the actual object, and not a copy of it. For more details, see References Explained.
void as a return type means that the return value is useless. void in a parameter list means that the function doesn't accept any parameters.
$... in function prototypes means and so on. This variable name is used when a function can take an endless number of arguments.
PHP does not require (or support) explicit type definition in variable declaration; a variable's type is determined by the context in which the variable is used. That is to say, if a string value is assigned to variable $var, $var becomes a string. If an integer value is then assigned to $var, it becomes an integer.
An example of PHP's automatic type conversion is the addition operator '+'. If either operand is a float, then both operands are evaluated as floats, and the result will be a float. Otherwise, the operands will be interpreted as integers, and the result will also be an integer. Note that this does not change the types of the operands themselves; the only change is in how the operands are evaluated and what the type of the expression itself is.
<?php
$foo = "0"; // $foo is string (ASCII 48)
$foo += 2; // $foo is now an integer (2)
$foo = $foo + 1.3; // $foo is now a float (3.3)
$foo = 5 + "10 Little Piggies"; // $foo is integer (15)
$foo = 5 + "10 Small Pigs"; // $foo is integer (15)
?>
If the last two examples above seem odd, see String conversion to numbers.
To force a variable to be evaluated as a certain type, see the section on Type casting. To change the type of a variable, see the settype() function.
To test any of the examples in this section, use the var_dump() function.
Note: The behaviour of an automatic conversion to array is currently undefined.
Also, because PHP supports indexing into strings via offsets using the same syntax as array indexing, the following example holds true for all PHP versions:
<?php
$a = 'car'; // $a is a string
$a[0] = 'b'; // $a is still a string
echo $a; // bar
?>See the section titled String access by character for more information.
Type casting in PHP works much as it does in C: the name of the desired type is written in parentheses before the variable which is to be cast.
<?php
$foo = 10; // $foo is an integer
$bar = (boolean) $foo; // $bar is a boolean
?>
The casts allowed are:
(binary) casting and b prefix forward support was added in PHP 5.2.1
Note that tabs and spaces are allowed inside the parentheses, so the following are functionally equivalent:
<?php
$foo = (int) $bar;
$foo = ( int ) $bar;
?>
Casting literal strings and variables to binary strings:
<?php
$binary = (binary) $string;
$binary = b"binary string";
?>
Note: Instead of casting a variable to a string, it is also possible to enclose the variable in double quotes.
<?php
$foo = 10; // $foo is an integer
$str = "$foo"; // $str is a string
$fst = (string) $foo; // $fst is also a string
// This prints out that "they are the same"
if ($fst === $str) {
echo "they are the same";
}
?>
It may not be obvious exactly what will happen when casting between certain types. For more information, see these sections:
PHP에서 변수는 변수명 앞에 달러사인을 덧붙여 표현된다. 변수명은 대소문자를 구별한다.
PHP에서 변수명은 다음 규칙을 따른다. 유효한 변수명은 문자나 밑줄로 시작하고, 그 뒤에 문자, 숫자, 밑줄이 붙을수 있다. 정규표현식으로 표현하면 다음과 같다: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
Note: 여기서 문자는 a-z, A-Z, 그리고 127부터 255까지(0x7f-0xff) 바이트를 의미합니다.
Note: $this은 특수 변수로, 할당할 수 없습니다.
변수 관련 함수는, 변수 관련 함수 레퍼런스를 참고하십시오.
<?php
$var = 'Bob';
$Var = 'Joe';
echo "$var, $Var"; // outputs "Bob, Joe"
$4site = 'not yet'; // invalid; starts with a number
$_4site = 'not yet'; // valid; starts with an underscore
$täyte = 'mansikka'; // valid; 'ä' is ASCII 228.
?>
기본값으로, 변수는 항상 값에 의해 할당되어야 합니다. 변수를 표현식으로 지정할때에 원래 표현식의 모든 값이 목표 변수로 복사된다. 이 말의 의미는 예를 들면, 어떤 변수값을 다른 변수로 지정한 후에, 그 변수중 어떤 하나를 변경하는것이 다른 변수에 영향을 미치지 않는다는 의미를 갖는다. 이런 종류의 지정에 대해서 표현식을 참고.
또한, PHP에서는 이와 다른 방법으로 변수에 값이 지정된다: 참조에 의한 지정. 이 용어의 의미는 새로운 변수가 원래 변수를 참조한다는 것이다.(즉, "원래 변수의 별명이 되는것" 이나 "가리키는 것") 새 변수의 변경은 원래 변수에 영향을 미치고, 그 반대도 가능하다.
참조에 의한 지정을 위해서는, 단순히 지정되는(소스 변수) 변수의 시작부분에 엠퍼센트(&)를 덧붙이면 된다. 예를 들면 다음 코드 예는 'My name is Bob'이 두번 출력된다.
<?php
$foo = 'Bob'; // Assign the value 'Bob' to $foo
$bar = &$foo; // Reference $foo via $bar.
$bar = "My name is $bar"; // Alter $bar...
echo $bar;
echo $foo; // $foo is altered too.
?>
주의할 것은 오직 이름이 부여된 변수만이 참조에 의해 지정된다는 것이다.
<?php
$foo = 25;
$bar = &$foo; // This is a valid assignment.
$bar = &(24 * 7); // Invalid; references an unnamed expression.
function test()
{
return 25;
}
$bar = &test(); // Invalid.
?>
PHP에서 변수를 초기화 할 필요는 없지만, 초기화는 매우 좋은 습관입니다. 초기화되지 않은 변수는 자료형과 사용되는 위치에 따라서 기본값을 가집니다 - 논리 기본값은 FALSE, 정수형과 소수형은 0, 문자열(echo()등에서 사용)은 빈 문자열로 설정되고, 배열은 빈 배열로 설정됩니다.
Example #1 초기화되지 않은 변수의 기본값
<?php
// 설정되지 않고 참조되지 않은 (사용되지 않은) 변수; NULL 출력
var_dump($unset_var);
// 논리 사용; 'false' 출력 (이 구문에 대한 설명은 3항 연산자를 참고하십시오)
echo($unset_bool ? "true\n" : "false\n");
// 문자열 사용; 'string(3) "abc"' 출력
$unset_str .= 'abc';
var_dump($unset_str);
// 정수 사용; 'int(25)' 출력
$unset_int += 25; // 0 + 25 => 25
var_dump($unset_int);
// 소수 사용; 'float(1.25)' 출력
$unset_float += 1.25;
var_dump($unset_float);
// 배열 사용; array(1) { [3]=> string(3) "def" } 출력
$unset_arr[3] = "def" // array() + array(3 => "def") => array(3 => "def")
var_dump($unset_arr);
// 객체 사용; 새 stdClass 객체 생성 (http://www.php.net/manual/kr/reserved.classes.php 참고)
// 출력: object(stdClass)#1 (1) { ["foo"]=> string(3) "bar" }
$unset_obj->foo = 'bar';
var_dump($unset_obj);
?>
초기화되지 않은 변수의 기본값에 의존하는 것은, 같은 변수명을 사용하는 파일을 포함하는 등에서 문제가 될 수 있습니다. 또한, register_globals를 켜놓은 상태에서 주요한 보안 위험입니다. 초기화되지 않은 변수를 사용할 때 E_NOTICE 등급의 오류가 발생하지만, 초기화되지 않은 배열에 원소를 추가할 때는 발생하지 않습니다. isset() 언어 구조로 변수가 초기화되었는지 확인 할 수 있습니다.
PHP는 실행되는 스크립트에 적용이되는 상당량의 미리 선언된 변수를 제공한다. 하지만, 이 변수의 대부분은 운영되는 서버, 서버의 버전, 서버의 설정, 다른 팩터와 관련되어 있어서 완벽하게 문서화되지 않았다. 이 중 몇개의 변수는 커맨드 라인에서 실행되는 PHP에서는 유효하지 않다. 예약된 미리 선언된 변수의 섹션을 참고.
PHP 4.2.0 이후 버전부터, PHP 디렉티브 register_globals의 기본값은 off가 되었다. register_globals를 off로 놓으면, 전역 유효영역안의 미리 선언된 변수 집합들에 영향을 미친다. 예를 들면, DOCUMENT_ROOT값을 얻기 위해서는 $DOCUMENT_ROOT 대신에 $_SERVER['DOCUMENT_ROOT']를, http://www.example.com/test.php?id=3에서 $id 대신에 $_GET['id']를, $HOME 대신에 $_ENV['HOME']을 사용해야 한다.
이와 관련된 변경사항은 register_globals의 설정 엔트리를 읽거나, 전역 등록 사용하기에 관한 보안 챕터는 물론, » 4.1.0과 » 4.2.0 Release Announcements도 참고하기 바란다.
superglobal arrays와 같은 가용한 PHP의 예약된 미리 선언된 변수를 사용하는 것을 추천한다.
4.1.0 버전 이후에, PHP는 웹서버, 환경, 유저 입력과 관련된 미리 선언된 배열 변수 집합을 추가적으로 제공한다. 이 새로운 배열은 자동적으로 전역화되기 때문에 더 특별해진다. 즉, 자동적으로 모든 유효영역안에서 적용이 가능하다. 이런 이유로, 이런 변수를 '자동전역변수'라고 한다. (PHP에서는 사용자-선언 슈퍼전역변수가 허용되지 않는다.) 슈퍼전역변수는 아래에 열거한다. 하지만, 이 변수 목록과 논의는 예약된 미리선언된 변수섹션을 참고한다. 또한 구버전의 미리선언된 변수($HTTP_*_VARS)가 아직도 존재한다는 것에 주의한다. PHP 5.0.0부터, 긴 형태의 PHP 예약 변수 배열을 register_long_arrays 지시어로 제거할 수 있습니다.
Note: 가변 변수
슈퍼전역변수는 함수나 클래스 메쏘드 안에서 가변 변수로는 쓰일수 없다.
Note: 자동 전역과 HTTP_*_VARS가 동시에 존재할 수 있습니다; 하지만 동일하지 않으며, 하나를 변경해도 다른 하나는 바뀌지 않습니다.
variables_order내의 특정 변수들이 설정되어있지 않으면, 적합한 PHP의 미리선언된 배열도 비워있게 된다.
변수의 유효영역은 변수가 정의된 환경을 말한다. 대부분의 경우 모든 PHP 변수는 한군데의 유효영역만을 갖는다. 이 한군데의 유효영역은 include되거나 require된 파일로도 확장된다. 예를 들면:
<?php
$a = 1;
include 'b.inc';
?>
위 예제코드에서는 include된 b.inc 스크립트안에서도 $a 변수가 사용가능하다. 하지만, 사용자-선언 함수에서는 로컬 함수 유효영역이 적용된다. 함수내에서 사용되는 모든 변수는 기본값으로 로컬 변수 유효영역 안으로 제한된다. 예를 들면:
<?php
$a = 1; /* global scope */
function test()
{
echo $a; /* reference to local scope variable */
}
test();
?>
위 스크립트에서 echo문이 $a의 로컬 버전을 참조하고, 이 영역 안에서 값을 지정되지 않았기 때문에 아무것도 출력되지 않는다. C에서 전역변수는 특별히 로컬 선언으로 덮어쓰지 않는이상은 자동적으로 함수안에서 사용가능하다는 점에서 C 언어와 약간 차이가 있다는 것에 주의해야 할것이다. 이런 생각으로 부주의하게 전역변수를 변경하려한다면 문제가 될것이다. PHP에서 전역변수가 함수내에서 계속적으로 사용이 된다면 함수안에서 global로 선언해야 합니다.
우선, global의 사용 예제입니다:
Example #1 global 사용하기
<?php
$a = 1;
$b = 2;
function Sum()
{
global $a, $b;
$b = $a + $b;
}
Sum();
echo $b;
?>
위 스크립느는 "3"를 출력할것이다. $a와 $b를 함수내에서 global로 선언함으로써, 각 변수에 대한 모든 참조는 전역 버전으로 참조될것이다. 함순에서 조작되는 전역변수의 수는 제한이 없다.
전역 유효영역의 변수에 접근할수 있는 두번째 방법이 특별 PHP-선언 $GLOBALS 배열을 사용하는 것이다. 이전 예제코드는 다음과 같이 다시 작성할 수 있습니다:
Example #2 global 대신 $GLOBALS 사용하기
<?php
$a = 1;
$b = 2;
function Sum()
{
$GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
}
Sum();
echo $b;
?>
$GLOBALS 배열은 전역변수명이 key가 되는 연관배열이고 배열의 원소 값이 그 변수의 내용이 된다. $GLOBALS이 어떻게 모든 유효영역에서 존재하는지 주의하라. 이유는 $GLOBALS이 슈퍼전역변수이기 때문이다. 아래에 슈퍼전역변수의 파워를 설명하는 예제코드를 보였다:
Example #3 자동 전역과 영역을 보여주는 예제
<?php
function test_global()
{
// 대부분의 예약 변수는 "자동 전역"이 아니기에,
// 함수 내부 영역에서 사용하려면 'global'이 필요합니다.
global $HTTP_POST_VARS;
echo $HTTP_POST_VARS['name'];
// 자동 전역은 어떠한 영역에서도 사용할 수 있고,
// 'global'이 필요하지 않습니다. 자동 전역은
// PHP 4.1.0부터 사용할 수 있고, HTTP_POST_VARS는
// 배제되었습니다.
echo $_POST['name'];
}
?>
변수 유효영역의 또 다른 중요한 기능이 static 변수이다. 정적(static) 변수는 로컬 함수 영역에서만 존재한다. 그러나 프로그램이 그 영역을 떠나지 않으면 그 값을 잃지 않는다. 다음 예제를 생각해 봅시다:
Example #4 정적 변수의 필요성을 보여주는 예제
<?php
function test()
{
$a = 0;
echo $a;
$a++;
}
?>
이 함수는 매번 호출될때마다 $a를 0으로 설정하고 "0"를 출력한다. $a++ 는 변수를 증가시키지만 함수에서 빠져나가면 $a 변수는 사라지게되므로 아무 가치가 없다. 현재 카운트 값을 잃지 않는 유용한 카운트 함수를 만들려면, $a 변수를 static으로 선언한다.
Example #5 정적 변수의 사용 예제
<?php
function test()
{
static $a = 0;
echo $a;
$a++;
}
?>
처음 함수를 호출할 때만 $a가 초기화 되고, test() 함수가 호출될때마다 $a 값을 출력하고 그 값이 증가합니다.
정적 변수는 또한 재귀함수를 다루는 한 방법을 제공한다. 재귀함수는 자기 자신을 호출하는 함수를 말한다. 재귀함수는 무한히 실행될수 있기 때문에 재귀함수를 작성할때는 주의가 필요하다. 재귀를 벗어나는 방법을 반드시 갖고 있어야 한다. 다음과 같은 단순 재귀함수는 10까지 카운트한다. 정적 변수 $count는 멈춰야 할 때는 안다.
Example #6 재귀 함수에서 정적 변수
<?php
function test()
{
static $count = 0;
$count++;
echo $count;
if ($count < 10) {
test();
}
$count--;
}
?>
Note: 정적 변수는 위 예제처럼 선언해야 합니다. 이 변수에 표현식의 결과를 할당하려 할 경우는 해석 오류를 발생합니다.
Example #7 정적 변수 선언하기
<?php
function foo() {
static $int = 0; // 적합
static $int = 1+2; // 오류 (표현식이기에)
static $int = sqrt(121); // 오류 (역시 표현식이기에)
$int++;
echo $int;
}
?>
PHP 4를 작동하는 Zend Engine 1은 static과 global을 참조를 통한 변수 변경자로 구현합니다. 예를 들어, 실제 전역 변수를 global 키워드를 사용하여 함수 영역 내부로 가져올 경우, 그 전역 변수의 참조를 생성합니다. 이로 인해 다음 예제에서 처럼 원하지 않은 동작을 할 수 있습니다:
<?php
function test_global_ref() {
global $obj;
$obj = &new stdclass;
}
function test_global_noref() {
global $obj;
$obj = new stdclass;
}
test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);
?>
위 예제코드를 실행하면 다음과 같은 결과가 유도된다.
이와 비슷한 동작이 static 절에서도 발생한다. 참조가 정적으로 저장되지 않는것이다:
<?php
function &get_instance_ref() {
static $obj;
echo 'Static object: ';
var_dump($obj);
if (!isset($obj)) {
// Assign a reference to the static variable
$obj = &new stdclass;
}
$obj->property++;
return $obj;
}
function &get_instance_noref() {
static $obj;
echo 'Static object: ';
var_dump($obj);
if (!isset($obj)) {
// Assign the object to the static variable
$obj = new stdclass;
}
$obj->property++;
return $obj;
}
$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo "\n";
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();
?>
위 예제코드를 실행하면 다음과 같은 결과가 유도된다.
위 예제 코드는 정적 변수에 대한 참조를 지정할때, &get_instance_ref()함수가 두번째로 호출되는 때에 기억되지 않는다는 것을 보여준다.
때때로 가변 변수명을 갖을수 있는것다는 것은 편리함을 준다. 즉, 변수명이 유동적으로 설정되거나 사용될수 있다. 일반적인 변수는 다음과 같은 구문에 의해 설정된다:
<?php
$a = 'hello';
?>
가변변수는 변수값을 취해서 변수명으로 취급한다. 위 예제코드는, hello를 두개의 달러사인을 사용하여 변수명으로 사용할수 있다.
<?php
$$a = 'world';
?>
이 지점에서 두 변수가 선언되었고 PHP 심볼 트리에 저장된다: $a는 "hello" 값을 갖고 $hello는 "world" 값을 갖게 된다. 따라서, 이 구문:
<?php
echo "$a ${$a}";
?>
다음과 완전히 똑같이 출력된다:
<?php
echo "$a $hello";
?>
즉, 둘다 hello world를 출력한다.
배열을 갖는 가변변수를 사용하기 위해서는 애매한 문제를 해결해야 한다. 즉 $$a[1]를 쓴다면 해석기는 $a[1]가 변수를 의미하는지 알수 있어야 한다. 또는 $$a가 변수이기를 바라고, [1]가 그 변수의 인덱스인지 알수 있어야 한다. 이런 애매한 문제를 해결하기 위한 문법: 첫번째 목적을 위해 ${$a[1]}과 두번째 목적을 위해 ${$a}[1]을 들수 있다.
가변 변수로 함수나 클래스 메쏘드 안에서 PHP 자동 전역 배열을 사용할 수 없음에 주의하십시오. $this 변수도 특수 변수로써, 동적으로 참조할 수 없습니다.
폼이 PHP 스크립트로 전달될때, 그 폼안의 정보가 스크립트내에서 자동적으로 유효해진다. 이 정보에 접근할 수 있는 많은 방법이 제공된다. 예를 들면:
Example #1 단순한 HTML 폼
<form action="foo.php" method="post">
이름: <input type="text" name="username" /><br />
메일: <input type="text" name="email" /><br />
<input type="submit" name="submit" value="전송합니다!" />
</form>
특별한 설정과 개인적인 선호에 의해, HTML 폼으로부터 데이터를 접근할수 있는 많은 방법이 존재한다. 몇가지르 예를 들면:
Example #2 단순한 POST HTML 폼으로 부터 데이터에 접근하기
<?php
// PHP 4.1.0부터 사용 가능
echo $_POST['username'];
echo $_REQUEST['username'];
import_request_variables('p', 'p_');
echo $p_username;
// PHP 6부터 사용 불가. PHP 5.0.0부터, 이러한 긴 예약 변수는
// register_long_arrays 지시어로 비활성화 할 수 있습니다.
echo $HTTP_POST_VARS['username'];
// PHP 지시어 register_globals = on 일 경우에 사용할 수 있습니다.
// PHP 4.2.0부터 기본값은 register_globals = off 입니다.
// 이 방법을 사용하는 것은 권장되지 않습니다.
echo $username;
?>
GET 폼을 사용하는 것은 적절한 GET 기선언 변수를 대신 사용할때를 제외하면 동일하다. GET은 QUERY_STRING (URL에서 '?'이후의 값)에도 적용이 된다. 따라서, 예를 들면 http://www.example.com/test.php?id=3는 $_GET['id']으로 접근할수 있는 GET 데이터를 포함한다. 또한 $_REQUEST와 import_request_variables()를 참고.
Note: $_POST 와 $_GET 같은 슈퍼전역 배열은 PHP 4.1.0 이후버전부터 사용되기 시작했다.
전에 설명한대로, PHP 4.2.0 이전에는 register_globals의 기본값이 on이였다. PHP 커뮤니티는 그 디렉티브 값이 off가 되어있다고 가정하고 적절하게 코딩하는 것을 추천하기 때문에 이 디렉티브값에 연연할 필요가 없다.
Note: magic_quotes_gpc 설정 디렉티브는 Get, Post, Cookie 값에 영향을 준다. 이 값이 켜져있으면, 그 값(It's "PHP!")은 자동적으로 (It\'s \"PHP!\")이 될것이다. 이 회피는 DB 입력을 위해 필요하다. 또한 addslashes(), stripslashes()과 magic_quotes_sybase를 참고한다.
PHP는 폼 변수가 쓰이는 환경안의 배열도 이해한다. (관련 faq를 참고) 예를 들면, 관련 변수를 함께 그룹화하거나, 다중 select 입력으로부터 값을 끄집어내기위해 이 기능을 사용할수 있다. 예로써, 자신에게 폼을 post하고 그 데이터를 출력해보자:
Example #3 좀더 복잡해진 폼 변수들
<?php
if ($_POST) {
echo '<pre>';
echo htmlspecialchars(print_r($_POST, true));
echo '</pre>';
}
?>
<form action="" method="post">
이름: <input type="text" name="personal[name]" /><br />
메일: <input type="text" name="personal[email]" /><br />
맥주: <br />
<select multiple name="beer[]">
<option value="warthog">Warthog</option>
<option value="guinness">Guinness</option>
<option value="stuttgarter">Stuttgarter Schwabenbräu</option>
</select><br />
<input type="hidden" name="action" value="submitted" />
<input type="submit" value="전송합니다!" />
</form>
form을 전달할때, 표준적인 submit 버튼 태그 대신 다음과 같이 image 태그를 사용할수 있다.
<input type="image" src="image.gif" name="sub" />
유저가 image의 어느곳에서 클릭하더라도 수행 폼은 두가지 추가적인 변수를 서버로 전송할것이다. sub_x와 sub_y. 이 변수는 image안에서 유저가 클릭하는 좌표를 갖는다. 실제로 브라우저에 의해 보내지는 변수명은 밑줄(_)이 아니라 마침표(.)를 포함한다. 그러나 PHP는 자동으로 마침표를 밑줄로 변환한다.
표준적으로, PHP는 스크립트내로 변수를 전달할때 변수명을 변경하지 않는다. 하지만, 점(마침표, full stop)은 PHP 변수명안에서 유효한 문자가 될수 없다는것에 주의해야 할것이다. 이에 유의하여 다음 코드를 보자:
<?php
$varname.ext; /* invalid variable name */
?>
현재, 해석기가 보게되는 것은 $varname이라는 변수와 그 뒤에 문자열 결합 연산자, 그 뒤에 벌거벗은 문자열(barestring) 'ext'이다. (즉, 따옴표로 둘러싸지 않은 문자열은 key나 예약된 단어와 일치하지 않음) 확실하게 이 결과는 원치 않은것이다.
이러한 이유로, PHP는 유입되는 변수명안의 점(.)을 밑줄(_)로 변경한다는것을 명심해야 한다.
PHP는 변수 타입을 결정하고 변수를(보통) 필요한 타입으로 변환하기 때문에, 어느 시간에 변수가 무슨 타입인지 알수가 없다. PHP는 변수가 무슨 타입인지 확인할수 있는 몇가지 함수를 제공한다. 그 함수들은 다음과 같다: gettype(), is_array(), is_float(), is_int(), is_object(), is_string(). 타입 챕터를 참고.
상수는 단순한 값을 위한 식별자(이름)이다. 이름이 제시하는것과 같이, 이 값은 스크립트 실행중에는 변경될수 없다. (실질적으로 상수가 아닌 마법 상수 을 제외하고) 상수는 기본적으로 대소문자를 구별한다. 관례상, 상수 식별자는 항상 대문자이다.
PHP에서 상수명은 같은 규칙을 따른다. 유효한 상수명은 문자나 밑줄로 시작하고 다른 문자나 숫자, 밑줄이 뒤를 따른다. 정규식으로는 다음처럼 표현할수 있다: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
Example #1 상수명으로 적합하거나 부적합한 이름들
<?php
// 유효한 상수명
define("FOO", "something");
define("FOO2", "something else");
define("FOO_BAR", "something more");
// 무효한 상수명
define("2FOO", "something");
// 유효하지만, 피해야할 상수명:
// 어느날 PHP에서 마법 상수를 제공할 수 있으며,
// 이 경우 스크립트를 사용할 수 없습니다
define("__FOO__", "something");
?>
Note: 여기서 문자는 a-z, A-Z와 아스키 문자 127에서 255까지이다 (0x7f-0xff).
superglobals처럼 상수의 유효범위(scope)는 전역적이다. 유효범위에 상관없이 스크립트의 어느곳에서도 상수를 참조할수 있다. 상수에 관한 더 자세한 정보를 위해 변수 범위 매뉴얼 섹션을 참고합니다.
define() 함수를 사용해서 상수를 정의할 수 있습니다. PHP 5.3.0부터 클래스 정의 밖에서 const 키워드를 사용할 수도 있습니다. 상수가 한번 정의되면, 변경하거나 해제(undefine)할 수 없습니다.
상수는 스칼라 데이터(boolean, integer, float, string)만 가질 수 있습니다. resource를 상수로 등록할 수 있지만, 피하십시오. 예상할 수 없는 결과를 낳을 수 있습니다.
단순히 상수명을 써서 상수값을 얻을 수 있다. 변수와는 달리 $가 상수명 앞으로 오면 안된다 동적으로 상수명을 취하려한다면 constant()함수로 상수값을 가져올수 있다. 정의된 모든 상수 목록을 구하려면 get_defined_constants() 함수를 쓴다.
Note: 상수와 (전역)변수는 서로 다른 네임스페이스(namespace)상에 있다. 이말의 의미는 예를 들면 TRUE와 $TRUE은 일반적으로 다르다는것이다.
해제된 상수를 사용한다면, PHP는 상수명 자체를 쓴것이라고 가정할것이다 즉,string으로 인식할것이다. (CONSTANT vs "CONSTANT") E_NOTICE로 이런 일이 발생했는지 알수 있다. 왜 $foo[bar]가 잘못됐는지 (bar를 상수로 define() 하지않았다면) 매뉴얼을 참고한다. 단순히 상수가 설정되었는지만 확인하려 한다면 defined()함수를 쓰면 됩니다.
다음은 상수와 변수의 차이점이다:
Example #1 상수 정의하기
<?php
define("CONSTANT", "Hello world.");
echo CONSTANT; // "Hello world."을 출력한다
echo Constant; // "Constant"를 출력하고 경고가 뜬다.
?>
Example #2 const 키워드를 사용해서 상수 정의하기
<?php
// PHP 5.3.0부터 작동
const CONSTANT = 'Hello World';
echo CONSTANT;
?>
참고: 클래스 상수.
PHP는 어떤스크립트에서도 유효한 많은 수의 미리 정의된 상수를 제공한다. 하지만 이 상수의 대부분은 다양한 확장(extension)에 의해 생성된다. 그래서 그 확장이 같이 컴파일되어 유효하거나 동적인 로딩이 되어있어야 이런 상수가 존재하게 된다.
일곱 가지 마법 상수가 존재한다. 이 상수들은 어디에서 쓰느냐에 따라 용도가 변경된다. 예를 들면, __LINE__상수의 값은 스크립트의 해당 줄과 관련이 있다. 이 특별한 상수들은 대소문자 구별이 없고 다음과 같다:
| 이름 | 설명 |
|---|---|
| __LINE__ | 파일의 현재 줄 번호 |
| __FILE__ | 파일의 전체경로와 파일명. 포함한 파일 안에서 사용하면, 포함된 파일명을 반환합니다.. PHP 4.0.2부터, __FILE__은 언제나 절대 경로를 가지고 있습니다. 이전에는 특정한 경우에서 상대 경로를 가지고 있었습니다. |
| __DIR__ | 파일의 디렉토리. 포함한 파일 안에서는, 포함된 파일의 디렉토리를 반환합니다. 이는 dirname(__FILE__)과 동일합니다. 디렉토리명은 루트 디렉토리가 아닌 이상, 마지막에 슬래시가 없습니다. (PHP 5.3.0에서 추가) |
| __FUNCTION__ | 함수명. (PHP 4.3.0에서 추가) PHP 5부터 이 상수는 정의된 그대로의 함수명을 반환합니다. (대소문자 구분) PHP 4에서는 항상 소문자였습니다. |
| __CLASS__ | 클래스명. (PHP 4.3.0에서 추가) PHP 5부터 이 상수는 정의된 그대로의 클래스명을 반환합니다. (대소문자 구분) PHP 4에서는 항상 소문자였습니다. |
| __METHOD__ | 클래스 메쏘드명 (PHP 5.0.0에서 추가) 메쏘드 명은 정의한 대로 반환됩니다. (대소문자 구분) |
| __NAMESPACE__ | 현재 이름공간 이름 (대소문자 구분). 이 상수는 컴파일 시에 정의됩니다. (PHP 5.3.0에서 추가) |
참고: get_class(), get_object_vars(), file_exists(), function_exists().
표현식은 PHP에서 가장 중요한 구성요소다. PHP에서 쓰는 거의 대부분이 표현식이다. 표현식을 정의한 가장 단순하고 가장 정확한 말은 "모든것이 값을 갖는다"는 것이다.
표현식의 가장 기본적인 형태가 상수와 변수이다. "$a = 5"라고 쓰면, $a에 '5'를 지정하는것이다.'5'는 확실히 5란 값을 갖는다. 다르게 표현하면 '5'는 5란 값을 갖는 표현식이 된다 (이경우에, '5'는 정수형 상수이다)
이렇게 지정하고 나면 $a의 값은 5가 될것이란 것도 기대할수 있을것이다. 그래서 $b = $a라고 쓴다면, $b = 5를 쓴것과 같이 동작할것이라고 기대할수 있을것이다. 다른말로, $a는 또한 5란 값을 갖는 표현식이다. 모든것이 제대로 작동한다면, 기대하던대로 될것이다.
표현식의 약간 더 복잡한 예가 함수이다. 다음 함수를 예로 들어보자.
<?php
function foo ()
{
return 5;
}
?>
함수의 개념에 익숙하다면 (그렇지 않으면, 함수에 관한 장을 참고) $c = foo()로 쓰는것이 $c = 5와 같을것이라고 생각할것이다. 옳은 생각이다. 함수는 반환된 값을 갖는 표현식이다. foo()가 5를 반환하기때문에 'foo()'표현식의 값은 5가 된다. 함수는 대체로 정적인 값보다는 계산값을 반환한다.
물론, PHP에서 값은 정수가 되어야 하는것은 아니다.. PHP에서는 4가지 스칼라 값 자료형을 지원한다: integer 값, 부동소수점 값(float), string 값, boolean 값. (스칼라 값은 배열과 다르게, 더 작게 쪼갤수 없는 값을 말한다) PHP는 두가지 조합형(스칼라값이 아닌)을 지원한다: 배열과 객체. 이 두가지 값형은 변수나 함수에서 넘기는 값으로 지정될수 있다.
PHP는 여기에 더하여, 많은 다른 언어들이 하는 방식의 표현식을 받아들입니다. PHP는 거의 모든것이 표현식이라는 관점에 입각한 표현식-지향 언어이다. 전술했던 예제 '$a = 5'를 보자. 이 식과 연관된 값은 '5'라는 정수상수 두개라는것과 $a는 5로 수정이 된다는 것을 알수 있다. 그러나 진실은 여기에 연관되어있는 것이 하나의 추가값이라는것이고, 이 추가된 값이 지정되어지는 값 자체라는 것이다. 지정 자체는 지정값 5만 적용된다. 실제로, '$a = 5'라는 식은 그것이 무엇을 하든 5라는 값을 갖는 표현식이라는 것이다. 따라서, '$b = ($a = 5)'라는 식은 '$a = 5; $b = 5'를 쓰는것과 같다 (세미콜른은 구문의 끝을 표시한다). 지정연산은 오른쪽에서 왼쪽방향으로 해석되므로 '$b = $a = 5'라고 쓸수 있다.
표현식-지향의 또다른 좋은 예는 전처리(pre)/후처리(post)되는 증가와 감소 연산이다. PHP 사용자와 다른 언어 사용자는 변수++과 변수--의 부호표시에 익숙할것이다. 이런 부호표시는 증가와 감소 연산자이다. PHP/FI 2에서 '$a++'문은 값을 갖지않는다 (즉, 표현식이 아니다), 그래서 어떤수단으로도 특정값을 지정하거나 사용할수 없다. PHP는 C처럼 이런 표현식을 사용할수 있어서 증가/감소 연산 능력을 확장시켰다. PHP는 C처럼 두가지 연산형이 존재한다 - 전처리-증가 와 후처리-증가. 전처리 증가와 후처리 증가 모두 변수를 증가시키고 변수에 적용하므로, 변수에 미치는 영향은 동일합니다. 차이점은 증가 표현식의 값에 달려있다. 전처리-증가, 즉 '++$변수' 는 값을 증가시켜 평가합니다. (PHP는 처음 값을 읽기 전에 값을 증가시킨다, 따라서 이름이 '전처리-증가'가 되는것이다) 후처리-연산, '$변수++'는 값을 증가시키기 전의 $변수의 처음값을 평가합니다. (PHP는 그 값을 읽은 후에 그 값을 증가시킨다, 그래서 '후처리-증가'가 되는것이다)
가장 흔한 표현식 형태는 비교 표현식입니다. 이 표현식은 FALSE나 TRUE로 평가합니다. PHP는 >(초과), >=(이상), ==(같음), !=(같지 않음), <(미만), <=(이하)를 지원합니다. 또한 엄격한 등가 연산자를 지원합니다: ===(같고 같은 자료형)과 !==(같지 않거나 다른 자료형). 이 표현식은 보통 if 구문과 같은 조건부 실행문에 사용됩니다.
이 장에서 취급할 제일 마지막 표현식의 예는 조합된 연산자-지정 표현식이다. $a를 1만큼 증가시키고자 한다면 단순히 '$a++'이나 '++$a'로 쓸수 있다는것을 이미 알고 있을것이다. 그러나 하나 이상의 값을 증가시키고자 한다면, 예를 들어 3을 증가시키고자 한다면 어떻게 해야 할까? '$a++'을 여러번 쓸수도 있다. 그러나 이런 식으로 쓰는것은 효과적이거나 편한 방법이 아니라는것을 쉽게 알수 있다. 좀더 평범하게 표현하면 '$a = $a + 3'이다. '$a + 3'은 $a에 3을 더한 값이 계산 되고 $a로 그 값이 지정된다. 그래서 $a에 3을 증가시킨 결과가 된다. PHP에서는 C와 같은 다른 언어처럼 더 짧은 형태로 쓸수있다. 그래서, 좀더 이해하기 쉽고 좀더 빨리 이해할수있다. $a의 현재 값에 3을 더하는 것은 '$a += 3'으로 쓸수 있다. 이 표현식의 의미는 정확히 '$a값을 취해 그 값에 3을 더하고 다시 $a에 계산된값을 지정하라'이다. 좀더 짧고 명확할 뿐만 아니라, 좀더 빠른 수행이 이루어진다. 일반적인 표현식의 값처럼 '$a += 3'의 값은 지정값이다. 3이 아니라, $a에 3을 더한 값이라는 것에 주의하라 (이값은 $a에 지정되는 값이다) 어떠한 두개연속의 연산자도 이런 연산자-지정 방식으로 사용될수 있다. 예를 들면, '$a -= 5' ($a의 값에서 5를 뺀것), '$b *= 7' ($b의 값에 7을 곱한것) 등등이 쓰일수 있다.
다른 언어에서 본적이 없다면 이상하게 보이는 표현식이 있다. 3중 조건적 연산자이다:
<?php
$first ? $second : $third
?>
first 에 속하는 표현식의 값이 TRUE (non-zero)이면 second 에 속하는 표현식이 적용되고, 이것이 조건적 표현식의 결과가 된다. 이 경우가 아니면, third 에 속하는 표현식이 적용되고, 그 값이 된다.
다음 예제 코드는 좀더 일반적으로 사용된 전처리/후처리-증가와 표현식을 이해하는데 도움이 될것이다.
<?php
function double($i)
{
return $i*2;
}
$b = $a = 5; /* $a와 $b에 5라는 값을 지정함 */
$c = $a++; /* 후처리-증가, $a 의 원래값을 적용함
$c는 (5)가 됨 */
$e = $d = ++$b; /* 전처리-증가, $b가 증가된 값이 적용됨
$d와 $e는 (6)이 됨 */
/* 여기서, $d와 $e는 6과 같다 */
$f = double($d++); /* 증가되기 전의 $d값의 두배가 적용됨
$f는 2*6 = 12가 됨 */
$g = double(++$e); /* 증가된 후의 $e값의 두배가 적용됨
$g는 2*7 = 14가 됨 */
$h = $g += 10; /* 우선, $g는 10만큼 증가되어 24가 됨.
지정된 값 (24)가 $h로 지정된다.
$h도 24값으로 지정된다 */
?>
몇몇 표현식은 구문으로 간주할 수 있습니다. 이런 경우는 구문이 'expr' ';'의 형태를 갖는다. 즉, 세미콜른이 표현식 뒤에 온다. '$b=$a=5;'에서 $a=5는 유효한 표현식이다. 그러나 그자체가 구문이 되지는 않는다. 하지만, '$b=$a=5;'는 유효한 구문이다
마지막으로 언급할 만큼 가치있는것이 표현식의 진리값이다. 많은 사건중, 주로 조건적 수행과 루프에서, 표현식의 특정 값에 흥미있지는 않을것이다. 그러나 그 값이 TRUE인지 FALSE인지는 중요하다. 상수 TRUE와 FALSE (대소문자를 구별하지 않음)는 두가지 논리값이다. 필요하면, 표현식은 자동적으로 논리값으로 변환된다. 더 자세한 정보는 자료형 변환을 참고할것.
PHP는 표현식의 완벽하고도 강력한 구현방법을 제공한다. 그런 방법을 완전히 문서화하는 것은 이 매뉴얼의 범위를 넘는다. 위 예제 코드들은 표현식이 무엇인지에 대한것과 유용한 표현식을 구축할수 있는 방법에 대한 아이디어를 줄것이다. 이후 매뉴얼에서는 유효한 PHP 표현식을 expr라고 쓰겠다.
연산자는 하나 이상의 값(또는, 프로그래밍 은어로 표현)을 받아서 다른 값을 산출합니다. (그러므로 구조 자체는 표현이 됩니다) 그러므로 (print처럼) 값을 반환하는 함수나 구조를 연산자로 생각할 수 있고, (echo처럼) 아무것도 반환하지 않는 것을 다른 것으로 생각할 수 있습니다.
세 종류의 연산자가 있습니다. 첫번째는 하나의 값에만 작용하는 일항 연산자입니다. 예를 들면, !(부정 연산자)나 ++(증가 연산자)가 있습니다. 두번째는 이항 연산자로 불립니다; 이 종류는 PHP가 지원하는 대부분의 연산자에 해당합니다. 목록은 아래의 연산자 우선권 섹션에 있습니다.
세번째는 삼항 연산자입니다: ?:. 이것은 세번째에 의존해서 두 표현 중 하나를 선택하는 데 사용합니다. 삼항 연산자를 괄호로 감싸는 건 매우 좋은 생각입니다.
연산자 우선권은 두 표현이 얼마나 "단단하게" 묶여 있는지 정의합니다. 예를 들어, 1 + 5 * 3 표현의 답은 18이 아닌 16입니다. 곱셈("*") 연산자가 덧셈(+) 연산자보다 높은 우선권을 가지기 때문입니다. 필요하다면, 우선권을 강제하기 위해 괄호를 사용할 수 있습니다. 예를 들면: (1 + 5) * 3은 18로 평가됩니다. 연산자 우선권이 같으면, 왼쪽에서 오른쪽 결합을 사용합니다.
다음 표는 높은 우선권을 가지는 연산자가 위쪽에 나오는 연산자 우선권 목록입니다. 같은 줄에 있는 연산자는 같은 우선권을 가지며, 이 경우 결합이 평가하는 순서를 결정합니다.
| 결합 | 연산자 | 추가 정보 |
|---|---|---|
| 무결합 | clone new | clone과 new |
| 왼쪽 | [ | array() |
| 무결합 | ++ -- | 증가/감소 |
| 무결합 | ~ - (int) (float) (string) (array) (object) (bool) @ | 자료형 |
| 무결합 | instanceof | 자료형 |
| 오른쪽 | ! | 논리 |
| 왼쪽 | * / % | 계산 |
| 왼쪽 | + - . | 계산 그리고 문자열 |
| 왼쪽 | << >> | 비트 |
| 무결합 | < <= > >= <> | 비교 |
| 무결합 | == != === !== | 비교 |
| 왼쪽 | & | 비트 그리고 참조 |
| 왼쪽 | ^ | 비트 |
| 왼쪽 | | | 비트 |
| 왼쪽 | && | 논리 |
| 왼쪽 | || | 논리 |
| 왼쪽 | ? : | 삼항 |
| 오른쪽 | = += -= *= /= .= %= &= |= ^= <<= >>= | 할당 |
| 왼쪽 | and | 논리 |
| 왼쪽 | xor | 논리 |
| 왼쪽 | or | 논리 |
| 왼쪽 | , | 다양한 사용 |
왼쪽 결합은 표현이 왼쪽에서 오른쪽으로 평가됨을 의미하며, 오른쪽 결합은 반대입니다.
Example #1 결합성
<?php
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
$a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2
$a = 1;
$b = 2;
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
?>
괄호를 사용하는 것은 표현의 가독성을 증가시킵니다.
Note: =이 대부분의 연산자보다 낮은 우선권을 가지지만, PHP는 다음과 같은 표현을 허용합니다: if (!$a = foo()), 이 경우 foo()의 반환값은 $a에 들어갑니다.
학교에서 배운 기본 계산을 떠올렸습니까? 그와 같이 작동합니다.
| 예제 | 이름 | 결과 |
|---|---|---|
| -$a | 부정 | $a의 반대. |
| $a + $b | 덧셈 | $a와 $b의 합. |
| $a - $b | 뺄셈 | $a와 $b의 차. |
| $a * $b | 곱셈 | $a와 $b의 곱. |
| $a / $b | 나눗셈 | $a와 $b의 몫. |
| $a % $b | 나머지 | $a를 $b로 나눈 나머지. |
나눗셈 연산자("/")는 두 연산수가 정수(또는 정수로 변환되는 문자열)가 아니고 수가 정확히 나눠질 수 있으면 정수 값을 반환합니다. 그렇지 않으면 소수 값을 반환합니다.
나머지 연산자는 계산하기 전에 정수로 변환(소수점 부분을 제거)합니다.
Note: 음수 $a에 대한 $a % $b의 나머지는 음수입니다.
매뉴얼 수학 함수 페이지를 참고하십시오.
기본 할당 연산자는 "="입니다. 처음에는 이것을 "같다"로 생각할 수 있습니다. 아닙니다. 실제로는 왼쪽 연산수가 오른쪽 표현의 값으로 설정됨을 의미합니다. ("를 설정"입니다)
할당 연산자의 값은 할당된 값입니다. 그러므로, "$a = 3"의 값은 3입니다. 이는 트릭 같은 일을 허용합니다:
<?php
$a = ($b = 4) + 5; // $a는 이제 9와 같고, $b는 4로 설정됩니다.
?>
기본 연산자에 추가로, 모든 이항 계산, 배열 합집합과 문자열 연산자에 대하여 "결합 연산자"가 존재합니다. 이를 사용해서 값을 표현으로 사용하고 그 표현의 결과를 값에 설정할 수 있도록 합니다. 예를 들면:
<?php
$a = 3;
$a += 5; // $a를 8로 설정, 다음과 같습니다: $a = $a + 5;
$b = "Hello ";
$b .= "There!"; // $b = $b . "There!";와 마찬가지로, $b를 "Hello There!"로 설정
?>
할당은 원래 값을 새로운 것으로 복사하기 때문에(값으로 할당), 하나의 변경은 다른 것에 영향을 주지 않습니다. 또한 빠듯한 루프 안에서 커다란 배열을 복사해야할 필요성이 존재하게 됩니다. $var = &$othervar; 구문을 사용해서, 참조로 할당도 지원합니다. '참조로 할당'은 두 변수가 같은 데이터를 가리키는 것을 의미하며, 아무것도 복사하지 않습니다. 참조에 대해서 알아보려면, 참조 설명을 읽어보십시오. PHP 5부터, 객체는 명시적으로 새로운 것을 만드는 clone 키워드를 사용하지 않는 한 참조로 할당됩니다.
비트 연산자는 정수에 있는 특정 비트를 끄거나 켤 수 있도록 합니다. 왼쪽과 오른쪽 인수가 모두 문자열이면, 비트 연산자는 문자의 아스키 값으로 연산합니다.
<?php
echo 12 ^ 9; // Outputs '5'
echo "12" ^ "9"; // Outputs the Backspace character (ascii 8)
// ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8
echo "hallo" ^ "hello"; // Outputs the ascii values #0 #4 #0 #0 #0
// 'a' ^ 'e' = #4
echo 2 ^ "3"; // Outputs 1
// 2 ^ ((int)"3") == 1
echo "2" ^ 3; // Outputs 1
// ((int)"2") ^ 3 == 1
?>
| 예제 | 이름 | 결과 |
|---|---|---|
| $a & $b | And | $a와 $b 모두에 설정된 비트가 설정됩니다. |
| $a | $b | Or | $a나 $b에 설정된 비트가 설정됩니다. |
| $a ^ $b | Xor | $a나 $b에 설정되었지만, 양쪽에 설정되지 않은 비트. |
| ~ $a | Not | $a에 설정되지 않은 비트가 설정되는, 역입니다. |
| $a << $b | Shift left | $a의 비트를 $b 단계만큼 왼쪽으로 시프트 (각 단계는 "2로 곱하기"를 의미합니다) |
| $a >> $b | Shift right | $a의 비트를 $b 단계만큼 오른쪽으로 시프트 (각 단계는 "2로 나누기"를 의미합니다) |
32비트 시스템에서 32비트 초과하는 오른쪽 시프트를 하지 마십시오. 결과가 32비트를 수 넘어가는 왼쪽 시프트를 하지 마십시오.
비교 연산자는 이름 그대로 두 값을 비교하도록 합니다. 자료형 비교표에서 다양한 자료형 관련 비교의 예제를 확인해 볼 수 있습니다.
| 예제 | 이름 | 결과 |
|---|---|---|
| $a == $b | Equal | $a와 $b가 같으면 TRUE. |
| $a === $b | Identical | $a와 $b가 같고, 같은 자료형이면 TRUE. (PHP 4에서 추가) |
| $a != $b | Not equal | $a가 $b와 같지 않으면 TRUE. |
| $a <> $b | Not equal | $a가 $b와 같지 않으면 TRUE. |
| $a !== $b | Not identical | $a가 $b와 같지 않거나, 같은 자료형이 아니면 TRUE. (PHP 4에서 추가) |
| $a < $b | Less than | $a가 $b보다 작으면 TRUE. |
| $a > $b | Greater than | $a가 $b보다 크면 TRUE. |
| $a <= $b | Less than or equal to | $a가 $b보다 작거나 같으면 TRUE. |
| $a >= $b | Greater than or equal to | $a가 $b보다 크거나 같으면 TRUE. |
정수를 문자열과 비교하면, 문자열이 수로 변환됩니다. 두개의 수 문자열을 비교하면, 정수로 비교됩니다. 이 규칙은 switch 구문에도 적용됩니다.
<?php
var_dump(0 == "a"); // 0 == 0 -> true
var_dump("1" == "01"); // 1 == 1 -> true
var_dump("1" == "1e0"); // 1 == 1 -> true
switch ("a") {
case 0:
echo "0";
break;
case "a": // never reached because "a" is already matched with 0
echo "a";
break;
}
?>
다양한 자료형에 대해서, 비교는 다음 표에 따라 이루어집니다. (순서대로)
| 연산수 1의 자료형 | 연산수 2의 자료형 | 결과 |
|---|---|---|
| null이나 string | string | NULL을 ""로 변환, 수치나 어휘 비교 |
| bool이나 null | anything | bool로 변환, FALSE < TRUE |
| object | object | 내장 클래스는 자신의 비교 함수를 정의할 수 있습니다. 다른 클래스는 비교할 수 없고, 같은 클래스는 배열과 같은 방식으로 프로퍼티를 비교합니다(PHP 4). PHP 5는 자체의 해석법을 가지고 있습니다. |
| string, resource, number | string, resource, number | 문자열과 자원을 수로 변환하여, 일반적인 수학 |
| array | array | 적은 멤버를 가진 배열이 작고, 연산수 1의 키가 연산수 2에서 발견되지 않으면 배열을 비교할 수 없고, 그렇지 않으면 - 값대 값으로 비교(아래 예제를 참고) |
| array | 모두 | array가 항상 큽니다 |
| object | 모두 | object가 항상 큽니다 |
Example #1 표준 배열 비교의 모사
<?php
// 표준 비교 연산자로 배열은 이렇게 비교합니다
function standard_array_compare($op1, $op2)
{
if (count($op1) < count($op2)) {
return -1; // $op1 < $op2
} elseif (count($op1) > count($op2)) {
return 1; // $op1 > $op2
}
foreach ($op1 as $key => $val) {
if (!array_key_exists($key, $op2)) {
return null; // uncomparable
} elseif ($val < $op2[$key]) {
return -1;
} elseif ($val > $op2[$key]) {
return 1;
}
}
return 0; // $op1 == $op2
}
?>
참고: strcasecmp(), strcmp(), 배열 연산자, 매뉴얼 자료형 섹션.
또다른 조건부 연산자는 "?:"(삼항) 연산자입니다.
Example #2 기본값 할당하기
<?php
// 사용 예제: 삼항 연산자
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
// 위 예제는 다음의 if/else 구문과 동일합니다
if (empty($_POST['action'])) {
$action = 'default';
} else {
$action = $_POST['action'];
}
?>
(expr1) ? (expr2) : (expr3) 표현은 expr1이 TRUE이면 expr2로 평가되고, expr1이 FALSE이면 expr3로 평가됩니다.
PHP 5.3부터, 삼항 연산자의 중간 부분을 비울 수 있습니다. 표현식 expr1 ?: expr3은 expr1이 TRUE이면 expr1, 아니면 expr3를 반환합니다.
Note: 삼항 연산자는 구문이므로, 변수로 평가되지 않고 구문의 결과로 평가되는 점에 주의하십시오. 이 점은 참조로 변수를 반환할 때 중요합니다. 그러므로 참조로 반환하는 함수에서 return $var == 42 ? $a : $b; 구문은 작동하지 않고, 경고가 발생합니다.
Note: 삼항 연사자를 "쌓는" 일을 피하길 권합니다. 하나의 구문에서 하나를 초과하는 삼항 연산자를 사용할 때, PHP 작동은 명확하지 않습니다:
Example #3 명확하지 않은 삼항 작동
<?php
// 얼핏 보기에, 'true'를 출력할 것 같습니다
echo (true?'true':false?'t':'f');
// 그러나 위의 실제 출력은 't'입니다
// 이는 삼항 표현이 왼쪽에서 오른쪽으로 평가되기 때문입니다
// 다음이 위 코드와 동일한 더 명확한 버전입니다
echo ((true ? 'true' : 'false') ? 't' : 'f');
// 여기서, 첫 표현이 'true'로 평가되고, 이것이
// (bool)true로 전환되어 평가된 후, 두번째
// 삼항 표현의 true쪽을 반환합니다.
?>
PHP는 하나의 오류 제어 연산자를 지원합니다: at 부호(@). PHP 표현의 앞에 덧붙이면, 그 표현에서 생성되는 모든 오류 메세지를 무시합니다.
track_errors 기능을 켜면, 표현이 생성한 모든 오류 메세지는 $php_errormsg 변수에 저장됩니다. 이 변수는 각 오류마다 덮어씌워지므로, 사용하려면 일찍 확인하십시오.
<?php
/* Intentional file error */
$my_file = @file ('non_existent_file') or
die ("Failed opening file: error was '$php_errormsg'");
// this works for any expression, not just functions:
$value = @$cache[$key];
// will not issue a notice if the index $key doesn't exist.
?>
Note: @ 연산자는 표현에만 작용합니다. 간단한 규칙으로: 어떠한 값을 얻을 수 있으면, @를 붙일 수 있습니다. 즉, 변수, 함수, include() 호출, 상수 등에 붙일 수 있습니다. 함수 정의, 클래스 정의, if와 foreach 같은 조건부 구문 등에는 붙일 수 없습니다.
error_reporting()과 매뉴얼 오류 다루기와 기록 함수 섹션을 참고하십시오.
현재 "@" 오류 제어 연산자는 스크립트 실행을 종료하는 치명적인 오류에 대한 오류 보고도 꺼버립니다. 즉, "@"를 어떠한 함수에서 오류를 제거하려고 사용하였을 때, 그 함수가 존재하지 않거나, 오타를 내면 그 위치에서 아무런 이유를 알려주는 지시도 없이 스크립트가 종료됩니다.
PHP는 하나의 실행 연산자를 지원합니다: 역따옴표(``). 홑따옴표가 아닌 점에 주의하십시오! PHP는 역따옴표 안의 내용을 쉘 명령으로 실행하려 할 것입니다; 출력을 반환합니다. (즉, 단순히 출력하는 것이 아닙니다; 변수에 할당할 수 있습니다) 역따옴표 연산자를 사용하는 것은 shell_exec()와 동일합니다.
<?php
$output = `ls -al`;
echo "<pre>$output</pre>";
?>
Note: 역따옴표 연산자는 안전 모드가 켜져있거나 shell_exec()가 비활성화 되면 사용할 수 없습니다.
매뉴얼 프로그램 실행 함수 섹션, popen(), proc_open(), PHP를 명령줄에서 사용하기를 참고하십시오.
PHP는 C 형식의 사전, 사후 증가 및 감소 연산자를 지원합니다.
Note: 증가/감소 연산자는 논리 값에 영향을 주지 않습니다. NULL 값을 감소하는 것도 영향이 없지만, 증가시키면 1이 됩니다.
| 예제 | 이름 | 효과 |
|---|---|---|
| ++$a | Pre-increment | $a를 1 증가하고, $a를 반환. |
| $a++ | Post-increment | $a를 반환하고, $a를 1 증가. |
| --$a | Pre-decrement | $a를 1 감소하고, $a를 반환. |
| $a-- | Post-decrement | $a를 반환하고, $a를 1 감소. |
간단한 예제 스크립트입니다:
<?php
echo "<h3>Postincrement</h3>";
$a = 5;
echo "Should be 5: " . $a++ . "<br />\n";
echo "Should be 6: " . $a . "<br />\n";
echo "<h3>Preincrement</h3>";
$a = 5;
echo "Should be 6: " . ++$a . "<br />\n";
echo "Should be 6: " . $a . "<br />\n";
echo "<h3>Postdecrement</h3>";
$a = 5;
echo "Should be 5: " . $a-- . "<br />\n";
echo "Should be 4: " . $a . "<br />\n";
echo "<h3>Predecrement</h3>";
$a = 5;
echo "Should be 4: " . --$a . "<br />\n";
echo "Should be 4: " . $a . "<br />\n";
?>
PHP는 문자 변수에 계산 연산을 할 경우, C가 아닌 펄의 규정을 따릅니다. 예를 들면, 펄에서 'Z'+1은 'AA'가 되지만, C에서 'Z'+1은 '['( ord('Z') == 90, ord('[') == 91)입니다. 문자 변수는 증가만 할 수 있고, 감소는 할 수 없으며, 아스키 알파벳 문자(a-z와 A-Z)만 지원합니다.
Example #1 문자 변수에 계산 연산
<?php
$i = 'W';
for ($n=0; $n<6; $n++) {
echo ++$i . "\n";
}
?>
위 예제의 출력:
X Y Z AA AB AC
논리값에 대한 증가나 감소는 영향이 없습니다.
| 예제 | 이름 | 결과 |
|---|---|---|
| $a and $b | And | $a와 $b가 모두 TRUE이면 TRUE. |
| $a or $b | Or | $a나 $b가 TRUE이면 TRUE. |
| $a xor $b | Xor | $a와 $b중 하나만 TRUE일 때만 TRUE. |
| ! $a | Not | $a가 TRUE가 아니면 TRUE. |
| $a && $b | And | $a와 $b가 모두 TRUE이면 TRUE. |
| $a || $b | Or | $a나 $b가 TRUE이면 TRUE. |
"and"와 "or" 연산자가 두 종류가 있는 것은, 다른 우선권을 가지기 때문입니다. (연산자 우선권 참고)
Example #1 논리 연산자 설명
<?php
// foo() will never get called as those operators are short-circuit
$a = (false && foo());
$b = (true || foo());
$c = (false and foo());
$d = (true or foo());
// "||" has a greater precedence than "or"
$e = false || true; // $e will be assigned to (false || true) which is true
$f = false or true; // $f will be assigned to false
var_dump($e, $f);
// "&&" has a greater precedence than "and"
$g = true && false; // $g will be assigned to (true && false) which is false
$h = true and false; // $h will be assigned to true
var_dump($g, $h);
?>
위 예제의 출력 예시:
bool(true) bool(false) bool(false) bool(true)
두 개의 string 연산자가 있습니다. 첫번째는 연결 연산자('.')로, 오른쪽과 왼쪽 인수의 연결을 반환합니다. 두번째는 연결 할당 연산자('.=')로, 오른쪽 인수를 왼쪽 인수에 덧붙입니다. 자세한 정보는 할당 연산자를 참고하십시오.
<?php
$a = "Hello ";
$b = $a . "World!"; // now $b contains "Hello World!"
$a = "Hello ";
$a .= "World!"; // now $a contains "Hello World!"
?>
| 예제 | 이름 | 결과 |
|---|---|---|
| $a + $b | Union | $a와 $b의 합집합. |
| $a == $b | Equality | $a와 $b가 동일한 키/값 쌍을 가지면 TRUE. |
| $a === $b | Identity | $a와 $b가 동일한 키/값 쌍을 동일한 순서와 동일한 자료형으로 가지면 TRUE. |
| $a != $b | Inequality | $a가 $b와 같지 않으면 TRUE. |
| $a <> $b | Inequality | $a가 $b와 같지 않으면 TRUE. |
| $a !== $b | Non-identity | $a가 $b와 동일하지 않으면 TRUE. |
+ 연산자는 오른쪽 배열에서 왼쪽 배열로 키를 유지하며 원소를 덧붙입니다. 중복되는 키를 덮어쓰지 않습니다.
<?php
$a = array("a" => "apple", "b" => "banana");
$b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");
$c = $a + $b; // Union of $a and $b
echo "Union of \$a and \$b: \n";
var_dump($c);
$c = $b + $a; // Union of $b and $a
echo "Union of \$b and \$a: \n";
var_dump($c);
?>
실행하면, 위 스크립트는 다음을 출력합니다:
Union of $a and $b:
array(3) {
["a"]=>
string(5) "apple"
["b"]=>
string(6) "banana"
["c"]=>
string(6) "cherry"
}
Union of $b and $a:
array(3) {
["a"]=>
string(4) "pear"
["b"]=>
string(10) "strawberry"
["c"]=>
string(6) "cherry"
}
동일한 키와 값을 가지고 있으면, 비교할 때 같은 배열 원소입니다.
Example #1 비열 비교하기
<?php
$a = array("apple", "banana");
$b = array(1 => "banana", "0" => "apple");
var_dump($a == $b); // bool(true)
var_dump($a === $b); // bool(false)
?>
instanceof는 PHP 변수가 어떤 클래스에서 생성된 객체인지 확인할 때 사용합니다:
Example #1 클래스에 instanceof 사용하기
<?php
class MyClass
{
}
class NotMyClass
{
}
$a = new MyClass;
var_dump($a instanceof MyClass);
var_dump($a instanceof NotMyClass);
?>
위 예제의 출력:
bool(true) bool(false)
instanceof는 변수가 부모 클래스에서 상속받은 클래스인지 확인할 때도 사용할 수 있습니다:
Example #2 상속 클래스에 instanceof 사용하기
<?php
class ParentClass
{
}
class MyClass extends ParentClass
{
}
$a = new MyClass;
var_dump($a instanceof MyClass);
var_dump($a instanceof ParentClass);
?>
위 예제의 출력:
bool(true) bool(true)
객체가 클래스의 인스턴스가 아닌지 확인하려면, 논리 not 연산자를 사용할 수 있습니다.
Example #3 객체가 클래스의 인스턴스가 아닌지 확인하기 위해 instanceof 사용하기
<?php
class MyClass
{
}
$a = new MyClass;
var_dump(!($a instanceof stdClass));
?>
위 예제의 출력:
bool(true)
마지막으로, instanceof는 변수가 인터페이스를 구현한 클래스의 객체 인스턴스인지 확인하기 위해 사용할 수 있습니다:
Example #4 클래스에 instanceof 사용하기
<?php
interface MyInterface
{
}
class MyClass implements MyInterface
{
}
$a = new MyClass;
var_dump($a instanceof MyClass);
var_dump($a instanceof MyInterface);
?>
위 예제의 출력:
bool(true) bool(true)
보통 instanceof를 문자 클래스명에 사용하지만, 다른 객체나 문자열 변수와도 사용할 수 있습니다:
Example #5 다른 변수와 instanceof 사용하기
<?php
interface MyInterface
{
}
class MyClass implements MyInterface
{
}
$a = new MyClass;
$b = new MyClass;
$c = 'MyClass';
$d = 'NotMyClass';
var_dump($a instanceof $b); // $b is an object of class MyClass
var_dump($a instanceof $c); // $c is a string 'MyClass'
var_dump($a instanceof $d); // $d is a string 'NotMyClass'
?>
위 예제의 출력:
bool(true) bool(true) bool(false)
주의해야할 함정이 있습니다. PHP 5.1.0 이전에, instanceof는 클래스명이 존재하지 않으면 __autoload()를 호출했습니다. 추가로, 클래스가 적재되지 않으면 치명적인 오류가 발생했습니다. 이는 동적 클래스 참조를 사용하거나, 클래스명을 가지는 문자열 변수로 해결할 수 있습니다:
Example #6 PHP 5.0 intanceof에서 클래스명 찾기와 치명적인 오류 피하기
<?php
$d = 'NotMyClass';
var_dump($a instanceof $d); // no fatal error here
?>
위 예제의 출력:
bool(false)
instanceof 연산자는 PHP 5에서 추가되었습니다. 이전에는 is_a()가 사용되었지만, is_a()는 instanceof의 기능으로 인해 배제되었습니다. PHP 5.3.0부터 is_a()는 배제되지 않게 되었습니다.
참고: get_class(), is_a().
모든 PHP 스크립트는 연속적인 구문으로 이루어진다. 하나의 구문은 지정문 이 될수도 있고, 함수 호출, 반복문, 조건문이 될수 있으며 심지어는 아무 내용이 없는 빈 문장일수도 있다. 한 구문은 보통 세미콜론(;)으로 끝난다. 또한 여러개의 구문을 중괄호({,})를 사용하여 하나의 그룹으로 만들어 사용할 수도 있다. 이 구문 그룹은 그 그룹의 모든 구문들이 하나의 구문인 것처럼 인식된다. 이 장에서는 여러 가지 구문형태에 대해 알아본다.
if문은 PHP를 포함해서 모든 언어에 있어서 가장 중요한 기능 중 하나이다. 이 제어문으로 각각 다른 코드에 대해 조건적인 수행을 가능케한다. if문의 기능은 C와 비슷하다:
if (expr)
statement
표현식에 관한 섹션에서 설명된것처럼 expr은 논리(Boolean)값으로 취급된다. expr이 TRUE와 같다면 PHP는 statement를 수행할것이고, FALSE라면 무시될것이다. 무슨값이 FALSE인지 알려면 '논리값으로 변환하기' 섹션을 참고한다.
다음 예는 $a가 $b보다 크다면 a는 b보다 크다를 출력할 것이다.
<?php
if ($a > $b)
echo "a는 b보다 크다";
?>
종종 하나 이상의 구문을 조건적으로 수행시켜야 하는 때가 있다. 물론 if절로 각 구문을 감싸줄 필요는 없다. 대신, 구문 그룹안에 몇개의 구문을 그룹화할 수 있다. 예를 들면, 이코드는 $a가 $b보다 크다면 a는 b보다 크다라고 출력할것이고, $a의 값을 $b로 지정하게 될것이다.
<?php
if ($a > $b) {
echo "a는 b보다 크다";
$b = $a;
}
?>
If문은 다른 if문안에 무한정으로 내포될수 있다. 이와 같은 기능은 프로그램의 여러부분을 조건적으로 수행하기 위한 유연성을 제공한다.
가끔은 특정 조건에 맞을때 구문을 수행하지 않고, 조건과 맞지 않을 때 다른 구문을 수행하게 하고 싶은 때가 있다. else 문은 이 목적을 위한 것이다. if문 다음의 else문은 if구문안의 표현식이 FALSE일때 수행된다. 예를 들면, 다음 코드는 $a가 $b보다 크다면 a는 b보다 크다 를 출력할것이고, 그렇지않다면 a는 b보다 크지 않다를 출력할것이다:
<?php
if ($a > $b) {
echo "a는 b보다 크다";
} else {
echo "a는 b보다 크지 않다";
}
?>
else문은 if문이 FALSE일때만 수행이 된다. 그리고 그들 모두 FALSE값이 될수있다면 elseif문 을 쓸수 있다. (elseif를 참고)
elseif, 이 이름에서 알수 있듯이, if와 else의 조합이다. else처럼 이 구문은 if절 다음에 와서 원래 if표현식이 FALSE와 같은 경우에 다른 구문을 수행한다. 그러나, else와는 달리 elseif조건 표현식이 TRUE일 때만 대체 표현식을 수행할것이다. 예를 들면 다음 코드는 a는 b보다 크다, a는 b와 같다나 a는 b보다 작다을 출력할것이다.
<?php
if ($a > $b) {
echo "a는 b보다 크다";
} elseif ($a == $b) {
echo "a는 b와 같다";
} else {
echo "a는 b보다 작다";
}
?>
같은 if절 안에 몇개의 elseif절이 존재할수 있다. 가장 먼저 TRUE가 되는 elseif표현식이 수행될것이다. PHP에서는 'else if' (두 단어)로 쓸수 있고 'elseif' (한 단어) 와 방식은 같다. 문장적(syntactic)으로는 다르다 (C에 익숙하다면, 이것은 같은 방식이다) 그러나 그 둘 모두 완전히 같은 결과를 보여줄것이다.
elseif절은 선행 if 표현식과 다른 elseif표현식이 FALSE이고, 이 elseif표현식이 TRUE일때만 수행된다.
Note: elseif와 else if은 위 예제처럼 대괄호를 사용할 때 정확히 같은 구문으로 간주됩니다. if/elseif 조건을 콜론을 사용해서 정의할 때, else if 처럼 두 단어로 나눠서는 안됩니다. PHP는 처리 오류로 실패합니다.
<?php
/* 부적합한 방법: */
if($a > $b):
echo $a." is greater than ".$b;
else if($a == $b): // 컴파일 되지 않습니다.
echo "위 줄은 처리 오류를 일으킵니다.";
endif;
/* 적합한 방법: */
if($a > $b):
echo $a." is greater than ".$b;
elseif($a == $b): // 단어가 붙어 있는 점에 주의.
echo $a." equals ".$b;
else:
echo $a." is neither greater than or equal to ".$b;
endif;
?>
PHP는 제어 구조를 위해 대체 문법을 제공한다; 즉 if, while, for, foreach, 그리고 switch. 각 경우에 대체 문법의 기본형태는 괄호열기를 콜른 (:)으로 대체하고 괄호닫기는 각각 endif;, endwhile;, endfor;, endforeach;, 또는 endswitch;으로 대체한다.
<?php if ($a == 5): ?>
A는 5와 같다
<?php endif; ?>
위 예에서는 대체 문법으로 쓰여진 if구문안에 "A는 5와 같다" HTML 블록이 포함되어있다. 이 HTML 블록은 $a가 5와 같을때만 출력될것이다.
대체 문법은 else와 elseif문에도 적용이 된다. 다음은 elseif와 else문 과 같이 있는 if문 절의 대체 형태이다:
<?php
if ($a == 5):
echo "a는 5와 같다";
echo "...";
elseif ($a == 6):
echo "a는 6과 같다";
echo "!!!";
else:
echo "a는 5도 아니고 6도 아니다";
endif;
?>
while는 PHP에서 제일 간단한 루프형이다. C와 똑같은 방식으로 동작한다. while문의 기본적인 형태는 다음과 같다:
while (expr)
statement
while문의 의미는 단순하다. while 표현식이 계속 TRUE이면, PHP에게 내포되어있는 구문(들)을 반복 수행하도 록 하라는것이다. 표현식의 값은 루프의 시작에서 매번 체크가 된다. 그래서 이 표현식 값이 내포된 구문(들)의 수행동안에 바뀔지라도 반복(iteration) 의 끝이 아니면 수행은 끝나지 않게 된다.(루프에서 PHP가 구문을 한번수행 할때 한번 반복(iteration)이다) 시작된지 얼마안되어 while표현식이 FALSE로 판명되면, 내포된 구문(들)은 즉시 수행을 멈출것이다.
if문과 마찬가지로 중괄호나 대체문법을 사용하여 구문의 그룹을 둘러쌈으로써 while루프 안에 여러 구문을 그룹화할 수 있다.
while (expr):
statement
...
endwhile;
다음 예는 모두 동일하다. 둘다 1부터 10까지의 숫자를 출력한다:
<?php
/* example 1 */
$i = 1;
while ($i <= 10) {
echo $i++; /* 출력하는 값은 증가하기
전의 $i입니다.
(post-increment) */
}
/* example 2 */
$i = 1;
while ($i <= 10):
echo $i;
$i++;
endwhile;
?>
do-while 루프는 시작부분이 아니라 각 반복(iteration)의 끝부분에서 표현식이 참인지 체크한다는것을 제외하고 while루프와 매우 비슷하다. 일반적인 while문과의 주요한 차이점은 do-while문의 첫번째 반복이 반드시 수행된다는것이다 (반복의 끝부분에서 표현식이 참인지 체크한다), 이와 같은 경우는 일반 while루프로 수행시킬수 없을것이다. (while루프에서는 각 반복의 시작부분에서 표현식이 참인지 체크되고, 시작부터 바로 그 값이 FALSE이면 그 루프는 즉시 수행을 멈추게 된다)
다음에 do-while루프의 한가지 문법을 보인다:
<?php
$i = 0;
do {
echo $i;
} while ($i > 0);
?>
위 루프는 정확히 한번 수행된다. 첫번째 반복(iteration) 이후에 표현식이 참인지 체크할때, FALSE가 되므로 ($i는 0보다 크지 않다) 루프 수행이 멈춘다.
고급 C 유저는 do-while루프의 다른 사용법에 익숙할것이다. 즉, do-while (0)으로 감싸고, break절을 사용하여 코드 블록의 중간에서 수행을 멈출수 있습니다. 다음 코드 예는 이런 경우를 보여준다:
<?php
do {
if ($i < 5) {
echo "i는 충분히 크지 않다";
break;
}
$i *= $factor;
if ($i < $minimum_limit) {
break;
}
echo "i is ok";
/* process i */
} while (0);
?>
이 코드를 바로 또는 전혀 이해할수 없다고 걱정하지 마라. 이런 '기능'을 사용하지 않고도 일반 스크립트나 심지어 훌륭한 스크립트를 작성할 수 있다.
for루프는 PHP에서 제일 복잡한 루프이다. C와 똑같은 방식으로 동작한다. for루프의 문법은 다음과 같다:
for (expr1; expr2; expr3)
statement
첫번째 표현식(expr1)은 루프의 시작에서 바로 조건없이 평가된다 (수행된다).
각 반복(iteration)의 시작부분에서 expr2이 평 가된다. 이 표현식이 TRUE이면 루프는 계속되고 내포된 구문(들)이 수행된다. FALSE이면, 루프 수행을 멈춘다.
expr3표현식은 각 반복의 끝부분에서 평가된다 (수행된다).
각 표현은 비어있거나 콤마로 구분한 여러 표현을 가질 수 있습니다. expr2에서, 콤마로 구분한 표현은 모두 평가되지만 결과는 마지막 부분에서만 가져옵니다. expr2이 비어있다는 것은 루프가 무제한 수행되어야 한다는 것을 의미한다 (PHP는 C처럼 TRUE로 인식) 이런 기법은 생각처럼 필요없지는 않다. 왜냐 하면 종종 for문의 표현식 대신에 break문으로 루프를 끝낼 필요가 있기 때문이다.
다음 예제 코드들을 보세요. 이 코드 모두 1부터 10까지의 숫자를 출력한다:
<?php
/* 예제 1 */
for ($i = 1; $i <= 10; $i++) {
echo $i;
}
/* 예제 2 */
for ($i = 1; ; $i++) {
if ($i > 10) {
break;
}
echo $i;
}
/* 예제 3 */
$i = 1;
for (; ; ) {
if ($i > 10) {
break;
}
echo $i;
$i++;
}
/* 예제 4 */
for ($i = 1, $j = 0; $i <= 10; $j += 1, print $i, $i++);
?>
물론, 첫번째 예제(혹은 네번째) 코드가 가장 좋은 방법이다. 그러나 for루프에서 빈 표현식을 사용해야 하는 경우도 부딪히게 될것이다.
PHP는 for루프에 대한 대체 "콜른 문법"을 지원한다.
for (expr1; expr2; expr3):
statement
...
endfor;
많은 사용자가 아래 예제처럼 배열을 탐색합니다.
<?php
/*
* 이 배열은 루프를 도는 동안
* 변경할 데이터를 가지고 있습니다.
*/
$people = Array(
Array('name' => 'Kalle', 'salt' => 856412),
Array('name' => 'Pierre', 'salt' => 215863),
);
for($i = 0; $i < sizeof($people); ++$i)
{
$people[$i]['salt'] = rand(000000, 999999);
}
?>
문제는 두번째 표현식입니다. 이 코드는 매 실행마다 배열의 크기를 계산하기 때문에 느려집니다. 크기는 변하지 않기 때문에, 크기를 저장하는 중간 변수를 사용하여 루프를 돌리도록 최적화 할 수 있습니다. 아래 예제가 보여줍니다:
<?php
$people = Array(
Array('name' => 'Kalle', 'salt' => 856412),
Array('name' => 'Pierre', 'salt' => 215863),
);
for($i = 0, $size = sizeof($people); $i < $size; ++$i)
{
$people[$i]['salt'] = rand(000000, 999999);
}
?>
PHP 4는 펄이나 다른 언어처럼 foreach구문을 지원합니다. 이런 구문은 간단하게 배열에 대한 작업을 수행하는 가장 쉬운 기법입니다. foreach는 배열에서만 작동하고 다른 데이터형을 갖는 변수나 초기화되지 않은 변수에 대해서 이 구문을 사용하려한다면 에러 메시지를 만날것입니다. 이 구문은 두가지 문법이 있습니다; 두번째보다는 첫번째문법이 더 유용한 사용법입니다:
foreach (array_expression as $value)
statement
foreach (array_expression as $key => $value)
statement
첫번째 형태는 array_expression에서 주어진 배열에 대해 루프를 돈다. 각 루프에서 현재 배열 원소의 값은 $value 로 지정되고 내부적인 배열 포인터는 하나씩 이동하게 된다 (그래서 다음 루프에서 다음 배열 원소를 보게 될것이다)
두번째 루프도 같은 일을 한다. 단 현재 배열 원소의 키(key)값은 각 루프의 $key변수로 지정된다.
PHP 5부터 객체 순환도 할 수 있습니다.
Note: foreach문이 처음 실행할때, 내부적인 배열 포인터는 자동적으로 배열의 첫번째 원소로 리셋된다. 따라서 foreach절 이전에 reset()함수를 호출할 필요는 없다.
Note: 배열이 참조되지 않는 이상, foreach는 지정한 배열 자체가 아닌 복사한 배열을 대상으로 작동합니다. foreach는 배열 포인터에 영향이 있습니다. foreach 도중이나 이후에는 리셋하지 않은 배열 포인터에 의존하지 마십시오.
PHP 5부터, $value 앞에 &를 붙여서 배열 원소를 쉽게 변경할 있습니다. 값을 복사하지 않고 참조합니다.
<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
$value = $value * 2;
}
// $arr은 이제 array(2, 4, 6, 8)입니다.
unset($value); // 마지막 원소로 참조를 제거합니다.
이는 반복할 배열을 참조할 수 있을 때(즉, 변수)만 가능합니다.
$value 참조와 마지막 배열 원소는 foreach 루프 뒤에도 남아 있습니다. unset()으로 제거하는 것을 권합니다.
Note: foreach는 '@'를 사용해서 에러메시지를 출력하지 못하도록 할 수 없습니다.
다음 예는 기능적으로 동일하다는것을 알 필요가 있다:
<?php
$arr = array("하나", "둘", "셋");
reset($arr);
while (list(, $value) = each($arr)) {
echo "값: $value<br />\n";
}
foreach ($arr as $value) {
echo "값: $value<br />\n";
}
?>
다음 예도 기능적으로 동일하다:
<?php
$arr = array("하나", "둘", "셋");
reset($arr);
while (list($key, $value) = each($arr)) {
echo "키: $key; 값: $value<br />\n";
}
foreach ($arr as $key => $value) {
echo "키: $key; 값: $value<br />\n";
}
?>
더 많은 예제 코드들이 사용법에 대해서 설명해준다:
<?php
/* foreach 예제 1: 값만 */
$a = array(1, 2, 3, 17);
foreach ($a as $v) {
echo "\$a의 현재 값: $v.\n";
}
/* foreach 예제 2: 값 (표시를 위해 수동으로 접근 순서를 출력) */
$a = array(1, 2, 3, 17);
$i = 0; /* 가상 목적으로만 사용 */
foreach ($a as $v) {
echo "\$a[$i] => $v.\n";
$i++;
}
/* foreach 예제 3: 키와 값 */
$a = array(
"one" => 1,
"two" => 2,
"three" => 3,
"seventeen" => 17
);
foreach ($a as $k => $v) {
echo "\$a[$k] => $v.\n";
}
/* foreach 예제 4: 다차원 배열 */
$a = array();
$a[0][0] = "a";
$a[0][1] = "b";
$a[1][0] = "y";
$a[1][1] = "z";
foreach ($a as $v1) {
foreach ($v1 as $v2) {
echo "$v2\n";
}
}
/* foreach 예제 5: 동적 배열 */
foreach (array(1, 2, 3, 4, 5) as $v) {
echo "$v\n";
}
?>
break는 현재 for, foreach, while, do-while 또는 switch절의 수행을 멈춘다.
break는 숫자 인수 옵션을 허용함으로써 내포된 구문구조의 깊이를 표시하고 거기서 빠져나올수 있게 해준다.
<?php
$arr = array('one', 'two', 'three', 'four', 'stop', 'five');
while (list (, $val) = each ($arr)) {
if ($val == 'stop') {
break; /* 여기서는 'break 1;'으로 슬 수 있습니다. */
}
echo "$val<br />\n";
}
/* 옵션 인수 사용하기. */
$i = 0;
while (++$i) {
switch ($i) {
case 5:
echo "At 5<br />\n";
break 1; /* switch만 빠져나갑니다. */
case 10:
echo "At 10; quitting<br />\n";
break 2; /* switch와 while을 빠져나갑니다. */
default:
break;
}
}
?>
continue는 루프 구조 내부에서 현재 루프 반복의 나머지 부분을 생략하고 조건 평가를 한 후 다음 반복 시작에서 실행을 지속하게 합니다.
Note: PHP에서 switch구문은 continue에 의해 루프 구조로 사용할수 있다는것을 참고할것.
continue는 숫자 인수 옵션을 사용하여 루프의 깊이를 표시할수 있고, 루프의 끝까지 건너뛸수 있다.
<?php
while (list($key, $value) = each($arr)) {
if (!($key % 2)) { // skip odd members
continue;
}
do_something_odd($value);
}
$i = 0;
while ($i++ < 5) {
echo "Outer<br />\n";
while (1) {
echo " Middle<br />\n";
while (1) {
echo " Inner<br/ >\n";
continue 3;
}
echo "This never gets output.<br />\n";
}
echo "Neither does this.<br />\n";
}
?>
continue 뒤의 세미콜론을 빼먹으면 혼란스러울 것입니다. 여기에 해서는 안되는 일의 예제입니다:
<?php
for ($i = 0; $i < 5; ++$i) {
if ($i == 2)
continue
print "$i\n";
}
?>
기대했던 결과는:
0 1 3 4
하지만 스크립트의 출력은:
2
print() 호출의 반환값은 int(1)이기 때문에, 위에서 언급한 선택적인 수 인수로 간주합니다.
switch구문은 연속적인 같은 표현식을 갖는 연속적인 IF구문과 비슷하다. 많은 경우, 하나의 변수(또는 표현식)으로 다른 많은 값과 비교할 필요가 있으며, 그 값이 동일한 코드의 파편들을 수행할 필요가 생기게 된다. 정확히 이런 목적을 위해 switch구문이 사용된다.
Note: 다른 언어와는 달리 continue문은 switch문에서 사용할수 있고, break문과 비슷하게 동작한다. 루프 내에 switch문을 포함하고 있고 바깥 루프의 다음 반복문으로 진행하고 싶다면 continue 2를 사용한다.
Note: switch/case는 느슨한 비교를 하는 점에 주의하십시오.
다음 예제 코드들은 같은 일을 서로 다르게 표현한 것입니다. 하나는 if와 elseif문을 사용한 것이고, 다른 하나는 switch문을 사용했습니다:
Example #1 switch 구조
<?php
if ($i == 0) {
echo "i는 0";
} elseif ($i == 1) {
echo "i는 1";
} elseif ($i == 2) {
echo "i는 2";
}
switch ($i) {
case 0:
echo "i는 0";
break;
case 1:
echo "i는 1";
break;
case 2:
echo "i는 2";
break;
}
?>
Example #2 문자열을 사용하는 switch 구조
<?php
switch ($i) {
case "apple":
echo "i는 apple";
break;
case "bar"
echo "i는 bar";
break;
case "cake":
echo "i는 cake";
break;
}
?>
실수하지 않기 위해 switch문이 어떻게 동작하는지 이해할 필요가 있다. switch문은 한줄씩 수행된다 (실제는, 한구문씩). 처음에는 아무 코드도 수행되지 않는다. switch 표현의 값과 일치하는 값을 가진 case 구문을 발견했을 때, PHP는 그 구분을 실행합니다. PHP는 switch블록의 끝부분이 될때까지, 또는 break문와 첫번째 조우를 할때까지 구문을 계속 수행해 간다. 만약 각 case 구문 목록의 끝부분에 break문을 쓰지않는다면 PHP는 다음 case문으로 계속 진행하게 된다. 예를 들면 다음과 같다:
<?php
switch ($i) {
case 0:
echo "i는 0과 같다";
case 1:
echo "i는 1과 같다";
case 2:
echo "i는 2와 같다";
}
?>
여기에서, $i가 0이라면, PHP는 모든 echo문을 실행합니다! $i가 1이라면, PHP는 마지막 두 echo문을 실행합니다. $i가 2일 때만, 원하는 동작('i는 2와 같다' 표시)을 합니다. 따라서, break을 잊어서는 안됩니다. (어떤 경우에는 일부러 빠트릴 수 있어도, 잊지 마십시오)
switch구문에서, 조건문은 오직 한번만 평가되고 각 case문에서 결과가 비교되어진다. elseif문에서는 조건문은 다시 평가된다. 조건문이 한번 이상의 비교가 필요한 복잡한 것이거나 거친(tight) 루프안에 있다면 switch문 좀 더 빠를것이다.
case에 대한 구문 목록은 비어있을수 있다. 이것은 단순히 다음 case문으로 제어권을 넘겨줄 뿐이다.
<?php
switch ($i) {
case 0:
case 1:
case 2:
echo "i는 3보다 작지만 음수는 아닙니다.";
break;
case 3:
echo "i는 3";
}
?>
특별한 case가 바로 default case문이다. 이것은 다른 case문과 모두 조건이 맞지 않을때의 경우를 위한 것입니다. 예를 들면:
<?php
switch ($i) {
case 0:
echo "i는 0과 같다";
break;
case 1:
echo "i는 1과 같다";
break;
case 2:
echo "i는 2와 같다";
break;
default:
echo "i는 0, 1, 2 어느것도 아니다";
}
?>
case의 표현식은 정수나 부동소수점 수와 문자열같은 단순형으로 평가되는 어던 표현식도 될수 있다. 여기에 단순형으로 재참조(dereference)되지 않는 배열이나 객체를 사용할수는 없다.
switch문을 위한 제어 구조의 대체 문법이 지원된다. 더 자세한 정보는 제어 구조의 대체 문법을 참고.
<?php
switch ($i):
case 0:
echo "i equals 0";
break;
case 1:
echo "i equals 1";
break;
case 2:
echo "i equals 2";
break;
default:
echo "i is not equal to 0, 1 or 2";
endswitch;
?>
case 뒤에 세미콜론 대신 콜론을 쓸 수 있습니다:
<?php
switch($beer)
{
case 'tuborg';
case 'carlsberg';
case 'heineken';
echo 'Good choice';
break;
default;
echo 'Please make a new selection...';
break;
}
?>
declare구문은 코드 블록의 수행 지시어를 활성화하기 위해 사용된다. declare문법은 다른 흐름 제어 구조의 문법과 비슷하다:
declare (directive) statement
directive 부분은 declare 블록의 동작을 활성화합니다. 현재는 두 지시어만 인식합니다: ticks 지시어(자세한 정보는 아래 ticks 지시어 참고)와 encoding 지시어(자세한 정보는 아래 encoding 지시어 참고).
Note: encoding 지시어는 PHP 5.3.0에서 추가되었습니다.
declare블록의 statement부분이 수행될것이다 - 어떻게 수행이 되고 수행중에 어떤 사이드 이펙트가 발생할지는 directive블록의 디렉티브에 달려있다.
declare 구문은 전역 유효영역 안에서 사용할수 있다. 그래서 모든 코드가 그 디렉티브에 영향을 받는다. (그러나 declare가 있는 파일을 포함하였을 때에는 원 파일에는 영향을 주지 않습니다)
<?php
// 이들은 동일합니다:
// 이를 사용할 수 있습니다:
declare(ticks=1) {
// 여기에 전체 스크립트
}
// 또는 이렇게 사용할 수 있습니다:
declare(ticks=1);
// 여기에 전체 스크립트
?>
PHP 5.3.0부터 틱은 배제되었고, PHP 6.0.0에서 제거될 예정입니다.
틱은 declare블록에서 파서에 의해 수행되는
N 저레벨(low-level) 구문마다 발생하는
이벤트이다. N 값은
declare블록의 directive부분에서
ticks=N 으로 지정할수 있다.
각 틱에서 발생하는 이벤트(들)은 register_tick_function()함수 를 써서 지정한다. 자세한 것은 아래 예제를 볼것. 각 틱에서는 하나 이상의 이벤트가 발생할수 있음에 주의해야 한다.
Example #1 PHP 각 코드 섹션의 분석표만들기(Profile)
<?php
// 호출될대의 시간을 기록하는 함수
function profile($dump = FALSE)
{
static $profile;
// Profile에 저장된 모든 시간 리턴하고, 삭제함
if ($dump) {
$temp = $profile;
unset($profile);
return $temp;
}
$profile[] = microtime();
}
// 틱 핸들러 설정
register_tick_function("profile");
// declare 블록 전에 함수를 초기화
profile();
// 코드 블록의 실행하고, 두번째 구문에 틱을 부여함
declare(ticks=2) {
for ($x = 1; $x < 50; ++$x) {
echo similar_text(md5($x), md5($x*$x)), "<br />;";
}
}
// 분석표에 저장된 데이터를 출력
print_r(profile(TRUE));
?>
위 예제 코드는 실행 블록안의 두번째 저레벨(low-level) 구문의 시간에 따라 'declare'블록 안의 PHP코드를 분석한다. 이런 정보로 어느 코드 부분에서 느려지는지 알아볼 수 있다. 이런 처리방법은 다른 기법으로 수행할수있다: 틱을 이용하는 것은 좀더 편하고 좀더 구현하기 쉽다.
틱은 디버깅, 단순한 멀티태스킹 구현, 백그라운드 I/O와 다른 많은 작업 에 적합하게 이용할수 있다.
register_tick_function()함수와 unregister_tick_function()함수를 참고하세요.
encoding 지시어를 사용하여 스크립트 별로 지정할 수 있는 인코딩입니다.
Example #2 스크립트의 인코딩 선언하기
<?php
declare(encoding='ISO-8859-1');
// code here
이름공간과 결합할 때, declare의 적합한 문법은 declare(encoding='...'); 뿐입니다. (...은 인코딩 값) 이름공간과 결합했을 때, declare(encoding='...') {}은 해석 오류를 발생합니다.
PHP 5.3에서는 PHP가 --enable-zend-multibyte로 컴파일 되지 않았을 경우, encoding 선언 값이 무시됩니다. PHP 6.0에서는, encoding 지시어가 파일이 생성된 인코딩을 스캐너에게 알려줍니다. 적절한 값은 UTF-8 등의 인코딩 이름입니다.
return()문이 함수안에서 호출된다면, 현재 함수의 수행을 즉시 끝내고, 함수 호출 결과값으로 return의 인수값을 넘겨준다. return()문은 eval()함수나 스크립트 파일의 수행을 종료시킨다.
전역 유효범위에서 호출된다면, 현재 스크립트 파일의 수행을 끝마친다. 현재 스크립트가 include()나 require()되었다면, 호출하고 있는 파일로 제어를 넘긴다. 더욱이, 현재 스크립트 파일이 include()되어있는것이면, return()에 주어지는 값은 include()호출에 대한 값으로 넘겨줄것이다. return()이 주 스크립트 파일에서 호출되면, 스크립트의 수행이 종료된다. 현재 스크립트 파일이 php.ini의 auto_prepend_file이나 auto_append_file 옵션에 의해 명명되었다면, 스크립트 파일의 수행은 중단된다.
좀더 자세한 정보는 Returning values 을 참고하세요.
Note: return()은 함수가 아닌 언어 구조이기 때문에, 인수를 괄호로 쌀 필요가 없습니다. 괄호가 없는 것이 일반적으로, PHP가 더 적은 일을 하게 합니다.
Note: 반환값이 참조로 반환될 때는 절대로 괄호를 사용하면 안되며, 동작하지 않습니다. 참조는 변수만 반환할 수 있으며, 구문 결과는 반환할 수 없습니다. return ($a);를 사용한다면, 변수를 반환하지 않고 ($a) 표현의 반환값을 반환합니다. (물론, $a의 값입니다)
require()는 실패시에 치명적인 E_ERROR 등급 오류가 발생한다는 점을 제외하면, include()와 동일합니다. 즉, include()가 경고(E_WARNING)만 발생하고 스크립트는 계속 진행되는 것과 달리, 스크립트가 중단됩니다.
작동에 관해서는 include() 문서를 참고하십시오.
include()문은 특정 파일을 인클루드 하고, 적용시킨다.
아래 내용은 require()에도 적용됩니다. 두 구조는 수행 실패를 다루는 방법을 제외하고 완전히 동일합니다. 둘 모두 Warning을 발생시키지만, require()는 Fatal Error가 나타납니다. 즉, 파일이 없을 때 페이지 처리를 멈추고 싶으면 require()를 사용하면 됩니다. include()는 멈추지 않고 스크립트가 계속 실행됩니다. 또한, 적합한 include_path 설정인지 확인해야 합니다. PHP 4.3.5 이전에는 포함한 파일 안에서 해석 오류가 발생해도 수행을 멈추지 않는 점에 주의하십시오. 이 버전부터는 멈춥니다.
파일을 포함할 때는 각 include_path에 대해서 먼저 현재 작업 디렉토리에서 상대 경로를 찾고, 실행중인 스크립트가 있는 디렉토리를 찾습니다. 즉, include_path가 libraries이고, 현재 작업 디렉토리가 /www/이며, 포함한 파일 include/a.php에 include "b.php"가 있으면, b.php는 먼저 /www/libraries/에서 찾고, 그 후에 /www/include/을 찾습니다. 파일 이름이 ./이나 ../로 시작하면, 현재 작업 디렉토리 안에서만 찾습니다.
파일이 인클루드 되면, 그 코드를 포함하는 코드는 인클루드가 발생한 줄의 변수 유효 범위를 물려받는다. 호출하는 파일의 그 줄에서 사용되는 어떤 변수도 그 줄부터는 호출된 파일안에서 사용이 가능하다. 그러나, 포함한 파일에서 선언한 모든 함수와 클래스는 전역 영역에 들어갑니다.
Example #1 기본적인 include() 사용예
vars.php
<?php
$color = 'green';
$fruit = 'apple';
?>
test.php
<?php
echo "A $color $fruit"; // A
include 'vars.php';
echo "A $color $fruit"; // A green apple
?>
인클루드가 호출하는 파일안의 함수내에서 발생한다면, 호출된 파일안의 모든 코드가 그 함수에서 정의된것처럼 동작한다. 그래서, 그 함수의 변수 유효범위를 따를것이다. 이 규칙의 에외는 포함이 일어나기 전에 평가되는 마법 상수입니다.
Example #2 함수 내에서 인클루드하기
<?php
function foo()
{
global $color;
include 'vars.php';
echo "A $color $fruit";
}
/* vars.php is in the scope of foo() so *
* $fruit is NOT available outside of this *
* scope. $color is because we declared it *
* as global. */
foo(); // A green apple
echo "A $color $fruit"; // A green
?>
파일이 인클루드되면, 파싱은 PHP모드의 밖으로 나가서 목적 파일의 시작부분은 HTML모드로 들어가게 되고, 끝부분에서 원래대로 회복된다. 이때문에, 목적 파일에서 PHP코드로서 수행되어야 하는 코드는 유효한 PHP 시작과 마침 태그 로 막아줘야 한다.
PHP에서 "URL fopen wrappers"가 활성화되어 있으면 (디폴트 설정임), URL(HTTP나 다른 지원 래퍼(wrapper) - 프로토콜 목록은 지원 프로토콜/래퍼 목록을 참고)을 사용하여 파일을 인클루드 할수 있다. 목적 서버가 목적 파일을 PHP코드로 해석한다면, HTTP GET으로 사용된 URL 리퀘스트 문자열은 변수로서 넘겨지게 될것이다. 이와같은 일은 파일을 인크루드 하고 부모 파일의 변수 유효범위를 상속하는 것과 같은 경우가 되지는 않는다. 스크립트는 실질적으로 원격 서버에서 실행이 되고 나서 로컬 스크립트에 포함된다.
PHP 4.3.0 이전의 윈도우 버전 PHP에서는 이 함수를 이용하여 원격 파일에 접근할 수 없습니다. allow_url_fopen을 활성화하여도 마찬가지입니다.
Example #3 HTTP로 include()하기
<?php
/* This example assumes that www.example.com is configured to parse .php
* files and not .txt files. Also, 'Works' here means that the variables
* $foo and $bar are available within the included file. */
// Won't work; file.txt wasn't handled by www.example.com as PHP
include 'http://www.example.com/file.txt?foo=1&bar=2';
// Won't work; looks for a file named 'file.php?foo=1&bar=2' on the
// local filesystem.
include 'file.php?foo=1&bar=2';
// Works.
include 'http://www.example.com/file.php?foo=1&bar=2';
$foo = 1;
$bar = 2;
include 'file.txt'; // Works.
include 'file.php'; // Works.
?>
원격 파일은 원격 서버에서 실행(파일 확장자와 원격 서버가 PHP를 실행하는가에 따라 다릅니다)되지만, 로컬 서버에서 실행할 수 있는 유효한 PHP 스크립트를 만들 수도 있습니다. 원격 서버에서만 실행한 결과를 그대로 출력해야 한다면, readfile() 함수가 더 적합합니다. 아니라면, 원격 스크립트가 유효하고 적합한 코드를 생성하도록 특별한 주의를 기울이십시오.
참고: 원격 파일, fopen(), file()에 관련 정보가 있습니다.
반환 다루기: include한 파일 안에서 그 파일의 수행을 종료하고, 호출한 스크립트로 돌아가기 위해서 return()문을 실행할 수 있습니다. 또한, 값을 반환하는 일도 가능합니다. include 호출을 일반 함수를 사용한 것처럼 값을 받을 수 있습니다. 그러나, 원격 파일을 포함하였을 때, 그 파일의 출력이 (다른 로컬 파일처럼) 유효한 PHP 시작과 끝 태그를 가지지 않는다면 이 값을 받을 수 없습니다. 이 태그들 안에 필요한 값을 정의하면, include한 파일의 어떤 위치에서라도 사용할 수 있습니다.
include()은 특별한 언어 구조이기 때문에, 인수를 괄호로 쌀 필요가 없습니다. 반환값을 비교할 때는 조심하십시오.
Example #4 include의 반환값 비교하기
<?php
// include(('vars.php') == 'OK'), 즉 include('')로 인식하여 작동하지 않습니다.
if (include('vars.php') == 'OK') {
echo 'OK';
}
// 작동합니다.
if ((include 'vars.php') == 'OK') {
echo 'OK';
}
?>
Example #5 include()와 return()문
return.php
<?php
$var = 'PHP';
return $var;
?>
noreturn.php
<?php
$var = 'PHP';
?>
testreturns.php
<?php
$foo = include 'return.php';
echo $foo; // prints 'PHP'
$bar = include 'noreturn.php';
echo $bar; // prints 1
?>
include가 성공했기 때문에 $bar의 값은 1입니다. 위 예제 사이의 차이에 주목하십시오. 처음 것은 포함한 파일 안에서 return()을 사용하였지만, 다른 것은 하지 않았습니다. 파일을 포함할 수 없으면 FALSE를 반환하고 E_WARNING을 발생합니다.
포함한 파일에서 함수를 정의하면, 어디서 return()을 했는지에 관계 없이 메인 파일에서 사용할 수 있습니다. 파일이 두번 포함되면, PHP 5는 함수가 이미 정의되어 있기 때문에 치명적인 오류를 발생하지만, PHP 4는 return() 뒤에 정의했다면 불평하지 않습니다. 이미 포함한 파일을 확인하기 위해서는 포함한 파일 안에서 조건적으로 return하기 보다는 include_once()를 사용하는 것을 권합니다.
PHP 파일을 변수로 "포함"하는 또 다른 방법은 출력 제어 함수를 include()와 함께 사용하여 출력을 캡쳐하는 것입니다. 예를 들면:
Example #6 PHP 파일을 포함하여 문자열로 변환하기 위해 출력 버퍼링 사용하기
<?php
$string = get_include_contents('somefile.php');
function get_include_constents($filename) {
if (is_file($filename)) {
ob_start();
include $filename;
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
return false;
}
?>
스크립트 안에 자동으로 파일을 포함하기 위해서는, php.ini의 auto_prepend_file과 auto_append_file 설정 옵션을 참고하십시오.
Note: 이것은 함수가 아닌 언어 구조이기 때문에, 가변 함수 방식으로 호출할 수 없습니다.
참고: require(), require_once(), include_once(), get_included_files(), readfile(), virtual(), virtual(), include_path.
require_once() 구문은 PHP가 파일을 이미 포함하였는지 확인하여 다시 include(require)하지 않는 점을 제외하면, require()와 동일합니다.
_once 동작에 대한 정보와, _once 없는 것과 어떻게 다른가에 대해서는 include_once() 문서를 참고하십시오.
include_once()문은 스크립트 수행기간동안 특정파일을 인클루드하고 적용시킨다. 이것은 include()문과 비슷하게 동작한다. 단지 파일의 특정 코드가 이미 인클루되었다면 그 코드는 다시는 인클루드 될수 없다는 차이점만 있다. 이 이름이 제시하듯이 한번만 인클루드할것이다.
include_once()는 특정 스크립트 수행기간동안 동일한 파일이 한번 이상 인클루드되고 적용될지도 모르는 상황에서 사용해야 할것이다. 그리고 함수 중복정의, 변수값 중복 지정 등의 문제를 회피하려면 정확히 한번만 인클루드할 때가 있을것이다.
require_once()와 include_once()의 더 많은 사용예는, 최신 PHP 소스 내의 » PEAR코드를 참고할것.
반환값은 include()와 동일합니다. 파일이 이미 포함되었으면, TRUE를 반환합니다.
Note: include_once()는 PHP 4.0.1에서 추가됨
Note: include_once()와 require_once()는 대소문자를 구별하지 않는 운영체제(윈도우 등)에서 기대하지 않은 동작을 할 수 있습니다.
Example #1 include_once()는 윈도우에서 대소문자를 구분하지 못합니다.
<?php
include_once "a.php"; // a.php를 포함합니다.
include_once "A.php"; // 윈도우에서 또다시 a.php를 포함합니다. (PHP 4만)
?>이 동작은 PHP 5에서 바뀌었습니다 - 경로를 표준화를 먼저 하기 때문에, C:\PROGRA~1\A.php를 C:\Program Files\a.php로 인식하고, 파일을 한 번만 포함합니다.
PHP 4.3.0 이전의 윈도우 버전 PHP에서는 이 함수를 이용하여 원격 파일에 접근할 수 없습니다. allow_url_fopen을 활성화하여도 마찬가지입니다.
참고: include(), require(), require_once(), get_required_files(), get_included_files(), readfile(), virtual().
The goto operator can be used to jump to another section in the program. The target point is specified by a label followed by a colon, and the instruction is given as goto followed by the desired target label. This is not a full unrestricted goto. The target label must be within the same file and context, meaning that you cannot jump out of a function or method, nor can you jump into one. You also cannot jump into any sort of loop or switch structure. You may jump out of these, and a common use is to use a goto in place of a multi-level break.
Example #1 goto example
<?php
goto a;
echo 'Foo';
a:
echo 'Bar';
?>
위 예제의 출력:
Bar
Example #2 goto loop example
<?php
for($i=0,$j=50; $i<100; $i++) {
while($j--) {
if($j==17) goto end;
}
}
echo "i = $i";
end:
echo 'j hit 17';
?>
위 예제의 출력:
j hit 17
Example #3 This will not work
<?php
goto loop;
for($i=0,$j=50; $i<100; $i++) {
while($j--) {
loop:
}
}
echo "$i = $i";
?>
위 예제의 출력:
Fatal error: 'goto' into loop or switch statement is disallowed in script on line 2
Note: The goto operator is available as of PHP 5.3.
다음과 같은 문법을 사용하여 함수를 선언한다:
Example #1 함수 사용을 설명하기 위한 가상 코드
<?php
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
{
echo "예제 함수.\n";
return $retval;
}
?>
모든 유효 PHP코드는 특정 함수 내에서 뿐만 아니라, 여러 다른 함수나 class정의 안에서도 나타날수있다.
함수 이름은 PHP의 다른 라벨과 같은 규칙을 따릅니다. 유효한 함수 이름은 문자나 _로 시작하고, 여러 개의 문자, 숫자, _가 붙습니다. 정규 표현식으로는 다음과 같이 표현됩니다: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*.
함수는 아래 두 예제처럼 조건적으로 정의할 경우를 제외하고, 참조하기 전에 정의할 필요는 없습니다.
아래 예제 코드와 같이 함수가 조건적으로 선언되면 그 함수가 호출되기 전에 함수를 선언해야 한다.
Example #2 조건적인 함수
<?php
$makefoo = true;
/* We can't call foo() from here
since it doesn't exist yet,
but we can call bar() */
bar();
if ($makefoo) {
function foo()
{
echo "I don't exist until program execution reaches me.\n";
}
}
/* Now we can safely call foo()
since $makefoo evaluated to true */
if ($makefoo) foo();
function bar()
{
echo "I exist immediately upon program start.\n";
}
?>
Example #3 함수 안의 함수
<?php
function foo()
{
function bar()
{
echo "foo()를 호출하기 전까지는 존재하지 않습니다.\n";
}
}
/* bar()를 호출할 수 없습니다.
아직 존재하지 않습니다. */
foo();
/* 이제 bar()를 호출할 수
있습니다. foo()를 실행하여
접근할 수 있게 되었습니다. */
bar();
?>
PHP의 모든 함수와 클래스는 전역입니다 - 함수가 내부에서 정의되었더라도 외부에서 호출할 수 있으며, 반대도 성립합니다.
PHP는 함수 오버로딩(overloading)을 지원하지 않으며, 함수 정의를 해제하거나 이미 선언된 함수를 다시 선언할수 없다.
Note: 함수명은 선언시에 그 함수를 호출하기 편하게 만들겠지만, 대소문자 구별을 하지 않는다.
함수에서 가변 길이 인수 목록과 인수 기본값을 지원합니다. 자세한 정보는 func_num_args(), func_get_arg(), func_get_args() 함수 레퍼런스를 참고하십시오.
PHP에서 재귀 함수 호출을 할 수 있습니다. 그러나 100-200 재귀 레벨을 넘어서는 함수/메쏘드 호출을 피하십시오. 스택 한계에 도달하여 현재 스크립트가 중단됩니다.
Example #4 재귀 함수
<?php
function recursion($a)
{
if ($a < 20) {
echo "$a\n";
recursion($a + 1);
}
}
?>
함수 인수를 통해서 함수에 정보를 넘겨줄수 있다. 이런 함수 인수는 콤마(,)로 구별되는 표현 목록이다.
PHP는 값에 의한 인수 전달(passing by value) (기본값), 참조에 의한 전달, 인수 기본값 기능을 지원합니다. 가변 길이 인수 목록도 지원하며, 자세한 정보는 func_num_args(), func_get_arg(), func_get_args() 함수 레퍼런스를 참고하십시오.
Example #1 함수에 배열 넘겨주기
<?php
function takes_array($input)
{
echo "$input[0] + $input[1] = ", $input[0]+$input[1];
}
?>
기본적으로, 함수 인수는 값에 의해 전달됩니다. (그래서 함수내의 인수 변수값을 변경해도 함수 밖에서는 바뀌지 않습니다) 함수가 그 인수를 바꾸게 하려면, 참조로 넘겨줘야 합니다.
항상 함수의 인수를 참조로 넘기게 하려면, 함수 정의에서 엠퍼샌드(&)를 인수 이름 앞에 붙이면 됩니다:
Example #2 참조에 의해 함수 인수 전달하기
<?php
function add_some_extra(&$string)
{
$string .= 'and something extra.';
}
$str = 'This is a string, ';
add_some_extra($str);
echo $str; // outputs 'This is a string, and something extra.'
?>
함수는 다음과 같이 스칼라 인수에 대해 C++스타일 기본값으로 지정할수있다:
Example #3 함수에 기본 인수 사용하기
<?php
function makecoffee($type = "cappuccino")
{
return "Making a cup of $type.\n";
}
echo makecoffee();
echo makecoffee(null);
echo makecoffee("espresso");
?>
위 예제 코드의 출력은 다음과 같다:
PHP는 array와 특별형 NULL을 기본값으로 사용할 수 있습니다. 예를 들면:
Example #4 스칼라 형이 아닌 기본값 사용하기
<?php
function makecoffee($types = array("카푸치노"), $coffeeMaker = NULL)
{
$device = is_null($coffeeMaker) ? "손" : $coffeeMaker;
return "$device(으)로 ".join(", ", $types)."를 만듭니다.\n";
}
echo makecoffee();
echo makecoffee(array("카푸치노", "라바짜"), "찻주전자");
?>
기본값은 상수 표현식이 될수 있으나 (예를 들면) 변수나 클래스 멤버가 될수는 없다.
기본 인수를 사용할때에는 모든 기본값은 기본값을 쓰지 않는 인수의 오른쪽으로 가야 한다; 그렇지 않으면, 기대하던대로 작동하지 않을것이다. 다음 예제 코드를 참고:
Example #5 기본 함수 인수가 잘못 사용된 예
<?php
function makeyogurt($type = "acidophilus", $flavour)
{
return "Making a bowl of $type $flavour.\n";
}
echo makeyogurt("raspberry"); // won't work as expected
?>
위 예제 코드의 출력은 다음과 같다:
위 코드를 아래 코드와 비교하라:
Example #6 기본 함수 인수의 정확한 사용예
<?php
function makeyogurt($flavour, $type = "acidophilus")
{
return "Making a bowl of $type $flavour.\n";
}
echo makeyogurt("raspberry"); // works as expected
?>
이 예제코드의 출력은 다음과 같다:
Note: PHP 5부터, 기본값을 참조로 넘길 수 있습니다.
PHP 4 이상에서는 사용자 선언 함수에서 가변 길이 변수 목록 기능을 지원합니다. 이 기능은 func_num_args(), func_get_arg(), func_get_args()함수를 사용하여 손쉽게 사용가능하다.
특별한 문법이 필요하지 않다. 인수 목록은 함수선언부에서 밝혀야하고 일반 인수와 동일하게 작동할것이다.
선택적인 return문을 사용하여 값을 돌려준다. 배열이나 객체를 포함하여 모든 타입을 돌려줄수있다. 이 구문에서 함수의 수행이 즉시 중단되고 현재 함수를 호출한 코드줄로 제어를 되돌린다. 자세한 정보는 return()섹션을 참고할것.
Example #1 return()의 사용예
<?php
function square($num)
{
return $num * $num;
}
echo square(4); // outputs '16'.
?>
함수는 여러 값을 반환할 수 없습니다. 그러나 배열을 반환하게 해서 비슷한 결과를 얻을 수 있습니다.
Example #2 여러 값을 취하기 위해 배열을 돌려줌
<?php
function small_numbers()
{
return array (0, 1, 2);
}
list ($zero, $one, $two) = small_numbers();
?>
함수에서 참조를 돌려주기위해서는, 함수 선언부와 돌려주는 변수값을 지정하는 곳에서 참조 연산자 & 를 사용해야 한다.
Example #3 함수에서 참조 돌려주기
<?php
function &returns_reference()
{
return $someref;
}
$newref =& returns_reference();
?>
참조에 관한 자세한 정보는, 참조 표현섹션을 참고.
PHP는 가변 함수에 대한 개념을 지원한다. 이 용어의 의미는 어떤 변수 뒤에 괄호가 따라온다면, PHP는 그 변수의 값을 갖는 함수를 찾아서 실행하려 할것이란 것이다. 이런 개념은 이기능 외에도 콜백과 함수 테이블 등등을 구현할수 있게 해준다.
가변 함수는 echo(), print(), unset(), isset(), empty(), include(), require()와 같은 언어 구조와 함께 작동하지 않을것이다. 래퍼 함수를 사용해서 이러한 구조를 가변 함수로 이용할 수 있습니다.
Example #1 가변 변수 사용예
<?php
function foo() {
echo "foo() 안입니다.<br />\n";
}
function bar($arg = '')
{
echo "bar() 안입니다; 인수는 '$arg'입니다.<br />\n";
}
// echo를 감싸는 래퍼 함수입니다.
function echoit($string)
{
echo $string;
}
$func = 'foo';
$func(); // foo()를 호출합니다.
$func = 'bar';
$func('test'); // bar()를 호출합니다.
$func = 'echoit';
$func('test'); // echoit()을 호출합니다.
?>
객체 메쏘드도 가변 함수 구문으로 호출할 수 있습니다.
Example #2 가변 메쏘드 사용예
<?php
class Foo
{
function Variable()
{
$name = 'Bar';
$this->$name(); // Bar() 메쏘드를 호출합니다.
}
function Bar()
{
echo "This is Bar";
}
}
$foo = new Foo();
$funcname = "Variable";
$foo->$funcname(); // $foo->Var()를 호출합니다.
?>
또 call_user_func(), variable variables, function_exists()섹션을 참고
PHP는 많은 함수와 상수로 표준화되었다. 그리고 특정 PHP확장 컴파일이 요구하는 함수도 제공한다. 이런 함수는 확장을 컴파일하지 않으면 "undefined function"같은 치명적 오류 메시지를 출력합니다. 예를 들면, 이미지 함수를 사용하기 위해서는 GD 지원이 가능하게 컴파일해야 합니다. mysql_connect() 함수를 사용하려면 MySQL을 지원하도록 컴파일해야 한다. 문자열과 변수 관련 함수와 같이 PHP의 모든 버전에 포함되어있는 많은 핵심 함수가 존재한다. phpinfo()나 get_loaded_extensions()를 호출하면 현재 PHP에 올라간 확장에 어떤것인지 확인할수 있다. 많은 확장이 기본값으로 활성화되어있고, PHP 매뉴얼은 여러 확장에 의해 분할되어있다는 것에 주의해야 한다. PHP를 셋업하는 방법을 알고 싶다면, 설정, 설치, 각 확장에 대한 챕터를 보라.
함수의 원형(prototype) 읽기와 이해는 함수 선언 읽는 법이라는 매뉴얼 섹션에서 설명한다. 함수가 돌려주는 것이나 함수가 값으로 직접 전달하는지 이해하는것이 중요하다. 예를 들면, str_replace()함수는 변경된 문자열을 돌려주는 반면에 usort()함수는 실질적으로 변수 자체에 전달하도록 동작한다. 각 매뉴얼 페이지는 각함수에 대해서 함수 인수와 동작 변경,성공과 실패시 돌려주는 값과 유용한 정보에 대해서 나와있다. 이런 중요한 차이점(아직은 희박) 을 아는 것은 PHP 코드를 정확하게 쓰는데 있어서 매우 결정적인 역할을 한다.
Note: string을 기대한 곳에 array를 넘기는 등, 함수에 주어진 인수가 기대한 것이 아닐 경우, 함수의 반환값은 정의되지 않았습니다. 이런 경우 NULL을 반환할 수 있지만, 이는 단순한 경우이며, 이에 의존하지 마십시오.
더불어 function_exists(), the function reference, get_extension_funcs(), dl()섹션을 참고할것.
익명 함수는 이름을 지정하지 않은 함수를 생성할 수 있게 합니다. 콜백 인수에 매우 유용하나, 다른 용도로 사용할 수도 있습니다.
Example #1 익명 함수 예제
<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
return strtoupper($match[1]);
}, 'hello-world');
// 출력: helloWorld
?>
익명 함수는 내부적으로 Closure 클래스로 구현됩니다.
Note: 익명 함수는 PHP 5.3.0부터 사용할 수 있습니다.
클래스는 변수들과 이 변수들과 같이 동작하는 함수의 집합체이다. 변수는 var로 정의하고 함수는 function으로 정의합니다. 클래스는 다음 구문을 사용하여 정의합니다:
<?php
class Cart {
var $items; // Items in our shopping cart
// Add $num articles of $artnr to the cart
function add_item ($artnr, $num) {
$this->items[$artnr] += $num;
}
// Take $num articles of $artnr out of the cart
function remove_item ($artnr, $num) {
if ($this->items[$artnr] > $num) {
$this->items[$artnr] -= $num;
return true;
} elseif ($this->items[$artnr] == $num) {
unset($this->items[$artnr]);
return true;
} else {
return false;
}
}
}
?>
위 코드에서 Cart라는 이름을 갖는 클래스는 카트(cart)를 위한 품목의 연관 배열, 그리고 카트에 아이템을 추가하거나 제거하는 두 개의 함수로 구성되어있다.
클래스 정의를 여러 파일로 나눌 수 없습니다. 또한, 메쏘드 선언 안에서 나누지 않는 한, 클래스 정의를 여러 PHP 블록으로 나눌 수 없습니다. 다음 코드는 작동하지 않습니다:
<?php
class test {
?>
<?php
function test() {
print 'OK';
}
}
?>
하지만, 다음 코드는 허용됩니다:
<?php
class test {
function test() {
?>
<?php
print 'OK';
}
}
?>
PHP 4에서는 다음 사항에 주의해야 한다.
Zend에서는 stdClass같은 명칭을 내부적으로 사용하며 이 명칭은 예약되어있다. 따라서 PHP에서 stdClass라는 클래스명을 만들수 없다.
__sleep과 __wakeup함수는 PHP 클래스에서 중요한 역할을 수행한다. 이들과 결합된 매직 기능을 원 하지 않는다면 이런 이름을 클래스내에서 사용할수 없다. 다음 글에서 자세하게 설명할것이다.
PHP에서 __으로 시작하는 함수명은 매직 기능을 수행하도록 예약되어있다. 문서화된 매직 기능을 원하지 않는다면 PHP에서 __를 갖는 함수명을 사용하지 않도록 한다.
PHP 4에서 var로 변수를 선언할때는 상수로만 초기화될수 있다. 상수가 아닌 값으로 초기화하려면, 클래스로부터 객체를 생성할때 자동적 으로 호출되는 함수에서 초기화할 필요가 있다. 이런 함수를 생성자(constructor) 라고 부른다. (다음글을 보세요)
<?php
class Cart {
/* PHP 4에서 이 코드는 작동하지 않을것이다 */
var $todays_date = date("Y-m-d");
var $name = $firstname;
var $owner = 'Fred ' . 'Jones';
/* 그러나, 배열은 고정값을 가질 수 있습니다 */
var $items = array("VCR", "TV");
}
/* 이와 같이 해야 한다 */
class Cart {
var $todays_date;
var $name;
var $owner;
var $items = array("VCR", "TV");
function Cart() {
$this->todays_date = date("Y-m-d");
$this->name = $GLOBALS['firstname'];
/* etc. . . */
}
}
?>
class는 타입이다. 즉, 실제 변수를 위한 청사진이다. new 연산자를 사용하여 원하는 이런 타입의 변수를 생성할 수 있다.
<?php
$cart = new Cart;
$cart->add_item("10", 1);
$another_cart = new Cart;
$another_cart->add_item("0815", 3);
?>
위 예제 코드는 Cart클래스의 $cart, $another_cart 객체를 생성한다. $cart의 add_item() 함수는 $cart 에 품목 번호가 10인 아이템 1개를 추가하고, $another_cart에 품목 번호가 0815인 아이템 3개를 추가한다.
$cart와 $another_cart 둘다 add_item(), remove_item() 함수와 items변수를 갖는다. 이들 모두 서로 다른 함수와 변수들이다. 이런 객체는 파일시스템의 디렉토리에 비유될수 있다. 파일 시스템에서는 서로 다른 디렉토리에 존재하는 두 개의 다른 README.TXT를 가질 수 있습니다. 디렉토리에서 최상위 디렉토리에서 이들 파일까지의 경로를 지정하는 것과 마찬가지로 , 호출하려는 함수의 완전한 이름을 지정해야 합니다: PHP에서, 최상위 디렉토리는 전역 이름공간이고, 경로 구분자는 ->입니다. 따라서, $cart->items과 $another_cart->items 은 서로 다른 변수를 지칭하는 것이다. 변수는 $cart->$items이 아니라, $cart->items 로 지정해야 한다는 것에 주의해야 한다. 즉, PHP에서 변수명은 오직 한개의 달러사인($) 기호만 허용된다.
<?php
// correct, single $
$cart->items = array("10" => 1);
// invalid, because $cart->$items becomes $cart->""
$cart->$items = array("10" => 1);
// correct, but may or may not be what was intended:
// $cart->$myvar becomes $cart->items
$myvar = 'items';
$cart->$myvar = array("10" => 1);
?>
클래스의 선언부에서는 프로그램이 객체에 접근할때 어느 객체명 밑에 속해있을지 알수 없다: Cart 클래스가 선언된 후에 그 객체가 $cart, $another_cart, 또다른 객체명을 갖을지 알 수 없는것이다. 따라서, Cart 클래스 선언부 안에서 $cart->items라고 쓸수 없다. 대신에, 클래스내의 함수나 변수에 접근할 수 있게 하려면 '내 소유'나 '현재 객체'라고 해석할수 있는 $this라는 의사-변수를 사용할수 있다. 따라서, '$this->items[$artnr] += $num' 이라는 코드는 '내 소유의 items 배열의 $artnr카운터를 $num만큼 더하라' 또는 '현재 객체의 items 배열의 $artnr 카운터를 $num만큼 더하라'고 해석할 수 있다.
Note: $this 모의 변수는 메쏘드가 정적으로 호출되었을 때는 일반적으로 정의되지 않습니다. 그러나, 정적 규칙: 메쏘드가 다른 객체 안에서 정적으로 호출되었을 때는 $this가 정의됩니다. 이런 경우, $this은 호출한 객체의 것입니다. 다음 예제가 이를 보여줍니다:
<?php
class A
{
function foo()
{
if (isset($this)) {
echo '$this is defined (';
echo get_class($this);
echo ")\n";
} else {
echo "\$this is not defined.\n";
}
}
}
class B
{
function bar()
{
A::foo();
}
}
$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>위 예제의 출력:
$this is defined (a) $this is not defined. $this is defined (b) $this is not defined.
Note: 클래스와 객체를 제어할 수 있는 몇가지의 유용한 함수가 제공된다. 클래스/객체 함수에서 확인할수 있다.
때때로 기존의 클래스와 비슷한 변수와 함수를 갖는 클래스가 필요할때 가 있다. 실제로, 모든 프로젝트에서 사용할수 있는 범용의 클래스를 선언하고, 특정 프로젝트에서 이런 클래스를 필요에 의해 변경하는 것은 좋은 습관이다. 이런 일을 수월하게 하기 위해서 클래스는 다른 클래스에서 확장(extension) 될수 있다. 이렇게 확장되거나 파생된 클래스는 원래 클래스의 모든 변수와 함수를 소유하고 (이런 경우를 아무도 죽지 않았음 에도 불구하고 '상속'이라고 부른다) 필요로 하는 확장된 선언을 추가할수 있다. 기존 클래스에서 기존 함수나 변수의 선언을 해제하여 뺄수는 없다. 확장 클래스는 항상 하나의 기존 클래스에만 연관되어있다. 즉 다중 상속은 지원되지 않는다. 클래스는 'extends'라는 키워드를 사용하여 확장된다.
<?php
class Named_Cart extends Cart {
var $owner;
function set_owner ($name) {
$this->owner = $name;
}
}
?>
위 코드는 Cart의 모든 변수와 함수는 물론 추가된 변수 $owner 와 추가된 함수 set_owner()를 갖는 클래스를 선언한다. 이로써 이름이 있는 카트를 만들고 카트의 소유자를 설정하고 얻어올수 있다. 이름이 있는 카트에서는 물론 기존의 일반 카트 함수 도 쓸수 있다:
<?php
$ncart = new Named_Cart; // 이름이 있는 카트 만들기
$ncart->set_owner("kris"); // 그 카트에 소유자를 설정
print $ncart->owner; // 소유자 이름을 출력
$ncart->add_item("10", 1); // (기존 cart에서 상속한 함수 사용)
?>
이런 경우를 "부모-자식" 관계라고 부르기도 한다. 부모 클래스를 만들고, 부모 클래스에 기반한 새 클래스를 만들려면 extends를 사용한다: 자식 클래스. 심지어 이런 새로운 자식 클래스를 사용하거나 이 자식 클래스에 기반한 다른 클래스도 만들수 있다.
Note: 클래스는 그것이 사용되기 전에 이미 선언되어 있어야 한다! Cart클래스를 상속하는 Named_Cart클래스가 필요하면 우선 Cart클래스를 먼저 선언해야 할것이다. Named_Cart클래스에 기반한 다른 클래스 Yellow_named_cart 를 생성하고자 한다면 Named_Cart클래스를 먼저 선언해야 한다. 짧게 말해서: 클래스가 선언되는 순서는 중요하다.
생성자는 new를 사용하여 클래스의 새 인스턴스를 생성할때 자동으로 호출되는 클래스 내의 함수를 말한다. 클래스명과 동일한 이름을 가지는 함수가 생성자가 됩니다. 클래스에 생성자가 없으면, 부모 클래스의 생성자가 호출됩니다. (존재할 경우)
<?php
class Auto_Cart extends Cart {
function Auto_Cart() {
$this->add_item("10", 1);
}
}
?>
위 코드는 Cart와 같은 Auto_Cart 클래스를 선언하고 "new"로 새로운 Auto_Cart가 생성될때마다 상품번호 "10"인 아이템 하나를 갖는 카트로 초기화하는 생성자를 만든다. 생성자는 인수를 취할수 있고 이런 인수로 인해 생성자를 더 유용하게 만들어주지만 없을수도 있다. 인수가 없는 클래스를 사용하려면 생성자의 모든 인수는 기본값을 제공해 줄수 있다.
<?php
class Constructor_Cart extends Cart {
function Constructor_Cart($item = "10", $num = 1) {
$this->add_item ($item, $num);
}
}
// Shop the same old boring stuff.
$default_cart = new Constructor_Cart;
// Shop for real...
$different_cart = new Constructor_Cart("20", 17);
?>
생성자에서 발생할수 있는 에러 메시지를 보이지 않게 하려면 @연산자를 사용할수 있다.즉, @new를 쓸수 있다.
<?php
class A
{
function A()
{
echo "I am the constructor of A.<br />\n";
}
function B()
{
echo "I am a regular function named B in class A.<br />\n";
echo "I am not a constructor in A.<br />\n";
}
}
class B extends A
{
}
// B()를 생성자로 호출합니다
$b = new B;
?>
클래스 A의 함수 B()는 의도하지 않았을지라도 즉시 클래스 B의 생성자가 될것이다. PHP 4에서는 그 함수가 클래스 B에서 선언되었는지 또는 거기서 상속되었는지는 상관하지 않는다.
PHP 4는 파생 클래스의 생성자에서 자동으로 부모 클래스의 생성자를 호출하지 않는다. 적절하게 상단에 생성자 호출을 전달할 책임은 당신에게 달려있다.
소멸자는 객체가 파괴될때, unset()함수나, 단순히 현재 영역을 벗어남으로써 자동으로 호출되는 함수이다. PHP에서는 소멸자가 없다. 대신 register_shutdown_function()을 사용하여 소멸자의 효과를 낼 수는 있습니다.
다음은 PHP 4 이후에서만 적용되는 글이다.
때때로 원래 클래스의 함수와 변수를 참조하거나 아직 어떤 인스턴스도 갖지 않는 클래스의 함수를 참조할 필요가 있다. 이런 목적으로 :: 연산자를 사용한다.
<?php
class A {
function example() {
echo "I am the original function A::example().<br />\n";
}
}
class B extends A {
function example() {
echo "I am the redefined function B::example().<br />\n";
A::example();
}
}
// 여기서는 클래스 A의 객체가 존재하지 않는다.
// 이 코드는
// I am the original function A::example().<br />를 출력한다.
A::example();
// B 클래스의 객체를 생성한다.
$b = new B;
// 여기서는 다음과 같이 출력할것이다.
// I am the redefined function B::example().<br />
// I am the original function A::example().<br />
$b->example();
?>
위 예제 코드는 클래스 A의 함수 example()이 호출된다. 그러나 클래스 A의 객체가 존재하지 않는다. 그래서 $a->example()와 비슷한 코드를 쓸수 없다. 대신에 '클래스 함수'인 example()을 호출한다. 즉, 그 클래스의 객체가 아니라 클래스 자체의 함수를 호출하는 것이다.
클래스 함수는 존재하지만, 클래스 변수는 존재하지 않는다. 실제로, 호출의 모든 시간동안 전혀 객체가 없었고 따라서, 클래스 함수는 어떤 객체 변수도 사용할수 없다 (그러나 로컬 변수와 전역 변수는 사용할수 있다) 그래서 $this를 전혀 사용하지 않는다.
위 예제 코드에서 클래스 B는 함수 example()을 재선언한다. ::을 사용하여 클래스 A의 example 구현에 대해 특별히 참조하지 않으면, 클래스 A의 원래 선언은 가려지게 되고 더이상 가용하지 않다. 이와 같이 하려면 A::example()라고 써야 한다 (다음섹션에서 설명한대로 parent::example() 라고 써야 한다).
이런 환경에서는 현재 객체가 있고 그 객체는 객체 변수를 갖을수도 있다. 따라서 객체 함수 안에서 사용할때에는 $this와 객체 변수를 사용해야 할것이다.
원래 클래스의 변수와 함수를 참조하는 코드를 짜야할 필요가 생길수 있다. 파생 클래스가 세분화되어 고안되었거나 원래 클래스의 코드에서 특수화되어 있는경우에는 더욱 그럴 필요성이 생긴다.
코드에서 원래 클래스명을 사용하는 대신에, 특별한 이름 parent 을 사용해야 한다. 이 용어는 현재 클래스의 extends선언 안에 주어진 원래 클래스를 참조한다는 의미를 갖는다. 이렇게 씀으로써 여러 곳에서 원래 클래스명을 쓰는것을 피할수 있다. 구현중에 상속이 세번 바뀌게 되면, 단순히 현재 클래스의 extends선언을 바꾸기만 하면 된다.
<?php
class A {
function example() {
echo "I am A::example() and provide basic functionality.<br />\n";
}
}
class B extends A {
function example() {
echo "I am B::example() and provide additional functionality.<br />\n";
parent::example();
}
}
$b = new B;
// This will call B::example(), which will in turn call A::example().
$b->example();
?>
serialize()함수는 PHP에 저장할수 있는 값은 뭐든지 바이트-스트림(byte-stream) 대표성을 내포하는 문자열로 돌려준다. unserialize()함수는 이런 문자열을 원래 변수값으로 되돌려준다. serialize를 사용하여 객체를 저장하면 객체 내의 모든 변수 를 저장할 수 있다. 객체 내의 함수들을 저장할 수는 없고, 오직 클래스의 이름만 저장될것이다.
객체를 unserialize()하기 위해서는, 그 객체의 클래스가 선언되어 있어야 한다. 즉, page1.php에서 클래스 A의 객체 $a 가 있고 이것을 일렬화하면, 클래스 A를 참조하는 문자열을 얻게 되고, 이 문자열은 $a에 속해있는 모든 변수값을 포함하게 될것이다. Page2.php에서 이 문자열을 비일렬화하려면, 클래스 A의 $a를 재생성하고, 클래스 A의 선언이 page2.php에 존재해야 한다. 예를 들면 인클루드 파일 안에 클래스 A의 클래스 선언부를 저장하고 page1.php와 page2.php 에서 이 파일을 인클루드 하면 된다.
<?php
// classa.inc:
class A {
var $one = 1;
function show_one() {
echo $this->one;
}
}
// page1.php:
include("classa.inc");
$a = new A;
$s = serialize($a);
// store $s somewhere where page2.php can find it.
$fp = fopen("store", "w");
fwrite($fp, $s);
fclose($fp);
// page2.php:
// this is needed for the unserialize to work properly.
include("classa.inc");
$s = implode("", @file("store"));
$a = unserialize($s);
// now use the function show_one() of the $a object.
$a->show_one();
?>
세션을 사용해서 객체를 등록하기 위해 session_register()함수를 사용한다면, 이 객체들은 각 PHP 페이지의 끝에서 자동으로 일렬화되고, 다음 페이지들 각각에서 자동으로 비일렬화된다. 이 객체들이 일단 세션의 일부분이 되면 페이지의 어느 부분에서도 이런 객체가 나타날 수 있다는것을 의미한다.
모든 페이지에서 실제로 이런 클래스를 사용하지 않더라도, 모든 페이지에 등록된 모든 객체의 클래스 선언을 인클루드하도록 한다. 이렇게 하지 않고, 존재하는 클래스 선언부없이 객체가 일렬화되면, 그 객체는 클래스 구성원을 잃게 될것이고 어떤 함수도 갖지 않는 __PHP_Incomplete_Class_Name 클래스의 객체가 될것이다. 즉, 그 객체는 쓸모없게 될것이다.
그래서 위 예제코드에서 $a가 session_register("a") 수행하여 세션의 일부분이 되면, page1.php와 page2.php뿐만 아니라 사용중인 모든 페이지에 classa.inc파일을 인클루드해야 한다.
serialize()는 클래스가 __sleep라는 매직 이름을 갖는 함수를 갖는지 체크한다. 이 함수를 갖고있다면, 일렬화되기 전에 이 함수가 수행된다. 이 함수는 객체를 깨끗하게 비울수 있고, 일렬화되어야 하는 그 객체의 모든 변수명을 갖는 배열을 돌려준다. 이 메쏘드가 아무것도 반환하지 않는다면, NULL이 일렬화되고 E_NOTICE가 발생합니다.
__sleep의 의도된 사용은 지연된 데이터를 커밋하거나 비슷한 정리 작업을 수행하는 것입니다. 또한, 완전히 저장할 필요가 없는 매우 거대한 객체를 갖고 있다면 이 함수를 유용하게 쓸수 있다.
반대로, unserialize()는 __wakeup라는 매직 이름을 갖는 함수의 존재를 체크한다. 이 함수가 존재하면, 객체가 갖고 있을지도 모르는 모든 자원을 해제할수 있다.
__wakeup의 의도된 사용은 일렬화동안에 소실될수 있는 모든 데이터베이스 접속을 재구축하고 다른 재초기화 작업을 수행 한다.
생성자 내로 참조를 만드는 것은 혼란스런 결과를 유도할수 있다. 이런 튜토리얼같은 섹션이 문제를 회피하도록 도와준다.
<?php
class Foo {
function Foo($name) {
// 전역 배열 $globalref 안에 참조를 만든다
global $globalref;
$globalref[] = &$this;
// 값을 전달하기 위해 이름을 부여한다
$this->setName($name);
// 그리고 그것을 출력한다
$this->echoName();
}
function echoName() {
echo "<br />", $this->name;
}
function setName($name) {
$this->name = $name;
}
}
?>
= 복사 연산자를 사용하여 만들어지는 $bar1과 =& 참조 연산자를 사용하여 만들어지는 $bar2 사이에 차이점이 있는지 확인해보자...
<?php
$bar1 = new Foo('set in constructor');
$bar1->echoName();
$globalref[0]->echoName();
/* output:
set in constructor
set in constructor
set in constructor */
$bar2 =& new Foo('set in constructor');
$bar2->echoName();
$globalref[1]->echoName();
/* output:
set in constructor
set in constructor
set in constructor */
?>
외관상으로 둘 사이에는 아무 차이점도 없다. 그러나 실제로 매우 중요한 사실이 하나 있다: $bar1과 $globalref[0]은 참조되지 않는다. 그들은 같은 변수가 아니다. 이것은 "new"가 기본적으로 참조를 돌려주지 않기 때문이다. 대신 그것은 복사본을 돌려준다.
Note: 참조 대신 복사본을 돌려주는것 (PHP 4이상의 버전은 참조 카운팅을 사용한다) 때문에 퍼포먼스가 나빠지지는 않는다. 반대로 참조 대신에 복사본을 사용하는 것이 대부분 더 낫다. 왜냐하면 참조를 생성하는 것은 가상적으로 복사본을 만드는 데 약간의 시간이 걸리기 때문이다 (그것들이 거대한 배열이나 객체이고 그들 중 하나만 바뀌고 다른것들이 연속적으로 존재한다면, 그리고 동시에 그들 모두를 변경하려한다면 참조를 쓰는것이 더 현명할것이다)
위에서 서술한 것을 검증하기 위해 아래 예제 코드를 보자.
<?php
// now we will change the name. what do you expect?
// you could expect that both $bar1 and $globalref[0] change their names...
$bar1->setName('set from outside');
// as mentioned before this is not the case.
$bar1->echoName();
$globalref[0]->echoName();
/* output:
set from outside
set in constructor */
// let us see what is different with $bar2 and $globalref[1]
$bar2->setName('set from outside');
// luckily they are not only equal, they are the same variable
// thus $bar2->name and $globalref[1]->name are the same too
$bar2->echoName();
$globalref[1]->echoName();
/* output:
set from outside
set from outside */
?>
마지막으로 다음 예제를 보고 이해하도록 하자.
<?php
class A {
function A($i) {
$this->value = $i;
// try to figure out why we do not need a reference here
$this->b = new B($this);
}
function createRef() {
$this->c = new B($this);
}
function echoValue() {
echo "<br />","class ",get_class($this),': ',$this->value;
}
}
class B {
function B(&$a) {
$this->a = &$a;
}
function echoValue() {
echo "<br />","class ",get_class($this),': ',$this->a->value;
}
}
// try to understand why using a simple copy here would yield
// in an undesired result in the *-marked line
$a =& new A(10);
$a->createRef();
$a->echoValue();
$a->b->echoValue();
$a->c->echoValue();
$a->value = 11;
$a->echoValue();
$a->b->echoValue(); // *
$a->c->echoValue();
?>
위 예제의 출력:
class A: 10 class B: 10 class B: 10 class A: 11 class B: 11 class B: 11
PHP 4에서 객체는 매우 단순한 방식으로 비교된다. 즉: 두 객체 인스턴스 가 같은 속성과 값을 갖고, 같은 클래스의 인스턴스라면 두 객체는 동일하다. 식별 연산자 (===)를 사용하여 두 객체를 비교할때에도 비슷한 규칙이 적용된다.
아래 예제 코드를 실행해보면:
Example #1 PHP 4에서 객체 비교를 위한 예제코드
<?php
function bool2str($bool) {
if ($bool === false) {
return 'FALSE';
} else {
return 'TRUE';
}
}
function compareObjects(&$o1, &$o2) {
echo 'o1 == o2 : '.bool2str($o1 == $o2)."\n";
echo 'o1 != o2 : '.bool2str($o1 != $o2)."\n";
echo 'o1 === o2 : '.bool2str($o1 === $o2)."\n";
echo 'o1 !== o2 : '.bool2str($o1 !== $o2)."\n";
}
class Flag {
var $flag;
function Flag($flag=true) {
$this->flag = $flag;
}
}
class SwitchableFlag extends Flag {
function turnOn() {
$this->flag = true;
}
function turnOff() {
$this->flag = false;
}
}
$o = new Flag();
$p = new Flag(false);
$q = new Flag();
$r = new SwitchableFlag();
echo "Compare instances created with the same parameters\n";
compareObjects($o, $q);
echo "\nCompare instances created with different parameters\n";
compareObjects($o, $p);
echo "\nCompare an instance of a parent class with one from a subclass\n";
compareObjects($o, $r);
?>
위 예제의 출력:
Compare instances created with the same parameters o1 == o2 : TRUE o1 != o2 : FALSE o1 === o2 : TRUE o1 !== o2 : FALSE Compare instances created with different parameters o1 == o2 : FALSE o1 != o2 : TRUE o1 === o2 : FALSE o1 !== o2 : TRUE Compare an instance of a parent class with one from a subclass o1 == o2 : FALSE o1 != o2 : TRUE o1 === o2 : FALSE o1 !== o2 : TRUE
위 출력중 어떤것은 위에서 설명한 비교 규칙이 적용된다는 것을 알수 있다. 같은 속성에 대해 같은 값을 갖고, 같은 클래스에서 파생된 인스턴스만 동일 하고 동치로 판단한다.
복합 객체를 갖는 경우에도 같은 비교 규칙이 적용된다. 아래 예제 코드에서는 컨테이너 클래스를 만들어서 Flag 객체의 결합 배열을 저장한다.
Example #2 PHP 4에서 복합 객체 비교
<?php
class FlagSet {
var $set;
function FlagSet($flagArr = array()) {
$this->set = $flagArr;
}
function addFlag($name, $flag) {
$this->set[$name] = $flag;
}
function removeFlag($name) {
if (array_key_exists($name, $this->set)) {
unset($this->set[$name]);
}
}
}
$u = new FlagSet();
$u->addFlag('flag1', $o);
$u->addFlag('flag2', $p);
$v = new FlagSet(array('flag1'=>$q, 'flag2'=>$p));
$w = new FlagSet(array('flag1'=>$q));
echo "\nComposite objects u(o,p) and v(q,p)\n";
compareObjects($u, $v);
echo "\nu(o,p) and w(q)\n";
compareObjects($u, $w);
?>
위 예제의 출력:
Composite objects u(o,p) and v(q,p) o1 == o2 : TRUE o1 != o2 : FALSE o1 === o2 : TRUE o1 !== o2 : FALSE u(o,p) and w(q) o1 == o2 : FALSE o1 != o2 : TRUE o1 === o2 : FALSE o1 !== o2 : TRUE
PHP 5는 새로운 객체 모델을 가집니다. PHP의 객체 조작은 완전히 새로 쓰여졌고, 더욱 나은 성능과 많은 기능을 허용합니다.
Every class definition begins with the keyword class, followed by a class name, which can be any name that isn't a reserved word in PHP. Followed by a pair of curly braces, which contains the definition of the classes members and methods. A pseudo-variable, $this is available when a method is called from within an object context. $this is a reference to the calling object (usually the object to which the method belongs, but can be another object, if the method is called statically from the context of a secondary object). This is illustrated in the following examples:
Example #1 $this variable in object-oriented language
<?php
class A
{
function foo()
{
if (isset($this)) {
echo '$this is defined (';
echo get_class($this);
echo ")\n";
} else {
echo "\$this is not defined.\n";
}
}
}
class B
{
function bar()
{
A::foo();
}
}
$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>
위 예제의 출력:
$this is defined (a) $this is not defined. $this is defined (b) $this is not defined.
Example #2 Simple Class definition
<?php
class SimpleClass
{
// member declaration
public $var = 'a default value';
// method declaration
public function displayVar() {
echo $this->var;
}
}
?>
The default value must be a constant expression, not (for example) a variable, a class member or a function call.
Example #3 Class members' default value
<?php
class SimpleClass
{
// invalid member declarations:
public $var1 = 'hello '.'world';
public $var2 = <<<EOD
hello world
EOD;
public $var3 = 1+2;
public $var4 = self::myStaticMethod();
public $var5 = $myVar;
// valid member declarations:
public $var6 = myConstant;
public $var7 = self::classConstant;
public $var8 = array(true, false);
}
?>
Note: There are some nice functions to handle classes and objects. You might want to take a look at the Class/Object Functions.
Unlike heredocs, nowdocs can be used in any static data context.
Example #4 Static data example
<?php
class foo {
// As of PHP 5.3.0
public $bar = <<<'EOT'
bar
EOT;
}
?>
Note: Nowdoc support was added in PHP 5.3.0.
To create an instance of a class, a new object must be created and assigned to a variable. An object will always be assigned when creating a new object unless the object has a constructor defined that throws an exception on error. Classes should be defined before instantiation (and in some cases this is a requirement).
Example #5 Creating an instance
<?php
$instance = new SimpleClass();
// This can also be done with a variable:
$className = 'Foo';
$instance = new $className(); // Foo()
?>
In the class context, it is possible to create a new object by new self and new parent.
When assigning an already created instance of a class to a new variable, the new variable will access the same instance as the object that was assigned. This behaviour is the same when passing instances to a function. A copy of an already created object can be made by cloning it.
Example #6 Object Assignment
<?php
$assigned = $instance;
$reference =& $instance;
$instance->var = '$assigned will have this value';
$instance = null; // $instance and $reference become null
var_dump($instance);
var_dump($reference);
var_dump($assigned);
?>
위 예제의 출력:
NULL
NULL
object(SimpleClass)#1 (1) {
["var"]=>
string(30) "$assigned will have this value"
}
A class can inherit methods and members of another class by using the extends keyword in the declaration. It is not possible to extend multiple classes, a class can only inherit one base class.
The inherited methods and members can be overridden, unless the parent class has defined a method as final, by redeclaring them with the same name defined in the parent class. It is possible to access the overridden methods or static members by referencing them with parent::
Example #7 Simple Class Inheritance
<?php
class ExtendClass extends SimpleClass
{
// Redefine the parent method
function displayVar()
{
echo "Extending class\n";
parent::displayVar();
}
}
$extended = new ExtendClass();
$extended->displayVar();
?>
위 예제의 출력:
Extending class a default value
Many developers writing object-oriented applications create one PHP source file per-class definition. One of the biggest annoyances is having to write a long list of needed includes at the beginning of each script (one for each class).
In PHP 5, this is no longer necessary. You may define an __autoload function which is automatically called in case you are trying to use a class/interface which hasn't been defined yet. By calling this function the scripting engine is given a last chance to load the class before PHP fails with an error.
Note: Exceptions thrown in __autoload function cannot be caught in the catch block and results in a fatal error.
Note: Autoloading is not available if using PHP in CLI interactive mode.
Note: If the class name is used e.g. in call_user_func() then it can contain some dangerous characters such as ../. It is recommended to not use the user-input in such functions or at least verify the input in __autoload().
Example #1 Autoload example
This example attempts to load the classes MyClass1 and MyClass2 from the files MyClass1.php and MyClass2.php respectively.
<?php
function __autoload($class_name) {
require_once $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
Example #2 Autoload other example
This example attempts to load the interface ITest.
<?php
function __autoload($name) {
var_dump($name);
}
class Foo implements ITest {
}
/*
string(5) "ITest"
Fatal error: Interface 'ITest' not found in ...
*/
?>
PHP 5 allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.
Note: Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to parent::__construct() within the child constructor is required.
Example #1 using new unified constructors
<?php
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "In SubClass constructor\n";
}
}
$obj = new BaseClass();
$obj = new SubClass();
?>
For backwards compatibility, if PHP 5 cannot find a __construct() function for a given class, it will search for the old-style constructor function, by the name of the class. Effectively, it means that the only case that would have compatibility issues is if the class had a method named __construct() which was used for different semantics.
PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as C++. The destructor method will be called as soon as all references to a particular object are removed or when the object is explicitly destroyed or in any order in shutdown sequence.
Example #2 Destructor Example
<?php
class MyDestructableClass {
function __construct() {
print "In constructor\n";
$this->name = "MyDestructableClass";
}
function __destruct() {
print "Destroying " . $this->name . "\n";
}
}
$obj = new MyDestructableClass();
?>
Like constructors, parent destructors will not be called implicitly by the engine. In order to run a parent destructor, one would have to explicitly call parent::__destruct() in the destructor body.
Note: Destructors called during the script shutdown have HTTP headers already sent. The working directory in the script shutdown phase can be different with some SAPIs (e.g. Apache).
Note: Attempting to throw an exception from a destructor (called in the time of script termination) causes a fatal error.
The visibility of a property or method can be defined by prefixing the declaration with the keywords: public, protected or private. Public declared items can be accessed everywhere. Protected limits access to inherited and parent classes (and to the class that defines the item). Private limits visibility only to the class that defines the item.
Class members must be defined with public, private, or protected.
Example #1 Member declaration
<?php
/**
* Define MyClass
*/
class MyClass
{
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // Works
echo $obj->protected; // Fatal Error
echo $obj->private; // Fatal Error
$obj->printHello(); // Shows Public, Protected and Private
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// We can redeclare the public and protected method, but not private
protected $protected = 'Protected2';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj2 = new MyClass2();
echo $obj2->public; // Works
echo $obj2->private; // Undefined
echo $obj2->protected; // Fatal Error
$obj2->printHello(); // Shows Public, Protected2, Undefined
?>
Note: The PHP 4 method of declaring a variable with the var keyword is still supported for compatibility reasons (as a synonym for the public keyword). In PHP 5 before 5.1.3, its usage would generate an E_STRICT warning.
Class methods must be defined with public, private, or protected. Methods without any declaration are defined as public.
Example #2 Method Declaration
<?php
/**
* Define MyClass
*/
class MyClass
{
// Declare a public constructor
public function __construct() { }
// Declare a public method
public function MyPublic() { }
// Declare a protected method
protected function MyProtected() { }
// Declare a private method
private function MyPrivate() { }
// This is public
function Foo()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}
$myclass = new MyClass;
$myclass->MyPublic(); // Works
$myclass->MyProtected(); // Fatal Error
$myclass->MyPrivate(); // Fatal Error
$myclass->Foo(); // Public, Protected and Private work
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// This is public
function Foo2()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate(); // Fatal Error
}
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // Works
$myclass2->Foo2(); // Public and Protected work, not Private
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
?>
The Scope Resolution Operator (also called Paamayim Nekudotayim) or in simpler terms, the double colon, is a token that allows access to static, constant, and overridden members or methods of a class.
When referencing these items from outside the class definition, use the name of the class.
As of PHP 5.3.0, it's possible to reference the class using a variable. The variable's value can not be a keyword (e.g. self, parent and static).
Paamayim Nekudotayim would, at first, seem like a strange choice for naming a double-colon. However, while writing the Zend Engine 0.5 (which powers PHP 3), that's what the Zend team decided to call it. It actually does mean double-colon - in Hebrew!
Example #1 :: from outside the class definition
<?php
class MyClass {
const CONST_VALUE = 'A constant value';
}
$classname = 'MyClass';
echo $classname::CONST_VALUE; // As of PHP 5.3.0
echo MyClass::CONST_VALUE;
?>
Two special keywords self and parent are used to access members or methods from inside the class definition.
Example #2 :: from inside the class definition
<?php
class OtherClass extends MyClass
{
public static $my_static = 'static var';
public static function doubleColon() {
echo parent::CONST_VALUE . "\n";
echo self::$my_static . "\n";
}
}
$classname = 'OtherClass';
echo $classname::doubleColon(); // As of PHP 5.3.0
OtherClass::doubleColon();
?>
When an extending class overrides the parents definition of a method, PHP will not call the parent's method. It's up to the extended class on whether or not the parent's method is called. This also applies to Constructors and Destructors, Overloading, and Magic method definitions.
Example #3 Calling a parent's method
<?php
class MyClass
{
protected function myFunc() {
echo "MyClass::myFunc()\n";
}
}
class OtherClass extends MyClass
{
// Override parent's definition
public function myFunc()
{
// But still call the parent function
parent::myFunc();
echo "OtherClass::myFunc()\n";
}
}
$class = new OtherClass();
$class->myFunc();
?>
Declaring class members or methods as static makes them accessible without needing an instantiation of the class. A member declared as static can not be accessed with an instantiated class object (though a static method can).
For compatibility with PHP 4, if no visibility declaration is used, then the member or method will be treated as if it was declared as public.
Because static methods are callable without an instance of the object created, the pseudo variable $this is not available inside the method declared as static.
Static properties cannot be accessed through the object using the arrow operator ->.
Calling non-static methods statically generates an E_STRICT level warning.
Like any other PHP static variable, static properties may only be initialized using a literal or constant; expressions are not allowed. So while you may initialize a static property to an integer or array (for instance), you may not initialize it to another variable, to a function return value, or to an object.
As of PHP 5.3.0, it's possible to reference the class using a variable. The variable's value can not be a keyword (e.g. self, parent and static).
Example #1 Static member example
<?php
class Foo
{
public static $my_static = 'foo';
public function staticValue() {
return self::$my_static;
}
}
class Bar extends Foo
{
public function fooStatic() {
return parent::$my_static;
}
}
print Foo::$my_static . "\n";
$foo = new Foo();
print $foo->staticValue() . "\n";
print $foo->my_static . "\n"; // Undefined "Property" my_static
print $foo::$my_static . "\n";
$classname = 'Foo';
print $classname::$my_static . "\n"; // As of PHP 5.3.0
print Bar::$my_static . "\n";
$bar = new Bar();
print $bar->fooStatic() . "\n";
?>
Example #2 Static method example
<?php
class Foo {
public static function aStaticMethod() {
// ...
}
}
Foo::aStaticMethod();
$classname = 'Foo';
$classname::aStaticMethod(); // As of PHP 5.3.0
?>
It is possible to define constant values on a per-class basis remaining the same and unchangeable. Constants differ from normal variables in that you don't use the $ symbol to declare or use them.
The value must be a constant expression, not (for example) a variable, a class member, result of a mathematical operation or a function call.
Its also possible for interfaces to have constants. Look at the interface documentation for examples.
As of PHP 5.3.0, it's possible to reference the class using a variable. The variable's value can not be a keyword (e.g. self, parent and static).
Example #1 Defining and using a constant
<?php
class MyClass
{
const constant = 'constant value';
function showConstant() {
echo self::constant . "\n";
}
}
echo MyClass::constant . "\n";
$classname = "MyClass";
echo $classname::constant . "\n"; // As of PHP 5.3.0
$class = new MyClass();
$class->showConstant();
echo $class::constant."\n"; // As of PHP 5.3.0
?>
Example #2 Static data example
<?php
class foo {
// As of PHP 5.3.0
const bar = <<<'EOT'
bar
EOT;
}
?>
Unlike heredocs, nowdocs can be used in any static data context.
Note: Nowdoc support was added in PHP 5.3.0.
PHP 5 introduces abstract classes and methods. It is not allowed to create an instance of a class that has been defined as abstract. Any class that contains at least one abstract method must also be abstract. Methods defined as abstract simply declare the method's signature they cannot define the implementation.
When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility. For example, if the abstract method is defined as protected, the function implementation must be defined as either protected or public, but not private.
Example #1 Abstract class example
<?php
abstract class AbstractClass
{
// Force Extending class to define this method
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// Common method
public function printOut() {
print $this->getValue() . "\n";
}
}
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
}
class ConcreteClass2 extends AbstractClass
{
public function getValue() {
return "ConcreteClass2";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass2";
}
}
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n";
$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') ."\n";
?>
위 예제의 출력:
ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2 FOO_ConcreteClass2
Old code that has no user-defined classes or functions named 'abstract' should run without modifications.
Object interfaces allow you to create code which specifies which methods a class must implement, without having to define how these methods are handled.
Interfaces are defined using the interface keyword, in the same way as a standard class, but without any of the methods having their contents defined.
All methods declared in an interface must be public, this is the nature of an interface.
To implement an interface, the implements operator is used. All methods in the interface must be implemented within a class; failure to do so will result in a fatal error. Classes may implement more than one interface if desired by separating each interface with a comma.
Note: A class cannot implement two interfaces that share function names, since it would cause ambiguity.
Note: Interfaces can be extended like classes using the extend operator.
Its possible for interfaces to have constants. Interface constants works exactly like class constants. They cannot be overridden by a class/interface that inherits it.
Example #1 Interface example
<?php
// Declare the interface 'iTemplate'
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
// Implement the interface
// This will work
class Template implements iTemplate
{
private $vars = array();
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
}
return $template;
}
}
// This will not work
// Fatal error: Class BadTemplate contains 1 abstract methods
// and must therefore be declared abstract (iTemplate::getHtml)
class BadTemplate implements iTemplate
{
private $vars = array();
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
}
?>
Example #2 Extendable Interfaces
<?php
interface a
{
public function foo();
}
interface b extends a
{
public function baz(Baz $baz);
}
// This will work
class c implements b
{
public function foo()
{
}
public function baz(Baz $baz)
{
}
}
// This will not work and result in a fatal error
class d implements b
{
public function foo()
{
}
public function baz(Foo $foo)
{
}
}
?>
Example #3 Multiple interface inheritance
<?php
interface a
{
public function foo();
}
interface b
{
public function bar();
}
interface c extends a, b
{
public function baz();
}
class d implements c
{
public function foo()
{
}
public function bar()
{
}
public function baz()
{
}
}
?>
Example #4 Interfaces with constants
<?php
interface a
{
const b = 'Interface constant';
}
// Prints: Interface constant
echo a::b;
// This will however not work because its not allowed to
// override constants. This is the same concept as with
// class constants
class b implements a
{
const b = 'Class constant';
}
?>
See also the instanceof operator.
Overloading in PHP provides means to dynamically "create" members and methods. These dynamic entities are processed via magic methods one can establish in a class for various action types.
The overloading methods are invoked when interacting with members or methods that have not been declared or are not visible in the current scope. The rest of this section will use the terms "inaccessible members" and "inaccessible methods" to refer to this combination of declaration and visibility.
All overloading methods must be defined as public.
Note: None of the arguments of these magic methods can be passed by reference.
Note: PHP's interpretation of "overloading" is different than most object oriented languages. Overloading traditionally provides the ability to have multiple methods with the same name but different quantities and types of arguments.
| 버전 | 설명 |
|---|---|
| 5.3.0 | Added __callStatic(). Added warning to enforce public visibility and non-static declaration. |
| 5.1.0 | Added __isset() and __unset(). |
__set() is run when writing data to inaccessible members.
__get() is utilized for reading data from inaccessible members.
__isset() is triggered by calling isset() or empty() on inaccessible members.
__unset() is invoked when unset() is used on inaccessible members.
The $name argument is the name of the member being interacted with. The __set() method's $value argument specifies the value the $name'ed member should be set to.
Member overloading only works in object context. These magic methods will not be triggered in static context. Therefore these methods can not be declared static.
Example #1 overloading with __get, __set, __isset and __unset example
<?php
class MemberTest {
/** Location for overloaded data. */
private $data = array();
/** Overloading not used on declared members. */
public $declared = 1;
/** Overloading only used on this when accessed outside the class. */
private $hidden = 2;
public function __set($name, $value) {
echo "Setting '$name' to '$value'\n";
$this->data[$name] = $value;
}
public function __get($name) {
echo "Getting '$name'\n";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
$trace = debug_backtrace();
trigger_error(
'Undefined property via __get(): ' . $name .
' in ' . $trace[0]['file'] .
' on line ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
/** As of PHP 5.1.0 */
public function __isset($name) {
echo "Is '$name' set?\n";
return isset($this->data[$name]);
}
/** As of PHP 5.1.0 */
public function __unset($name) {
echo "Unsetting '$name'\n";
unset($this->data[$name]);
}
/** Not a magic method, just here for example. */
public function getHidden() {
return $this->hidden;
}
}
echo "<pre>\n";
$obj = new MemberTest;
$obj->a = 1;
echo $obj->a . "\n\n";
var_dump(isset($obj->a));
unset($obj->a);
var_dump(isset($obj->a));
echo "\n";
echo $obj->declared . "\n\n";
echo "Let's experiment with the private property named 'hidden':\n";
echo "Privates are visible inside the class, so __get() not used...\n";
echo $obj->getHidden() . "\n";
echo "Privates not visible outside of class, so __get() is used...\n";
echo $obj->hidden . "\n";
?>
위 예제의 출력:
Setting 'a' to '1' Getting 'a' 1 Is 'a' set? bool(true) Unsetting 'a' Is 'a' set? bool(false) 1 Let's experiment with the private property named 'hidden': Privates are visible inside the class, so __get() not used... 2 Privates not visible outside of class, so __get() is used... Getting 'hidden' Notice: Undefined property via __get(): hidden in <file> on line 70 in <file> on line 29
__call() is triggered when invoking inaccessible methods in an object context.
__callStatic() is triggered when invoking inaccessible methods in a static context.
The $name argument is the name of the method being called. The $arguments argument is an enumerated array containing the parameters passed to the $name'ed method.
Example #2 overloading instantiated methods with __call and __callStatic
<?php
class MethodTest {
public function __call($name, $arguments) {
// Note: value of $name is case sensitive.
echo "Calling object method '$name' "
. implode(', ', $arguments). "\n";
}
/** As of PHP 5.3.0 */
public static function __callStatic($name, $arguments) {
// Note: value of $name is case sensitive.
echo "Calling static method '$name' "
. implode(', ', $arguments). "\n";
}
}
$obj = new MethodTest;
$obj->runTest('in object context');
MethodTest::runTest('in static context'); // As of PHP 5.3.0
?>
위 예제의 출력:
Calling object method 'runTest' in object context Calling static method 'runTest' in static context
PHP 5 provides a way for objects to be defined so it is possible to iterate through a list of items, with, for example a foreach statement. By default, all visible properties will be used for the iteration.
Example #1 Simple Object Iteration
<?php
class MyClass
{
public $var1 = 'value 1';
public $var2 = 'value 2';
public $var3 = 'value 3';
protected $protected = 'protected var';
private $private = 'private var';
function iterateVisible() {
echo "MyClass::iterateVisible:\n";
foreach($this as $key => $value) {
print "$key => $value\n";
}
}
}
$class = new MyClass();
foreach($class as $key => $value) {
print "$key => $value\n";
}
echo "\n";
$class->iterateVisible();
?>
위 예제의 출력:
var1 => value 1 var2 => value 2 var3 => value 3 MyClass::iterateVisible: var1 => value 1 var2 => value 2 var3 => value 3 protected => protected var private => private var
As the output shows, the foreach iterated through all visible variables that can be accessed. To take it a step further you can implement one of PHP 5's internal interface named Iterator. This allows the object to decide what and how the object will be iterated.
Example #2 Object Iteration implementing Iterator
<?php
class MyIterator implements Iterator
{
private $var = array();
public function __construct($array)
{
if (is_array($array)) {
$this->var = $array;
}
}
public function rewind() {
echo "rewinding\n";
reset($this->var);
}
public function current() {
$var = current($this->var);
echo "current: $var\n";
return $var;
}
public function key() {
$var = key($this->var);
echo "key: $var\n";
return $var;
}
public function next() {
$var = next($this->var);
echo "next: $var\n";
return $var;
}
public function valid() {
$var = $this->current() !== false;
echo "valid: {$var}\n";
return $var;
}
}
$values = array(1,2,3);
$it = new MyIterator($values);
foreach ($it as $a => $b) {
print "$a: $b\n";
}
?>
위 예제의 출력:
rewinding current: 1 valid: 1 current: 1 key: 0 0: 1 next: 2 current: 2 valid: 1 current: 2 key: 1 1: 2 next: 3 current: 3 valid: 1 current: 3 key: 2 2: 3 next: current: valid:
You can also define your class so that it doesn't have to define all the Iterator functions by simply implementing the PHP 5 IteratorAggregate interface.
Example #3 Object Iteration implementing IteratorAggregate
<?php
class MyCollection implements IteratorAggregate
{
private $items = array();
private $count = 0;
// Required definition of interface IteratorAggregate
public function getIterator() {
return new MyIterator($this->items);
}
public function add($value) {
$this->items[$this->count++] = $value;
}
}
$coll = new MyCollection();
$coll->add('value 1');
$coll->add('value 2');
$coll->add('value 3');
foreach ($coll as $key => $val) {
echo "key/value: [$key -> $val]\n\n";
}
?>
위 예제의 출력:
rewinding current: value 1 valid: 1 current: value 1 key: 0 key/value: [0 -> value 1] next: value 2 current: value 2 valid: 1 current: value 2 key: 1 key/value: [1 -> value 2] next: value 3 current: value 3 valid: 1 current: value 3 key: 2 key/value: [2 -> value 3] next: current: valid:
Note: For more examples of iterators, see the SPL Extension.
Patterns are ways to describe best practices and good designs. They show a flexible solution to common programming problems.
The Factory pattern allows for the instantiation of objects at runtime. It is called a Factory Pattern since it is responsible for "manufacturing" an object. A Parameterized Factory receives the name of the class to instantiate as argument.
Example #1 Parameterized Factory Method
<?php
class Example
{
// The parameterized factory method
public static function factory($type)
{
if (include_once 'Drivers/' . $type . '.php') {
$classname = 'Driver_' . $type;
return new $classname;
} else {
throw new Exception ('Driver not found');
}
}
}
?>
Defining this method in a class allows drivers to be loaded on the fly. If the Example class was a database abstraction class, loading a MySQL and SQLite driver could be done as follows:
<?php
// Load a MySQL Driver
$mysql = Example::factory('MySQL');
// Load a SQLite Driver
$sqlite = Example::factory('SQLite');
?>
The Singleton pattern applies to situations in which there needs to be a single instance of a class. The most common example of this is a database connection. Implementing this pattern allows a programmer to make this single instance easily accessible by many other objects.
Example #2 Singleton Function
<?php
class Example
{
// Hold an instance of the class
private static $instance;
// A private constructor; prevents direct creation of object
private function __construct()
{
echo 'I am constructed';
}
// The singleton method
public static function singleton()
{
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
}
// Example method
public function bark()
{
echo 'Woof!';
}
// Prevent users to clone the instance
public function __clone()
{
trigger_error('Clone is not allowed.', E_USER_ERROR);
}
}
?>
This allows a single instance of the Example class to be retrieved.
<?php
// This would fail because the constructor is private
$test = new Exam