Docker – PHP/Apache

手動でインストール

DockerのUbuntu+Apache環境にPHPをインストールする。

インストール中、タイムゾーンの選択を求められる。

インストール完了後、apache2をリスタート。

このあと/var/www/htmlに以下のような内容でphpinfo.phpファイルを作成。

ブラウザーからlocalhost:8080/phpinfo.phpにアクセスして以下のような内容を確認。

  • タイムゾーンはOSでAsia/Tokyoにしたが、PHPではUTCになっている
  • php.iniの場所が確認できる(/etc/php/8.1/apache2/php.ini)

DockerfileとComposeでインストール

手動でのインストールと同じ手順をDockerfileとComposeで管理する。

Dockerfileの内容は以下の通り。

  • aptでsystemctl, apache2, phpをインストール
  • apt-getでtzdataをインストール
  • /etc/timezoneに”Asia/Tokyo”を書き込む
  • dpkg-reconfigureでtzdataを再設定(noninteractiveで)

上記のDockerfileの内容でコンテナをビルド。

phpinfoのdateの項目中default timezoneがAsia/Tokyoになっているのが確認できる。

以下の内容でphp.iniをDokerfileと同じ場所に置き、DockerfileにADD ./php.ini /etc/php/8.1/apache2/php.iniを書くという方法も紹介されていたが、それがなくてもPHPのタイムゾーンは変更されていた。

ただしmbstringの方は今後設定が必要かもしれない。

 

PHP – json

概要

JSONの文字列が与えられたときの扱い。

  1. json_decodeで文字列をPHPの変数に変換
  2. json_encodeでPHPの変数を文字列に変換
    • このとき、JSON_UNESCAPED_UNICODEJSON_PRETTY_PRINTのフラグを立てる

json_decode

json_decode関数は、引数で与えられたJSON文字列をPHPの変数に変換する。

JSONのキーや単体の要素はstringに、{ ... }stdClassのオブジェクトに変換され、キー=>値がオブジェクトのプロパティーとなっている。

json_encode

そのままエンコードした場合

json_encodeは、PHPの変数で表現されたJSONコードを文字列に変換する。

ただしこのとき、ユニコードはエスケープされ、改行を含まない文字列となる。

オプションフラグの設定

以下の2つのフラグをセットする。

JSON_UNESCAPED_UNICODE
ユニコード文字をエスケープせずに扱う。
JSON_PRETTY_PRINT
JSONの構造に即した改行・インデントを適用する。

これによって、ユニコード文字列はエスケープされず、JSONの構造に即した改行・インデントが適用された文字列が得られる。

 

PHP – Pythonのzip()

Pythonのzip()関数は、複数のコレクションの要素をパラレルに取り出すことができる。

PHPでは、array_map()関数を使って同様のことができる。

以下はコードで確認した例。

これをforeachに入れて各要素を配列で受け取れば、複数配列の要素をパラレルに得ることができる。

 

さくらサーバー – Laravel~インストール

概要

さくらレンタルサーバーのスタンダードプランを利用していて、そこにLaravelをインストールしてみた記録。以下の2つの方法を試してみた。

  • composerをドキュメントルートに配置し、ドキュメントルート下にプロジェクトを作成
  • composerをドキュメントルートと別の場所に配置し、ドキュメントルート下で公開

ローカルで開発したプロジェクトをデプロイする手順はこちら

ドキュメントルートへのインストール

composerのインストール

ssh接続後~/www(ドキュメントルート)に移動し、composer.pharをダウンロード。

インストール確認。

プロジェクト作成

~/wwwディレクトリーでテスト用のプロジェクトを作成。

動作確認

welcomeページ

ブラウザーでURLを指定。

結果は以下のエラー。

Forbidden
You don’t have permission to access this resource.

 

URLを以下のように指定して、welcomeページが無事表示される。ドキュメントルート下にプロジェクトを配置すると、publicディレクトリー内が公開対象になる。

ルーティング

以下のルーティングで'Hello'が表示される。

コントローラー

TestControllerコントローラーを作成してアクションを定義し、その中で文字列を渡す。

ルーティングを以下のように変更。

これでブラウザーに'Hello!'と表示される。

ビュー

resource/viewsディレクトリーに以下のビューファイルtest.blade.phpを作成。

TestControllerを以下のように修正。

これでブラウザーにアクセスすると、タブのタイトルが'Laravel Test'となり、h1要素のフォントで'Hello from blade!'と表示される。

別ディレクトリーへのインストール

composerのインストール

ドキュメントルート下にプロジェクトを配置するのは気持ち悪いので、別に配置する。ここではユーザーホーム下のディレクトリーに配置してみる。ライブラリーを加えていないので、インストールはcomposer.pharを移動して配置するのみ。

まずcomposer_testディレクトリーを作ってその下にcomposer.pharを移動。また、先にドキュメントルートに作ったプロジェクトを削除しておく。

移動先でcomposerの動作確認。

プロジェクトの作成

composer_testディレクトリー下に先と同じ手順でプロジェクトを作成。

公開ディレクトリーへのシンボリックリンク

公開ディレクトリー以外に配置したプロジェクトは、クライアントからは認識されない。そこでプロジェクトのpublicディレクトリーのシンボリックリンクをドキュメントルート下に作成する。

ここではシンボリックリンク名をプロジェクト名と同じ名前にして、~/wwwディレクトリー下に作成。

この状態で以下のURLを指定するとwelcomeページが表示される。

コントローラー・ビュー

新しいプロジェクトでTestControllerコントローラーを作成。

ビューを呼び出すアクションを定義。

ルーティングを定義。

resources/views/ディレクトリーにtest.blade.phpファイルを以下の内容で作成。

これでブラウザーにアクセスすると、タブのタイトルが'Laravel Test'となり、h1要素のフォントで'Hello from blade!'と表示される。

Laravelのバージョン指定

composerでプロジェクトを作成するときにLaravelのバージョン指定が可能だが、さくらサーバーでワイルドカードを使うとうまくいかない。

以下のようにワイルドカードを指定しない方法だと、無事にプロジェクトが作成される。

バージョン確認。

プロジェクトの設定

タイムゾーンとロケールをconfig/app.phpファイルで設定。

データベースはさくらサーバーの設定に従って、.envファイルで設定。DB_HOSTはmysql5.7アップグレード後の場合、phpMyAdminなどで使われるサーバー名。

 

Laravel – Collection – 先頭・末尾などの例外処理

コールバックを用いるメソッドで、コールバック内で先頭要素や末尾要素に応じた処理をしたい場合、クロージャ―のuseを使う。ただしこの方法は、全要素に対して先頭・末尾などの判定処理が行われる。

以下の例ではコレクションの要素を並べた1つの文字列を返すが、文字列の最初に'('、最後に')'を付加し、要素間には','を置いている。

要点は以下のとおり。

  • クロージャ―のuseで呼び出し元のコレクションインスタンスを指定
  • クロージャ―内でコレクションインスタンスの先頭要素/末尾要素に等しいかどうかを判定し、それらに応じた処理を実行

 

Laravel – Collection – グルーピングと集計

概要

LaravelCollectionには、count()sum()などの集計用メソッドが準備されている。groupBy()メソッドも準備されているが、これはグルーピングされたキー列の値で配列をまとめるだけなので、直接groupBy()の結果をcount()などに適用することはできない。

たとえば以下のようなコレクションがあって、

groupBy()によってgenderでグルーピングすると以下のようなコレクションが得られる。

この結果を単にcount()メソッドに渡すと、malefemaleの2つのグループあることから、グループ数に対応する'2'が返される。

これを、male/female各グループの要素数をカウントしたり、グループごとの身長の集計値を出したりするようにしたい。

map()メソッドの利用したグループ処理

map()メソッドはコールバックを引数にとり、そのコールバックの引数には元のコレクションの各要素が順次与えられる。

たとえば先のグルーピングの結果をmap()メソッドに渡すと、2つの要素malefemale(その中身は連想配列の配列)が順次与えられる。これらグループ化された配列に対して、Collectionの集計メソッドを使うことができる。

この場合、グループ化された1つ目のグループの各要素に関する処理、2つ目のグループの各要素に関する処理・・・と実行される。

集計例

count()の例

性別ごとの人数をカウントする例。

average()の例

性別ごとの平均身長を計算する例。

 

 

Laravel – Collection – コールバックによる操作

概要

Collectionには引数にコールバックをとるメソッドが準備されている。これらはコレクションの各要素にコールバックで定義された処理をし、その結果に応じて要素の絞り込み、各要素への処理の適用、各要素を用いた縮退処理を行う。

いずれも元のコレクションは変更されず、戻り値として新たなコレクションやオブジェクト、変数などが返される。

単純配列型に対するメソッド

filter()~条件に合う要素の絞り込み

filter()は、設定した条件により元のコレクションの要素の一部を取り出す。

  • filter()のコールバックは、各要素に対応する引数を1つ撮る
  • コールバックの戻り値は、受け取った要素に対する条件の評価結果(true/false)
  • filter()の戻り値として、元のコレクションのうち条件に合致する要素だけが残ったコレクションが返される

以下の例は、奇数要素のみを取り出す例。

基数要素だけが残ったコレクションが得られる。

以下は4未満の要素のみを残す例。

4未満の要素のみが残っている。

reject()~条件に合わない要素の絞り込み

reject()filter()の逆で、条件に合う要素を取り除いた残りのコレクションを返す。

以下は奇数要素のみを取り除く例。

奇数要素が除かれ、偶数要素のみが残っている。

map()~各要素への処理のマッピング

map()は設定した処理を元のコレクションの全要素に適用する。

  • map()のコールバックは、各要素に対応する引数を1つ撮る
  • コールバックの戻り値は、処理の結果更新される各要素の値
  • map()の戻り値として、元のコレクションの各要素にコールバックの処理が適用されたコレクションが返される

以下はコレクションの各要素を10倍する例。

元の要素が10倍された結果になっている。

reduce()~縮退処理

ここでいう縮退とは、各要素やその加工結果を1つの結果にまとめ込んでいくものとする。

例として「コレクションの各要素の値の合計を求める」という処理の場合、「合計値」という結果に要素ごとの値を「足し込む」という処理になる。

このためreuce()filter()map()と以下の2点で異なる。

  • コールバックの引数は縮退の途中結果とその時点での要素の2つの引数をとる
  • reduce()自身が上記のコールバックと縮退処理の初期値の2つの引数をとる

コールバックについては以下のとおり。

  • reduce()のコールバックは、各時点までに蓄積された処理結果(たとえば$carry)と、その時点で処理される要素(たとえば$element)の2つの引数をとる
  • コールバックの戻り値は、受け取った$carryに対して$elementに関して処理された新たな$carryの内容
  • 最終的なreduce()の戻り値として、$carryの縮退結果が返される

以下はコレクションの各要素の和を求める例で、縮退の初期値を0としてreduce()の第2引数で与え、第1引数のコールバックでは$carryに各要素の値を足し込んでいる。

結果は1~5までの和になる。

以下は初期値を0→900に変更した例。

初期値0ではなく900に対する足し込みとなっている。

また次の例では、要素の値を文字列として後ろにつなげていく。初期値には空文字列''を指定している。

結果は以下のように、値がつなげられた文字列になる。

連想配列への適用

以下の連想配列を使う。

filter()

連想配列のコレクションにフィルターを適用する場合。

ただしこれはwhere()による操作で代替できる。

map()

連想配列のコレクションにmap()を適用した例。genderキー列の値に応じて内容を書き換えている('male''m''female''f')。

また以下の例では、groupBy()でグルーピングされたコレクションに対してmap()を適用し、グループごとの要素数をカウントしている(グルーピングと集計参照)。

reduce()

以下は連想配列のコレクションに対してreduce()を適用して、要素のheightキー列の値の二乗和を求め、その結果から分散を計算している。

なおコールバックにuseを使い、処理中の要素がコレクションの末尾要素のときに、集計結果を使った計算をさせ、reduce()の結果が直接分散となるようにもできる。

 

Laravel – Collection – 基本操作

概要

コレクションは配列と同じように要素の集合体だが、細やかな操作・集計などのメソッドを備えている。

コレクションの作成~collect()ヘルパー

collect()ヘルパーの引数に配列を入れて、Collectionのインスタンスを得られる。

与えるのは連想配列でもよい。

値の参照

ブラケット([])による参照

以下のような連想配列を準備する。

配列のインデックスや連想配列のキーを指定するのと同じようにして、ブラケット([])で要素を参照できる。

get()メソッドによる参照

ブラケットの代わりにget()メソッドを用いても要素を参照できる。

random()~ランダムに1つ取り出す

random()メソッドを呼び出すたびに、コレクションの要素がランダムに1つ返される。

first()/last()

first()メソッド/last()メソッドは、コレクションの先頭要素/末尾要素を返す。

値のセット

ブラケット([])によるセット

配列や連想配列と同じように、インデックスやキーを指定して値をセットできる。

put()メソッドによるセット

put(index/key, value)でも指定したインデックス/キーの要素の値をセットできる。

空のコレクションと要素の追加

空のコレクションの生成

collect()メソッドの引数を省略すると、空のCollectionインスタンスが生成される。

ブラケット([])による追加

存在しないインデックスやキーを指定して値をセットすると、新たに要素が追加される。

ブラケットでキーを指定しないと、末尾にデータが追加される。

put()メソッドによる追加

put(index/key, value)でも要素を追加できる。

値の引き抜き

pull()メソッドは、指定したインデックス/キーの要素をコレクションから抜き取る。その要素はコレクションから削除され、戻り値として返される。

以下の例では、pull()メソッドで2つの要素を抜き取っている。

スタック

Collectionにはpush()メソッドとpop()メソッドが準備されていて、コレクションをスタックのように扱える。以下のデータで確認する。

push()メソッド

push()メソッドは、引数で指定した値をコレクションの末尾に追加する。

2つ以上の引数を指定してもエラーにはならないが、1つ目の引数の値のみが使われてプッシュされる。

pop()メソッド

pop()メソッドは、コレクションの末尾から要素を抜き取り、戻り値として返す。

空かどうかの確認

isEmpty()/isNotEmpty()は、コレクションが空か/空でないかを確認して結果をtrue/falseで返す。

nullの場合はCollectionのインスタンスではないので、これらのメソッドの結果はエラーになる。

コレクションから配列への変換

toArray()メソッドは、コレクションの内容を配列として返す。toArray()のほかall()メソッドでも同じ結果が得られる。

 

Laravel – Collection – 集計・加工

集計

コレクションの要素の個数、合計値、平均などを求めるメソッドが準備されている。これらのメソッドは、コレクションの要素に基づいた処理結果を1つの数値として返す。

クエリービルダーのメソッドでも書いたが、データベースに対するクエリーに関するメソッドというよりも、Collectionの要素を集計するメソッドととらえた方がよい。

以下の2つのコレクション$c$pで確認する。

count()~要素数

コレクションの要素の数を返す。引数を指定しても無視される。

max()/min()~最大値・最小値

コレクションの要素の最大値/最小値を返す。

連想配列を要素とする配列の場合は、キーを指定してその値の最小値/最大値を取得できる。値が文字列を含む場合、辞書順での最小値/最大値となる。

連想配列で引数を指定しないと、最初のキー列の値で判定され、その値を持つ要素が連想配列として返される。

sum()/average()/avg()~合計値・平均値

コレクションの要素の合計値/平均値を返す。

連想配列の場合は、集計するキー列を指定する。引数を指定しないとエラー、文字列を値に含むキーを指定すると警告が出て結果は0になる。

並べ替え

コレクションの要素を並べ替え、結果のコレクションを返す。元のコレクションは影響を受けない。

reverse()~逆順に並べる

reverse()メソッドは、元のコレクションの要素を逆順にしたコレクションを返す。引数を指定しても無視される。

shuffle()~シャッフル

shuffle()メソッドは、元のコレクションの要素の値をシャッフルしたコレクションを返す。

sort()~昇順ソート

sort()メソッドは元のコレクションの値の昇順で要素を並べ替える

連想配列型でも使えるが、引数を指定するとエラーになる。引数なしで呼ぶと、1つ目のキー列の内容でソートされる。

sortBy()~引数キーの昇順

sortBy()メソッドは引数にキーを指定して、そのキーの値の昇順で要素を並べ替えたコレクションを返す。

以下の例ではnameを指定して名前の昇順で並べ替えている。文字列は辞書順でソートされる。

以下の例ではheightを指定して並べ替えている。身長の数値が昇順となるように並んでいる。

sortByDesc()~引数キーの降順

sortByDesc()メソッドは引数にキーを指定して、そのキーの値の降順で要素を並べ替えたコレクションを返す。

以下の例では、身長の高い順に並べ替えている。

コレクションの変形・取出し

pluck()~キー列の取出し

pluck()メソッドは引数にキーを指定し、そのキーの値を単純配列のコレクションとして取り出す。pluckは英語で「摘む」という意味。

以下はgenderキーの値を取り出している例。

flatten()~コレクションの展開

flatten()メソッドは、多次元配列型のコレクションの要素を再帰的にたどって1次元の配列型に並べる。

連想配列はキーが無視され、値が使われる。

多次元配列の場合、再帰的に要素をたどって1次元化する。

SQL的処理

クエリービルダーメソッドと同等のwhere()groupBy()がある。ただしこれらのメソッドは、クエリービルダーの様にはクエリーを生成はしない。

where()~条件による抽出

where()メソッドはクエリービルダーメソッドのwhere()と同じ。

groupBy()~キーによるグルーピング

groupBy()メソッドは、指定したキー列の値で要素をグルーピングする。

  • 元の配列の要素として、指定したキー列の値をキーとした配列ができる
  • その配列の要素として、各キーに対応した値を持つ元の要素が格納される

以下の例ではgenderキーによってグルーピングしている。genderキーの値malefemaleをキーとする配列が作られ、キーがmaleの配列にはgendermaleの要素、キーがfemaleの配列にはgenderfemaleの要素が格納されている。

 

Laravel – Collection

クエリービルダーget()メソッドの結果、Eloquent\Collectionのインスタンスが得られるが、これはSupport\Collectionを継承している。

ここではSupport\Collectionの操作方法を整理する。

基本操作

  • コレクションの作成や要素の参照・追加などの基本操作
  • スタックのような操作、空かどうかの判定、配列への変換操作も含む

集計・加工

  • 要素数のカウントや最小値・最大値の取得、合計・平均の計算
  • 各種並べ替え
  • キーの抜き出し、一次元展開
  • where、groupBy
  • グループ化された結果の集計については一工夫必要

コールバックによる操作

  • filterによる要素の条件抽出
  • mapによる各要素に対する処理定義
  • reduceによるコレクション→スカラー値への縮退処理
  • useによる元のコレクションの参照