코딩배우기

왕초보를 PHP린이를 위한 PHP 기초

탁이 2021. 6. 19. 09:48

이번에는 PHP에 대한 기초 내용을 소개합니다. 저도 PHP린이이기 때문에 잘못된 내용이 있다면 덧글로 지적 바랍니다. 

환경

PHP v5.5에서하고 있습니다. php를 설치하여 Web 서버 (Apache 등)에 올리면 움직입니다.
 
 
PHP는

.php

파일에
<?php

//insert code...

?>
 
처럼 쓸 수 있습니다. 이렇게만 하면 작성 끄읕! 그럼 바로 PHP로 들어가 볼까요.

변수

PHP는 형태의 선언이없고 JavaScript와 같은 var도 없습니다. 

$

을 달아 변수를 선언합니다.
$msg = "Hello World";
echo $msg;

$msg

라는 변수에 문자열의

"Hello World"

대입 한 형태입니다.

echo

를 사용함으로써 변수를 전개 해 WEB 페이지에 출력 해줍니다. 이 때

$msg

의 형은

String 형입니다.

PHP가 취급하는 형태에는 다음과 같은 것들이 있습니다

  • 문자열 처리
    • string
  • 숫자를 처리
    • int
    • float
  • 부울 (true / false)
    • boolean
  • 배열
  • 객체
  • null 
형태 등은

var_dump

등을 이용하여 쉽게 확인할 수 있습니다
$msg = "Hello World";
var_dump($msg);

상수

방금 변수는 나중에 변경할 수있는 상자였습니다. 상수는 한번 정의하면 나중에 바꿀 수없는 것이되어 있습니다. 상수를 정의 할 때

define

키워드를 사용합니다.
define("PI",3.141592);

echo PI;
 
이때주의 할 점은

$

필요 없다 라는 것과 상수를 정의 할 때

모두 대문자 로하는 것이 사실상의 표준이라는 것입니다.

PI

상수이므로 나중에
PI = 3;
 
또한 상수는 몇 처음부터 정의되어있는 것이 있습니다.
var_dump(__LINE__); //행의 수
var_dump(__FILE__); //파일 패스
var_dump(__DIR__);  //드렉토리 패스

문자열

문자열은

" "

' '

로 둘러 싸서 처리 할 수 있습니다. 이 차이는 따옴표 안에 변수를 전개 할 수 있는지 여부입니다.
$name = "honggildong";

echo "My name is $name";
 
이렇게하면 큰 따옴표 안에 변수를 배포 할 수 있습니다. 또한 변수 확장은 더 알기 쉽게 작성할 수 있습니다.
$name = "honggildong";

echo "My name is $name";
echo "My name is ${name}";
echo "My name is {$name}";
 
이것은 모두 같은 출력 결과입니다. 는 단일 아니면 안되는 때 어떻게 할 것인가.

문자열 연결

변수를 확장 한 것과 문자열을 연결 시키면 동일한 수 있습니다.
$name = "honggildong";

echo 'My name is '.$name;
 
PHP 에서는

.

을 사용하여 연결합니다.

배열

비슷한 데이터를 하나의 이름으로 관리하고 싶을 때 사용할 수있는 것이 배열입니다.
$colors = array("red","blue","yellow");
 
PHP5.4 이상이면

[]

로 바꿀 수 있습니다.
$colors = ["red","blue","yellow"];
 
이 경우, 예를 들어 red를 꺼내고 싶은 경우
echo $colors[0];
 
처음부터 0..1..2..3 ..  순이기 때문에, red는 0 번째. 대괄호로 꺼낼 수 있습니다. 

연관 배열

쓰는 법을 살펴 보자
$members = [
  "hong" => "honggildong",
  "hoge" => "hogehogeo"
];
 
꺼내는 방법도 간단하게되어 있습니다.
echo $members["hong"]; //honggildong

루프 및 조건 분기

루프 (for, while)와 조건 분기 (if, switch)는 다른 언어와 다르지 않기 때문에 생략합니다. PHP는 HTML에 삽입 할 경우가 종종있다고 생각하는데요.
?><ul>
  <?php for($i=0;$i<10;$i++){ ?>
  <li><?php echo $i ?></li>
  <?php } ?>
</ul>
 
라고 쓰는 건 가독성이 떨어지기 때문에,

콜론 구문

이라는 것을 사용 작성할 수 있습니다.
?><ul>
  <?php for($i=0;$i<10;$i++): ?>
  <li><?php echo $i ?></li>
  <?php endfor; ?>
</ul>
 
처음 중괄호를

:

로 바꾸고, 마지막 중괄호를

end〇〇

로 대체 할 수 있습니다.

함수

함수는 여러 프로세스를 하나로 묶어주는 것입니다. 함수는

인수

반환 값

이 존재합니다. 우선 단순히

Hello World

echo

하는 hello 함수를 만들어 봅니다
function hello(){
  echo "Hello World";
}

hello(); //Hello World
 
다른 언어와 같네요.

function

를 사용하여 함수를 정의합니다. 이름을 인수에 취하면 어떻게 될까.
function hello($name){
  echo "Hello ${name}";
}

hello("gildong"); // Hello gildong

gildong

$name

대입하여 사용하고 있습니다. 덧붙여이

$name

이 hello 함수 안에서만 사용할

로컬 변수

입니다. 이 함수 외부에서

$name

액세스 할 수 없습니다. 반환 값을 사용한 경우에는 어떻게해야할까요?
function hello($name){
  return "Hello ${name}";
}

echo hello("gildong"); // Hello gildong

return

키워드로, 그 함수에서 값을 반환 할 수 있습니다.

클래스

클래스라는 것은 설계도 잘 알려져 있습니다. 여러 번 같은 것이 등장하는 경우는이 클래스를 사용하는 것이 좋다고 알려져 있습니다. 쓰는 법을 살펴 보자. 에서 사용자를 관리하는

User

클래스를 만들어 보자.
class User{
  //property
  public $name;

  //constructor
  public function __construct($name){
    $this->name = $name;
  }

  //method
  public function sayName(){
    echo "Hello $this->name !";
  }
}
 
클래스 이름은

첫 글자가 대문자

라는 약속이 있으므로 주의합니다.

property

클래스는

constructor

, ,

method

가 있습니다.

property

그 클래스가 가지는 값입니다.


constructor

그 클래스가 인스턴스화 될 때 절대적이라는 것입니다.


method

그 클래스가 가지고있는 기능이라고 생각합니다. 이 User 클래스는

$name

라는 속성을 가지고 있습니다. 인스턴스 때 constructor에 의해 그 $ name에 인수로 들어온 것이 대입됩니다. 인스턴스하려면

new

키워드를 사용합니다.
$gildong = new User("gildong");
 
이제

$gildong

자신의 이름과 sayName ()를 사용할 수 있습니다. 자신의 이름에 액세스하려면
echo $gildong->name;
 
sayName 
$gildong->sayName();
 
라는 식으로 사용할 수 있습니다.

클래스의 상속

클래스를 만들 때, 아까의 클래스에 닮아 있지만 여기에 차별화하고 있고 ,, 조금 다른 움직임을 시키고 싶다. . 같은 것이 있었던 것처럼 그 클래스를 또한 1에서 쓰는 것은별로, 잘되지 않습니다. 그럴 때 이전 만든 클래스를 계승하고 새로운 것을 만드는

클래스의 상속

이 편리 하겠지요. 아까 만든 User 클래스를 상속시켜 SpecialUser라는 클래스를 만듭니다.
class User {
  public $name;

  public function __construct($name){
    $this->name = $name;
  }

  public function sayHi(){
    echo "Hello $this->name !";
  }
}

class SpecialUser extends User {
  public function saySpecialHi(){
    echo "I am Special $this->name";
  }
}
 
SpecialUser 클래스를 만드는데 User 클래스를 상속하려면

extends

를 사용합니다. 이제 SpecialUser 클래스는 자신의 방법도 사용할 수 있지만, User 클래스의 것도 사용할 수 있습니다. SpecialUser 인스턴스 때도
$gildong = new SpecialUser("gildong");
 
라고 해도 됩니다. 이때 생긴 SpecialUser는 User를 계승하고 있기 때문에, SpecialUser 자식 클래스. User가 부모 클래스라고합니다.

over ride

여기에서 User 클래스의

sayHi

메소드를 SpecialUser 클래스로 쓰면 어떻게되는 것입니까?
class User {
  public $name;

  public function __construct($name){
    $this->name = $name;
  }

  public function sayHi(){
    echo "Hello $this->name !";
  }
}

class SpecialUser extends User {
  public function sayHi(){
    echo "I am Special $this->name";
  }
}
 
이렇게하면
$gildong = User("gildong"); //User클래스
$hong = SpecialUser("hong"); //SPUser클래스

$gildong->sayHi(); // Hello gildong
$hong->sayHi(); // I am Special hong
 
같은 방법인데, 특별한 hong 군과 빤삐 한 gildong에서는 움직임이 다릅니다. 이를

over ride

말합니다. 단순히 "덮어 쓰기"입니다. 이 over ride 유용하지만, 바라지 않는 경우도 있다고 생각합니다. 이 때 사용할 수있는 것이

final

키워드입니다. 아까 User 클래스의 sayHi를 final을 사용하여 over ride 수 없도록합시다.
class User {
  public $name;

  public function __construct($name){
    $this->name = $name;
  }

  final public function sayHi(){
    echo "Hello $this->name !";
  }
}

class SpecialUser extends User {
  public function sayHi(){
    echo "I am Special $this->name";
  }
}
 
User 클래스에

final

를 붙이는 것으로, SpecialUser의 sayHi 방법은 over ride 에 실패하기 때문에 오류가 됩니다. 다음은 권한입니다.

권한

지금까지 수업 시간에 나오는

public

이것이 권한입니다. 권한에는 다음의 3 가지가 있습니다.
  1. public
  2. protected
  3. private 
public은

전역에서 액세스 가능

protected는

부모 클래스와 클래스 내에서만 접근 가능

private는

클래스 내에서만 접근 가능

하도록 되어 있습니다.
class User {
  public $name;

  public function __construct($name){
    $this->name = $name;
  }

  public function sayHi(){
    echo "Hello $this->name !";
  }
}

class SpecialUser extends User {
  public function sayHi(){
    echo "I am Special $this->name";
  }
}
 
이 상태에서는 User 클래스의

$name

는 public으로 선언하고 있기 때문에 인스턴스화한

$gildong


$gildong->name

에 액세스 할 수있었습니다. 이를
class User {
  private $name;

  public function __construct($name){
    $this->name = $name;
  }

  public function sayHi(){
    echo "Hello $this->name !";
  }
}

class SpecialUser extends User {
  public function sayHi(){
    echo "I am Special $this->name";
  }
}
 
private 이라면 ​​클래스 내에서 액세스 할 수 있지만 다른 곳에서 액세스 할 수 없기 때문에, SpecialUser로

$this->name

액세스 할 수 없으며

$gildong->name

액세스 할 수 없습니다. SpecialUser로 허용할 때는 private를 protected합시다!

static 대해

static은 클래스를 인스턴스화없이 사용할 수 있도록하는 구조입니다.
class User {
  public $name;
  public static $count = 0;
  public function __construct($name){
    $this->name = $name;
    self::$count++;
  }
  public static function getMes(){
    echo "Hello from static!";
  }
}

User::getMes();
$tom = new User("tom");
echo User::$count; //1
 
static을 붙인 메소드와 속성

클래스명::메소드

에 액세스 할 수 있습니다. User 클래스에서 자신을보고 싶다면. 그땐

self

를 사용하여

self::$count

같이 사용합니다.

추상 클래스

abstract class BaseUser{ //추상클래스
  public $name;
  abstract public function sayHi();
}

class User extends BaseUser{
  public function sayHi(){
    echo "Hello";
  }
}
 
선언 할 때

abstract

키워드를 답니다. 추상 클래스는 그 자체를 인스턴스화 할 수 없습니다. 추상 클래스의 메서드는 확장 메서드를 구현하지 않으면 안된다는 약속을 가지게 할 수 있습니다. 지원하지 않을 경우 오류가 발생합니다. 권한도 추상 클래스에 맞게 않으면 안됩니다.

interface

그런데, 추상 클래스와 비슷하다 것이

interface

라는 것이 있습니다.
interface sayHi {
  public function sayHi(); //interface는 절대public
}
interface sayHello{
  public function sayHello();
}

class User implements sayHi,sayHello {
  public function sayHi(){
    echo "Hi!";
  }
  public function sayHello(){
    echo "hello";
  }
}
 
class는 크게 자체의 설계도인데 비해 interface는 더 세세한 부품 부품에서 본 것이라는 인식을하고 있습니다. (틀렸다면 댓글주세요.) interface로 선언 한 것도 클래스에서 구현 해 나가지 않으면 안됩니다. 하지만, 지금까지의

extends

대신

implements

이라는 것을 사용합니다. 여기에서 큰 차이가

추상 클래스는 하나이지만, interface는 여러 번 추가 할 수 있다

라는 점입니다. 그래서 더 세세한 부품 (걷기, 말하기)을 만드는데는 interface를 사용하여 대부분 (인간, 동물, 자동차 등)을 정의하는 클래스를 사용할 수 있습니다.

외부 파일로드

외부 파일로드에 관해서는 파일을 나눠서 설명해 보겠습니다. 먼저 새로운 functions.php를 만듭니다. functions.php에는 다음과 같은 내용이 있다고 합시다.
function hello(){
  echo "Hello";
}

.......
 
함수를 정의하고 있고,이

functions.php

index.php

에서 읽어 들이기 위해선
require "functions.php"; 
require_once "functions.php";
include "functions.php";
include_once "functions.php";
 
이 4 개에서 파일을로드 할 수 있습니다. require와 include의 차이점은 require는 파일 이름이 다른 띠거나하면 오류가 발생합니다. include는 무시하고 그대로 진행합니다. ??? _ once 한 번 읽고 있으면 통해. 읽고해야 읽을 것입니다.
require "functions.php";

hello();
 
라이브러리 등도 이 방법으로 로드할 수 있습니다. 그렇다면 자신이 만든 것과 다른 사람이 만들었지만 이름이 같은 경우 어떻게하면 좋을까요?

네임 스페이스

그것을 해결해주는 것이,

namespace

입니다. 먼저 사용해보세요. functions.php의 처음
namespace gildong\functions;

function hello(){
  echo "Hello";
}
 
같이 씁니다. 주의하지 않으면 안되는 것이, 네임 스페이스 선언은 가장 먼저하지 않으면 안됩니다. 
// use honggildong\functions as func;
// use honggildong\functions
 
use를 사용하여 네임 스페이스를 사용할 수 있습니다. 또한

use honggildong\functions as func

이 honggildong \ functions에 func라는 이름으로 이 가운데는 사용해요 라는 것입니다.

use honggildong\functions

라면 맨 마지막 functions를 취할 것입니다. 이 네임 스페이스를 어떻게 사용 하는가?
require "functions.php";
use honggildong\functions as func;

func\hello();
 
따라서, 그 함수의 첫째, use에서 지정한 문자를 붙입니다. 이제 라이브러리 등과의 충돌을 피할 수 있습니다.

예외 처리

이제 종반입니다. 마지막으로, 예외 처리 방법에 대해 정리하고자합니다. 예를 들어, 나눗셈을하는

division()

함수를 만들고 싶습니다.
function division($num1,$num2){
  return $num1 / $num2;
}

echo division(4,2); // 2
 
이 함수의 약점은

$num2

두 0이 들어간 경우입니다.  
function division($num1,$num2){
  if($num2 === 0){
    return "2번째에 0은 지정할 수 없습니다.";
  }else{
    return $num1 / $num2;
  }
}
 
이렇게하여 먼저 0이 오면 if를!  이것은 예외 처리의 작성에 다음과 같이 작성 될 것입니다.
function division($num1,$num2){
  try {
    if($b === 0){
      throw new Exception("can not use 0");
    }
    return $num1 / $num2;
  } catch (Exception $e) {
    return $e->getMessage();
  }
}
 
throw에서 Exception이라는 클래스를 인스턴스화 한 것을 catch에 던지고 있다는 느낌입니다. Exception 클래스이므로 catch 분들, $ e라는 저장 해주고 있습니다. 그 후

getMessage()

라는 메소드를 사용하여 Exception 인스턴스 때 인수에 넣은 값을 얻을 수 있습니다. 이제 예외 처리가 온 경우에도 단순한 오류가 아니라 자신이 만든 것으로 바꿀 수있었습니다.

정리

아직 PHP린이입니다. 잘못된 내용이 있으면 코멘트 란에서 지적 바랍니다.