PHP – 多次元連想配列のソート

概要

キー列が同じ連想配列を要素とする配列の要素を特定のキーに従ってソートするには、以下のようにarray_column()array_multisort()を使う。

問題

以下のような配列があり、この配列の要素をnameageなどで並べ替える方法。

array_multisort()を使う

array_multisort()は第1引数指定した1次元配列の順番に従って、第3引数の配列の要素をソートする。第2引数にはソートの昇順/降順を指定する。

たとえば以下の例では、2つの要素を持つ連想配列の配列を並べ替えている。

この例の流れは以下のとおり。

  • 第1引数の配列[3, 2, 1]の各要素が$aの各要素に対応している
  • 第2引数で昇順(SORT_ASC)を指定
  • 第3引数の配列がこれに従って並べ替えられ、内容が変更される

なお第1引数と第3引数の次数が等しくない場合はWarningとなり、第3引数の配列は変更されずに処理が進む。

また、第1引数の配列の要素が文字列の場合は辞書順で並べ替えられる。

array_column()

array_multisort()の第1引数に第3引数のあるキー列を選べば、そのキー列に従って並べ替えられる。

問題の配列の'age'のキー列は以下のとおり。

手順

このキー列の値の昇順で元の配列を並べ替えるには、第1引数に上のarray_culumn()を適用すると、'age'の昇順で配列が並べ替えられる。

降順に並べ替えたいときはSORT_DESCを指定する。

 

PHP – Pythonのzip()

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

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

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

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

 

HTML – input – file

基本形

ファイルアップロードは、FORM要素とINPUT要素のそれぞれで属性の設定が必要。

FORM要素は以下のように記述する。

  • methodPOST
  • enctype属性に"multipart/form-data"を設定する

INPUT要素は以下のように記述する。

  • type属性を"file"に設定する
  • methodPOST
  • name属性を設定する
    • この属性値で言語やフレームワークによってファイルを扱う
    • 以下の例ではname属性値を"file"としている

この場合の動作は以下のとおり。

  • "ファイルを選択"ボタンを押すとダイアログがファイル選択ダイアログが表示される
  • 一度に1つのファイルを選択できる
  • ファイルを選択して"開く"ボタンを押すとファイルがアップロードされる

複数ファイルの選択

基本形ではダイアログで1つのファイルしか選択できない。複数ファイルを選択・アップロードできるようにするには、INPUT要素を以下のように記述する。FORM要素に変更はない。

  • type属性を"file"に設定する
  • methodPOST
  • name属性の値の末尾に[]を付けて配列にする
    • 以下の例ではname属性値を"files[]"としている
  • multiple属性を追加

これによってファイル選択ダイアログで複数のファイルが選択・送信できるようになる。

 

さくらサーバー – Laravel~デプロイ

概要

ローカルで開発したLaravelのプロジェクトを、さくらのレンタルサーバーにデプロイした時の記録。

  • ローカルで
    • CentOS7~Laravel~MySQLで開発
    • 必要に応じてデータベースのダンプファイルも含める
    • GitHubのリポジトリーに登録
  • さくらサーバーにssh接続
    • 秘密鍵と公開鍵をさくらサーバーにコピー
    • GitHubのリポジトリーをclone
    • 必要に応じてデータベースのダンプファイルから復帰
    • Laravelのpublicディレクトリーのシンボリックリンクを公開ディレクトリーに作成

躓いたのは以下の点

  • ssh鍵ファイルのパーミッション設定
  • login/registerのパス設定

Laravelを直接さくらサーバー上でインストールする手順はこちら

ローカルでの開発

プロジェクトの開発

通常の方法によって、ローカル環境でLaravelプロジェクトを開発。このとき、さくらのサーバー上で利用可能なPHP/Laravel/MySQLのバージョンを確認しておく。

データベースのダンプ

開発中にデータベースの実データを扱っている場合は、データベースの内容をダンプファイルに出力しておく

今回はリポジトリーのディレクトリーにダンプファイルを保存して、GitHub経由で共有した。

GitHubへのpush

ローカルの開発結果をコミットしてGitHubへpush。以下の手順によった。

  1. git add -f .venderディレクトリーなども含めてステージング
  2. git commit -mでコミット
  3. git pushでGitHubのリポジトリーに反映

ローカルでの状況は以下のとおり。

  • プロジェクトの配置→.../laravel/PROJECT/
  • ローカルサーバー→PROJECT/下でサーバーを起動
  • ローカルでのアクセス→localhost:3000/
  • GitHubのリポジトリー→laravelディレクトリー以下

さくらサーバーでのデプロイ

ssh接続の準備

GitHubとSSHでやり取りする準備。

  •  秘密鍵(id_rsa)と公開鍵(id_rsa.pub)をさくらサーバーにアップロード
    • アップロード先は~/.ssh/ディレクトリー
    • .ssh/ディレクトリは既に存在していて、パーミッションは700
  • アップロードした2つの鍵ファイルのパーミッションを600に変更する必要がある

ssh鍵でのエラー

当初、鍵ファイルのパーミッションが他者から読み取り可能のままになっていて接続できなかった。

2つの鍵のパーミッションを600に変更して解決。

プロジェクトの配置計画

さくらサーバーでの配置計画は以下のようにした。

  • プロジェクト本体は公開領域以外に置く
  • 公開領域にプロジェクトのpublicディレクトリーのシンボリックリンクを置く
  • シンボリックリンクの名前をプロジェクト名にする

これによって、”サイト名/プロジェクト名“というURLをアプリケーションのメインページとすることができる。

プロジェクトのダウンロード

GitHubのリポジトリーをさくらサーバーのユーザーホームディレクトリー下でclone。

故人開発であり、git pull/pushにするとサーバー側での.envの編集などの本質でない操作などが反映されてしまうので、ローカル側で編集したプロジェクトをさくらサーバー上でcloneするのがよいと考えた。

.envファイルの編集

さくら側のMySQLに接続するため、.envファイルの以下を変更。

  • MYSQL_HOSTはさくらのMySQLホスト名
    • mysql**.ユーザー名.sakura.ne.jpなど
  • DB_NAMEはさくら上でのDB名
    • ユーザー名_任意のDB名など
  • USER/PASSはMySQLに接続するためのユーザー名とパスワード

publicディレクトリーのシンボリックリンク

非公開に置いたプロジェクトのうち、公開対象のpublicディレクトリーのシンボリックリンクを公開領域(~/www)に作成する。リンク名はプロジェクト名と同じにした。

ログイン・サインアップできない

Laravelでの症状

当初プロジェクトをさくらサーバーに配置したとき、以下のような状況になった。

  • 非認証時のメインページや説明ページなどは表示・遷移できる
  • ログインやサインアップのフォームページも表示される
  • ログインページで入力後にボタンを押すと、WordPressのログイン画面に遷移してしまう
  • サインアップページで入力後にボタンを押すとWordPressの「ページが見つかりませんでした」表示

元々ドメイン直下ではWordPressが実行されるようになっていて、サブディレクトリーでLaravelを動かそうとしてこのような状況になった。

URL指定による同じ状況の再現

LoginController/RegisterControllerredirectToを変えたり、ルーティングファイルやindex.phpを触ったりしてみたが、状況は変わらず。その中で、以下のことに気づく。

  • URLで直接http://DOMAIN.com/loginを指定すると、WordPressのログイン画面に遷移する
  • URLで直接http://DOMAIN.com/registerを指定すると、WordPressの「ページが見つかりませんでした」表示

原因特定

Laravelではいずれもボタンを押した後に上と同じ状況になることに気づき、login.blade.phpregister.blade.phpを見てみると、POSTを発しているform要素のaction"/login""/register"を直に書いていた。

これらをルート名で"{{ route('login') }}""{{  route('register') }}"に変更したところ、正常にログインとサインアップができるようになった。これらのルート名は、Auth::routes()で設定自動的に設定されるので、artisanで確認。

考えてみれば至極当然の挙動で、ローカルと本番で配置形態が変わる場合に備えて徹底的にroute()を使うのがよさそう。

 

さくらサーバー – 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などで使われるサーバー名。