- 投稿日:2020-06-23T21:54:40+09:00
Vdebugを使ってVimでPHPのデバッグ環境を整える
PHPはずっとPHPStormで書いていて不自由はなかったのですが、最近他の言語でvimを使いだしたところ、全部vimでやりたくなる一過性の病にかかったのでPHPでデバッグ環境を整えています。
PHPのxdebugを実行するのにvimのプラグインVdebugを使います。
vim-vdebug/vdebug: Multi-language DBGP debugger client for Vim (PHP, Python, Perl, Ruby, etc.)全部マニュアルに書いてあるので読めば終了なんですが、せっかく触りながらマニュアルの内容を確かめたので備忘として残しておきます。
ただし、CLIでローカル実行した場合についてです。
ブラウザからのリクエストで起動する場合やリモートデバッグはまたいつか追記するかもしれません。インストール・初期設定
xdebugのインストールはすでにたくさん記事があるので省略。
Vdebugのインストール
僕はPlugin managerにjunegunn/vim-plugを使っています。
.vimrccall plug#begin('~/.vim/plugged') " Debug Plug 'vim-vdebug/vdebug' call plug#end().vimrcに追記してから
:PlugInstall呼び出しスクリプトの作成
また、CLIから実行する場合は、環境変数
XDEBUG_CONFIG
でidekey
の指定が必要です。毎回打つのが面倒なのでショートカット用のshellscriptを作ります。php-xdebug#!/bin/bash export XDEBUG_CONFIG="idekey=xdebug" /usr/bin/php "$@"phpのパスは環境に合わせます。
実行権限付与して適宜パスの通っている場所に移します。$ chmod +x php-xdebug $ mv php-xdebug /to/your/path/こんな風に使用。
$ php-xdebug myscript.php
使い方
基本の使い方
- 止めたい行にブレークポイントを設置(F10)
- Debuggerをスタート(F5)
- Terminal別タブでそのブレークポイントを通過する処理を呼び出し
- Debuggerをストップ(F6を2回)
windowの見方
よく使うキーバインド
- F5・・Start
- F6・・Stop
- F2・・Step Over
- F3・・Step In
- F4・・Step Out
- F9・・Run To Cursor
- F10・・Toggle Break Point
ブレークポイント
- F10でtoggle
:BreakpointWindow
でブレークポイント一覧を確認
- このウィンドウで消したいブレークポイントの行にカーソルをあわせて
dd
で該当ブレークポイントを削除:BreakpointRemove *
で一括削除いろんなブレークポイント
F10の通常の行ブレークポイント以外にいくつかの特性を持ったブレークポイントを利用できます。
使い方:Breakpoint <type> <arguments>conditional
行ブレークポイントと似ていますが、ブレークが発動する条件を指定できます。
使い所は「ループの◯回目のみ止めたい」とかですかね。
標準の行ブレークポイント以外では唯一これだけ使いそうな気がします。例)$xが2の場合のみブレーク:Breakpoint conditional $x == 2exception
指定した例外が発生した場合にブレークする
例:Breakpoint exception PDOExceptioncall
指定の関数が呼び出された場合にブレークする。マニュアルを見るに、挙動は保証されていないようです。
:Breakpoint call open_filereturn
指定の関数からreturnされた場合にブレークする。同じく、挙動は保証されていないようです。
:Breakpoint return open_filewatch
指定の変数に書き込みがあった場合にブレークする。マニュアルにはxdebugでサポートされていないので期待するなと書いてあります。僕の環境では動かなかったです。特に期待してなかったので大丈夫でした。
:Breakpoint watch $myvar任意の式の評価
実行ポイントのコンテキストで任意の式を評価させることができます。デバッガーの醍醐味とも言える機能ですね。
実行方法が3種類あります。1) 記述した式を評価する方法
:VdebugEval $x * 3これはwatch windowに表示されますが、ステップを進めるとデフォルトのwatch windowに戻ります。
指定した式の評価をwatch windowに固定表示させたい場合は:VdebugEval!
を使います。:VdebugEval! $x * 3デフォルトのwatch windowに戻したい場合は式無しで以下を打ち込みます
:VdebugEval!2)visualモードで選択した式を評価する方法
v
で選択後<leader>e
で評価3) traceウィンドウで評価を確認する
:VdebugTrace
を使うとwatch windowとは別にtrace windowで式をトレースできます。
VdebugEval!
と似ていますが、watch windowをデフォルトとのままにしつつ式の評価を追うことができます。:VdebugTrace $x細かい設定とか
デフォルトオプション
let g:vdebug_options = { \ 'port' : 9000, \ 'timeout' : 20, \ 'server' : '', \ 'on_close' : 'stop', \ 'break_on_open' : 1, \ 'ide_key' : '', \ 'debug_window_level' : 0, \ 'debug_file_level' : 0, \ 'debug_file' : '', \ 'path_maps' : {}, \ 'watch_window_style' : 'expanded', \ 'marker_default' : '⬦', \ 'marker_closed_tree' : '▸', \ 'marker_open_tree' : '▾', \ 'sign_breakpoint' : '▷', \ 'sign_current' : '▶', \ 'continuous_mode' : 1, \ 'simplified_status': 1, \ 'layout': 'vertical', \}個別で上書き
.vimrcif !exists('g:vdebug_options') let g:vdebug_options = {} endif let g:vdebug_options.port = 9001まとめて上書き
.vimrclet g:vdebug_options = { \ '"port' : 9000, \ 'break_on_open' : 0, \ 'ide_key' : '', \}基本はデフォルトのまま使っていますが、
break_on_open
は0にしています。これは実行されるスクリプトの1行目でステップが止まるかどうかの指定です。ブレークポイントより前で止まっても鬱陶しいのでオフにしています。レイアウト
g:vdebug_options.layout
にhorizontal
を指定するとレイアウトがデフォルトから変わります。
感想
- evaluationを複数同時にtraceできない点以外はIDEの場合とくらべて特に不便とかはなかったです。
- 投稿日:2020-06-23T21:31:22+09:00
PHP基礎<PHPの書き方・表示方法>
前書き
PHPを基礎から学習しています。
積み重ねのアウトプットとして更新していきます。PHPの書き方
index.php<?php // 開始タグ echo ('cat'); echo ('<br>'); //改行 echo ('こんにちは'); // プログラム echo (123); ?> // 終了タグ
- 開始タグ<?phpと終了タグ?>を書き、その間にプログラムを記述する
- PHP ファイルの拡張子は .php とする
- '○○'シングルクオーテーションは必ず必要
- echoの場合は( )が無くても可
- ; (セミコロン)は必ず付ける
- コメントアウトは//から改行までか/* から */の範囲に記述する
ブラウザにPHPを表示する
- MAMPを使ってPHPを表示する
http://localhost:8888/(PHPプロジェクトのフォルダ名)/(PHPファイル名).php
と入力すればブラウザで表示が確認ができる。あとがき
初回は基本の書き方のみまとめました。
次回は変数について、初心者の勉強のまとめをしていきたいと思います!
- 投稿日:2020-06-23T21:03:53+09:00
メディアクエリの使い方
メディアクエリの使い方
個人アプリでレスポンシブ対応が必要だったので、その使い方を記事にまとめました。
index.blade.php<div class = "content"> @foreach($posts as $post) <img src="/storage/{{$post->image}}" class="image" width=293px height=293px> @endforeach </div>index.css@media (max-width: 1420px) { .content { margin: 90px 218px 0; } } @media (max-width: 1420px) { .image { width: 280px; height: 280px; } } @media (max-width: 1340px) { .content { margin: 90px 200px 0; } } @media (max-width: 1340px) { .image { width: 260px; height: 260px; } } @media (max-width: 1260px) { .content { margin: 90px 180px 0; } } @media (max-width: 1260px) { .image { width: 240px; height: 240px; } }こんな感じで要素の幅によって中身のサイズを調整してあげる。
検証機能を使えば、幅が簡単にわかるので、それを見ながら調整していけば、
自然にビューのレスポンシブができるようになります!
- 投稿日:2020-06-23T20:19:42+09:00
Laravel環境構築時のエラー解決 Mac
エラー内容
$ composer global require laravel/installer Changed current directory to /Users/ooshiroippei/.composer Using version ^3.1 for laravel/installer ./composer.json has been created Loading composer repositories with package information Updating dependencies (including require-dev) Your requirements could not be resolved to an installable set of packages. Problem 1 - Installation request for laravel/installer ^3.1 -> satisfiable by laravel/installer[v3.1.0]. - laravel/installer v3.1.0 requires ext-zip * -> the requested PHP extension zip is missing from your system. Installation failed, deleting ./composer.json.ext-zipが必要
重要なエラー箇所を和訳すると、
「laravel/installer v3.1.0にはext-zipが必要です。リクエストされたPHP拡張zipがシステムにありません」と書かれている。原因
Macに最初から入っているPHPにはzipのサポート機能がないためエラーが起こっていた。
解決策
これは改めてPHPを入れ直すことで解決できる。
①MacにPHPを再インストールするには「Homebrew」を使う。
こちらを参考。
https://awesome-linus.com/2019/08/17/mac-homebrew-install/②PHPをインストールする
//HomeBrewのバージョン確認まで終わったらインストール $ brew install php //zipがサポートされているか確認 $ php --ri zip //Laravelインストール $composer global require laravel/installer各エラー対策
Extension 'zip' not present.とエラーが出た場合
$ brew link phpbrew link phpでエラー
Linking /usr/local/Cellar/php/7.4.7...
Error: Could not symlink sbin/php-fpm
/usr/local/sbin is not writable.$brew doctor Warning: The following directories do not exist: /usr/local/Frameworks /usr/local/sbin You should create these directories and change their ownership to your account. sudo mkdir -p /usr/local/Frameworks /usr/local/sbin //実行 sudo chown -R $(whoami) /usr/local/Frameworks /usr/local/sbin //実行 Warning: You have unlinked kegs in your Cellar. Leaving kegs unlinked can lead to build-trouble and cause brews that depend on those kegs to fail to run properly once built. Run `brew link` on these: php Warning: /usr/bin occurs before /usr/local/bin This means that system-provided programs will be used instead of those provided by Homebrew. The following tools exist at both paths: Consider setting your PATH so that /usr/local/bin occurs before /usr/bin. Here is a one-liner: echo 'export PATH="/usr/local/bin:$PATH"' >> /Users/user/.bash_profile rake bundle tidy sqlite3 bundler rails //各エラー項目に出ているコマンドを実行していく。 $sudo mkdir -p /usr/local/Frameworks /usr/local/sbin $sudo chown -R $(whoami) /usr/local/Frameworks /usr/local/sbin $echo 'export PATH="/usr/local/sbin:$PATH"' >> /Users/user/.bash_profile //パスを通したあとは必ずsourceで際読み込み $source ~/.bash_profile //バージョンを確認 $php -v //zipを確認 $ php --ri zip zip Zip => enabled Zip version => 1.15.6 Libzip headers version => 1.7.0 Libzip library version => 1.7.1 //Laravelインストール $composer global require laravel/installer
- 投稿日:2020-06-23T17:59:21+09:00
PHPコールバック入門
コールバック
PHPの要素で関数として呼び出すことができるものをコールバック(またはCallable)といいます。
参考:PHP: コールバック / Callable - Manual
Examples
例1
PHPfunction hello() { echo 'こんにちは。'; } echo is_callable('hello') . PHP_EOL; call_user_func('hello');result1 こんにちは。
is_callable
— 引数が、関数としてコール可能な構造であるかどうかを調べる
call_user_func
— 最初の引数で指定したコールバック関数をコールする例2
PHPfunction hello() { echo 'こんにちは。'; } call_user_func(hello);resultPHP Warning: Use of undefined constant hello - assumed 'hello' (this will throw an Error in a future version of PHP) in ...PHP 関数はその名前を単に文字列として渡します。
例3
PHPfunction sum($int1, $int2) { return $int1 + $int2; } echo is_callable('sum') . PHP_EOL; echo call_user_func_array('sum', [2, 5]);result1 7
call_user_func_array
— パラメータの配列を指定してコールバック関数をコールする例4
PHP$hello = function () { echo 'こんにちは。'; }; echo is_callable($hello) . PHP_EOL; call_user_func($hello);result1 こんにちは。
一般的なユーザー定義関数とは異なり、 無名関数 もパラメータとして渡せます。
ちなみに・・
PHP$hello = function () { echo 'こんにちは。'; }; var_dump($hello);resultobject(Closure)#1 (0) { }無名関数はPHPが用意している
Closure
という特別なクラスのインスタンスとして実現されています。無名関数の実装には Closure クラスを使っています。
例5
PHPclass Player { private $name; public function __construct($name) { $this->name = $name; } public function getname() { return $this->name; } } $ichiro = new Player('イチロー'); echo is_callable([$ichiro, 'getname']) . PHP_EOL; echo call_user_func([$ichiro, 'getname']);result1 イチローオブジェクトのインスタンスを渡すには配列を使います。 配列の 0 番目の要素にオブジェクトを、 そして 1 番目の要素にメソッド名を指定します。
例6
PHPclass Car { public static function honk() { echo 'ビッビー'; } } echo is_callable(['Car', 'honk']) . PHP_EOL; call_user_func(['Car', 'honk']);result1 ビッビー静的なクラスメソッドの場合、オブジェクトのインスタンスは不要です。 0 番目の要素として、オブジェクトのかわりにクラス名を指定します。
例7
PHPclass Car { public static function honk() { echo 'ビッビー'; } } echo is_callable('Car::honk') . PHP_EOL; call_user_func('Car::honk');result1 ビッビーPHP 5.2.3 以降では、 'ClassName::methodName' 形式で指定することもできます。
おしまい
- 投稿日:2020-06-23T17:59:21+09:00
PHPコールバック関数入門
Callable
PHPの要素で関数として呼び出すことができるものをコールバックまたは callable といいます。
参考:PHP: コールバック / Callable - Manual
本記事のタイトルにもあるとおり、コールバック関数といわれることもあるようです(実際 PHP マニュアルにも書かれています)。
無用な混乱をさけるため、本記事では呼び方を callable で統一することにします。
Examples
説明を読んだだけでは理解できないと思いますので、callable の例をたくさんみていくことにしましょう。
例1
PHPfunction hello() { echo 'こんにちは。'; } echo is_callable('hello') . PHP_EOL; call_user_func('hello');result1 こんにちは。
5行目の
is_callable
は、引数が callable であるかどうかを調べてくれる関数です。
is_callable
— 引数が、関数としてコール可能な構造であるかどうかを調べる引数が callable なら
true
を、 そうでなければfalse
を返します。
また、echo true
は1
を出力しecho false
は何も出力しません。上記の例では
1
が出力されていますので、is_callble
の引数である文字列hello
は callable であることがわかりました。
callable であるということは、文字列hello
を関数として呼び出せるということです。実際に、7行目で
call_user_func
という関数をつかって callable である文字列hello
を関数として呼び出しています。
call_user_func
— 最初の引数で指定したコールバック関数をコールする
こんにちは。
と出力されていますので、1〜3行目で定義されている関数hello
が呼び出されたことがわかりますね。一般に、関数
foo
が定義されているとき文字列foo
は callable となります。
このとき文字列foo
をcall_user_func
にわたすことによって、関数foo
を呼び出すことができます。例2
PHPfunction hello() { echo 'こんにちは。'; } is_callable(hello); call_user_func(hello);PHP Warning: Use of undefined constant hello - assumed 'hello' (this will throw an Error in a future version of PHP) in ... PHP Warning: Use of undefined constant hello - assumed 'hello' (this will throw an Error in a future version of PHP) in ...今回はエラーが出てしまいました。
エラーメッセージをよく読むと
Use of undefined constant hello - assumed 'hello'
と書かれています。
これは「定義されていない定数hello
をつかっているようだけど、それは文字列hello
のことじゃないか?」という意味です。例1の5行目と7行目では、
hello
を二つのシングルクォーテーション(''
)でかこむことによって、それが文字列であることを表していました。今回の例では、シングルクォーテーションでかこむことをしなかったため、
hello
は定数として解釈されます。
このとき PHP は定数hello
の値を関数にわたそうとします。
ところが定数hello
は定義されていませんので、PHP はたいへん狼狽し、エラーメッセージを吐き、森へ帰ってしまったというわけです(?)。PHP 関数はその名前を単に文字列として渡します。
例3
PHPfunction sum($int1, $int2) { return $int1 + $int2; } echo is_callable('sum') . PHP_EOL; echo call_user_func_array('sum', [2, 5]);result1 7
1〜3行目で定義されている関数
sum
は、二つの数値をうけとって、それらの和を返すというものです。これを実行するためには
sum(2, 5)
のように二つの引数を指定する必要があります。このような場合でも、文字列
sum
自体は callable です。
これは5行目の命令によって1
が出力されていることからわかります。さて、文字列
sum
が callable だということは、文字列sum
を関数として呼び出せるということです。
sum
のような引数を必要とする関数を callable によって呼び出したいときは、call_user_func_array
という関数をつかいます。
call_user_func_array
— パラメータの配列を指定してコールバック関数をコールする第一引数には callable を、第二引数には呼び出される関数にわたしたい式を配列にしたものを指定します。
7行目では、
call_user_func_array
の第一引数には callable である文字列sum
を、第二引数には配列[2, 5]
を指定しました。これによって関数
sum
が呼び出され、関数sum
の第一引数には2
が、第二引数には5
がわたされます。
このとき関数sum
は2
と5
の和である7
を返しますので、この7
がecho
されて7
が出力されたというわけです。
余談・・
つぎのコードは今回の例の7行目をecho call_user_func('sum');
にとりかえたものです。PHPfunction sum($int1, $int2) { return $int1 + $int2; } echo is_callable('sum') . PHP_EOL; echo call_user_func('sum');これを実行すると、もちろんエラーが出るのですが、このときのエラーメッセージはつぎのようになります。
resultPHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function sum(), 0 passed in ... and exactly 2 expected in ......
「関数
sum
にわたす引数が少なすぎるよ!」といわれています。
ということは、関数sum
の呼び出し自体は問題なく行われたということです。先ほどみたとおり、文字列
sum
自体は callable でした。
ですので、call_user_func
の引数に文字列sum
を指定してあげれば、関数sum
を呼び出すこと自体は問題なくできるというわけです。
例4
PHP$hello = function () { echo 'こんにちは。'; }; echo is_callable($hello) . PHP_EOL; call_user_func($hello);result1 こんにちは。
1〜3行目で、変数
hello
に無名関数を代入しています。無名関数は callable です。
これは5行目の命令によって1
が出力されていることからわかります。一般的なユーザー定義関数とは異なり、 無名関数 もパラメータとして渡せます。
7行目では、
call_user_func
に変数hello
の値である無名関数をわたすことによって、その無名関数自身を呼び出しています。
ちなみに・・
PHP$hello = function () { echo 'こんにちは。'; }; var_dump($hello);resultobject(Closure)#1 (0) { }無名関数はPHPが用意している
Closure
という特別なクラスのインスタンスとして実現されています。無名関数の実装には Closure クラスを使っています。
例5
PHPclass Player { private $name; public function __construct($name) { $this->name = $name; } public function getname() { return $this->name; } } $ichiro = new Player('イチロー'); echo is_callable([$ichiro, 'getname']) . PHP_EOL; echo call_user_func([$ichiro, 'getname']);result1 イチロー1〜10行目で、
Player
クラスを定義しています。このクラスのなかでgetname
というメソッドを定義しました。つづく12行目で
Player
クラスのインスタンスを作成し、変数ichiro
に代入しています。このとき、配列
[$ichiro, 'getname']
は callable です。
この配列をcall_user_func
の引数に指定することで、変数ichiro
に代入されたPlayer
クラスのインスタンスのgetname
メソッドを呼び出すことができます。オブジェクトのインスタンスを渡すには配列を使います。 配列の 0 番目の要素にオブジェクトを、 そして 1 番目の要素にメソッド名を指定します。
めんどくさくなってきたので詳しく説明はしませんが、
イチロー
と出力されていることから、所期のメソッドが呼び出されたことがわかります。例6
PHPclass Car { public static function honk() { echo 'ビッビー'; } } echo is_callable(['Car', 'honk']) . PHP_EOL; call_user_func(['Car', 'honk']);result1 ビッビー1〜5行目で、
Car
クラスを定義し、そのなかでhonk
という静的メソッドを定義しました。このとき、配列
['Car', 'honk']
は callable です。
この配列をcall_user_func
の引数に指定することで、Car
クラスの静的メソッドhonk
を呼び出すことができます。静的なクラスメソッドの場合、オブジェクトのインスタンスは不要です。 0 番目の要素として、オブジェクトのかわりにクラス名を指定します。
例7
PHPclass Car { public static function honk() { echo 'ビッビー'; } } echo is_callable('Car::honk') . PHP_EOL; call_user_func('Car::honk');result1 ビッビークラスの定義は例6とおなじです。
例6では、配列
['Car', 'honk']
が callable であることをたしかめました。
今回の例は、文字列Car::honk
もまた callable であることを表しています。'ClassName::methodName' 形式で指定することもできます。
クラスの静的メソッドを callable として表現する方法は二種類あるということですね。
おしまい
callable の例をたくさんみてもらいました。
これで callable とは何なのか、多少なりとも理解が深まったと思います。また、本記事では説明が不十分な箇所も多々あるかと思います。
疑問に思うところがあったら、適宜公式マニュアル等を参照してください。最後まで読んでいただき、ありがとうございました。
- 投稿日:2020-06-23T13:40:00+09:00
PHP/Laravelの書き方の基本ルールまとめる(PHPフレームワークLaravel入門に入る前に)part3
クラスとインスタンスについて
クラスとインスタンスとは
PHPには原本となる型を再利用して効率化を測る機能があります。それがクラスとインスタンスです。
クラスが原本となる型。
インスタンスが型を元にして作成されたものです。
型の中身には、メソッドとプロパティという要素が存在しています。
メソッドが機能(関数や制御構造など)
プロバティがデータ(名前や性別といった属性)になります。
以前まとめたものがこちらになりますので参照ください。クラス定義
覚えること
クラス定義方法
インスタンス作り方
値のアクセス方法
値の入れ方
メソッドの実行方法
コンストラクタ
クラス定義ファイルの読み込み
スタティックプロパティとスタティックメソッドまずはこいつら
・クラス定義方法
・インスタンス作り方
・値のアクセス方法
・値の入れ方
・メソッドの実行方法
```記述例.php
<?phpclass staff {
//インスタンスのプロパティ
public $name;
public $age;
//インスタンスのメソッド
public fanction hello(){
echo "こんにちは","\n";
}
}
?><!DOCTYPE html>
クラスを定義する
<?php //Staffのインスタンスを作る $hana = new Staff(); $taro = new Staff(); //プロパティの値を設定する $hana->name = "花"; $hana->age = "21"; $taro->name = "太郎"; $taro->age = "35"; //インスタンスを確認する print_r($hana); print_r($taro); //メソッドを実行する $hana->hello(); $taro->hello(); ?>
```実行例.html//print_r($hana); //print_r($taro); Staff Object ( [name] => 花 [age] => 21 ) Staff Object ( [name] => 太郎 [age] => 35 ) //$hana->hello(); //$taro->hello(); こんにちは! こんにちは!クラス定義方法.phpclass クラス名{ //クラス名の文頭は基本的に大文字 public const 定数名 = 値; //設定した値は変更できない public $変数名 //プロパティ public function メソッド名(){ } }インスタンス作り方.php$変数名 = new クラス名(); //()は省略できる値のアクセス方法.php$インスタンス->プロパティ名値の入れ方.php$インスタンス->プロパティ名 = 値メソッドの実行方法.php$インスタンス->メソッド名(引数)クラスのメソッドにクラス自身のプロパティを利用する時(例文にはのってない)
public function hello(){ echo "こんにちは、"{$this->name}です!","\n"; } //$this -> プロパティ名をつけることでアクセスが可能つぎはこいつら
・コンストラクタ
・クラス定義ファイルの読み込み
・スタティックプロパティとスタティックメソッド例文.php<?php //Staffクラスファイルを読み込む require_once("Staff.php") ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Staff クラスメンバーを使う</title> </head> <body> <pre> <?php //クラスメソッドを実行 Staff::deposit(100); Staff::deposit(150); //クラスプロパティを確認する echo Staff::$piggBank, "円になりました。"\n"; //インスタンスを作る $hana = new Staff("花",21); //インスタンスメソッドを実行する $hana->latePenalty(); //クラスプロパティを確認する echo Staff::$piggyBank, "円になりました。"\n"; ?> </pre> </body> </html>出力例.html250円になりました。 1250円になりました。コンストラクタ.phpfunction__construct(引数1、引数2…){ //処理 }コンストラクタは、インスタンスを作成した時に自動で発動するメソッド。
クラス定義ファイルの読み込み.phprequire_once() //()にはひっぱり元のファイルが置いてあるパスを記入。(同じフォルダ内にある場合はファイル名でも良い)クラス定義をする場合はクラス定義をしたファイルを作り、利用するファイル上で読み込ませるのが主流。
読み込ませるための指示がrequire_once()スタティックプロパティとスタティックメソッド.phpclass クラス名{ //スタティックプロパティ public static const定数名 = 値; public static $変数名; //スタティックメソッド public static function メソッド名(){ } }クラス自身にプロパティやメソッドを付与することも可能。
生成するインスタンスが共通項として持つ物に関しては、こちらを利用する。クラスの継承
新たにクラスを作成する際、既存のクラスを再利用して作成ができる。
覚えること
・継承の仕方
・継承したメソッド、プロパティ、コンストラクタの利用方法
・継承したクラスの情報の上書き方法(オーバーライド)継承の仕方
継承の仕方.phpclaas 子クラス extends 親クラス{ } //新たに生成するクラス名が「子クラス」継承先のことを「親クラス」と呼ぶ継承したメソッド、プロパティ、コンストラクタの利用方法
継承したメソッド、プロパティ、コンストラクタの利用方法.php子クラス名 -> 継承されたメソッド名() //継承したメソッドの利用方法 子クラス名 -> プロパティ名 //継承したプロパティの利用方法 parent::__construct(引数); 処理 } //継承したコンストラクトの利用方法メソッドとプロパティは通常通り記述すれば問題なし。(継承はメソッドとプロパティのコードがコピーされていると認識すれば良い)
コンストラクトの場合のみ、parent::をつける。(継承したコンストラクトを使うのか子クラスにコンストラクトを付与したのかわかるようにするため)継承したクラスの情報の上書き方法(オーバーライド)
継承したプロパティやメソッドのデータを上書きすることができる。上書きする場合は、子クラスへ親クラスに存在するメソッドやプロパティと同じ名前でメソッドやプロパティを付与する。
トレイト
よくわかりません。
誰か教えてください。
- 投稿日:2020-06-23T00:44:54+09:00
【デザインパターン】PHPでTemplate Methodパターンの実装をしてみた
環境
- PHP 7.2.18
Template Methodパターンとは
Template とと言うのは、よくいろんな人が「テンプレ」などと略すアレです。
メールなどの定型文や、作品のベースとなるひな形などの「決まった様式」のことを指すことが多いですよね。
Template Methodパターンの名前の由来もそこからきていて、決まった処理の流れなどを抽象クラスで「枠」として定めて、具体的な実装の内容は具象クラスで実装するものとなります。Template Methodパターンは何がいいか
Template Methodパターンを使うことで、似たような処理、繰り返し使われるような処理を共通化することができます。
関数による処理の共通化をすることもあるとは思いますが、クラスでそれを行うのがTemplate Methodパターンといったところです。例題の概要
例として簡単なプログラムを作りました。
「鳥の情報を返す」テンプレートに対して、具体的な鳥のクラス(カラス,ペンギン,ダチョウ)を実装して処理を共通化させました。
最終的にそれぞれの鳥の情報を表に表示します。
イメージ図とクラス図です。イメージ図
クラス図
ファイル構成
ソースコード
https://github.com/nooboolean/template_method_practice
実装
まずは、テンプレートである抽象クラスの定義
今回の実装で共通となる処理は、それぞれのオブジェクト(鳥たち)の「種類」「名前」「出産方法」「移動手段」の情報をこの順番で返す処理です。
「種類」や「出産方法」などの、鳥であれば共通となる情報は、抽象クラスで実装してしまっています。
その他の鳥の種類ごとに変化する「名前」や「移動手段」に関しては、具体的な実装を具象クラスに任せています。AbstractBird.php<?php abstract class AbstractBird { private $birdInfo; final public function getInfo() { $this->birdInfo['type'] = $this->getType(); $this->birdInfo['name'] = $this->getName(); $this->birdInfo['birthType'] = $this->getBirthType(); $this->birdInfo['howToMovement'] = $this->gethowToMovement(); return $this->birdInfo; } final private function getType() { return '鳥類'; } protected abstract function getName(); final private function getBirthType() { return '卵生'; } protected abstract function gethowToMovement(); } ?>この後は、この抽象クラスを継承した具象クラスで具体的な実装をしていきます。
次は具象クラス(カラスクラスなど)の用意
抽象クラスである「鳥」クラスができたので、後はそれらの具体的な実装を書き込む「カラスクラス」などの具象クラスを作成していきます。
「名前」や「移動手段」などの、「鳥」の種類によってそれぞれ変わる情報は、それぞれの鳥の種類のクラスに実装します。
今回は、カラスクラス/ペンギンクラス/ダチョウクラスを作成しました。Crow.php<?php namespace Birds; require_once('./AbstractBird.php'); use AbstractBird; class Crow extends AbstractBird { final protected function getName() { return 'カラス '; } final protected function gethowToMovement() { return '飛ぶ'; } } ?>Penguin.php<?php namespace Birds; require_once('./AbstractBird.php'); use AbstractBird; class Penguin extends AbstractBird { final protected function getName() { return 'ペンギン'; } final protected function gethowToMovement() { return '泳ぐ'; } } ?>Ostrich.php<?php namespace Birds; require_once('./AbstractBird.php'); use AbstractBird; class Ostrich extends AbstractBird { final protected function getName() { return 'ダチョウ'; } final protected function gethowToMovement() { return '走る'; } } ?>あとは、この具象クラスを実際に
new
してデータを取得し表示して完了です!それぞれの具象クラスを実行して情報の表示
最後にそれぞれのクラスを
new
してデータを取得して表示します。
抽象クラスで処理を共通化しているため、同じ様な処理をこのようにシンプルに管理することができます。index.php<?php require_once('./Birds/Ostrich.php'); require_once('./Birds/Penguin.php'); require_once('./Birds/Crow.php'); use Birds\Ostrich; use Birds\Penguin; use Birds\Crow; $Ostrich = (new Ostrich)->getInfo(); $Penguin = (new Penguin)->getInfo(); $Crow = (new Crow)->getInfo(); ?> <?php echo "<table border = '1'>"; echo " <tr>"; echo " <th>種類</th>"; echo " <th>名前</th>"; echo " <th>出産方法</th>"; echo " <th>移動手段</th>"; echo " </tr>"; echo " <tr>"; echo " <th>$Ostrich[type]</th>"; echo " <th>$Ostrich[name]</th>"; echo " <th>$Ostrich[birthType]</th>"; echo " <th>$Ostrich[howToMovement]</th>"; echo " </tr>"; echo "</table>"; ?> <?php echo "<table border = '1'>"; echo " <tr>"; echo " <th>種類</th>"; echo " <th>名前</th>"; echo " <th>出産方法</th>"; echo " <th>移動手段</th>"; echo " </tr>"; echo " <tr>"; echo " <th>$Penguin[type]</th>"; echo " <th>$Penguin[name]</th>"; echo " <th>$Penguin[birthType]</th>"; echo " <th>$Penguin[howToMovement]</th>"; echo " </tr>"; echo "</table>"; ?> <?php echo "<table border = '1'>"; echo " <tr>"; echo " <th>種類</th>"; echo " <th>名前</th>"; echo " <th>出産方法</th>"; echo " <th>移動手段</th>"; echo " </tr>"; echo " <tr>"; echo " <th>$Crow[type]</th>"; echo " <th>$Crow[name]</th>"; echo " <th>$Crow[birthType]</th>"; echo " <th>$Crow[howToMovement]</th>"; echo " </tr>"; echo "</table>"; ?>ブラウザ確認
- 投稿日:2020-06-23T00:25:30+09:00
関数の中で関数を出力
関数の中で関数を出力
今回は勉強を進めているときに、疑問に思った
関数内での関数や変数の記述の仕方について発見があったので
書き留めておきますまずびっくりしたのが関数内で別の関数は出力できる!ということ
<?php $n = 2; function test($n) { return $n**2; } function hoge($n) { if(test($n) < 100) { //関数外定義 echo "100以下" . PHP_EOL; } echo "OK!!" . PHP_EOL; } hoge($n); //100以下 //OK!!過去の学習から関数内で定義した変数は関数内でしか使えない
関数外で定義した変数を使いたければ引数で渡せこれを学んだばかりの私は先入観から
「関数においても同じだろう」
このような安易な考えから
<?php $n = 2; function test($n) { return $n**2; } $fuga = test($n);//わざわざ変数に直す function hoge($fuga) { if(test($fuga) < 100) { echo "100以下" . PHP_EOL; } echo "OK!!" . PHP_EOL; } hoge($n); //100以下 //OK!!という風にかなり遠回りな記述をしていました。
そしてさらに驚いたのは、
<?php $n = 2; function hoge($n) { function test($n) {//関数内で関数定義 echo "2乗します" . PHP_EOL; return $n**2; } if(test($n) < 100) { echo "100以下" . PHP_EOL; } echo "OK!!" . PHP_EOL; } hoge($n); test($n);//関数外で出力 // 2乗します // 100以下 // OK!! // 2乗します関数の中で定義した別の関数が、関数の外で出力できることです。
もはや{}の囲いから外へ脱走しまくっていますw
用途は少なそうだが頭に入れておいて損はなさそうです。