클래스
매개변수에 부모 클래스를 자료형으로 선언하면 상속받은 자식 객체를 매개변수로 전달가능
클래스 내부에서 new self() // 해당 클래스를 반환
:: 는 상수 접근용
self::클래스의 프로퍼티 상수명 , 클래스명::클래스의 프로퍼티 상수명 , this::클래스의 프로퍼티 상수명 // 클래스내의 클래스의 프로퍼티 상수명 접근
static
클래스의 프로퍼티와 함수에 static을 사용시 클래스명::프로퍼티명 , 클래스명::함수명으로 접근가능
static메서드 안에서는 this를 사용할수없다. 그러므로 self를 사용하길 권장
self와 $this의 차이
self는 현재 클래스를 가리킨다(즉 self를 사용할때는 클래스의 static지시자와 함께 사용된다)
$this는 현재 객체를 가리킵니다.(static메서드 안에서 this를 사용할수없는것도 this는 객체지시자이기때문이다)
extend / abstract /interface / trait / final
__construnc() // 클래스내의 생성자
__destruct() // 클래스내의 소멸자, 스크립트가 종료될때 실행되거나 unser(객체명)될때 실행됨
상속시 부모의 __cunstuct()를 호출함
자식에서 cunstruct()를 호출할시 부모의 cunstruct()를 호출하지 않는다. 그러므로 자식의 cunstrunct안에서 parent::__cunstruct()를 해줘야한다
final을 클래스와 함수에 사용하면 상속불가능해진다
abstract클래스는 객체를 만들수없다
abstract클래스는 부모에 abstract메서드가 있으면 반드시 자식에서 구현해야한다
interface는 부모에 메서드가 있으면 반드시 자식에석 구현해야한다
trait는 다중상속이 안되는 문제점을 보안하기 위해 나왔다 use trait명을 명령어로 사용한다
class A{ function __construct(){echo 1;} } class B extends A{ // function __construct(){echo 2;} // 2.만약 이 부분이 있으면 1을 출력하지않고 2만출력한다 } $b=new B(); // 1.자식 객체를 생성할시 부모의 생성자함수를 호출한다, 그러나 자식의 생성자함수가 존재할시에는 부모의 생성자 함수를 호출하지않고 자식의 생성자함수만 호출한다
매직메서드 / 매직상수
매직상수명 // 메타적인 정보를 가진다
매직메서드() // 예를들면 construct()
__call() // 클래스의 메서드 호출시 일치하는 메서드가 없으면 call()의 메서드를 자동적으로 호출
__invoke() // 객체명() 으로 호출하면 invoke의 내용이 자동적으로 호출
__set() // 클래스의 프로퍼티의 값을 초기화할때 자동적으로 호출
__get() // 클래스의 프로퍼티의 값을 가져올때 자동적으로 호출
직렬화? // 객체를 만약에 직렬화 serialize()하면 저장가능한 문자열 형태가 되는데 이를 DB에 저장하거나 네트워크로 다른 컴퓨터에 보낸다. 그리고 이를 역직렬화 하여 나중에 해당 객체를 사용하거나 또한 다른 컴퓨터로 전송이 가능하다 (즉 현재 객체를 저장가능한 형태로 만들수있다는것)
// __call()예제 class MyClass { public function __call($method, $args) { echo "__call입니다"; } } $myclass = new MyClass(); $myclass->bar(); // __call입니다 // bar()메서드가 없기때문에 // __invoke() 예제 class Calculator { public function add($a, $b) { return $a + $b; } public function __invoke($a, $b) { return $this->add($a, $b); } } $calculator = new Calculator(); $result = $calculator(2, 3); // $result는 5입니다. //객체를 메서드처럼 사용하면 __invoke가 호출된다
네임스페이스
namespace 이름 = namespace 이름 {} // 이 둘은 같다
namespace A\B // 선언
use A\B\클래스명 // 사용 ,use사용후 클래스명 만으로 사용가능 ,require필요
\만 사용하면 전역 네임스페이스를 가리키고 , \를 사용하지않으면 현재속한 네임스페이스를 가리킨다
역슬래시만을 사용하여 전역 네임스페이스를 가리키는것에 이점은 중복을 방지할수있고, 더욱 빠른 속도로 찾을수있다
중복방지에 도움이 될수있다고 생각한 예제
네임스페이스 / require (20230516에 추가 작성 )
require 해서 해당 파일안에 내용을 사용가능하고 그 파일안에서 또 분류해서 사용할수있는게 namespace
require한뒤 require한 해당 파일에 namespace가 있으면 use로 지정해줘야한다 ( require > namespace / 사용위해 use )
역슬래시로 시작하는 구문을 사용하는 이유?
내가 경험한것중에 Exception클래스를 예제로 말하면
namespace를 사용하는 파일 내부에서 new Execption()를 하면 경고가 뜬다 해당 파일의 네임스페이스 내부에 Exception클래스가 없기때문에..
그래서 new \Execption()를 사용해서 글로벌 네임스페이스에있는 Exception을 지정해줘야한다
제너레이터/이터레이터
제너레이터란?// iterator를 사용하기 쉽게 만든것
iterator란? // for(x) 빌트인에서 x에 사용가능한 반복가능 기능을 정의한 인터페이스
for문 (시간빠름/메모리많이차지) -> 제너레이터(시간느림/메모리적게차지) -> 이터레이터 (제너레이터랑같음,인터페이스를 구현하는데 번거롭다)
$a=$b=1 ; //$a와 $b에 둘다 1이 할당됨
참조변수
앰퍼샌드 & 를 사용하면 변수의 참조 주소를 공유하게 되며, 변수중 하나의 값을 변경해도 다른 변수들도 변경된다
$val1 = 'TEST1'; $val2 = & $var1; $val2 = 'TEST2'; echo $val1; // TEST1
클로저
익명함수는 클로저를 반환한다 // 클로저는 클래스
stdClass // 키와 값형태의 배열을 프로퍼티와 값형태의 빈 객체로 변경함 // (Object)배열명
익명함수는 클로저 클래스의 객체다 // $foo = fn()=>’hi’ 익명함수는 클로저의 객체이다;
// 클로저 예제 // 클로저 사용1 $closure_bar=fn()=>'hi'; echo $closure_bar(); // hi // 클로저 사용2 function foo(){return 'hi';}; $closure_foo = Closure::fromCallable('foo'); echo $closure_foo(); // hi // 클로저의 call메서드로 객체의 내용을 호출하는 예제 class A{ public $message = "hi"; } $closure_a = fn()=>$this->message; echo $closure_a->call(new A()); // hi // 익명함수들이 클로저를 반환하는지 확인 var_dump(fn()=>'hi'); // 익명함수의 클로저 반환확인 $closure_1=function(){return 'hi';}; var_dump($closure_1); // 클로저 반환 확인
클로저 사용이유와 좋은점
함수 외부에서 $count변수를 조작할수없다
function getCounter() { $count = 0; // 클로저 반환 return function () use (&$count) { return ++$count; }; } $counter = getCounter(); echo $counter(); // 출력: 1 echo $counter(); // 출력: 2 // 클로저란? // 자신을 둘러싼 환경에 정의된 변수에 접근가능하다 // 예를 들면 use를 사용하여 getCount() 함수 안에 정의된 $count에 접근가능하다 // 클로저사용 이유 // 이점1. 함수 외부에서 $count변수를 조작할수없다
리플렉션
리플렉션이란? 클래스명만으로 객체를 호출가능하고 클래스의 정보를 추출할수있다
사용이유는 클래스명 만으로 객체의 정보를 유연하게 사용할수있기때문이다
즉 문자열인 클래스명만으로 객체를 호출가능하기 때문에 유용하다는 뜻
예를들면 의존성 주입때 사용되는데 리플렉션으로 해당 클래스의 생성자함수를 읽고 필요한 의존성(객체)를 주입하는등의 작업이 가능하다
class MyClass { public $name = 'John'; public function getName() { return $this->name; } } $ref = new ReflectionClass('MyClass'); // 클래스(리플랙션) 취득 $obj = $ref->newInstanceArgs(); // 객체생성 echo $obj?->getName(); // 1.리플렉션으로 만든 객체의 메서드 호출 ($obj가 null이 들어갈수있어서 컴파일에러가 발생하기때문에 ?를 사용함) // John $property = $ref->getProperty('name'); // 객체의 프로퍼티 (리플렉션) 취득 echo $property->getValue($obj); // 2.변경전 프로퍼티 가져옴 // John $property->setValue($obj,'KIM'); // 프로퍼티를 변경 echo $property->getValue($obj); // 3.변경된 프로퍼티를 호출 // KIM
세션
세션은 클라이언트에선 쿠키에 세션 ID를 저장하고 서버에서 그 세션ID에 대한 파일을 가지므로써 관리된다
서버에서 세션ID에 대한 파일을 관리하는 방법이 두가지가 있는데 하나는 파일로 저장하여 관리하는것이고 또 하나는 DB의 테이블에 저장하는 방식이다
기본적으로 세션ID가 유출되면 굉장히 위험하다
SPL라이브러리의 sql_autoload에 대해서
spl_autoload_register()는 함수를 require/include할 수고를 없애준다
spl_autoload_register(function ($class_name) { include $class_name . '.php'; // include 'MyClass.php' //2.그러므로 파일명과 클래스명을 일치시키는것이 좋다 }); $obj = new MyClass(); // 1. 해당 객체를 호출하는 타이밍에 spl_autoload_register()를 호출하여 include하게된다
PDO (PHP Data object )
디비와 PHP를 연결하는 PHP의 확장모듈의 클래스
쿼리를 사용할때 exec , query , prepare등을 사용하지만 sqlInjection을 방지가능한 prepare을 주로 쓴다
prepare을 사용시 :변수명 형식으로 사용될때가 있고 이는 bindParam()함수로 나중에 맵핑을 해줘야한다
Composer
php의 라이브러리 관리툴
composer init // 해당 폴더를 컴포저를 사용하는 프로젝트로 만들수있으며 composer.json이 만들어진다
composer install // 기존에 composer.json에 있는 라이브러리르 설치한다
composer require 라이브러리명 // 해당 라이브러리를 설치한다
verdor폴더 // 설치한 라이브러리가 존재하는 폴더 npm의 node_module과 비슷하다
접근제어자
public 클래스내, 클래스외의 어디에서라도 액세스 가능
protected 같은 클래스 및 자식클래스에서 액세스 가능
private 같은 클래스안에서만 액세스 가능
Protected같은 경우는 외부에서 접근이 어려운 경우가 많기때문에 (상속받지 않은 클래스에서 접근시)
개발을 하며 디버깅하다보면 해당 객체내부에 protected 멤버변수가 많고 해당 내용을 취득하기위해 gettter / setter 로 해당 값을 가져와야하는 경우가 많다
class Item{ public $color = 'red'; protected $label = 'saewookang'; private $price = 0.0; public function getLabel() { return $this->label; } public function getPrice() { return $this->price; } } $item = new Item(); $item->color; // red $item->label; // 에러 $item->price; // 에러 $item->getLabel(); // saewookang $item->getPrice(); // 0.0