投稿

12月, 2022の投稿を表示しています

[資格] PHP8技術者認定上級/準上級試験

PHP8技術者認定上級/準上級試験を受けてきてなんとか合格できたました。 PHP技術者認定試験について 概要 PHP技術者認定試験はPHP技術者認定機構が開催する試験で、PHPのバージョンと試験レベルにより別れています。現在は以下の試験が配信されています。 PHP5初級試験 PHP7初級試験 PHP5上級試験 PHP8上級試験 (今回受けた試験) 受験について PHP技術者認定試験の受験方法は、オデッセイコミュニケーションズのテストセンターでCBT(Computer Based Testing)により配信されていますので、会員登録して試験の予約をします。 https://cbt.odyssey-com.co.jp/ PHP8上級 PHPの言語仕様から実用的なプログラミングテクニックまでのスキル・知識を問われる試験です。 試験情報 1. PHP8上級試験情報 試験名 PHP8技術者認定上級/準上級試験 問題数 30問 試験時間 120分 合格ライン 5割正解:準上級、7割正解:上級 受験料(税込み) ¥16,500 前提条件 無し、誰でも受験・認定可能 参考書 PHP8上級試験専用の問題集やテキストは現在のところ(2022年12月)無さそうです。以下の標準テキストを参考にしました。 独習PHP 第4版 PHP8を学ぶための標準教科書 試験範囲の大部分をカバーできる 学習方法 Prime Studyの模擬試験 Prime Studyより無料の模擬試験が配信されているので、まずこちらを利用しました。誤記等が少しありますが、実際の試験にかなり近いです。 ただし回答についての解説などはないので自分で調べる必要があります。 https://study.prime-strategy.co.jp/ 実際に動かして動作を確認 Prime Studyの模擬試験は解説がないので、実際に動かし

[PHP] WEBアプリケーションの脆弱性 - XSS(クロスサイトスクリプティング)脆弱性と対策について

イメージ
XSS(クロスサイトスクリプティング)についてと、PHPにおけるXSS対策についてまとめます。 XSS(クロスサイトスクリプティング)とは クロスサイトスクリプティング(以下XSS)とは、Webサイトの脆弱性を突いた悪意のある攻撃のことを言います。 その多くは、スクリプトによってWebページを改ざんしたリンクを用意し、そのリンクを踏んだ第三者の個人情報やID/PASSWORD等の機密情報を抜き取る手口が上げられます。 XSSの概要図 まず攻撃者は、正規のサイトに悪意のあるスクリプトを埋め込みWebページを改ざんします。実際に正規サイトのWebページを書き換えるわけではなく、スクリプトを埋め込んだリンクを用意して、Webページの利用ユーザーがリンクを踏むのを待ちます。 Webページ利用者は、攻撃者が用意したリンクを踏んでしまうと、悪意のあるスクリプトによってWebページが改ざんされた状態でブラウザに表示されます。例えば、ログイン画面のformタグのacsion属性を書き換えられてしまうと、ログイン情報(ID/PASSWORD)が、攻撃者が用意したサーバーにPOSTされてしまう等の被害が考えられます。 上記の通り改ざんされたWebページから攻撃者の用意したサーバーへ機密情報が送信されたり、偽サイトへ誘導されてしまいます。最初に表示されるページが正規サイトのページなだけに、閲覧者は気づきにくく非常に危険です。 なお、この時のデータの流れが、攻撃者→正規サイト、閲覧者→偽サイト、とクロスすることからクロスサイトスクリプティングと名づけられています。 XSS脆弱性のコード もっとも簡単な例でXSS脆弱性を再現してみます。 index.html まずは簡単なFormとSubmitボタンがあるWebページを用意します。 <html> <head> <title>XSS検証</title> </head> <body> <form action="/xss-test/test.php" method="POST"> <input type="tex

[PHP] NULL判定を行う演算子

変数の値がNULLの時に初期値を設定するようなコードは、これまでif文でisset関数やempty関数、is_null関数などを使って判定し初期値を代入していましたが、NULL判定用の条件演算子、NULL判定用の代入演算子を使うことで簡潔に記述できるようになりました。 NULL判定を行う条件演算子 構文 変数 ?? 初期値 [実装例]変数のNULL判定 以下の例では、変数$var1、$var2、$var3、$var4に対してNULLの場合に初期値を代入しています。 注意する点としては、対象の変数が未定義の場合($var2)もNULLとして扱われ、空文字($var3)の場合はNULLとして扱われない点です。 コード $var1 = null; //$var2 $var3 = ""; $var4 = 1; $var1 = $var1 ?? 'default'; $var2 = $var2 ?? 'default'; $var3 = $var3 ?? 'default'; $var4 = $var4 ?? 'default'; echo "var1=", $var1, "\n"; echo "var2=", $var2, "\n"; echo "var3=", $var3, "\n"; echo "var4=", $var4, "\n"; 実行結果 $ php test_null.php var1=default var2=default var3= var4=1 NULL判定を行う代入演算子 構文 変数 ??= 初期値 [実装例]変数のNULL判定 代入演算子を使って記述すると、上記のコードをさらに簡潔に記述することが出来ます。実行すると同じ結果になります。 $var1 = null; //$var2 $var3 = ""; $var4 = 1; $var1 ??= 'default'; $var2 ??= 'default';

[PHP] エラー出力の制御について

イメージ
PHPのエラー出力の制御は、php.iniのerror_reportingに設定する方法と、もしくはプログラム実行時に関数で設定する方法があります。 プログラムで設定する場合は、ini_set関数で設定するか、専用のerror_reporting関数で設定する方法があります。 error_reporting関数 error_reporting関数は、引数にエラーの種類を表す定数を指定し、どの種類のエラーを出力するのかを設定することが出来ます。 なお引数の設定値はint型のため数値リテラルを設定することもできますが、組み込み定数を使って指定することが推奨されています。 公式マニュアル: https://www.php.net/manual/ja/function.error-reporting.php error_reporting関数のシグネチャ 1. error_reporting関数 引数 int (error_level) ※PHP8.0からnullの指定が可能、nullの場合はデフォルト(32767)が設定され、すべてのエラーを出力する設定になる。 戻り値 int $error_level引数指定ありの場合は、変更前のエラーレベルを返す。 $error_level引数指定なしの場合は、現在のエラーレベルを返す。 error_levelについて error_levelはPHPコアに組み込まれており、いつでも利用できます。 2. error_level定数 E_ERROR (1) 重大なエラー、復帰不可能なためスクリプトは中断する E_WARNING (2) 実行時の警告、スクリプトは続行できる E_PARSE (4) コンパイル時のパースエラー E_NOTICE (8) 実行時の警告、スクリプトは続行できる E_ALL (32767) 全てのエラーを出力する 0 全てのエラーを出力しない、定数は無し

[PHP] 参照(リファレンス)について

参照(リファレンス)とは、メモリ上のアドレスそのものを代入し、複数の変数を同一のものとして扱うことが出来ます。 ここではPHPのリファレンスについて正しく理解するためにまとめます。 リファレンスの代入 構文 変数の前に「&」を付けると、変数のメモリ上のアドレスであるリファレンスを取得することが出来ます。 &変数 [実装例]リファレンスの代入 コード 以下の例では、変数$aの参照を変数$bに代入し、そのあと変数$bを更新しています。 $a = 1; $b = &$a; $b = 2; var_dump($a, $b); 実行結果 実行すると変数$a、$bどちらも同じように更新されていることが分かります。 $ php test_reference.php int(2) int(2) [実装例]リファレンスの解除 コード unset関数でリファレンスの解除が出来ます。 $a = 1; $b = &$a; unset($b); $b = 2; var_dump($a, $b); 実行結果 $ php test_reference.php int(1) int(2) 参照渡し 関数やメソッドの引数に、変数の参照を渡してやることが出来ます。 [実装例]参照渡し コード 以下の例では、関数addVarの引数を参照渡しにして、関数内で$varの値を更新しています。 function addVar(int &$var) { $var++; } $var = 1; addVar($var); var_dump($var); 実行結果 実行結果は、関数の外で宣言された$varの値が更新されていることが分かります。 $ php test_reference.php int(2) 変数以外を渡すとエラー 参照渡しが設定されている引数に、変数以外の値を直接渡すことはできません。 例えば関数addVarの呼び出しを、 addVar(1); とすると、以下のエラーが発生します。 $ php test_reference.php Fatal error: Uncaught Error: addVar(): Argument #1 ($var) cann

[PHP] マジックメソッド - クラスオブジェクトについての処理

クラスのオブジェクトに関するマジックメソッドについて3つほどまとめます。 __toStringメソッド __toStringメソッドは、クラスのオブジェクトを文字列として出力しようとした際に呼び出されるマジックメソッドです。 通常クラスのオブジェクトは、文字列として出力しようとしてもconvertエラーとなってしまい出力できません。 class Test { private string $name; public function __construct(string $name) { $this->name = $name; } } $test = new Test("Hoge"); echo "name=", $test, "\n"; $ php test_magic-method.php name= Fatal error: Uncaught Error: Object of class Test could not be converted to string in .¥test_magic-method.php:101 Stack trace: #0 {main} thrown in .\test_magic-method.php on line 101 これを解決するのが__toStringメソッドです。 マジックメソッドのシグネチャ 1. __toStringメソッドのシグネチャ アクセス修飾子 public メソッド名 __toString 戻り値 string [実装例]クラスオブジェクトの文字列変換 冒頭のコードに__toStringメソッドを実装して、文字列に変換した場合の出力を指定します。 コード class Test { private string $name; public function __construct(string $name) { $this->name = $name; } public functi

[PHP] マジックメソッド - 未定義属性の処理

マジックメソッドとは、クラスに定義されるメソッドで、あらかじめ役割が決められたいくつかのメソッドのことを言います。 以下の記事で取り上げたコンストラクタとデストラクタについても、マジックメソッドの一種です。 https://www.s-watanabe.work/2022/12/php_11.html ここでは、未定義の属性への操作しようとしたときに呼び出されるメソッドについてまとめていきます。 __setメソッドと__getメソッド PHPは基本的に未定義の属性へのアクセスが可能になっています。例えば以下のコードはエラーにならずに実行可能です。 class Test { } $test = new Test(); $test->name = 'Hoge'; echo "name=", $test->name, "\n\n"; var_dump($test); 実行結果は以下のようになります。 $ php test_magic-method.php name=Hoge object(Test)#1 (1) { ["name"]=> string(4) "Hoge" } この属性をセットする時の処理を制御するのが __setメソッド、属性を取得する処理を制御するのが __getメソッドです。 マジックメソッドのシグネチャ __setメソッド 1. __setメソッドのシグネチャ アクセス修飾子 public or なし メソッド名 __set 第一引数 string (属性名) 第二引数 mixed (値) 戻り値 void __getメソッド 2. __getメソッドのシグネチャ アクセス修飾子 public or なし メソッド名 __get 第一引数 string (属性名) 戻り値 mix

[PHP] コンストラクタとデストラクタ

コンストラクタ PHPでクラスを利用する際に、最初にnew演算子によってクラスのインスタンスを作成するという作業を行いますが、この時に実行されるメソッドをコンストラクタと言います。 コンストラクタは省略可能で、省略した場合引数を持たないデフォルトのコンストラクタが内部的に用意されます。 コンストラクタの定義構文 public function __construct(引数) { // プロパティなどの初期化処理 } [実装例]コンストラクタでメンバー変数を初期化する コード class Test{ private int $id; private string $name; public function __construct(int $id, string $name) { echo __METHOD__, "\n"; $this->id = $id; $this->name = $name; } } $test = new Test(1, "Test Name"); var_dump($test); 実行結果 $ php test_construct.php Test::__construct object(Test)#1 (2) { ["id":"Test":private]=> int(1) ["name":"Test":private]=> string(9) "Test Name" } [間違った実装例]引数なしのコンストラクタを呼び出す 引数ありのコンストラクタを定義した状態で、引数なしのコンストラクタを呼び出すとエラーになります。コンストラクタをクラスに明示的に定義した時点で、デフォルトのコンストラクタは無効になります。 コード class Test{ private int $id; private string $name; public function __construct(int $id, string $na

[PHP] 抽象クラスとインターフェース

PHPの抽象クラスとインターフェースについてです。 抽象クラス 抽象クラスは継承される前提のクラスで、それ自体ではインスタンスを生成することが出来ないクラスです。 インスタンスは生成できませんが、メソッドやプロパティは持つことが可能で、これらは基本的に継承されたサブクラスから呼ばれて扱われます。 抽象クラスの最大の特徴は、抽象メソッドを持つことが可能です。抽象メソッドとは、処理を記載しないメソッドで、サブクラスでオーバーライドされて処理が実装されます。 抽象クラスを継承したサブクラスでは、抽象メソッドを必ずオーバーライドしなくてはなりません。 抽象クラスと抽象メソッドの定義構文 abstract class 抽象クラス名 { abstract function 抽象メソッド名(シグネチャ) : 戻り値(任意); } [実装例]抽象メソッドをオーバーライドする コード abstract class TestAbstract { abstract function printName(string $name) : void; } class Test extends TestAbstract { function printName(string $name) : void { print "Hello {$name}.\n"; } } $test = new Test(); $test->printName("abstract"); 実行結果 $ php test_abstract.php Hello abstract. [実装例]抽象クラスからサブクラスに継承されたメソッドを実行する 抽象クラスに定義されたメソッドから、サブクラスに継承されたメソッドを実行することが出来ます。 コード 以下の例ではTestクラスでオーバーライドされたprintNameメソッドを、親クラスであるTestAbstractクラスのtestメソッドから呼び出しています。 抽象クラス事態はインスタンスを持つことはできませんが、サブクラスであるTestクラスのインスタンスがあるため、testメソッド内で$thisキーワードが使用できます。 abst

[PHP] static修飾子について

static修飾子を使った静的変数、静的プロパティ、静的メソッドについてです。 静的変数 関数内で定義された変数のスコープはローカルスコープと言い、呼び出し元のスコープや外部のスコープからは参照できず、関数が終了したら値ごと破棄されます。 しかし、変数を静的変数で定義することで、変数の値を関数終了後も値を維持しておくことが可能です。 定義 static 変数; [実装例] 通常の変数定義 コード 以下のコードは通常の変数定義です。 function counter() { $var = 0; $var++; return $var; } $count = counter(); print "count={$count}\n"; $count = counter(); print "count={$count}\n"; $count = counter(); print "count={$count}\n"; 実行結果 ローカル変数 $var の値は counter関数が終了するたび破棄されるので、何度呼び出しても結果は変わりません。 $ php test_static.php count=1 count=1 count=1 [実装例] 静的変数での変数定義 コード 以下のコードは変数 $var を、静的変数で定義した例です。 function counter() { static $var = 0; $var++; return $var; } $count = counter(); print "count={$count}\n"; $count = counter(); print "count={$count}\n"; $count = counter(); print "count={$count}\n"; 実行結果 $var の値はcounter関数の終了後も保持されているのが分かります。 $ php test_static.php count=1 count=2 count=3 静的プロパティ クラスのプロパティをst

[PHP] コールバック関数について

PHPのコールバック関数とは、呼び出し先関数の中でさらに呼び出される関数のことを言います。コールバック=「後で呼び出される」という意味があります。 ここではコールバック関数の基本的な使い方、無名関数を使った呼び出し、コールバック関数を使ったいくつかの例についてまとめていきます。 コールバック関数 実装例 コールバック関数はcallable型で定義され、呼び出された関数内で実行(コールバック)されます。 以下の例は一番簡単な例です。test_callback関数の引数にコールバックさせたい関数名を指定して、test_callback内でコールバックしています。 コード function test_function() { print __FUNCTION__ . "\n"; } function test_callback(callable $function) { $function(); } test_callback("test_function"); 実行結果 $ php test_callback.php test_function 無名関数で指定する実装例 callable型は以下のように無名関数で指定することも可能です。 コード function test_callback(callable $function) { $function(); } test_callback(function() { print __FUNCTION__ . "\n"; }); 実行結果 無名関数で指定した場合、関数名が無いので __FUNCTION__ は以下のように出力されます。 $ php test_callback.php {closure} array_map関数 配列の全要素に対して処理を行う array_map関数は配列の全要素に対して処理を行うための関数です。従来配列の全要素に対して処理を行う場合、for文やforeach文を使用して記述していましたが、これが簡潔に記述できるようになります。 なお、array_map関数は引数に指定した配列を直接変更するのではなく、処理した結果の配列を返します。

[PHP] 可変関数/可変変数について

可変関数は関数名を変数に設定して、変数に応じて対応する処理を呼び出すことが出来る関数です。 また、関数と同様に、変数に関しても可変にすることが出来ます。 可変関数 構文 $変数() [実装例]通常の関数を可変関数として呼び出す コード function test_variable_function(string $value) { echo $value . "\n"; } $function = "test_variable_function"; $function("call variable function test."); 実行結果 このコードは正しく実行でき、以下のように出力されます。 call variable function test. [実装例]オブジェクトのメソッドを可変関数として呼び出す - 1 クラスオブジェクトのメソッドを可変関数で呼び出す場合は、呼び出すための変数を配列で指定し、第一引数にオブジェクトのインスタンス、第二引数にメソッド名を指定します。 コード class Test { function test_variable_function(string $value) { echo $value . "\n"; } } $function = [new Test(), "test_variable_function"]; $function("call variable function test."); [実装例]オブジェクトのメソッドを可変関数として呼び出す - 2 クラスオブジェクトのメソッドを可変関数で呼び出す場合は、呼び出すための変数を配列で指定し、第一引数にオブジェクトのインスタンス、第二引数にメソッド名を指定します。 コード class Test { function test_variable_function(string $value) { echo $value . "\n"; } } $test = new Test(); $function

[PHP] 無名関数とアロー関数について

無名関数はその名の通り、名前を持たない関数で、クロージャーとも呼ばれます。 無名関数 構文 function(引数) { 処理; } [実装例]無名関数を変数に入れて使う コード $func = function(string $value) { print "Hello {$value}\n"; }; $func("Test"); このコードの正しく実行でき、結果は以下のようになります。 実行結果 $ php test_anonymous_function.php Hello Test [実装例]呼び出し元スコープの変数を使う コード(誤) 無名関数の呼び出し元のスコープに定義されている変数は、無名関数内でそのまま扱うことはできません。例えば以下のコードは実行時にエラーになります。 $name = "Hoge"; $func = function(string $value) { print "Hello {$value} {$name}\n"; }; $func("Test"); 実行結果(誤) $ php test_anonymous_function.php Warning: Undefined variable $name in ./test_anonymous_function.php on line 5 Hello Test コード(正) 呼び出し元スコープの変数を無名関数内で利用するには、function定義時にuseキーワードを使用して無名関数に渡してやります。 $name = "Hoge"; $func = function(string $value) use ($name) { print "Hello {$value} {$name}\n"; }; $func("Test"); 無名関数内で呼び出し元スコープの変数を使うには、useキーワードに使用する変数を指定する 実行結果(正) $ php test_anonymous_function.php Hello Test Ho

[PHP] PHP8のインストール (Win)

イメージ
PHP8のインストールについてまとめます。 インストール PHPの最新のコードは公式サイトで公開されています。また、最新以外のコードもChangelogの確認も含めて取得することが可能です。 パッケージダウンロード 公式サイト( https://www.php.net/ )を開き、上段メニューのDownloadsをクリックします。 ダウンロードページ( https://www.php.net/downloads )を開き、自身の環境に合ったパッケージを選択します。 ここでは、Windows10にセットアップするので「Windows Downloads」をクリックします。 Zipファイルのパッケージをクリックしてダウンロードします。 ファイル指紋の確認(任意) ダウンロードしたZipファイルにはSHA256ファイル指紋が付いています。この値を確認することで、ファイルが改ざんされていないかを確認することが出来ます。 Windowsの場合、certutilコマンドで以下のようにして確認します。 $ certutil -hashfile php-8.1.13-nts-Win32-vs16-x64.zip SHA256 SHA256 ハッシュ (対象 php-8.1.13-nts-Win32-vs16-x64.zip): 766630b4168c830820ace21df301b8816e6675c5ed26395a3d7c5fdef1690dd8 CertUtil: -hashfile コマンドは正常に完了しました。 セットアップ PHPのセットアップはダウンロードしたZipファイルを任意の場所へ展開するだけでOKです。 ここでは「c\php」へ展開しました。 環境変数 展開したディレクトリのパスを環境変数に設定すれば、セットアップは完了です。 Windowsボタンから「設定」を開く 「システム」をクリック 「詳細情報」をクリック 「システムの詳細設定」をクリック 「詳細設定」タブから「環境変数」をクリック 「システムの環境変数」の「Path」を選択し、編集をクリック PHPを展開したディレクトリのパスを追加して「OK」をクリック システムのプロパティで適用しOKをクリック