PHP로 객체지향 프로그래밍 하는 방법

31367 
Created at 2006-09-28 04:36:09 
245   0   0   0  
#######################################################################
## Object Oriented Programming in PHP: The way to large PHP projects ##
#######################################################################

This arcticle introduces Object Oriented Programming (OOP) in PHP. I will show you how to code less and better by using some OOP concepts and PHP tricks. Good luck!

Concepts of object oriented programming: There're differences between authors, I can mention that a OOP language must have:


Abstract data types and information hidding
Inheritance
Polymorphism
The encapsulation is done in php using classes:

<?php

class Something {
   // In OOP classes are usually named starting with a cap letter.
   var $x;

   function setX($v) {
       // Methods start in lowercase then use lowercase to seprate
       // words in the method name example getValueOfArea()
       $this->x=$v;
   }

   function getX() {
       return $this->x;
   }
}

?>

Of course you can use your own nomenclature, but having a standarized one is useful.

Data members are defined in php using a "var" declaration inside the class, data members have no type until they are assigned a value. A data member might be an integer, an array, an associative array or even an object. Methods are defined as functions inside the class, to access data members inside the methods you have to use $this->name, otherwise the variable is local to the method.

You create an object using the new operator:

$obj=new Something;

Then you can use member functions by:

$obj->setX(5);
$see=$obj->getX();

The setX member function assigns 5 to the x datamember in the object obj (not in the class), then getX returns its value: 5 in this case.

You can access the datamembers from the object reference using for example: $obj->x=6; however, this is not a very good OOP practice. I enforce you to set datamembers by defining methods to set them and access the datamembers by using retrieving methods. You'll be a good OOP programmer if you consider data members inaccesible and only use methods from the object handler. Unfortunately PHP doesn't have a way to declare a data member private so bad code is allowed.

Inheritance is easy in php using the extend keyword.

<?php

class Another extends Something {
   var $y;
   function setY($v) {
       // Methods start in lowercase then use lowercase to seperate
       // words in the method name example getValueOfArea()
       $this->y=$v;
   }

   function getY() {
       return $this->y;
   }
}

?>

Objects of the class "Another" now has all the data members and methods of the parent class (Something) plus its own data members and methods. You can use

$obj2=new Something;
$obj2->setX(6);
$obj2->setY(7);

Multiple inheritance is not supported so you can't make a class extend two or more different classes.

You can override a method in the derived class by redefining it, if we redefine getX in "Another" we can't no longer access method getX in "Something". If you declare a data member in a derived class with the same name as a data member in a Base class the derived data member "hides" the base class data member when you access it.

You might define constructors in your classes, constructors are methods with the same name as the class and are called when you create an object of the class for example:

<?php

class Something {          
   var $x;

   function Something($y) {
       $this->x=$y;
   }

   function setX($v) {    
       $this->x=$v;          
   }

   function getX() {
       return $this->x;
   }
}

?>

So you can create an object by:

$obj=new Something(6);

And the constructor automatically asigns 6 to the data member x. Constructors and methods are normal php functions so you can use default arguments.

function Something($x="3",$y="5")

Then:

$obj=new Something(); // x=3 and y=5
$obj=new Something(8); // x=8 and y=5
$obj=new Something(8,9); // x=8 and y=9

Default arguments are used in the C++ way so you can't pass a value to Y and let X take the default value, arguments are asigned form left to right and when no more arguments are found if the function expected more they take the default values.

When an object of a derived class is created only its constructor is called, the constructor of the Parent class is not called, this is a gotcha of PHP because constructor chaining is a classic feature of OOP, if you want to call the base class constructor you have to do it explicitely from the derived class constructor.It works because all methods of the parent class are available at the derived class due to inheritance.

<?php

function Another() {
   $this->y=5;
   $this->Something();   //explicit call to base class constructor.
}

?>

A nice mechanism in OOP is to use Abstract Classes, abstract classes are classes that are not instanciable and has the only purpose to define an interface for its derived classes. Designers often use Abstract classes to force programmers to derive classes from certain base classes so they can be certain that the new classes have some desired functionality. There's no standard way to do that in PHP but:

If you do need this feature define the base class and put a "die" call in its constructor so you can be sure that the base class is not instanciable, now define the methods (interface) putting "die" statements in each one, so if in a derived class a programmer doesn't override the method then an error raises. Furthermore you might need to be sure since php has no types that some object is from a class derived from you base class, then add a method in the base class to identify the class (return "some id"), and verify this when you receive an object as an argument. Of course this doesn't work if the evil programmer oveerides the method in the derived class but genrally the problem is dealing with lazy programmers no evil ones! Of course is better to keep the base class unreachable from the programmers, just print the interface and make them work!

There're no destructors in PHP.

Overloading (which is different from overriding) is not supported in PHP. In OOP you "overload" a method when you define two/more methods with the same name but different number or type of parameters (depending upon the language). Php is a loosely typed language so overloading by types won't work, however overloading by number of parameters doesn't work either.

It's very nice sometimes in OOP to overload constructors so you can build the object in different ways (passing different number of arguments). A trick to do something like that in PHP is:

<?php

class Myclass {
   function Myclass() {
       $name="Myclass".func_num_args();
       $this->$name();
       //Note that $this->$name() is usually wrong but here
       //$name is a string with the name of the method to call.
   }

   function Myclass1($x) {
       code;
   }
   function Myclass2($x,$y) {
       code;
   }
}

?>

With this extra working in the class the use of the class is transparent to the user:

$obj1=new Myclass('1'); //Will call Myclass1
$obj2=new Myclass('1','2'); //Will call Myclass2

Sometimes this is very nice.


# Polymorphism

Polymorphism is defined as the ability of an object to determine which method to invoke for an object passed as argument in runtime time. For example if you have a class figure which defines a method draw and derived classes circle and rectangle where you override the method draw you might have a function which expects an argument x and then call $x->draw(). If you have polymorphism the method draw called depends of the type of object you pass to the function. Polymorphism is very easy and natural in interpreted languages as PHP (try to imagine a C++ compiler generating code for this case, which method do you call? You don't know yet which type of object you have!, ok this is not the point). So PHP happily supports polymorphism.

<?php

function niceDrawing($x) {
   //Supose this is a method of the class Board.
   $x->draw();
}

$obj=new Circle(3,187);
$obj2=new Rectangle(4,5);

$board->niceDrawing($obj);    //will call the draw method of Circle.
$board->niceDrawing($obj2);   //will call the draw method of Rectangle.

?>


OOP programming in PHP
Some "purists" will say PHP is not truly an object oriented language, which is true. PHP is a hybrid language where you can use OOP and traditional procedural programming. For large projects, however, you might want/need(?) to use "pure" OOP in PHP declaring classes, and using only objects and classes for your project. As larger and larger projects emerge the use of OOP may help, OOP code is easy to mantain, easy to understand and easy to reuse. Those are the foundations of software engineering. Applying those concepts to web based projects is the key to success in future web sites.

Advanced OOP Techniques in PHP
After reviewing the basic concepts of OOP I can show you some more advanced techniques:


Serializing
PHP doesn't support persistent objects, in OOP persistent objects are objects that keep its state and funcionality across multiple invocations of the application, this means having the ability of saving the object to a file or database and then loading the object back. The mechanism is known as serialization. PHP has a serialize method which can be called for objects, the serialize method returns a string representation of the object. However serialize saves the datamembers of the object but not the methods.

In PHP4 if you serialize the object to string $s, then destroy the object, and then unserialize the object to $obj you might still access the object methods! I don't recommend this because (a) The documentation doesn't guarrantee this beahaviour so in future versions it might not work. (b) This might lead to 'illusions' if you save the serialized version to disk and exit the script. In future runs of the script you can't unserialize the string to an object an expect the methods to be there because the string representation doesn't have the methods! Summarizing serializing in PHP is VERY useful to save the data members of an object just that. (You can serialize asociative arrays and arrays to save them to disk too).

Example: <?php

$obj=new Classfoo();
$str=serialize($obj);
// Save $str to disk

//...some months later

//Load str from disk
$obj2=unserialize($str)

?>

You have the datamembers recovered but not the methods (according to the documentation). This leads to $obj2->x as the only way to access the data members (you have no methods!) so don't try this at home.

There're some ways to fix the problem, I leave it up to you because they are too dirty for this neat article.

Full serialization is a feature I'd gladly welcome in PHP.

Using classes to manipulate stored data
One very nice thing of PHP and OOP is that you can easily define classes to manipulate certain things and the call the appropiate classes whenever you want. Suposse you have a html form where the user selects a product by selecting it's product ID, you have the data of the products in a database and you want to display the product, show its price, etc etc. You have products of different types, and the same action might have different meanings for different kind of products. For example showing a sound might mean playing it while for some other kind of products might mean to display a picture stored in the database. You might use OOP and PHP to code less and code better:

Define a class product, define which methods the class should have (example display), then define classes for each type of product which extends the product class (class SoundItem, class ViewableItem, etc...) override the methods you define in product in each of this classes make them do what you want. Name the classes according to the "type" column you store in the database for each product a typical product table might have (id,type,price,description,etc etc)... Then in the processing script you can retrieve the type from the database and instanciate an object of the class named type using:

<?php

$obj=new $type();
$obj->action();

?>

This is a very nice feature of PHP, you might then call the display method of $obj or any other method regardless the type of object you have. With this technique you don't have to touch the processing script when you add a new type of object, just add a class to handle it. This is quite powerful, just define the methods all objects regardless of its type should have, implement them in different ways in different classes and use them for any type of object in the main script, no ifs, no 2 programmers in the same file, eternal happiness. Do you agree programming is easy, mainteinance is cheaper and reusability is real now?

If you command a group of programmers is easy to divide the tasks, each one might be responsable for a type of object and the class that handles it. Internacionalization can be done using this technique, apply the proper class according to a language field selected by the user, etc.


Copying and cloning
When you create an object $obj you can copy the object by doing $obj2=$obj, the new object is a copy (not a reference) of $obj so it has the state $obj had in the moment the assignment was made. Sometimes you don't want this, you just want to create a new object of the same class as obj, calling the constructor of the new object as if you had used the new statement. This can be done in PHP using serialization and a base class that all other classes must extend.


Entering a danger zone
When you serialize an object you get a string which has a certain format, you may investigate it if you are curious, one of the things the string has is the name of the class (nice!) you may extract it using:

<?php

$herring=serialize($obj);
$vec=explode(':',$herring);
$nam=str_replace(""",'',$vec[2]);

?>

So suposse you create a class "Universe" and force that all classes must extend universe, you can define a method clone in Universe as:

<?php

class Universe {
   function clone() {
       $herring=serialize($this);
       $vec=explode(':',$herring);
       $nam=str_replace(""",'',$vec[2]);
       $ret=new $nam;
       return $ret;
   }
}

//Then:

$obj=new Something();
   //Something extends Universe !!
$other=$obj->clone();

?>

What you get is a new object of class Something created the same way as using new, the constructor is called, etc. I don't know if this is useful for you, but the Universe class which knows the name of the derived class is a nice concept to experiment. The only limit is your imagination.

Note: I'm using PHP4, something I write here may not work in PHP3.


Tags: OOP PHP Share on Facebook Share on X

◀ PREVIOUS
파일에서 한줄만 읽어다 return 해주는 소스
▶ NEXT
웹페이지 긁어서 타이틀 뿌려주는 소스
  댓글 0
로그인을 하시면 댓글을 등록 할 수 있습니다.
SIMILAR POSTS

웹페이지 긁어서 타이틀 뿌려주는 소스 (created at 2006-09-28)

파일에서 한줄만 읽어다 return 해주는 소스 (created at 2006-09-28)

어떤 파라메터가 넘어왔는지 알아내는 함수 (created at 2006-09-28)

PHP에서 메일 함수가 동작하지 않을때 (created at 2006-09-28)

파일 업로드 (file upload) 사이즈 늘리기 (created at 2006-09-28)

음력-양력 변환기 (created at 2006-09-28)

정수 연산시 무조건 올림, 무조건 버림, 반올림 처리 방법 (created at 2006-10-06)

이미지를 지정된 비율로 자르기 (crop) (created at 2006-10-10)

구글 메일(GMail)로 메일 발송하기 (created at 2006-10-10)

지정날짜에 이미지 보여주기 혹은 감추기 (created at 2006-10-10)

MAC에 Apache, PHP, MySQL 설치 - MAMP로 쉽게 설치 할 수 있어 (created at 2014-09-03)

CentOS 6.x에 APM(Apache+PHP+MySQL) 설치 및 초기 설정 방법 (created at 2017-03-14)

MVC(Model-view-controller) pattern은 Django, Rails와 같은 웹 어플리케이션 개발에 주로 응용되는 아키텍쳐 (created at 2017-12-21)

OTHER POSTS IN THE SAME CATEGORY

File Attribute 바꾸는 방법 (created at 2006-09-29)

wave 파일 mixing 하기. (웨이브 믹싱) (created at 2006-09-29)

ATL/ActiveX 에서 자바스크립트로 데이터(문자열) 보내기 (created at 2006-09-29)

System Log-Off, Suspend, Reboot, Shutdown 시키기 (created at 2006-09-29)

GDI+ 에서 이미지 반투명 처리하기.. (created at 2006-09-29)

자기자신 IP알아내기(로칼컴퓨터) (created at 2006-09-29)

프로세스명으로 프로세스 죽이는 함수 (created at 2006-09-29)

빈폴더 찾아내기 (created at 2006-09-29)

IE 패치에 따른 object, embed, applet 대처 방안 (created at 2006-09-28)

Virtusertable (created at 2006-09-28)

웹서버 및 웹메일 설정 방법 (created at 2006-09-28)

음력-양력 변환기 (created at 2006-09-28)

PHP에서 메일 함수가 동작하지 않을때 (created at 2006-09-28)

어떤 파라메터가 넘어왔는지 알아내는 함수 (created at 2006-09-28)

웹페이지 긁어서 타이틀 뿌려주는 소스 (created at 2006-09-28)

파일에서 한줄만 읽어다 return 해주는 소스 (created at 2006-09-28)

HTML 긁어오는 프로그램 소스 (created at 2006-09-28)

작업관리자에 프로그램 안뜨게 하기 (created at 2006-09-28)

파일 업로드 (file upload) 사이즈 늘리기 (created at 2006-09-28)

String Find Function (StrFnd) (created at 2006-09-28)

Toolbar에서 Icon 없애기 (created at 2006-09-28)

웹브라우져가 떠서 웹페이지 보이게 하는 소스 (created at 2006-09-28)

ActiveX에 다이얼로그 붙이기 (created at 2006-09-28)

드라이브 문자 알아내는 소스 (created at 2006-09-28)

모달리스 다이얼로그의 종료 버튼을 클릭했을 때 종료가 안될때... (created at 2006-09-28)

ActiveX에서 바이너리 데이터 파라메터로 안깨지게 받는법 (created at 2006-09-28)

ListCtrl에서 아이템 추가하기 예제 (created at 2006-09-28)

DirectShow - NULL Rendering Example (created at 2006-09-28)

Broadcast를 이용한 Application 종료 (created at 2006-09-28)

IE Control을 사용하여 만든 어플리케이션에서 javascript로 어플리케이션에 정의된 함수 호출하는 방법 (created at 2006-09-28)

UPDATES

자리 마음에 안든다고 6급 공무원 패는 농협 조합장 (created at 2024-03-26)

85세 딸 짜장면 사주는 102세 어머니 (created at 2024-03-26)

1990년대 감각파 도둑 (created at 2024-03-26)

치매에 걸린 69살의 브루스 윌리스가 전부인 데미무어를 보고 한 말 (updated at 2024-03-22)

일제강점기가 더 살기 좋았을지도 모른다는 조수연 국민의힘 후보 - 친일파? (updated at 2024-03-14)

성일종 인재육성 강조하며 이토 히로부미 언급 - 인재 키운 선례? (updated at 2024-03-13)

경제는 대통령이 살리는 것이 아닙니다 라던 윤석열대통령 - 상황 안좋아지자 여러 전략을 펼쳤지만, 부작용 속출했던 2024년의 봄 (updated at 2024-03-13)

극빈의 생활을 하고 배운것이 없는 사람은 자유가 뭔지도 모를 뿐 아니라 왜 개인에게 필요한지에 대한 필요성을 못느낀다는 윤석열 대통령 (updated at 2024-03-08)

조선일보를 안본다는 사람들이 말하는 그 이유 - 천황폐하, 전두환 각하, 김일성 장군 만세? (created at 2024-03-07)

광폭타이어를 장착하면 성능이 좋아질거라는 착각 (updated at 2024-03-03)

면허시험장에서 면허갱신하면 하루만에 끝나나? (updated at 2024-03-03)

신한은행/신한투자증권 금융거래 종합보고서 다운로드 방법 (updated at 2024-02-26)

100년 된 일본 장난감 회사가 내놓은 변신 기술에 난리난 과학계 (created at 2024-02-26)

알리에서 발견한 한글 지원하는 가성비 쩌는 무선 기계식키보드 (updated at 2024-02-25)

쌍팔년도가 1988년인줄 알았던 1인 (updated at 2024-02-23)

이쁜 색으로 변신한 테슬라 사이버트럭 (created at 2024-02-23)

2024년 카타르 아시안컵 4강전 전날 한국 대표팀 내부에 있었던 이강인의 폭주 (updated at 2024-02-21)

강릉 맛집 지도 (updated at 2024-02-20)

간이 안좋을 때 나타나는 증상 20가지 (updated at 2024-02-20)

배설물을 이용하여 일본에 저항했던 독립운동가 조명하 (updated at 2024-02-20)

요건 몰랐지롱? 이순신을 사랑한 외국인 (created at 2024-02-20)

원빈도 머리빨 (created at 2024-02-19)

대표적인 대한민국의 미남배우 중 하나인 원빈 (created at 2024-02-19)

백제의 건국 시조 온조왕 (updated at 2024-02-19)

700년동안 대한민국 고대국가의 한축이었던 백제시대 (created at 2024-02-19)

대머리들에게 주는 대머리의 조언 (created at 2024-02-17)

일본의 여성 락그룹 프린세스 프린세스의 "다이아몬드" (created at 2024-02-17)

결혼식 직전 연락두절된 신랑 (created at 2024-02-17)

대한민국 축구팀 파문으로 인해 중국 소셜미디어까지 등장한 탁구 전도사 이강인 (updated at 2024-02-16)

조국의 반격으로 흥미진진하게 흘러가는 한국의 정치판 - 데뷰와 동시에 한동훈 장관에게 던진 4개의 질문 (updated at 2024-02-15)

2024년 카타르 아시안컵 4강전 전날 내분사태로 갑자기 회자되는 이승우선수의 친화력 (created at 2024-02-15)

카카오뱅크 금융거래종합보고서/잔액증명서/거래내역서 발급 방법 (created at 2024-02-14)

아이가 최고의 스승이었다 (created at 2024-02-13)

이제는 국민 유행어로 등극한 한동훈의 "싫으면 시집가" (updated at 2024-02-13)

설 연휴 잔소리 메뉴판 - 이제 잔소리 하기전에 요금부터... (updated at 2024-02-10)

로버트 드니로의 70년 전 모습 (created at 2024-02-08)

카메라 어플로 만들어본 슈퍼걸 - 엄... 최종 작품은 왠지... (created at 2024-02-08)

앞트임 하고 새롭게 태어난 대한민국의 젊은 용사 (created at 2024-02-08)

비가 억수로 내리던 2024년의 2월 어느날 캘리포니아의 밤 카니예 웨스트와 그의 아나 비앙카 센소리 (updated at 2024-02-08)

스케방형사 1화 - 수수께끼의 전학소녀사키 (created at 2024-02-05)

백제와 일본의 교류가 가장 활발했던 시기는 근초고왕 시대 (created at 2024-02-05)

일에 찌들은 아빠가 꿈에서 깨어나지 않자 구출해주는 짱구 (created at 2024-02-03)

이제는 할아버지가 된 휴 그랜트(Hugh Grant)가 블랙핑크 콘서트에 다녀온 후 소감 (created at 2024-02-03)

다시 한번 감상해보는 추억의 날리면 패러디 (updated at 2024-02-01)

25년간 노예로 살다가 돌아온 남동생 (created at 2024-02-01)

가까우면서도 멀게 느껴지는 나라 일본 (created at 2024-02-01)

친구와 비교하다가 이혼하게 된 부부 (created at 2024-02-01)

요꼬 미나미노의 바람의 마도리걸(風のマドリガル) (created at 2024-01-30)

옛날 어린이들이 신문을 챙겨봤던 이유 (created at 2024-01-30)

Remaster된 요꼬 미나미노(南野陽子)의 판도라의 연인(パンドラの恋人) (updated at 2024-01-30)