English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

PHP 基礎チュートリアル

PHP 高級チュートリアル

PHP & MySQL

PHP 参考マニュアル

PHPのクラスとオブジェクト

このチュートリアルでは、PHPでオブジェクト指向に書く方法を学びます。

オブジェクト指向プログラミングとは何か

オブジェクト指向プログラミング(OOP)は、クラスとオブジェクトの概念に基づくプログラミングモデルです。プロセス指向プログラミングとは異なり、プロセス指向プログラミングではデータに対する操作を実行するプロセスや関数を書くことに焦点を当てていますが、オブジェクト指向プログラミングでは、データと関数を含むオブジェクトの作成に焦点を当てています。

通常のまたはプロセス指向プログラミングに対して、オブジェクト指向プログラミングには多くの利点があります。最も重要な点を以下に示します:

  • プログラムにクリアなモジュール構造を提供します。

  • これにより、「自己重複を避けろ」(DRY)原則を守ることができ、コードのメンテナンス、修正、デバッグがより簡単になります。

  • これにより、より少ないコード、より短い開発時間、そして非常に高い再利用性でより複雑な動作を作成することができます。

以下のセクションでは、PHPでクラスとオブジェクトがどのように動作するかを説明します。

提示:プロセス指向プログラミングスタイルで書かれたプログラムは、プログラムが一つまたは複数のプロセスで構成されていることを意味します。プロセスは特定のタスクを実行するためのプログラミング文の集合です。

提示:「自己重複を避けろ」(Don‘t Repeat Yourself、DRY)原則の背後にある考え方は、アプリケーションでよく使われるコードを抽象化し、それを単一の場所に配置して重用することで、コードの重複を減らすことです。

クラスとオブジェクトの理解

クラスとオブジェクトは、オブジェクト指向プログラミングの二つの主要な側面です。クラスは独立した変数と関数の集合で、特定のタスクを実行するために協力して動作します。一方、オブジェクトはクラスの単一のインスタンスです。

クラスはテンプレートや設計図として機能し、その中から多くの個別のオブジェクトを作成できます。単一のオブジェクトを作成する際には、各オブジェクトの一部の属性が異なる値を持っている場合でも、同じ一般的な属性と行動を継承します。

例えば、クラスを家の設計図と考えてください。設計図自体は家ではなく、家の詳細な設計です。オブジェクトは、その設計図に基づいて実際に建てられた実際の家です。同じ設計図に基づいて同じ家を複数建てることができますが、各家の内部には異なる塗料、内装、家具があるかもしれません。以下の図のように示されています。

classキーワードを使用してクラスを宣言し、そのクラスの名前と括弧({})を続けます。以下の例を参照してください。

Recangle.phpという名前のPHPファイルを作成し、以下のサンプルコードをその中に置きます。これにより、クラスコードをプログラムの残りの部分から分離し、必要な場所でRecangle.phpファイルを含めることで、どこでも使用することができます。

<?php
class Rectangle
{
    //声明属性
    public $length = 0;
    public $width = 0;
    
    //周長を求めるメソッド
    public function getPerimeter(){
        return (2 * ($this->length + $this->width));
    }
    
    //面積を求めるメソッド
    public function getArea(){
        return ($this->length * $this->width);
    }
}
?>

上記の例の属性とメソッドの前にpublicキーワードは、アクセス修飾子、これはその属性またはメソッドがどこからでもアクセスできることを意味します。この内容についての詳細は、本章の後半で詳しく説明します。

注意:文法的には、クラス内の変数は属性と呼ばれ、関数はメソッドと呼ばれます。また、クラス名は通常PascalCase(パスカル命名法)で書かれており、つまり各接続された単語は大文字で始まります(例:MyClass)。

クラスが定義されると、newキーワードを使用してそのクラスからオブジェクトを作成できます。このオブジェクトインスタンスを通じて、直接クラスのメソッドと属性にアクセスできます。

別のPHPファイルtest.phpを作成し、以下のコードをその中に置きます。

<?php
//クラス定義を含む
class Rectangle
{
    //声明属性
    public $length = 0;
    public $width = 0;
    
    //周長を求めるメソッド
    public function getPerimeter(){
        return (2 * ($this->length + $this->width));
    }
    
    //面積を求めるメソッド
    public function getArea(){
        return ($this->length * $this->width);
    }
}
 
//Rectangleクラスから新しいオブジェクトを作成します
$obj = new Rectangle;
 
//オブジェクトの属性値を取得します
echo $obj->length; // 出力: 0
echo $obj->width; // 出力: 0
 
//设置对象属性值
$obj->length = 30;
$obj->width = 20;
 
//変更を表示するために再度オブジェクトの属性値を読み取ります
echo $obj->length; // 出力: 30
echo "<br>";
echo $obj->width; // 出力: 20
 
 
//调用对象方法
echo $obj->getPerimeter(); // 出力: 100
echo "<br>";
echo $obj->getArea(); // 出力: 600
?>
测试看看‹/›

矢印記号(-》(は、指定されたオブジェクトが持つ属性とメソッドにアクセスするためのOOP構造です。仮変数$thisは、呼び出しオブジェクト(つまりメソッドが属するオブジェクト)への参照を提供します。

同一クラスの複数のインスタンスを使用する場合、オブジェクト指向プログラミングの本質的な力が明確に現れます。以下の例を参照してください:

<?php
//クラス定義を含む
class Rectangle
{
    //声明属性
    public $length = 0;
    public $width = 0;
    
    //周長を求めるメソッド
    public function getPerimeter(){
        return (2 * ($this->length + $this->width));
    }
    
    //面積を求めるメソッド
    public function getArea(){
        return ($this->length * $this->width);
    }
}
 
//Rectangleクラスから複数のオブジェクトを作成します
$obj1 = new Rectangle;
$obj2 = new Rectangle;
 
//二つのオブジェクトのメソッドを呼び出します
echo $obj1->getArea(); //出力:0
echo $obj2->getArea(); //出力:0
 
//設定します$obj1属性値
$obj1->length = 30;
$obj1->width = 20;
 
//設定します$obj2属性値
$obj2->length = 35;
$obj2->width = 50;
 
//再度、二つのオブジェクトのメソッドを呼び出します
echo $obj1->getArea(); //出力:600
echo "<br>";
echo $obj2->getArea(); //出力:1750
?>
测试看看‹/›

上記の例のように、異なるオブジェクト上でgetArea()メソッドを呼び出すと、该方法が異なるデータセットに対して操作を行います。各オブジェクトインスタンスは完全に独立しており、独自の属性とメソッドを持っています。したがって、彼らが同じクラスに属している場合でも、独立して操作することができます。

コンストラクタとデストラクタを使用して

オブジェクト指向プログラミングを簡素化するために、PHPはいくつかのマジックメソッドを提供しており、これらのメソッドはオブジェクト内で特定の操作が行われると自動的に実行されます。

例えば、新しいオブジェクトが作成されるたびに、マジックメソッド__construct()(構造関数と呼ばれます)が自動的に実行されます。同様に、マジックメソッド__destruct()(デストラクタと呼ばれます)がオブジェクトが破壊される際に自動的に実行されます。オブジェクトが破壊されると、デストラクタはそのオブジェクトに割り当てられたすべてのリソースをクリアします。

<?php
class MyClass
{
    // 构造函数
    public function __construct(){
        echo ' 类 "' . __CLASS__ . '" 已启动<br>';
    }
    
    // デストラクタ
    public function __destruct(){
        echo 'クラス "' . __CLASS__ . '" 已破壊<br>';
    }
}
 
//新しいオブジェクトを作成します
$obj = new MyClass;
 
//ファイルの最後にメッセージを出力します
echo "ファイルの最後に到達しました。";
?>
测试看看‹/›

上面示例中的PHP代码将产生以下输出:

クラス "MyClass" が起動しました
ファイルの最後に到達しました。
クラス "MyClass" が破壊されました

スクリプトが終了すると、デストラクタが自動的に呼び出されます。しかし、デストラクタを明示的にトリガーするには、PHPのunset()関数を使用してオブジェクトを破壊することができます。以下のように:

<?php
class MyClass
{
    // 构造函数
    public function __construct(){
        echo ' 类 "' . __CLASS__ . '" 已启动<br>';
    }
    
    // デストラクタ
    public function __destruct(){
        echo 'クラス "' . __CLASS__ . '" 已破壊<br>';
    }
}
 
//新しいオブジェクトを作成します
$obj = new MyClass;
 
// オブジェクトを破壊します
unset($obj);
 
//ファイルの最後にメッセージを出力します
echo "ファイルの最後に到達しました。";
?>
测试看看‹/›

今、以下のPHPコードは以下の結果を生成します:

クラス "MyClass" が起動しました
クラス "MyClass" が破壊されました
ファイルの最後に到達しました。

提示:スクリプトが完了すると、PHPは実行中に割り当てられたすべてのリソースを自動的にクリアします。例えば、データベース接続を閉じる、オブジェクトを破壊するなどです。

注:__CLASS__は以下のものですマジック定数、それが属するクラスの名前を含んでいます。クラスの外に発生する場合は空です。

クラスを継承する方法

クラスはextendsキーワードを使用して、別のクラスの属性やメソッドを継承できます。継承プロセスは、オブジェクト指向プログラミングモデルが使用される理由の最も強力なものの1つです。

<?php
//クラス定義を含む
class Rectangle
{
    //声明属性
    public $length = 0;
    public $width = 0;
    
    //周長を求めるメソッド
    public function getPerimeter(){
        return (2 * ($this->length + $this->width));
    }
    
    //面積を求めるメソッド
    public function getArea(){
        return ($this->length * $this->width);
    }
}
 
//既存のクラス定義に基づいて新しいクラスを定義します
class Square extends Rectangle
{   
    //このメソッドを使用して、矩形が正方形でもあるかどうかをテストします
    public function isSquare(){
        if($this->length == $this->width){
            return true; // 正方形
        } else{
            return false; //不是正方形
        }
    }
}
 
//从Square类创建一个新对象
$obj = new Square;
 
// 设置对象属性值
$obj->length = 20;
$obj->width = 20;
 
// 调用对象方法
if($obj->isSquare()){
    echo "正方形的面积是";
} else{
    echo "矩形的面积是";
};
echo $obj->getArea();
?>
测试看看‹/›

上面示例中的PHP代码将产生以下输出:

正方形的面积是 400

正如您在上面的示例中看到的,尽管Square的类定义既没有显式包含getArea()方法,也没有显式包含$length和$width属性,但是Square类的实例可以使用它们,因为它们继承自父Rectangle类。

提示:由于子类是从父类派生的,因此也称为派生类,其父类称为基类。

控制属性和方法的可见性

在使用类时,您甚至可以使用可见性关键字来限制对其属性和方法的访问,以实现更好的控制。 有三个可见性关键字(从最可见到最不可见):public,protected,private,它们确定如何以及从何处访问和修改属性和方法。

  • public - 可以从类内部和外部的任何位置访问公共属性或方法。 这是PHP中所有类成员的默认可见性。

  • protected - 受保护的属性或方法只能从类本身或子类或继承类(即扩展该类的类)中访问。

  • private - 私有属性或方法只能从定义它的类中访问。甚至子类或继承的类也无法访问私有属性或方法。

以下示例将向您展示这种可见性实际上是如何工作的:

<?php
//クラス定義
class Automobile
{
    //声明属性
    public $fuel;
    protected $engine;
    private $transmission;
}
class Car extends Automobile
{
    // 构造函数
    public function __construct(){
        echo ' 类 "' . __CLASS__ . '" 已启动<br>';
    }
}
 
//从Automobile类创建对象
$automobile = new Automobile;
 
//尝试设置$automobile对象属性
$automobile->fuel = 'Petrol'; // ok
$automobile->engine = '1500 cc'; // 致命的なエラー
$automobile->transmission = 'Manual'; // 致命的なエラー
 
//Carクラスからオブジェクトを作成しました
$car = new Car;
 
//試みて$carオブジェクト属性を設定しました
$car->fuel = 'Diesel'; // ok
$car->engine = '2200 cc'; // 致命的なエラー
$car->transmission = 'Automatic'; // undefined
?>

静的属性とメソッド

アクセス修飾子の他に、属性とメソッドもstatic(静的)として宣言できます。これにより、クラスのインスタンスなしでもアクセスできます。以下のように範囲解析演算子(::)を使用して静的属性とメソッドにアクセスできます:ClassName::$propertyとClassName::method()。

静的メソッドを使用できるにもかかわらず、以下の例のように、静的属性にアクセスすることはできません:

<?php
//クラス定義
class HelloClass
{
    //静的属性を宣言します
    public static $greeting = "Hello World!";
    
    //静的メソッドを宣言します
    public static function sayHello(){
        echo self::$greeting;
    }
}
//静的属性とメソッドに直接アクセスしようと試みました
echo HelloClass::$greeting; //出力:Hello World!
HelloClass::sayHello(); //出力:Hello World!
 
//オブジェクトを通じて静的属性とメソッドにアクセスしようと試みました
$hello = new HelloClass;
echo $hello->greeting; // 厳重な警告
$hello->sayHello(); //出力:Hello World!
?>

上記の例では、キーワードselfは'現在のクラス'を意味します。それはドル記号($)で始まることはありませんし、常に::演算子(例えばself :: $ name)で始まります。

selfキーワードはthisキーワードとは異なり、'現在のオブジェクト'または'クラスの現在のインスタンス'を表します。このキーワードは常にドル記号($)で始まり、次に->演算子(例えば$ this-> name)。

注意:静的メソッドはクラスのインスタンス(すなわちオブジェクト)なしで呼び出せるため、staticと宣言されたメソッドでは仮変数$thisが使用できません。

現在、オブジェクト指向プログラミングの基本概念を理解していただけることを願っています。PHPとMySQLデータベースのセクションでOOPに関する多くの例を見つけることができます。