프로그래밍 언어 문법 | ||
{{{#!wiki style="margin: -16px -11px; word-break: keep-all" | <colbgcolor=#0095c7><colcolor=#fff,#000> 언어 문법 | C(포인터 · 구조체 · size_t) · C++(자료형 · 클래스 · 이름공간 · 상수 표현식 · 특성) · C# · Java · Python(함수 · 모듈) · Kotlin · MATLAB · SQL · PHP · JavaScript · Haskell(모나드) |
마크업 문법 | HTML · CSS | |
개념과 용어 | 함수(인라인 함수 · 고차 함수 · 람다식) · 리터럴 · 상속 · 예외 · 조건문 · 반복문 · 참조에 의한 호출 · eval · 네임스페이스 | |
기타 | #! · == · === · deprecated · NaN · null · undefined · 배커스-나우르 표기법 | |
프로그래밍 언어 예제 · 목록 · 분류 | }}} |
1. 개요
- 이 문서는 PHP의 문법을 설명한다.
- 문법의 정보는 PHP 공식 홈페이지 PHP.net의 영문 매뉴얼을 기준으로 한다.
2. 편집 지침
- 소스코드 작성 시 아래 문법을 사용하시기 바랍니다.
{{{#!syntax php 소스코드}}}
- PHP 코딩 표준인 PSR-1과 PSR-12를 지켜 주시기 바랍니다.
- 또한 PHP 7 이후의 내용을 다룹니다.
3. 기본 문법
기본적인 PHP코드는 다음과 같다.각 php파일은 <?php로 시작되며 끝태그(?>)는 php코드만 있을 경우 붙이지 않는 것을 권장한다.[1] short_open_tag를 활성화시키면 <?로 시작할 수 있지만 이는 XML 문법과 혼동의 여지가 있어 권장되지 않는다.
3.1. 명령 구분
PHP에서는 명령이 끝나면 반드시 세미콜론을 붙여야 한다. 붙이지 않아도 되는 경우는 단 하나, 명령 바로 뒤에 ?>가 후행할 경우 뿐이다.3.2. 주석
PHP에서 주석을 처리하는 방법에는 세 가지가 있다. 다른 종류의 주석이 섞여 있으면 중첩할 수 없다.3가지 방법이 있지만 // 와 /* 여러줄주석 */ 이 주로 쓰인다.
#!syntax php
<?php
// C++ 형태의 한 줄 주석
# 쉘 형태의 한 줄 주석
/*
여러 줄 주석
*/
4. 자료형
자료형(타입)의 종류는 아래와 같다.- 스칼라형
- int: 정수형(integer)
- float: 실수형
- bool: true / false 인 boolean 값. 지정하려면 true나 false를 적으면 된다.
- string: 문자와 문자열
- 복합형
- array: PHP의 배열은 딕셔너리와 연결리스트의 기능이 합쳐져 있다.
- object: 객체
- callback / callable: 호출 가능 함수[2]
- iterable: 객체인데 배열처럼 반복가능한 타입.[3]
- 특수형
- null
- resource: 외부 리소스에 대한 정보가 들어간다. 해당 기능에 대해 세션을 생성한다고 이해해도 된다. stream, curl 등이 있다.(PHP 8.1 부터는 모두 object 타입으로 바뀌고 resource형은 삭제되었다.)
double이라는 자료형을 추가로 소개하는 경우가 있는데, PHP공식 문서를 보면 float과 동일하게 취급하며, 단지 역사적 사유로 두 이름이 생겼다고 한다. float 사용이 권장이다.
변수형을 지정해 줄 필요가 없으며, 사용처에 따라 PHP엔진에서 자동으로 결정한다.이용할 수 없는 변수를 참조하거나 쓰려고 하면 undefined가 표시된다.
그 밖에 union 등이 있다.
이들의 자료형을 확인하는 함수도 있다. 자세한 내용은 후술한다.
5. 변수
- PHP에서 변수선언은
$
로 시작하며 변수를 선언할 때에는 자료형(타입)을 지정하지 못하지만 함수의 매개변수, 리턴값과 클래스의 프로퍼티(맴버변수)는 타입을 지정할 수 있다. 변수명에 아무거나 넣을 수 있는 건 아니고 문자나 밑줄로 시작해야 하며 그 뒤에 문자, 숫자, 밑줄이 붙을 수 있다. 대소문자를 구분한다.
{{{#!syntax php
$a = 1;
}}}- 달러를
$$a
와 같이 여러 개 쓸 수도 있는데 이 경우 달러가 하나 제거된 변수의 변수값을 변수명으로 삼는 변수가 되는데 아래방식은 비권장이며 코드를 볼때 동작을 예측하는 게 어렵기 때문에 가급적이면 쓰지 말아야 한다.
{{{#!syntax php
$a = 'b';
$b = 1;
echo $$a; // 1
}}}$b = 1;
echo $$a; // 1
5.1. 미리 선언된 변수
PHP 4까지는$this
가 임의의 변수로 사용하는 게 가능했지만, PHP 5에서 클래스 내의 자기 참조자 기능이 부여되면서 클래스 밖에서 $this
를 쓸 시 예외를 발생시키게 되었다.미리 선언된 변수(Predeclared variables) PHP 엔진에서 예약한 변수라서 사용자가 해당 이름을 쓸수없다.
- $GLOBALS
- $_GET
- $_POST
- $_FILES
- $_REQUEST
- $_HTTP
- $_ENV
- $_SESSION
- $_SERVER
- $_COOKIE
- $http_response_header
- $argc
- $argv
- $php_errormsg(비권장)
5.2. 변수의 범위
- 타 언어에서 지역변수와 전역변수로 구분하듯 PHP도 마찬가지이다.
- PHP에서 변수는 기본적으로 함수 범위로 지정되어있다.(함수 안과 밖에 같은 이름의 변수가 있을 때 서로 다르다는 뜻이다.)
- 함수가 없을 때는 클래스 내부나 PHP 파일 안에서 변수에 접근 가능하다.
- include로 다른 파일을 불러오면 include로 가져온 파일의 변수에도 접근 가능하다.
{{{#!syntax php
$a = 1; // 기본적으로 선언한 변수는 전역변수이다.
$b = 2;
function foo()
{
global $b; // 전역변수 $b를 사용할 수 있게 해 준다. 쉼표를 통해 여러 개를 정의할 수 있다.
echo $a; // 전역변수 a가 아닌 지역변수 a를 불러온다. 따라서 지정되지 않은 변수다.
echo $b; // 전역변수 b를 불러와 2가 정상적으로 출력된다.
echo $GLOBALS['a']; //비권장 사항이며 PHP 8.1 부터는 Deprecate 되는 사용법이다.
}echo $a; // 전역변수 a가 아닌 지역변수 a를 불러온다. 따라서 지정되지 않은 변수다.
echo $b; // 전역변수 b를 불러와 2가 정상적으로 출력된다.
echo $GLOBALS['a']; //비권장 사항이며 PHP 8.1 부터는 Deprecate 되는 사용법이다.
}}}
- function foo()의 맨 마지막 줄처럼 $GLOBALS['변수명']을 사용하면 지역변수의 영역을 침범하지 않으면서도 전역변수를 불러올 수 있다.
6. 상수
- 상수 선언은
const
키워드를 이용한 방법과 동적으로 선언하는 방식인define()
함수를 쓰는 방법이 있다.const
는 PHP 5.3(2009년 출시)이상에서만 지원된다.
{{{#!syntax php
const CON = "상수";
const CON = "상수"; // 같은 이름이므로 뒤에 것은 무시 당하고 앞에 쓴 거를 사용한다.
const CON = "상수"; // 같은 이름이므로 뒤에 것은 무시 당하고 앞에 쓴 거를 사용한다.
define("상수명1", "상수");
define("상수명1", "상수1아님ㅋ"); // 같은 이름이므로 뒤에 것은 무시 당하고 앞에 쓴 거를 사용한다.
}}}define("상수명1", "상수1아님ㅋ"); // 같은 이름이므로 뒤에 것은 무시 당하고 앞에 쓴 거를 사용한다.
- 예약어와 연산자를 제외한 문자열은 따로 상수로 선언하지 않았을 경우 그 문자열과 동일한 값을 지닌 상수로 취급하며, 경고를 띄운다.[4]
- PHP 5.3 이후에는 const 문법이 권장된다. 그러나 const 는 런타임에 상수를 새로 선언할 수 없어서 그런경우에는 define을 쓴다.
- PHP 9부터는 다른 언어들처럼 동일한 이름의 상수가 있으면 문법 오류로 취급하게 바뀐다.
7. 표현식과 연산자
7.1. 연산자의 이용
변수와 변수 사이, 변수의 앞과 뒤에 연산자가 붙는다.연산자는 어떠한기능을 문법적기호로 만들어 둔것을 말한다.
여러 연산자가 있을때 우선순위가 있다.[5]
이 표에서 위쪽에 있는것이 우선순위가 높다.
우선 순위가 같은부류는 표사이의 간격으로 표시했다.
위치 | 연산자 | 결합방향 | 기능 |
왼쪽 | new | 새로운 객체를 생성한다. | |
왼쪽 | clone | 기존 객체를 면제한다. | |
[] | 왼쪽에서 오른쪽 | 배열을 생성한다. |
왼쪽 | ->(화살표) | 왼쪽에서 오른쪽 | 객체의 프로퍼티를 참조한다. |
왼쪽 | + , - | 숫자의 양수 음수표기 예) -3 | |
무관 | ++, -- | 1증가, 1감소 | |
무관 | ~ | 비트연산 중 not 연산을 한다. | |
왼쪽 | (int), (float), (string), (bool) (array), (object) | 괄호안에 적은 타입으로 형변환을 한다. | |
왼쪽 | @ (에러 컨트롤연산자) | 코드가 적힌 해당줄에서 일어나는 오류를 무시한다. |
왼쪽 | instanceof | 어떤 클래스에서 생성한 인스턴스인지 확인 true, false 를 반환한다. |
7.1.1. 산술 연산자
연산자 +,-,*,/를 통해 사칙연산을 할 수 있다. 그 외는 다음과 같다.연산자 | 기능 |
** | 왼쪽 수를 오른쪽 수만큼 제곱한다. |
++ | 1을 더한다. |
-- | 1을 뺀다. |
- | 부호를 바꾼다. |
7.1.2. 논리 연산자
논리 연산자는 다음과 같다. 우선순위 순으로 나열한다.- not (!)
- and (&&)
- xor
- or (||)
8. 기본 입출력
- 기본 출력은 echo, print(), printf()가 있다.
{{{#!syntax php
$a = 'world';
// 온점으로 문자열을 붙여서 출력한다.
echo 'Hello '.$a;
echo 'Hello '.$a;
// 반점으로 붙일 수도 있다.
echo 'Hello', $a;
echo 'Hello', $a;
// 아예 함수처럼 쓸 수도 있다. 물론 이렇게 쓴다고 해서 echo가 함수는 아니다.
echo('Hello', $a);
}}}echo('Hello', $a);
{{{#!syntax php
<?php// 둘 다 된다.
print("Hello world");
printf("Hello world");
}}}print("Hello world");
printf("Hello world");
- PHP를 템플릿처럼 HTML을 곧바로 출력하는 용도로 쓸 때에는 PHP와 HTML을 따로 출력하는 것이 좀 더 빠르다. 출력 구문을 쓰면 PHP 인터프리터를 거쳐서 출력하지만, 코드블럭을 닫은 뒤에 HTML을 직접 집어넣으면 PHP 인터프리터를 거치지 않기 때문이다.
{{{#!syntax php
// 기존 방법대로 print나 echo를 활용한다.
echo '<hr>';
echo '<hr>';
// 코드블럭을 일시적으로 닫고 HTML을 직접 작성한다.
?><hr>
}}}?><hr>
- 아래와 같은 축약 표현도 많이 쓰이는데, 주로 HTML 코드 속에 PHP 변수를 출력하는 경우에서 널리 쓰인다. 물론 함수를 사용할 수도 있다. PHP 5.3까지는 short_open_tag를 켜지 않았을 경우 예외가 발생하는 문제가 있었다.
{{{#!syntax php
}}}
- php://input // 그 밖에 입력
- php파일을 서버에서 직접 사용하거나 터미널에서 입력할 때
- file_get_contents('php://stdin');
9. 함수
9.1. 함수의 선언
함수선언은 function 키워드로 한다.#!syntax php
<?php
function add($a, $b) // 정수 두개를 더하는 함수
{
return $a + $b;
}
add(1, 2); // 함수 사용. 3을 반환한다.
매개변수 타입과 리턴 타입을 지정할 수도 있다. 리턴 타입은 함수이름 끝에 : 타입
#!syntax php
<?php
function add(int $a, int $b ): int // int 형으로 반환한다.
{
return $a + $b;
}
add(1, 2); // 함수 사용.
매개변수에 기본값을 지정하는 것도 가능하다.
#!syntax php
<?php
function add($a = 'bar' )
{
return $a;
}
add('foo'); // foo 반환
add(); // bar 반환
매개변수 앞에 &을 붙이면 참조를 통해 값을 전달할 수 있다.
...
을 사용해 여러 인자를 받을 수 있다.#!syntax php
<?php
function add(...$a)
{
return $a[0] + $a[1];
}
add(1, 2); // 함수 사용. 3을 반환한다.
9.2. 변수에 함수 할당
#!syntax php
// PHP에서는 변수에 객체, 배열, 함수, int, string, float 타입의 값과 같이 다양한 것을 대입할 수 있다.
$test = function myName()
{
return '홍길동';
}
$test(); // myName() 함수 사용
9.3. 익명 함수
- 말 그대로 이름이 없는 함수다.
- 보통 프로그래밍언어에서는 람다식이라고도 한다.
- 다른 변수에 대입해서 쓰거나 클로저에 사용된다.
- 아래의 예시처럼 사용할 수 있다.
#!syntax php
<?php
$add = function (int $a, int $b ): int // $add 라는 변수에 대입
{
return $a + $b;
};
$add(1, 2);
9.4. 화살표 함수
- fn 키워드와 함께 PHP 7.4 부터 도입되었다.
- 보통 프로그래밍 언어에서는 람다식이라고도 하는 익명 함수를 편하게 쓸 수 있게 되었다.
- fn 키워드는 function의 줄여쓰기이다.
#!syntax php
$add = fn($x, $y) => $x + $y; // 익명함수를 $add 라는 변수에 할당하고 있다.
$add(1,2); // 리턴 값 3, 변수에 할당 했으므로 실행할때도 변수를 통해 호출한다.
(fn($x, $y)=>$x +$y)(1,2) // 즉시 실행함수로 선언 한 예시
//----------- 아래는 클로저를 이용한 예시이다.
$y = 1;
$add = fn($x) => $x + $y; // 선언
$add(2); //리턴 값 3
// 실행 클로저는 클로저가 선언된 바깥의 변수를 참조 할 수 있어서
//변수 y의 1과 매개변수 x의 2로 1+2 가 되었다.
//위 코드와 같은 코드를 기존문법으로 적으면
$y = 1;
$add = function($x) use ($y) //PHP 에서 클로저는 use 키워드를 사용했다.
{
return $x + $y;
}
$add(2); //리턴 값 3
9.5. 즉시실행 함수
- 자기 실행함수 또는 즉시 실행 함수라고 부른다.(IIFE)
- 함수를 정의함과 동시에 바로 실행된다.
#!syntax php
<?php
(function (int $a, int $b ): int
{
return $a + $b;
})(1,2); // 바로 실행됨
10. 객체 지향
- PHP언어의 객체 지향은 클래스기반 객체지향이다.
- 객체라는 같은 주제, 역할을 하는 데이터와 함수들을 묶어서 관리하는 것이다.
- PHP에서는 클래스로 작성한다. 이때 클래스는 해당객체의 설계도이고 클래스에서 객체를 생성하는데 이를 영어로 인스턴스라고 한다.
10.1. 클래스
#!syntax php
//Animal.php
<?php
class Animal { // 동물에 관한 클래스
private string $eatType; //먹이 종류
private int $legs; // 다리개수
function __construct($eatType, $legs)
{
$this->eatType = $eatType; //객체에 접근할때에는 -> 를 이용한다.
$this->legs = $legs;
}
function getEatType(){
return $this->eatType;
}
function setEatType($eatType){
$this->eatType = $eatType;
}
function getLegs() {
return $this->legs;
}
function setLegs($legs) {
$this->legs = $legs;
}
}
//초식을 하는 네발 짐승
$animal1 = new Animal("초식", 4); // 객체 생성할때 new 를 쓴다.
$animal1->eatType = "잡식"; // $eatType 이 private 이라 접근불가
$animal1->getEatType(); // getter와 setter 를 만들어 접근해야한다.
PHP의 객체지향은 PHP 5.2부터 도입되어 기능이 늘어나고 있다. 클래스는 크게 두 가지로 구성되어있다. 데이터와 함수이다. 여기서 클래스의 데이터가 들어갈 변수는 프로퍼티라고 부른다. 함수는 클래스의 프로퍼티를 입출력하거나 조작하는데 메서드라고 부르기도 한다.
PHP에서 클래스는 기본적으로 public이다. PHP 클래스에서 프로퍼티 private, public, protect로 접근제한자를 지정할 수 있다.
생성자는 fucntion __constructor()를 쓴다. 생성자란 '클래스에서 객체를 생성할때 안에 들어갈 데이터를 어떤값으로 설정하는가?'에 대한 방법을 정의한 메서드이다. PHP 5부터 바뀐 문법이다. PHP 4까지는 클래스명과 동일한 이름의 메소드를 생성자로 삼았다.
클래스 안에서 클래스의 프로퍼티에 접근할때는 "$this->프로퍼티"를 쓰며 -> 뒤에 $ 기호를 붙이지 않는다.[6]
- 클래스에서 객체들의 관계
- extends 라는 키워드로 기반(base) 클래스의 기능들을 파생클래스가 이어받을 수 있다. 이를 상속 또는 계승이라고 한다.
- 위에서 만든 동물(Animal) 클래스와 파생된 새(bird) 클래스를 살펴보자.
- 어떤 클래스를 파생한 클래스는 원래 클래스를 부모, 파생된 클래스는 자식이라고 표현한다.
{{{#!syntax php
class bird extends Animal {
private $wings; //날개
function __construct($eatType, $legs, $wings);
{
function __construct($eatType, $legs, $wings);
{
parent::__construct($eatType, $legs); // 부모클래스의 기능을 호출할때 parent::함수이름으로 호출한다.
$this->wings = 2;
}$this->wings = 2;
function getWings() {
return $this->wings;
}function setWings($wings) {$this->wings = $wings;
}}
$비둘기 = new bird("잡식", 2, 2);
$삼족오 = new bird("잡식", 3, 2);
$삼족오 = new bird("잡식", 3, 2);
//Animal을 extends 했기 때문에 부모클래스인 Animal 클래스의 메서드를 쓸 수 있다.
echo $비둘기->getLegs(); // 2
echo $삼족오->getLegs(); // 3
}}}echo $삼족오->getLegs(); // 3
10.2. 인터페이스
추상 메서드
10.3. 트레이트
- 트레이트는 객체지향에서 여러 클래스를 계승하지 않고 공통되는 부분을 가져다 구성하는 것을 뜻한다.
- 루비 언어의 믹스인과 같다.
[1] PHPStorm 같은 IDE에서부터 클래스 파일이 아닌 이상 끝태그 뒤에 아무것도 없으면 노란 밑줄이 쳐지고 '끝태그를 없앨 것'을 도움말로 띄울 정도이다.[2] PHP 5.3에서 추가되었다.[3] PHP 7.1에서 도입[4] PHP 8부터는 빈값을 리턴하고 경고를 띄운다.[5] 사칙연산을 예로 들면 *,/ 가 +,- 보다 먼저계산해야된다는 것과 같은의미[6] -> 뒤에 $를 붙이는 경우는 상황에 따라 프로퍼티를 달리 취해야 하는 경우이다. 위의 달러 여러 개 쓰는 변수와 비슷한 맥락이다.