PHP-Class – Pengetahuan Dasar


class

Setiap pendefinisian class dimulai dengan pendefinisian kata kunci class (Keyword class) diikuti dengan sebuah nama kelas yang mana, nama tersebut adalah kata yang  diperkenankan dalam penulisan PHP, kemudian diikuti dengan tanda kurung kurawal “{  }” (curly braces), yang mana  berisi definisi dari  metoda dan anggota class. Suatu pseudo-variable $this adalah pemanggilan metoda yang dipanggil dari dalam suatu kontek object

Sebagai contoh kita bisa melihat gambaran atau ilustrasi dibawah ini:

Contoh #1  variable $this dalam bahasa  object-oriented

<?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();
?>

Contoh diatas akan mengeluarkan output :

$this is defined (a)
$this is not defined.
$this is defined (b)
$this is not defined.

Contoh #2 Pendefinisian Sederhana Class ( Simple Class definition)

<?php
class SimpleClass
{
// member declaration
// member yang di deklarasikan
public $var = 'a default value';

// method declaration

// metoda pengdeklarasian

public function displayVar() {
echo
$this->var;
}
}
?>

Nilai default harus sebuah ekpresi konstanta, bukan untuk sebuah variabel, sebuah member class atau sebuah pemanggilan fungsi.

Contoh  #3 Nilai Default Member Class (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.

new

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();
?>

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);
?>

The above example will output:

NULL
NULL
object(SimpleClass)#1 (1) {
   ["var"]=>
     string(30) "$assigned will have this value"
}

extends

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();
?>

The above example will output:

Extending class
a default value

Autoloading Objects> <Introduction


Last updated: Fri, 13 Mar 2009

add a note add a note User Contributed Notes
The Basics

Arpit
06-Feb-2009 02:14

//try this code if you define a new class inside an object method than we can refer to "$class->message"
//unset this instance doesn't affected the previous one
//it will not report a fatal error

<?php

class MyClass {
public
$message = 'Hello';

public function

MyClassFunction() {
function
InnerFunction() {
$class = new MyClass;
print_r($class);
echo
$class->message;
unset(
$class);//unset this doesn't affected the previous one or we can also use different name $classNew=new MyClass;
}
innerFunction();
}
}

$class = new MyClass;
$class->MyClassFunction();
?>

ialsoagree
03-Feb-2009 12:23

I think it's worth mentioning that if you define a function inside of an object method, that function cannot refer to "$this" - doing so will result in PHP reporting a fatal error:

Fatal error: Using $this when not in object context

<?php
class MyClass {
public
$message = 'Hello';

public function

MyClassFunction() {
function
InnerFunction() {
echo
$this->message; // Reports a fatal error
}
innerFunction();
}
}

$class = new MyClass;
$class->MyClassFunction();
?>

This issue cannot be solved by using the Scope Resolution Operator if you're trying to access a variable:

<?php
class MyClass {
public
$message = ‘Hello’;

public function MyClassFunction() {
function
InnerFunction() {
echo
MyClass::message; // Reports a fatal error
}
innerFunction();
}
}

$class = new MyClass;
$class->MyClassFunction();
?>

Additionally, you can NOT create a public function to access that variable:

<?php
class MyClass {
public
$message = ‘Hello’;

public function MyClassFunction() {
function
InnerFunction() {
MyClass::echoSomething();
}
innerFunction();
}

public function echoSomething() {
echo
$this->message; // Reports a fatal error
}
}

$class = new MyClass;
$class->MyClassFunction();
?>

Note that in this last case, the error is generated on the line below echoSomething function declaration, not at MyClass::echoSomething();

However, it is worth noting that when called directly, echoSomething works fine:

<?php
class MyClass {
public
$message = ‘Hello’;

public function MyClassFunction() {
function
InnerFunction() {
MyClass::echoSomething();
}
innerFunction();
}

public function echoSomething() {
echo
$this->message; // Echoes ‘Hello’
}
}

$class = new MyClass;
$class->echoSomething();
?>

hugo (@) apres (dot) net
17-Jan-2009 04:37

A simple approach to Multiple Inheritance

You can give yourself something approaching multiple inheritance with the following class:

<?php

class inheritance{

var

$bases = array();

static function

error_die( $errno, $errstr, $errfile, $errline ) {
$backtrace = debug_backtrace();
$detail = $backtrace[4];
var_dump( $backtrace );
echo
'<b>Fatal Error</b>: '.$errstr.' of class <b>'.$detail["class"].'</b> in <b>'.$detail["file"].'</b> on line <b>'.$detail["line"].'</b><br/>';
die();
}

private function

fatal( $text ) {
set_error_handler( array( 'inheritance', 'error_die' ) );
trigger_error( $text, E_USER_ERROR );
restore_error_handler();
}

function

__call( $name, $args ) {
if(
$this->bases )
foreach(
$this->bases as $base )
if(
method_exists( $base, $name ) )
return
$base->$name( $args );
$this->fatal( "Call to undefined method <b>".$name."</b>" );
}

function

__set( $name, $value ) {
if(
$this->bases )
foreach(
$this->bases as $base )
if(
property_exists( $base, $name ) ) {
$base->$name = $value;
return;
}
}

function

__get( $name ) {
if(
$this->bases )
foreach(
$this->bases as $base )
if(
property_exists( $base, $name ) )
return
$base->$name;
}

function

__isset( $name ) {
if(
$this->bases )
foreach(
$this->bases as $base )
if(
property_exists( $base, $name ) )
return isset(
$base->$name );
}

function

__unset( $name ) {
if(
$this->bases )
foreach(
$this->bases as $base )
if(
property_exists( $base, $name ) ) {
unset(
$base->$name );
return;
}
}

function

inherits( $name, $args = '' ) {
return
array_unshift( $this->bases, new $name( $args ) );
}

}

?>

Most of the qualities of multiple inheritance provided by this class are revealed by the following code:

<?php //test inheritance

class base0 {
public
$base0var;
public
$basevar;

function base0declare() {
echo
‘I am base 0’;
}
function
basedeclare() {
self::base0declare() {
}
}

class base1 extends base0 { // simple linear inheritance here
public $base1var;
public
$basevar;

function based1declare() {
echo
‘I am base 1’;
}
function
basedeclare() {
self::base1declare()
}
}

class base2
public $base2var;
public
$basevar;
function
based2declare() {
echo
‘I am base 2’;
}
function
basedeclare() {
self::base2declare
}
}
?>

Multiple inheritance is achieved by extending the inheritance class, and then in the __construct function placing calls to the “inherits” method of the inheritance class. Each call pushes an instance of the inherited class into an array var which functions as a LIFO stack. Using the magic methods, any failed method call, property set, get, isset or unset is intercepted by the inheritance base class which then attempts to resolve the reference. Object method name conflicts are resolved simply by the later inheritance masking the scope of the earlier inherited method. I recognize there are shortcomings to the approach I offer here, but it works for all my current multiple inheritance needs and offers simplicity and ease of understanding as benefits.

<?php
class base_test extends inheritance { // multiple inheritance

function __construct() {
$this->inherits( ‘base1’ );
$this->inherits( ‘base2’ );
}

} ?>

Here are some code fragments you can try out to test things.

<?php

$testobj = new base_test();
var_dump( $testobj );
$testobj->base2declare();
$testobj->base1declare();
$testobj->base0declare();
$testobj->basedeclare();
$testobj->base2var = 27;
echo
$testobj->base2var;

?>

I’d be interested in hearing any comments.

chris (@) xeneco (dot) co (dot) uk
27-Nov-2008 11:25

Regarding object inheritance:

I hope this helps someone, it should help if you're new to OOPS

<?php

class A {

public

$x = 'A';

public function

foo() {
$b = new B;
$b->bar();
return
$this->x;
}
}

class

B extends A {
public function
bar() {
$this->x = 'B';
}
}

$a = new A

echo $a->foo(); //A

?>

I was doing something similar to this (example is greatly simplified to show logic) and spent a long while trying to work out why I would always get 'A' and never get 'B'. Now, after a few weeks, I have revisited the problem and have worked out why:

The code ‘new B’ creates a new instance of class B. While class B extends class A, it is a new object and not an extension of the object created by ‘new A’

The value of $x is set to ‘B’ within the object $b, but not in object $a.

If within A::foo(), one was to access $b->x then one would obtain the vale ‘B’, for example

<?php

class C {

public $x = ‘C’;

public function foo() {
$c = new C;
$c->bar();
$this->x = $c->$x
return $this->x;
}
}

class D extends C {
public function
bar() {
$this->x = ‘D’;
}
}

$c = new C

echo $c->foo(); //D

?>

Jeffrey
08-Oct-2008 10:49

A PHP Class can be used for several things, but at the most basic level, you'll use classes to "organize and deal with like-minded data". Here's what I mean by "organizing like-minded data". First, start with unorganized data.

<?php
$customer_name
;
$item_name;
$item_price;
$customer_address;
$item_qty;
$item_total;
?>

Now to organize the data into PHP classes:

<?php
class Customer {
$name; // same as $customer_name
$address; // same as $customer_address
}

class

Item {
$name; // same as $item_name
$price; // same as $item_price
$qty; // same as $item_qty
$total; // same as $item_total
}
?>

Now here's what I mean by "dealing" with the data. Note: The data is already organized, so that in itself makes writing new functions extremely easy.

<?php
class Customer {
public
$name, $address; // the data for this class…

// function to deal with user-input / validation
// function to build string for output
// function to write -> database
// function to  read <- database
// etc, etc
}

class Item {
public
$name, $price, $qty, $total; // the data for this class…

// function to calculate total
// function to format numbers
// function to deal with user-input / validation
// function to build string for output
// function to write -> database
// function to  read <- database
// etc, etc
}
?>

Imagination that each function you write only calls the bits of data in that class. Some functions may access all the data, while other functions may only access one piece of data. If each function revolves around the data inside, then you have created a good class.

wbcarts at juno dot com
21-Aug-2008 01:11

CLASSES and OBJECTS that represent the "Ideal World"

Wouldn't it be great to get the lawn mowed by saying $son->mowLawn()? Assuming the function mowLawn() is defined, and you have a son that doesn't throw errors, the lawn will be mowed.

In the following example; let objects of type Line3D measure their own length in 3-dimensional space. Why should I or PHP have to provide another method from outside this class to calculate length, when the class itself holds all the neccessary data and has the education to make the calculation for itself?

<?php

/*
* Point3D.php
*
* Represents one locaton or position in 3-dimensional space
* using an (x, y, z) coordinate system.
*/
class Point3D
{
public
$x;
public
$y;
public
$z; // the x coordinate of this Point.

/*
* use the x and y variables inherited from Point.php.
*/

public function __construct($xCoord=0, $yCoord=0, $zCoord=0)
{
$this->x = $xCoord;
$this->y = $yCoord;
$this->z = $zCoord;
}

/*
* the (String) representation of this Point as "Point3D(x, y, z)".
*/
public function __toString()
{
return
'Point3D(x=' . $this->x . ', y=' . $this->y . ', z=' . $this->z . ')';
}
}

/*
* Line3D.php
*
* Represents one Line in 3-dimensional space using two Point3D objects.
*/
class Line3D
{
$start;
$end;

public function

__construct($xCoord1=0, $yCoord1=0, $zCoord1=0, $xCoord2=1, $yCoord2=1, $zCoord2=1)
{
$this->start = new Point3D($xCoord1, $yCoord1, $zCoord1);
$this->end = new Point3D($xCoord2, $yCoord2, $zCoord2);
}

/*
* calculate the length of this Line in 3-dimensional space.
*/
public function getLength()
{
return
sqrt(
pow($this->start->x - $this->end->x, 2) +
pow($this->start->y - $this->end->y, 2) +
pow($this->start->z - $this->end->z, 2)
);
}

/*
* The (String) representation of this Line as "Line3D[start, end, length]".
*/
public function __toString()
{
return
'Line3D[start=' . $this->start .
', end=' . $this->end .
', length=' . $this->getLength() . ']';
}
}

/*
* create and display objects of type Line3D.
*/
echo '<p>' . (new Line3D()) . "</p>\n";
echo
'<p>' . (new Line3D(0, 0, 0, 100, 100, 0)) . "</p>\n";
echo
'<p>' . (new Line3D(0, 0, 0, 100, 100, 100)) . "</p>\n";

?>

<--  The results look like this  -->

Line3D[start=Point3D(x=0, y=0, z=0), end=Point3D(x=1, y=1, z=1), length=1.73205080757]

Line3D[start=Point3D(x=0, y=0, z=0), end=Point3D(x=100, y=100, z=0), length=141.421356237]

Line3D[start=Point3D(x=0, y=0, z=0), end=Point3D(x=100, y=100, z=100), length=173.205080757]

My absolute favorite thing about OOP is that “good” objects keep themselves in check. I mean really, it’s the exact same thing in reality… like, if you hire a plumber to fix your kitchen sink, wouldn’t you expect him to figure out the best plan of attack? Wouldn’t he dislike the fact that you want to control the whole job? Wouldn’t you expect him to not give you additional problems? And for god’s sake, it is too much to ask that he cleans up before he leaves?

I say, design your classes well, so they can do their jobs uninterrupted… who like bad news? And, if your classes and objects are well defined, educated, and have all the necessary data to work on (like the examples above do), you won’t have to micro-manage the whole program from outside of the class. In other words… create an object, and LET IT RIP!

ashraf dot samhouri at hotmail dot com
24-May-2008 01:35

@info -- 20-April

This is because you requested class "b" before defining it, not because you defined class "b" before "a". It doesn't make a difference which class you define first.

info at youwanttoremovethisvakantiebaas dot nl
20-Apr-2008 10:40

if you do this
<?php

$x

= new b();

class

b extends a {}

class

a { }

?>
PHP will tell you "class b not found", because you've defined class b before a. However, the error tells you something different.... Got me a little confused :)

david dot schueler at tel-billig dot de
15-Feb-2008 02:16

If you just want to create a new object that extends another object and you want to copy all variables from the father object, you may use this piece of code:
<?php
$father
=& new father();
$father->a_var = "Hello World.";

$son = new son($event);

$son->say_hello();

class

father {
public
$a_var;
}

class

son extends father {
public function
__construct($father_class) {
foreach (
$father_class as $variable=>$value) {
$this->$variable = $value;
}
}

public function

say_hello() {
echo
"Son says: ".$this->a_var;
}
}
?>
This outputs:

Son says: Hello World.

So you dont have to clone the entire object to get the contents of the variables from the father object.

aaron at thatone dot com
16-Dec-2007 02:46

I was confused at first about object assignment, because it's not quite the same as normal assignment or assignment by reference. But I think I've figured out what's going on.

First, think of variables in PHP as data slots. Each one is a name that points to a data slot that can hold a value that is one of the basic data types: a number, a string, a boolean, etc. When you create a reference, you are making a second name that points at the same data slot. When you assign one variable to another, you are copying the contents of one data slot to another data slot.

Now, the trick is that object instances are not like the basic data types. They cannot be held in the data slots directly. Instead, an object's "handle" goes in the data slot. This is an identifier that points at one particular instance of an obect. So, the object handle, although not directly visible to the programmer, is one of the basic datatypes.

What makes this tricky is that when you take a variable which holds an object handle, and you assign it to another variable, that other variable gets a copy of the same object handle. This means that both variables can change the state of the same object instance. But they are not references, so if one of the variables is assigned a new value, it does not affect the other variable.

<?php
// Assignment of an object
Class Object{
public
$foo="bar";
};

$objectVar = new Object();
$reference =& $objectVar;
$assignment = $objectVar

//
// $objectVar --->+---------+
//                |(handle1)----+
// $reference --->+---------+   |
//                              |
//                +---------+   |
// $assignment -->|(handle1)----+
//                +---------+   |
//                              |
//                              v
//                  Object(1):foo="bar"
//
?>

$assignment has a different data slot from $objectVar, but its data slot holds a handle to the same object. This makes it behave in some ways like a reference. If you use the variable $objectVar to change the state of the Object instance, those changes also show up under $assignment, because it is pointing at that same Object instance.

<?php
$objectVar
->foo = “qux”;
print_r( $objectVar );
print_r( $reference );
print_r( $assignment );

//
// $objectVar —>+———+
//                |(handle1)—-+
// $reference —>+———+   |
//                              |
//                +———+   |
// $assignment –>|(handle1)—-+
//                +———+   |
//                              |
//                              v
//                  Object(1):foo=”qux”
//
?>

But it is not exactly the same as a reference. If you null out $objectVar, you replace the handle in its data slot with NULL. This means that $reference, which points at the same data slot, will also be NULL. But $assignment, which is a different data slot, will still hold its copy of the handle to the Object instance, so it will not be NULL.

<?php
$objectVar
= null;
print_r($objectVar);
print_r($reference);
print_r($assignment);

//
// $objectVar —>+———+
//                |  NULL   |
// $reference —>+———+
//
//                +———+
// $assignment –>|(handle1)—-+
//                +———+   |
//                              |
//                              v
//                  Object(1):foo=”qux”
?>

alan at alan-ng dot net
10-Oct-2007 04:41

The following odd behavior happens in php version 5.1.4 (and presumably some other versions) that does not happen in php version 5.2.1 (and possibly other versions > 5.1.4).

<?php

$_SESSION

['instance']=...;

$instance=new SomeClass;

?>

The second line will not only create the $instance object successfully, it will also modify the value of $_SESSION['instance']!

The workaround I arrived at, after trial and error, was to avoid  using object names which match a $_SESSION array key.

This is not intended to be a bug report, since it was apparently fixed by version 5.2.1, so it’s just a workaround suggestion.

mep_eisen at web dot de
10-Aug-2007 01:06

referring to steven's post:
****
Perhaps this is because =& statements join the 2 variable names in the symbol table, whereas = statements applied to objects simply create a new independent entry in the symbol table that simply points to the same location as other entries. I don't know for sure - I don't think this behavior is documented in the PHP manual, so perhaps somebody with more knowledge of PHP's internals can clarify what is going on.
****

lets talk about
a =& b;
b = c;

PHP internally marks a to be a reference to b. If You reassign b PHP does not update a. But if you access a once more PHP looks at the current value of b (now containing c).

Both statements (a=b and a=&b) seem to do the same but they don't. However this changed for objects from PHP4 to PHP5. Where PHP4 needed this operator to avoid object cloning, PHP5 does not need it.

It is explained in chapter 21 (References Explained). It's important to understand that a becomes a reference and the following code will not modify b:
a =& b;
a =& c;

Dan Dascalescu
27-Oct-2006 06:00

If E_STRICT is enabled, the first example will generate the following error (and a few others akin to it):

Non-static method A::foo() should not be called statically on line 26

The example should have explicitly declared the methods foo() and bar() as static:

class A
{
static function foo()
{
...

~ oleh desktopku pada Maret 20, 2009.

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

 
%d blogger menyukai ini: