PHP Velho Oeste 2024

クラス

クラスは、変数およびこれらの変数で動作する関数の集まりです。 変数は var で、そして関数は function で定義します。 クラスは次のような構文により定義されます。

<?php
class Cart
{
    var 
$items;  // 買い物カゴの中のアイテム

    // $num 個の $artnr を買い物カゴに加えます

    
function add_item ($artnr$num)
    {
        
$this->items[$artnr] += $num;
    }

    
// $num 個の $artnr を買い物カゴから出します

    
function remove_item ($artnr$num)
    {
        if (
$this->items[$artnr] > $num) {
            
$this->items[$artnr] -= $num;
            return 
true;
        } elseif (
$this->items[$artnr] == $num) {
            unset(
$this->items[$artnr]);
            return 
true;
        } else {
            return 
false;
        }
    }
}
?>

この例は、買い物カゴの中の物の連想配列と、買い物カゴにアイテムを加えたり 除いたりする二つの関数からなる Cart という名前のクラスを 定義します。

警告

複数のファイルで分割してクラスを定義することは できません。また、関数定義の内部分割されている 場合を除き、複数の PHP ブロックで分割してクラスを定義することも できません。次の例は正しく動作しません:

<?php
class test {
?>
<?php
    
function test() {
        print 
'OK';
    }
}
?>

しかし、次の例は許されます:

<?php
class test {
    function 
test() {
        
?>
        <?php
        
print 'OK';
    }
}
?>

以下の注意書きはPHP 4に関するものです。

警告

名前stdClassは、Zendにより内部的に使用され、保 存されています。PHPでstdClassという名前のクラ スを使用することはできません。

警告

関数__sleepおよび__wakeupは、 PHPクラス内で使用される特殊な関数です。これらの関数に付随する特殊 な機能を使用する場合以外は、クラス内でこれらの名前を付けた関数を 使用することはできません。詳細な情報については、以下を参照ください。

警告

PHP は、__ で始まる全ての関数名を特殊な関数として予約しています。 ドキュメントに記載された特殊関数の機能を使用する場合以外は、__ を含む関数名を使用しないことを推奨します。

PHP 4では、変数varについては定数による初期化の みが可能です。定数以外で初期化を行う場合には初期化関数が必要です。 この初期化関数は、オブジェクトがクラスから構築される際に自動的に コールされます。このような関数はコンストラクタと呼ばれます。(以下 参照)

<?php
class Cart
{
    
/* 以下のコードはPHP 4では動作しません。 */
    
var $todays_date date("Y-m-d");
    var 
$name $firstname;
    var 
$owner 'Fred ' 'Jones';
    
/* Arrays containing constant values will, though. */
    
var $items = array("VCR""TV");
}

/* 以下に正しい方法を示します。 */
class Cart
{
    var 
$todays_date;
    var 
$name;
    var 
$owner;
    var 
$items = array("VCR""TV");

    function 
Cart()
    {
        
$this->todays_date date("Y-m-d");
        
$this->name $GLOBALS['firstname'];
        
/* 等など. . . */
    
}
}
?>

クラスは型、つまり、実際の変数の雛型です。new演 算子により所望の型の変数を作成する必要があります。

<?php
$cart 
= new Cart;
$cart->add_item("10"1);

$another_cart = new Cart;
$another_cart->add_item("0815"3);
?>

この例は、クラスCartのオブジェクト$cartおよび $another_cartを作成します。 $cartオブジェクトの関数 add_idem() で、商品番号10の商品一つをカートに追加しています。 商品番号0815の商品3つが$another_cart に追加されています。

$cart$another_cartは共に関数 add_item()remove_item() と変数 items を有しています。これらは、異なる関数および変数です。 オブジェクトは、ファイルシステムのディレクトリに似たようなものであると 考えられます。ファイルシステムでは、別のディレクトリに置く限り、 二つの異なるREADME.TXTを保持することが可能です。 ディレクトリではトップディレクトリから各ファイルにアクセスするには、 フルパス名を入力する必要がありますが、これと全く同様にコールしたい 関数の完全な名前を指定する必要があります。PHPの用語では、最上位の ディレクトリはグローバル名前空間であり、パス名のセパレータは、 -> となります。つまり、$cart->items$another_cart->items は、二つの異なる変数です。 $cart->itemsという名前の変数は、 $cart->$itemsではない、つまり、PHP の変数名は ドル記号 ($) を一つだけ有することに注意してください。

// 正しい、$は一つ
$cart->items  = array("10" => 1); 

// $cart->$items は、$cart->"" になるため、正しくない。
$cart->$items = array("10" => 1);

// 正しいが、意図しているかどうかによらず、
// $cart->$myvar は、 $cart->items となる
$myvar = 'items';
$cart->$myvar = array("10" => 1);

クラス定義の内部では、プログラムでアクセス可能なオブジェクト名を知ることはできません。 Cart クラスが書かれている時点では、そのオブジェクトの名前が後で $cart になるのか $another_cart になるのか、 それとも別のものになるのかはわかりません。 つまり、Cart クラスの中では $cart->items と書くことはできないのです。代わりに、 クラスの中からそのクラス内の関数や変数にアクセスするために、 疑似変数 $this を使用することが可能です。 $this は、「自分自身の」または「カレントのオブジェクト」 と読み変えることができます。つまり、 '$this->items[$artnr] += $num' は、 「同じクラス内の配列 items の $artnr カウンタに $num を追加する」または「カレントオブジェクト内の配列 items の $artnr カウンタに $num を追加する」と読み変えることが可能です。

注意:

擬似変数 $this は、メソッドが静的にコールされた場合に 常に定義されるわけではありません。しかし、はっきりしていることは: もしメソッドが別のオブジェクトから静的にコールされている場合は $this が定義されるということです。 この場合、$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.

注意:

クラスとオブジェクトを処理する優れた関数がいくつかあります。 クラス/オブジェクト関数 をざっとみてみると良いでしょう。

add a note add a note

User Contributed Notes 5 notes

up
7
ender911t at gmail dot com
8 years ago
Overrides in child are called when calling a function from the parent

<?PHP
class Par
{
   var
$test;
   function
__construct($in)
   {
     
$this->test = $in;
   }

   function
getTest()
   {
      return
$this->test;
   }

   function
runTest()
   {
      return
$this->getTest();
   }
}

class
Chi extends Par
{
   var
$i;
   function
__construct($in)
   {
     
$this->i = $in;
     
parent::__construct($in."X");
   }

   function
getTest()
   {
      return
$this->i;
   }

   function
runParentTestA()
   {
      return
parent::runTest();
   }

   function
runParentTestB()
   {
      return
parent::getTest();
   }
}

$p = new Par("par");
$c = new Chi("chi");

echo
$p->runTest()." == par";
echo
$c->runTest()." == chi";
echo
$c->runParentTestA()." == chi";
echo
$c->runParentTestB()." == chiX";
?>
up
5
anthonymccuen at yahoo dot com
11 years ago
You can also use "var" to declare multiple public instance variables like in C:

int main(int *argc, const char *argv[]) {
    int a, b, c, d, e, f;
   
    a = 50;
    // blah blah blah code here
    // ...
   
    return 0;
}

Same as PHP:

<?php
class MyClass {
    var
$myvar, $anotherVar, $something, $str;
}
?>
up
1
masonswolf at gmail dot com
11 years ago
You can invoke a class above its definitions in some cases, but there are very important exceptions to this behavior. If your class extends another class, and the interpreter doesn't see the extended class first, then it won't be added to the symbol table until the code has stepped through it in runtime. As a result, if you try to invoke it above the definition, you'll get a "class not found" fatal error.

And those suck.

So, to provide an example, the following will output a fatal error
<?php
Bar
::bar();
exit;

class
Bar extends Foo { } //will fatal because Foo not seen yet

class Foo {
    static function
bar() { echo 'yep, this is Foo::bar'; }
}
?>

However, THIS code will work just fine:
<?php
Bar
::bar();
exit;

class
Foo {
    static function
bar() { echo 'yep, this is Foo::bar'; }
}

class
Bar extends Foo { } //will work because Foo came first
?>

Notice that if you include a file containing the class you will extend, and then extend the class in the same file as its invocation, you can also get the class not found fatal. This happens even if the 'include' call happens before the child class's definition.

Eg. the following will also output a fatal error
<?php
include_once('file_with_foo.php');

Bar::bar();
exit;

class
Bar extends Foo { }
?>

Hope that clarifies things.
up
-9
pov at fingerprint.fr
12 years ago
I just discovered a behaviour that has to be mentioned.

Let's consider the following file

<?php
Foo
::bar();
exit;

class
Foo {
  function
bar() { echo 'yep, this is Foo::bar'; }
}
?>

You may expect :
- an error on the Foo::bar call, because the class is not defined
- removing the code after the exit without side-effect

But it won't, and it will output the string !
It seems every class definition is executed at parse-time.

But without errors; if your file is
<?php
Foo
::bar();
exit;

class
Foo {
  function
bar() { echo 'yep, this is Foo::bar'; }
}
class
Foo {
  function
bar() { echo 'yep, this is another Foo::bar'; }
}
?>
it will still output the first string, not doing any "Already exiting class" error !

So if you intend preventing a double include by doing in an included file :
<?php
if (class_exists('Foo')) { return; }

class
Foo {
  static function
register() { ... }
}
Foo::register();
?>
the Foo::register method won't be called !

Very strange development choice; I suppose it is due to ascending compatibility.
Hope it can help...
up
-10
boukeversteegh at gmail dot com
13 years ago
You can also instantiate objects using variables containing the name of the class:

<?php

$type
= 'Foo';
$foo   = new $type();

print_r( $foo );
/* Prints:
Foo Object
(
)
*/
?>

The following works as well:
<?php

$somefoo   
= new Foo();
$anotherfoo = new $somefoo();

# so you don't have to do:
$anotherfoo = new get_class( $somefoo)();
?>
To Top