@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.
クラスの基礎
class
各クラスの定義は、classキーワードで始まり、クラス名が続きます。 クラス名には、PHPの予約語以外のあらゆる名前を 使用することができます。 波括弧の中に、クラスのメンバーとメソッドの定義が記述されます。 メソッドがオブジェクトコンテキストからコールされる場合 (通常は、メソッドが属するオブジェクトですが、 メソッドが第二のオブジェクトのオブジェクトの コンテキストから スタティックに コールされる場合には、別のオブジェクトとなる場合もあります)、 疑似変数 $this が利用可能です。 以下にこの例を示します。
例1 オブジェクト指向言語における $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()
{
A::foo();
}
}
$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>
上の例の出力は以下となります。
$this is defined (a) $this is not defined. $this is defined (b) $this is not defined.
例2 簡単なクラス定義
<?php
class SimpleClass
{
// メンバ宣言
public $var = 'a default value';
// メソッド宣言
public function displayVar() {
echo $this->var;
}
}
?>
デフォルト値は定数でなければなりません。(たとえば) 変数、クラスのメンバあるいは関数コールなどは使用できません。
例3 クラスのメンバのデフォルト値
<?php
class SimpleClass
{
// 無効な形式のメンバ宣言
public $var1 = 'hello '.'world';
public $var2 = <<<EOD
hello world
EOD;
public $var3 = 1+2;
public $var4 = self::myStaticMethod();
public $var5 = $myVar;
// 有効な宣言
public $var6 = myConstant;
public $var7 = self::classConstant;
public $var8 = array(true, false);
}
?>
注意: クラスやオブジェクトを扱うための、便利な関数があります。 クラス/オブジェクト関数 を参照ください。
ヒアドキュメントとは異なり、nowdoc は静的データコンテキストでも使用することができます。
例4 静的なデータの例
<?php
class foo {
// PHP 5.3.0 以降で対応
public $bar = <<<'EOT'
bar
EOT;
}
?>
注意: Nowdoc は PHP 5.3.0 以降で使用可能です。
new
あるクラスのインスタンスを生成する際、新たにオブジェクトが作成され、 変数に代入される必要があります。 新しいオブジェクトが作成される際には、そのオブジェクトが エラー時に 例外を投げる よう定義された コンストラクタを有していない限り、 常にオブジェクトが代入されます。 クラスは、そのインスタンスを作成する前に定義すべきです (これが必須となる場合もあります)。
例5 インスタンスを作成する
<?php
$instance = new SimpleClass();
?>
クラスのコンテキストにおいては、 new self や new parent のようにして新しいオブジェクトを作成することができます。
作成済みのクラスのインスタンスを新たな変数に代入する場合、新しい変数は、 代入されたオブジェクトと同じインスタンスにアクセスします。 この動作は、インスタンスを関数に渡す場合も同様です。 作成済みのオブジェクトのコピーは、その クローンを作成 することにより作成可能です。
例6 オブジェクトの代入
<?php
$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" }
extends
クラスは、宣言部にextendsキーワードを含めることで、他のクラスのメソッドとメソッドと メンバーを継承することができます。他重継承を行うことはできず、クラスが継承できるベース クラスは一つだけです。
継承されたメソッドとメンバーは、親クラスで final としてメソッドが定義されていない限り、親クラスで定義されたのと同じ名前で 再度宣言を行うことでオーバーライドすることができます。 parent::で 参照することにより、このオーバーライドされたメソッドまたはスタティックメンバーに アクセスすることができます。
例7 簡単なクラスの継承
<?php
class ExtendClass extends SimpleClass
{
// 親クラスのメソッドを再定義
function displayVar()
{
echo "Extending class\n";
parent::displayVar();
}
}
$extended = new ExtendClass();
$extended->displayVar();
?>
上の例の出力は以下となります。
Extending class a default value
クラスの基礎
24-May-2008 03:35
21-Apr-2008 12: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 :)
15-Feb-2008 03: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.
16-Dec-2007 03: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"
?>
10-Oct-2007 06: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.
10-Aug-2007 03: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;
27-Oct-2006 08: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()
{
...
