PHP 5.6.0 released

クラスの基礎

class

各クラスの定義は、classキーワードで始まり、クラス名が続きます。 そしてその後に波括弧のペアが続き、 その中にはクラスのプロパティとメソッドの定義を記述します。

クラス名には、PHP の予約語 以外でラベルとして有効なあらゆる名前を使用することができます。 有効なクラス名は、先頭が文字あるいはアンダースコアで始まり、 その後に任意の数の文字/数字/アンダースコアが続くものです。 正規表現で表すと、 ^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$ のようになります。

クラスの中には、 定数変数 ("プロパティ" といいます) そして関数 ("メソッド" といいます) を含めることができます。

例1 簡単なクラス定義

<?php
class SimpleClass
{
    
// プロパティの宣言
    
public $var 'a default value';

    
// メソッドの宣言
    
public function displayVar() {
        echo 
$this->var;
    }
}
?>

メソッドがオブジェクトコンテキストからコールされる場合は、 疑似変数 $this が利用可能です。 $this は、呼び出し元オブジェクト (通常は、メソッドが属するオブジェクトですが、 メソッドが第二のオブジェクトのオブジェクトの コンテキストから スタティックに コールされる場合には、別のオブジェクトとなる場合もあります) への参照です。

例2 $this 疑似変数の例

<?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()
    {
        
// 注意: E_STRICT が有効な場合、次の行で警告が発生します
        
A::foo();
    }
}

$a = new A();
$a->foo();

// 注意: E_STRICT が有効な場合、次の行で警告が発生します
A::foo();
$b = new B();
$b->bar();

// 注意: E_STRICT が有効な場合、次の行で警告が発生します
B::bar();
?>

上の例の出力は以下となります。

$this is defined (A)
$this is not defined.
$this is defined (B)
$this is not defined.

new

あるクラスのインスタンスを生成するには、new キーワードを使わなければなりません。エラー時に 例外をスローするような コンストラクタを定義していない限り、 オブジェクトが常に生成されます。 クラスは、そのインスタンスを作成する前に定義しなければなりません (これが必須となる場合もあります)。

クラス名を含む文字列を new で指定すると、 そのクラスのインスタンスを作成します。クラスが名前空間に属している場合は、 完全修飾名を指定しなければなりません。

例3 インスタンスを作成する

<?php
$instance 
= new SimpleClass();

// 変数を使うこともできます
$className 'Foo';
$instance = new $className(); // Foo()
?>

クラスのコンテキストにおいては、 new selfnew parent のようにして新しいオブジェクトを作成することができます。

作成済みのクラスのインスタンスを新たな変数に代入する場合、新しい変数は、 代入されたオブジェクトと同じインスタンスにアクセスします。 この動作は、インスタンスを関数に渡す場合も同様です。 作成済みのオブジェクトのコピーは、その クローンを作成 することにより作成可能です。

例4 オブジェクトの代入

<?php

$instance 
= new SimpleClass();

$assigned   =  $instance;
$reference  =& $instance;

$instance->var '$assigned will have this value';

$instance null// $instance と $reference は null になります

var_dump($instance);
var_dump($reference);
var_dump($assigned);
?>

上の例の出力は以下となります。

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

PHP 5.3.0 以降では、オブジェクトのインスタンスを作成する別の方法が新たに導入されました。

例5 新しいオブジェクトの作成

<?php
class Test
{
    static public function 
getNew()
    {
        return new static;
    }
}

class 
Child extends Test
{}

$obj1 = new Test();
$obj2 = new $obj1;
var_dump($obj1 !== $obj2);

$obj3 Test::getNew();
var_dump($obj3 instanceof Test);

$obj4 Child::getNew();
var_dump($obj4 instanceof Child);
?>

上の例の出力は以下となります。

bool(true)
bool(true)
bool(true)

extends

クラスは、宣言部に extends キーワードを含めることで、他のクラスのメソッドと プロパティを継承することができます。多重継承を行うことはできず、クラスが継承できるベース クラスは一つだけです。

継承されたメソッドやプロパティをオーバーライドするには、 親クラスで定義されているのと同じ名前でそれを再宣言します。 しかし、親クラスでそのメソッドが final 定義されている場合はオーバーライドできません。 オーバーライドされた元のメソッドや静的プロパティにアクセスするには、 parent:: で参照します。

メソッドをオーバーライドするときには、パラメータのシグネチャも同じでなければなりません。 もし違っていれば、PHP は E_STRICT レベルのエラーとなります。ただしコンストラクタは例外で、 異なるパラメータでオーバーライドすることができます。

例6 簡単なクラスの継承

<?php
class ExtendClass extends SimpleClass
{
    
// 親クラスのメソッドを再定義
    
function displayVar()
    {
        echo 
"Extending class\n";
        
parent::displayVar();
    }
}

$extended = new ExtendClass();
$extended->displayVar();
?>

上の例の出力は以下となります。

Extending class
a default value

::class

PHP 5.5 以降では、class キーワードでクラス名の解決ができるようになりました。 ClassName クラスの完全修飾名を文字列で取得するには、 ClassName::class とします。 これは、 名前空間つきのクラスと組み合わせると特に便利です。

例7 クラス名の解決

<?php
namespace NS {
    class 
ClassName {
    }
    
    echo 
ClassName::class;
}
?>

上の例の出力は以下となります。

NS\ClassName

add a note add a note

User Contributed Notes 19 notes

up
162
aaron at thatone dot com
6 years ago
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"
?>
up
61
Doug
3 years ago
What is the difference between  $this  and  self ?

Inside a class definition, $this refers to the current object, while  self  refers to the current class.

It is necessary to refer to a class element using  self ,
and refer to an object element using  $this .
Note also how an object variable must be preceded by a keyword in its definition.

The following example illustrates a few cases:

<?php
class Classy {

const      
STAT = 'S' ; // no dollar sign for constants (they are always static)
static     $stat = 'Static' ;
public    
$publ = 'Public' ;
private   
$priv = 'Private' ;
protected 
$prot = 'Protected' ;

function
__construct( ){  }

public function
showMe( ){
    print
'<br> self::STAT: '  self::STAT ; // refer to a (static) constant like this
   
print '<br> self::$stat: ' . self::$stat ; // static variable
   
print '<br>$this->stat: '  . $this->stat ; // legal, but not what you might think: empty result
   
print '<br>$this->publ: '  . $this->publ ; // refer to an object variable like this
   
print '<br>' ;
}
}
$me = new Classy( ) ;
$me->showMe( ) ;

/* Produces this output:
self::STAT: S
self::$stat: Static
$this->stat:
$this->publ: Public
*/
?>
up
26
wbcarts at juno dot com
6 years ago
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!
up
10
Notes on stdClass
5 years ago
stdClass is the default PHP object. stdClass has no properties, methods or parent. It does not support magic methods, and implements no interfaces.

When you cast a scalar or array as Object, you get an instance of stdClass. You can use stdClass whenever you need a generic object instance.
<?php
// ways of creating stdClass instances
$x = new stdClass;
$y = (object) null;        // same as above
$z = (object) 'a';         // creates property 'scalar' = 'a'
$a = (object) array('property1' => 1, 'property2' => 'b');
?>

stdClass is NOT a base class! PHP classes do not automatically inherit from any class. All classes are standalone, unless they explicitly extend another class. PHP differs from many object-oriented languages in this respect.
<?php
// CTest does not derive from stdClass
class CTest {
    public
$property1;
}
$t = new CTest;
var_dump($t instanceof stdClass);            // false
var_dump(is_subclass_of($t, 'stdClass'));    // false
echo get_class($t) . "\n";                   // 'CTest'
echo get_parent_class($t) . "\n";            // false (no parent)
?>

You cannot define a class named 'stdClass' in your code. That name is already used by the system. You can define a class named 'Object'.

You could define a class that extends stdClass, but you would get no benefit, as stdClass does nothing.

(tested on PHP 5.2.8)
up
21
Marcus
3 years ago
Here's another simple example.

<?php
// PHP 5

// class definition
class Bear {
   
// define properties
   
public $name;
    public
$weight;
    public
$age;
    public
$sex;
    public
$colour;

   
// constructor
   
public function __construct() {
       
$this->age = 0;
       
$this->weight = 100;
    }

   
// define methods
   
public function eat($units) {
        echo
$this->name." is eating ".$units." units of food... ";
       
$this->weight += $units;
    }

    public function
run() {
        echo
$this->name." is running... ";
    }

    public function
kill() {
        echo
$this->name." is killing prey... ";
    }

    public function
sleep() {
        echo
$this->name." is sleeping... ";
    }
}

// extended class definition
class PolarBear extends Bear {

   
// constructor
   
public function __construct() {
       
parent::__construct();
       
$this->colour = "white";
       
$this->weight = 600;
    }

   
// define methods
   
public function swim() {
        echo
$this->name." is swimming... ";
    }
}

?>
up
10
info at youwanttoremovethisvakantiebaas dot nl
6 years ago
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 :)
up
10
Manish Gupta
2 years ago
Some thing that may be obvious to the seasoned PHP programmer, but may surprise someone coming over from C++:

<?php
class Foo
{
$bar = 'Hi There';

public function Print(){
    echo
$bar;
}
}
?>

Gives an error saying Print used undefined variable. One has to explicitly use (notice the use of <?php $this->bar ?>):

<?php
class Foo
{
$bar = 'Hi There';

public function Print(){
    echo
this->$bar;
}
}
?>

<?php echo $this->bar; ?> refers to the class member, while using $bar means using an uninitialized variable in the local context of the member function.
up
7
Jeffrey
5 years ago
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.
up
3
moty66 at gmail dot com
5 years ago
I hope that this will help to understand how to work with static variables inside a class

<?php

class a {

    public static
$foo = 'I am foo';
    public
$bar = 'I am bar';
   
    public static function
getFoo() { echo self::$foo;    }
    public static function
setFoo() { self::$foo = 'I am a new foo'; }
    public function
getBar() { echo $this->bar;    }           
}

$ob = new a();
a::getFoo();     // output: I am foo   
$ob->getFoo();    // output: I am foo
//a::getBar();     // fatal error: using $this not in object context
$ob->getBar();    // output: I am bar
                // If you keep $bar non static this will work
                // but if bar was static, then var_dump($this->bar) will output null

// unset($ob);
a::setFoo();    // The same effect as if you called $ob->setFoo(); because $foo is static
$ob = new a();     // This will have no effects on $foo
$ob->getFoo();    // output: I am a new foo

?>

Regards
Motaz Abuthiab
up
1
php at kingsquare dot nl
1 year ago
Just to be clear: the correct way of validating a classname, as stated in the docs is:

$valid = preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $className);

(thanks to salathe@php.net & aharvey@php.net for clearing me up!)
up
1
alan at alan-ng dot net
6 years ago
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.
up
0
sklemnov at gmail dot com
8 months ago
Small subtlety to anyone just starting out: using $this is for referencing an instance of the current class (there are exceptions to this, but on the basic level it is mostly true; please do not downvote this, it's not meant to be a PhD dissertation).

For instance,

class TestClass{
  private $variable = "Hello";
  function ReturnVar(){
    return $this->variable;
  }
  function SetVar($input){
    $this->variable = $input;
  }
}
$t = new TestClass();
echo $t->ReturnVar();
$t->SetVar("Test");
echo $t->ReturnVar();

This is a useless piece of code that illustrates $this in functions.

echo $t->ReturnVar();

outputs "Hello", and then:

$t->SetVar("Test");

sets the object $t's copy of $variable to "Test". Finally,

echo $t->ReturnVar();

returns the new value of $t's copy of $variable, namely "Test".

using $this in the ReturnVar() function tells PHP that you want to return $t's copy of $variable.

Suppose we took $this out of the above code:

class TestClass{
  private $variable = "Hello";
  function ReturnVar(){
    return $variable;
  }
  function SetVar($input){
    $variable= $input;
  }
}
$t = new TestClass();
echo $t->ReturnVar();
$t->SetVar("Test");
echo $t->ReturnVar();

Would show nothing at all! PHP would not know that you meant to reference object $t's version of $variable.
up
1
Dan Dascalescu
7 years ago
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()                                                                                                          
    {
...
up
-1
chris (@) xeneco (dot) co (dot) uk
5 years ago
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

?>
up
-3
the_french_cow at hotmail dot com
5 years ago
For those of us who are new to inheritance, private functions are not visible in an inherited class. Consider:

<?php
   
class A {
        protected function
func1() {
            echo(
"I'm func1 in A!<br/>");
        }

        private function
func2() {
            echo(
"I'm func2 in A!<br/>");
        }
    }
   
    class
B extends A {
        public function
func3() {
            echo(
"I'm func3 in B!<br/>");
           
$this->func1();
           
$this->func2();  // Call to private function from extended class results in a fatal error
       
}
    }
   
   
$b = new B;
   
$b->func3();  // Ends in a fatal error

// OR

   
$b->func1();  // Call to protected function from outside world results in a fatal error
?>

If you want a function to be accessible in class B but not to the outside world, it must be declared as protected.
up
-8
ben dot corne at gmail dot com
4 years ago
method calling context aware. By this I mean it will get treated differently while being in a new statement compared to being in a regular call.

Example:
<?php
class Foo {
  private
$className = 'Bar';
 
  public function
make() {
    return new
$this->className();
  }
 
  public function
callClassName() {
  
$this->className();
  }

  public function
className() {
    echo
"foo\n";
  }

};

class
Bar {
  public function
hello() {
    echo
"bar\n";
  }
};

$foo = new Foo();
$bar = $foo->make();

echo
"expecting 'bar': ";
$bar->hello();

echo
"expecting 'foo': ";
$foo->callClassName();
?>

even tough $this->className() is written two times in exactly the same way, the one contained in a new statement gets the className field and the other performs the actual method.
up
-8
ialsoagree
5 years ago
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();
?>
up
-6
ialsoagree
5 years ago
Unfortunately, Arpit's solution creates a new class and leaves the old class inaccessible. If you need access to members of the class you are in you'll be unable to get such access. This can be a huge problem.

However, there is a solution:

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

   public function
MyClassFunction() {
       function
innerFunction(&$this_thing, $message = null) {
         
$this_thing->message = (!is_null($message)) ? $message : $this_thing->message;
         
$this_thing->echo_something();
       }
      
innerFunction($this); // echoes 'Hello'
      
innerFunction($this, '<br/>New Message'); // echoes '<br/>New Message'
  
}
  
   public function
echo_something() {
       echo
$this->message;
   }
}

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

By passing $this as a variable by reference, you can access members of the class and even update them. If you don't want to be able to update them, you can simply pass $this to the function but not as a reference.
up
-9
alex c
5 years ago
ok this really basic but I always forget this. I always get an error like:

Fatal error: Call to a member function on a non-object

when i deal with oops

if it were me finding the error i'd search the internet for hours and then it would occur to me, I'm putting my class operator inside a function, but i would define the class in global file.

so like this:
test.php
<?
include(class.php);
$class = new newclassname;

function function1(){
  $class->dofunc();
}
?>

you'll get some die errors and try and do this with function1,

function function1(){
  newclassname::dofunc();
}

but if you're using $this inside your class then you'll get another error on non object

so basically, all you need to do is:

function function1(){
  $class = new newclassname;
  $class->dofunc();
}

or

function function1(){
  global $class;
  $class->dofunc();
}

i know it's simple, but it always gets me!
To Top