削除された内容 追加された内容
→‎クラス: PHP公式サイトでは言及されていないですが、C#が同様にコンストラクタを仲介して readonly なクラス変数との値のやりとりをする仕組みです。
クラスをサブページ化したので、こちらメインページからは除去。
20 行
# [[PHP/入門/関数とは]]
# [[PHP/入門/変数の種類]] ※進捗0%
# [[PHP/クラス]]
 
::::{{節スタブ}}
25 ⟶ 26行目:
== 前書き ==
PHPの動作は、Web上における[[Perl]]のそれとよく似ていますが、Perlと異なり[[HTML]]の内部にスクリプトを記述し実行することができるので、動的な[[w:ウェブサイト|ウェブサイト]]を作成する際に、より容易に用いることができます。また、[[w:MySQL|MySQL]]などの[[w:データベース|データベース]]との親和性も高く、これは[[w:MediaWiki|MediaWiki]]などのソフトウェアにも活かされています。
PHPは20202022年6月現在、2つの主要なバージョン (PHP5とPHP7.4以降とPHP8.0以降) が提供されています。
 
PHP6は破棄され、ありません。
158 ⟶ 159行目:
 
実行結果は、もし実行に成功すれば、webブラウザでのアクセス時に青い四角のアニメーション(始点の左から、右にむかってアニメーションします)が表示されます。
 
=== クラス ===
==== 基本 ====
PHP にはクラスというものがあり、使い方は下記コードのように、変数などをまとめるものです。配列とは異なり、クラスなら、たとえば整数と文字列など、型の違ったものもまとめる事ができます。
 
<syntaxhighlight lang="PHP">
<?php
class sample
{
public $a;
public $b;
}
 
$dummy = new sample; // インスタンス
 
$dummy->a = 5;
$dummy->b = "asd";
 
printf("%d\n", $dummy->a);
printf("%s\n", $dummy->b);
 
?>
</syntaxhighlight>
 
実行結果
<pre>
5
asd
</pre>
 
public は、プログラミング用語でアクセス修飾子というものの一種です。public で修飾された要素は、クラス外部からアクセスできます。(C++やJavaに同様の「アクセス修飾子」という機能があり、似たような機能です。というか、C++やJavaのほうが実装が先で、それをあとからPHPが実装を真似ました。)
 
アクセス修飾子には、public のほか private があります。private で修飾された要素は、そのクラス内部の他の要素からしかアクセスできなくなります。
 
PHP のクラスの定義では、要素にひとつずつ public か private かなどの指定をしないといけません。<code>public class</code> (※エラーになる)や <code>public {$a; $b}</code> (※エラーになる)などと宣言してもエラーになります。
 
<code>$dummy = new sample;</code>の作業は、「インスタンス」という作業であり、こうすることでクラスの実体(メモリ上などでの実配置に相当)を1つ作成します。インスタンスをしないと、まだ実体が確保されておらず、なのでクラスの宣言文内部の各要素にはアクセス不能です(そもそもメモリ上などに実体が無いので)。
 
PHPのクラスの場合でのインスタンスは <code>$変数名 = new クラス名;</code>という書式で行います。<code>new</code>という演算子が必ず必要です。new演算子をもちいた変数への代入という書式によって、インスタンスが行われます。
 
 
<code> -> </code> はアロー演算子というものです。C++などに同様の名前の演算子があります。(なお、標準Cにもアロー演算子というものはあるが、意味は異なります。)
 
PHPでは、クラスで宣言した要素にアクセスする際、アロー演算子で上記コードのようにアクセスします。PHP のクラスの利用でなぜアロー演算子を使うのかと言われても、そのように仕様が決まっているので、「そういう規則だから」としか言い様がありません。
 
なお、クラスのブロック内で定義された変数や定数のことを(上記コードの $a や $b のこと)、プロパティと言います。クラスでは、プロパティの他にも、クラスのブロック内で関数を定義することができ、そのようなクラス内関数のことをメソッドと言います。
 
 
;他の言語との相違点
C++ には「構造体」というクラスと似た機能がありますが、しかしPHPには「構造体」はありません。なお、構造体は標準C言語にもあります(またなお、標準C言語にクラス機能は無い)。
 
「クラス」と言われる機能はC++以降の新しい時代の他の多くのプログラミング言語にもありますが、しかしその機能はプログラミング言語ごとに差が大きいです。
 
==== 動的プロパティ ====
現状のPHP8.1および以前のバージョンでは下記コードのようにクラスで宣言していない変数(下記コードの場合の $a がそれである)であっても、その後に追加できる。
 
<syntaxhighlight lang="PHP">
<?php
class sample
{
// $a の宣言を消去
public $b;
}
 
$dummy = new sample; // インスタンス
 
$dummy->a = 16; // $a は冒頭のクラスでは宣言されていない
$dummy->b = 31; // 本コードでは以降は不使用。参考用に記述
 
printf("%d\n", $dummy->a);
?>
</syntaxhighlight>
 
実行結果
<pre>
16
</pre>
 
上記コードの $b のようにクラス内ですでに宣言されているプロパティのことを静的プロパティと言います。
一方、上記コードのクラス内からは消された $a のように、クラス外で初めて宣言されたプロパティのことを動的プロパティと言います。
 
 
PHP のメンバ変数には定数を定義することも出来ます。その場合、 $はつけません。下記コードの場合「$var3」だとエラーになります。
 
また、定数メンバにアクセスするには、インスタンス後(new後)に、<code>クラス名::メンバ変数名</code>でアクセスします。通常変数の場合とは違うので、注意してください。アクセス方法を間違えると、インタプリタ実行時のエラー実行不能になったり、思わぬバグを招くので、要注意です。
 
<syntaxhighlight lang="PHP">
<?php
class SimpleClass
{
const var1 = 1+2;
}
 
$dummy = new SimpleClass;
print($dummy::var1);
 
?>
</syntaxhighlight>
 
実行結果
<pre>
3
</pre>
 
 
下記は、意図的にセミコロン2個とアロー演算子を間違えた例です。
 
<syntaxhighlight lang="PHP">
<?php
class SimpleClass
{
const var1 = 1+2;
}
 
$dummy = new SimpleClass;
print($dummy::var1) . "\n";
 
 
// $dummy::var1 = 5; // エラーになる
$dummy->var1 = 5; // アローのほうに定義できるが・・・
print($dummy::var1) . "\n"; // セミコロン2個のほうは3のまま
print($dummy->var1) . "\n"; //
 
?>
</syntaxhighlight>
 
実行結果
<pre>
3
 
Deprecated: Creation of dynamic property SimpleClass::$var1 is deprecated in /home/ユーザー名/test.php on line 12
3
5
</pre>
 
このように、アロー演算子のとセミコロン2個のは、それぞれ別々の変数として扱われます。
 
「Deprecated: 」と警告的なメッセージが出るように、これはバグの原因になりやすいので、const宣言したクラス変数のアロー演算子変数の作成は、なるべく避けるのが安全でしょう。
 
==== コンストラクタ ====
下記コードは、 [https://www.php.net/manual/ja/language.oop5.properties.php 公式マニュアル]のうち、説明の簡単のために、これから説明する「コンストラクタ」と関係ない部分の変数をaaとかbbbbとかに変えたものです。
 
<syntaxhighlight lang="PHP">
<?php
 
class User
{
public int $id;
public ?string $name;
 
public function __construct(int $aa, ?string $bbbb)
{
$this->id = $aa;
$this->name = $bbbb;
}
}
 
$ist = new User(123, null);
 
var_dump($ist->id);
var_dump($ist->name);
 
?>
</syntaxhighlight>
 
実行結果
<pre>
int(123)
NULL
</pre>
 
コンストラクタは、そのクラスのインスタンスが生成(new)されたときに実行される関数のことですが、PHPではコンストラクタ名が "__construct" に決まっています。これ以外のものに名前を変えるとエラーになります。
 
このセクションで重要なのは、上記のコンストラクタの説明です。下記はおまけの話題にすぎません。
 
<code>var_dump</code> は単なる出力表示の一種です。気になるなら、 print などの見慣れた関数に置き換えても構いません。
 
<code>int</code> や <code>?string </code> は型名です。最近のPHPでは、クラスの変数の宣言の際、型をつけられます。詳しくは公式マニュアルなどをお読みください。
 
==== readonly プロパティ ====
readonly プロパティを用いると、クラスのインスタンス作成時に一度しか変数を代入できなくなります。このため、宣言後に書き換えされたくないクラス変数のある場合、役立ちます。
 
下記コードは、公式サイトにあるコードをもとに、wiki用に、意図的にエラーになる行をコメントアウトしたものです。(エラー行はコメントアウトしてあるので、実行すると成功する。)
 
<syntaxhighlight lang="PHP">
<?php
 
class Test {
public readonly string $prop;
 
public function __construct(string $prop) {
// 正しい初期化
$this->prop = $prop;
}
}
 
$test = new Test("foobar");
// 正しいプロパティの読み取り
var_dump($test->prop); // string(6) "foobar"
 
// 不正な再代入です。同じ値を代入することは問題ありません。
// $test->prop = "foobar"; // wiki用にコメントアウト
// Error: Cannot modify readonly property Test::$prop
?>
 
</syntaxhighlight>
 
実行結果
<pre>
string(6) "foobar"
 
</pre>
 
readonly は、必ずコンストラクタを仲介して、readonly なクラス変数と呼出側の値のやりとりをしなければなりません。
 
公式サイトを見ても特に明言はされてないですが、しかしそうしないとエラーになります。
 
また、PHP公式サイトでは言及されていないですが、C#が同様にコンストラクタを仲介して readonly なクラス変数との値のやりとりをする仕組みです。
 
コンストラクタを仲介せずにもっと気軽に使いたいかもしれませんが、無理か、仮にどうにか実行が出来たとしても非推奨でしょう。