はじめに
Step1
ログイン画面の作成

今回は、共通のIDとパスワードではなく、ユーザー毎にIDとパスワードを登録してもらいそのアカウントでログイン
してもらう形にしようと思います。
ということで、「Visual Studio Code」のファイルメニューから「新しいテキストファイル」を選択します。

まずは、データベースに接続する際の、データベース名、ユーザー名、パスワード等を定義する用のファイルを作成します。
これをしておけば、実際に運用するデータベースに移行する際にこのページだけ変更すれば良いことになります。
なので、他のファイルからわざと切り離します。
ということで、「名前を付けて保存」をします。ファイル名は「env.php」とします。
あとおいさんの都合で「lf_transfer」というファルダを作成してその中に保存します。

このファイルでのコードは簡素で、画像のとおりになります。
ここでは、「define」という定数を定義する命令文を用いてデータベース名等を定義します。
この命令文の良いところはプログラムのどこからでも呼び出せるグローバルな定義ができることです。
以上で、このファイルでの作業は完了になります。
データベース側にさきほど設定したデータベース名やユーザーを登録します。
ただし、いきなり運用するサーバーで設定するのは憚れるので、「MAMP」の仮想サーバーに設定します。
「MAMP」のことがわからない方は「Day2」を参照ください。
ということで、「MAMP」を起動します。

「Open WebStart page」を押します。


「TOOLS」の「PHPMYADMIN」を選択します。

「New」を選択します。

今回データベース名は「flft」とします。入力後、「Creat」ボタンを押し確定します。

テーブル名を決めます。今回は「usertb」とします。またColumn数は3とします。
これは、id、id名及びパスワードの3項目をデータベースに保存したいためです。

画像のとおり入力し、「Save」ボタンを押します。

もう一度「New」ボタンを押します。

「Check privileges」を押します。

「Add user account」を押します。

画像のように入力して、「Go」ボタンを押します。これでデータベース側の作業は完了になります。

次は実際にデータベースに接続する機能を備えたファイルを作成します。 「新しいテキストファイル」を選択します。

名前を「dbconnect.php」として保存します。

「require_once」でファイル「env.php」を呼び出します。
またエラー表示してもらえるように「display_errors」を「true」にしておきます。
データベースとの接続用のメソッドは「connect」とし、この中に接続するコードを書いていきます。

データベースに接続するためのSQL文を設定し、変数「$dsn」に格納します。
ここでポートの設定(8889)をしていますが、通常はいらないみたいです。おいさんの場合はこれを設定しないと
エラーがでてしまうのでやむなく設定しております。

画像は実際にデータベースに接続するコードになります。
中身は今一つわかりません。こういう書き方だという理解でお願いします。
これで、データベースに接続するファイルの作業はすべて完了になります。

データベースに接続する準備ができたので、次はデータベースに何のデータを入れるかを命令するファイルを作成します。
「新しいテキストファイル」を選択します。

名前を「userlogic.php」として保存します。

「dbconnect.php」を一度読み込みます。
次に「UserLogic」という名前のクラスを設定します。ちなみにクラスなので名前はなんでも良いのです。

まずは、ログインしているかの確認するメソッドを作成します。
メソッド名は「checkLogin」とします。また、メソッドを定義する場合、その情報を書き込んだほうが良いらしく、
メソッドの上に表示するようです。今回は、引数がなくログインしているかしていないかで、「true」か「false」を
返す関数になります。
なので、画像のような書き方になります。ちなみに「@param」に引数の情報(変数の型と変数名)を書き、「@return」に
返り値(変数の型と変数名)を書くようです。

メソッド内にコードを追記します。ここでは、連想配列「$_SESSION」の中の「login_user」キーに値がなければ
「false」を返すコードになります。
ここで、いきなり「$_SESSION」という変数(配列)が登場していますが、まずはこれが何かについて説明します。
そもそもPHPでのWebアプリケーションには、それ自体に保存機能を有していなかったようです。そのため今回のように
ログインしたかどうかの情報を保持することができなかったようです。そこで、一次的な情報を格納できるよう「$_SESSION」という
スーパーグローバル変数ができたようです。
今回はこの変数に「login_user」キーが設定されているかを利用しているコードになります。
ここで一旦このファイルの作業は完了とします。

ここからやっとログイン画面を作成していきます。
「新しいテキストファイル」を選択します。

ファイル名は「login_form.php」とします。

「!」→「Tab」キーを押してhtmlのベースコードを表示させます。
また、タイトルを「ログイン画面」とします。

css文を追記して、スタイルを指定します。

css文の続きになります。これでcss文は完了になります。

「body」タグ内にログイン画面を作成していきます。
「form」タグでユーザーIDとパスワードを入力できるようにします。

ブラウザを起動して実行した画面になります。シンプルですがログイン画面になっています。
この時点でIDとパスワードを持っていない場合は、一番下の「新規登録はこちら」ボタンを押していただくことなります。

ファイル上部にphp文を差し込みます。
まずは、「session_start();」というコードを追記します。
これは、以前触れた「$_SESSION」をこのファイルで有効にするコードになります。
最後に、「userlogic.php」を一度読み込みます。

ブラウザを起動して実行した画面になります。シンプルですがログイン画面になっています。
この時点でIDとパスワードを持っていない場合は、一番下の「新規登録はこちら」ボタンを押していただくことなります。

ファイル上部にphp文を差し込みます。
まずは、「session_start();」というコードを追記します。
これは、以前触れた「$_SESSION」をこのファイルで有効にするコードになります。
最後に、「userlogic.php」を一度読み込みます。

通常別クラスのメソッドを使用する場合、インスタンスをして使用できるようにしますが、画像のようなコードでもメソッドを
使用でるようです。
今回は、「checkLogin」メソッドを使用しログイン確認ができていれば、「mypage.php」ファイルへ遷移するようなコードになります。

「mypage.php」ファイルへ遷移せず、下の行へプログラムが流れてきた場合は何かしらのエラーを抱えていることになります。
なのでるので、変数「$err」にその内容を格納しておきます。
格納が終われば一度セッションを止めるようにしています。

エラー内容は知りたいので表示できるようにしておきます。
これで、このファイルでの作業はすべて完了になります。

このファイルでの遷移先は「signup_form.php」、「login.php」及び「mypage.php」の3ファイルになります。
どれから作成してもよいのですが、まずは新規登録機能から実装使用と思います。
「新しいテキストファイル」を選択します。

名前を「signup_form.php」として保存します。

「!」→「Tab」キーを押してhtmlのベースコードを表示させます。
また、タイトルを「ユーザー登録画面」とします。

css文でスタイルの設定をします。

続きになります。

「body」タグ内にコードを追加していきます。
ここでは新規登録になりますので、IDとパスワードを入力できる画面構成にします。
入力したデータは「POST」形式で「register.php」ファイルに送るようにします。

ブラウザで画面を確認してみます。まあシンプルですが機能としては十分と思います。

ログイン済みかの確認のため、PHP文を差し込みます。
コードは画像のとおりになります。

追加したコードの1行目は、三項演算子という書き方になります。内容としては、「$_SESSION['login_err']」に値が存在すれば
その値を、値が存在しなければNullを返すコードにしています。
今回はその返り値を変数「$login_err」に格納し、その後「$_SESSION['login_err']」の値を消すようにしています。

ここからは、セキュリティ上の対策を2つしようと思います。
そのコードは別ファイルで関数化することにしますので、「新しいテキストファイル」を選択します。

名前を「function.php」として保存します。

一つ目のセキュリティ対策は、クロスサイトスクリプティング(xss)攻撃の対策になります。どんな攻撃かよく理解できませんが、
とりあえずエスケープ処理というものを実行すれば良いようです。
コードとしては簡単で画像のとおり、対象の文字に「htmlspecialchars」をかぶせれば良いようです。

二つ目のセキュリティ対策は、クロスサイトリクエストフォージェリ(CSRF)攻撃の対策になります。
こちらは、正規ユーザーを装ってサーバに偽のリクエストを送信し、意図しない行動を取らせる攻撃ということのようです。
この攻撃を防ぐためにワンタイムトークンなるものを採用するようです。
これは、まずページを表示する前にランダムな文字(トークン)を生成し、ユーザーセッションに保存します。今回はこれを
「functions.php」で行います。その後、今回の場合「signup_form.php」で生成したトークンを「hidden」形式で送ります。
リクエスト先(register.php)でその送信されたトークンとセッションに保存されたトークンと一致すれば処理を続けるという
仕組みのようです。
兎にも角にも、この画像ではトークンの生成とそれをセッションに保存する処理を関数化しています。

「signup_form.php」ファイルにも戻ります。そのファイル内で「functions.php」の関数を使用したいので、 一度読み込みます。

画像のとおりのコードを追加し「hidden」形式で他のデータとともに、「register.php」に送ります。

受け取り先の「register.php」ファイルを作成します。
このファイルでは、IDとパスワードを保存する処理を行います。
「新しいテキストファイル」を選択します。

何度も出ていますが名前を「register.php」として保存します。

コードを入力する前に一度「userlogic.php」に移動し、新規保存のメソッドを作成します。 「userlogic.php」に移動し、「createUser」メソッドを準備します。

画像はメソッド内のコードになります。今回は新規に保存なのでSQL文は「INSERT INTO」になります。
また安全対策としてパスワードをハッシュ化しています。これは、アルゴリズムより、適当な文字に置き換えて元のデータを
自分や他の人が推測できなくするようです。
なのでデータベースのパスワードの項目はよくわからない文字が羅列している値が保存されている状態になります。
これで、「userlogic.php」ファイルでの作業は終了になります。

「register.php」ファイルに戻ります。
まずはトークンが一致するか確認します。コードは画像のとおりになります。

次は入力されたデータの確認(バリデーション)を行います。
送られてきたデータは、「filter_input」で受け取るようにします。

バリデーションでエラーが無ければ、先ほど作った新規保存メソッドを利用してデータベースに保存します。

html分部を作成していきます。
「!」→「Tab」キーを押してhtmlのベースコードを表示させます。

css文によりスタイルを設定します。

続きになります。

エラーがあれば表示するようにします。
もしなければ「ユーザー登録が完了しました」を表示するようにします。
これで、このファイル他、「signup_form.php」からの一連の作業が完了になります。

まだ何もしていない残りのファイルは、「login.php」及び「mypage.php」になります。
ここからは、先に「login.php」から作成していきます。
「新しいテキストファイル」を選択します。

名前を「login.php」として保存します。

このファイルでは、「login_form.php」から送られてきたidとパスワードがデータベースに登録されているか
確認するものになります。
まずは、送られてきたデータのバリデーションを行います。コードは画像のとおりになります。

エラーがあった場合表示するようにします。

まだ、UserLogicクラスにloginメソッドを作成していないですが、あるものとして実行処理をします。
これにより、アカウントをもっているユーザーかどうか確認できるようになります。

html分部を作成していきます。「!」→「Tab」キーを押してhtmlのベースコードを表示させます。

css文でスタイルの設定をします。

続きになります。

画像は「body」タグ部分になります。これでこのファイルの作業は完了になりますが、「userlogic.php」ファイルにメソッドを 作成することを残しているのでそちらをしていきます。

「userlogic.php」ファイルに移動し、loginメソッドを作成します。
引数は、ID名とパスワードになります。

次にID名から関連するデータを取得する処理をしますが、これは別メソッドで実行するようにします。

etUserByIdnameメソッドを作成します。単純にID名からデータを取得するコードになります。

要求したデータを取得できましたので、パスワードの照合を行います。
ここで、「password_verify」はユーザーが入力したパスワードと、データベースに保存されているハッシュ化された
パスワードを比較し、一致するかを確認するために使用される命令文のようです。
一致した場合、「session_regenerate_id(true)」で古いセッションIDを無効化させるようです。ここは理解できていません。
ともかく画像のとおりのコードで作業は完了になります。
Step2
マイページの作成1

最後に残しておいた「mypage.php」ファイルを作成します。このページはすでにログインできているページになりますので、
ここからが本来達成したい機能(ファイル転送システム)を実装する作業になります。
「新しいテキストファイル」を選択します。

名前を「mypage.php」として保存します。

ログインの確認をしておきます。ログインできていれば、変数「$login_user」にID名を格納します。

「!」→「Tab」キーを押してhtmlのベースコードを表示させます。

phpファイルの保存先に、新たに「uploads」ファルダを作成します。
このフォルダの中に転送したいファイルを保存するようにします。

先ほど作ったファルダの下層にログイン名ごとにファルダを確保しようと思います。
また、その上の行の変数名を変更します。(意味はないです。名前が気に食わないだけです)

はじめはログイン名のフォルダが存在しないので、「mkdir」でフォルダを作成します。

ブラウザで実行し、フォルダが作成されているか確認してみます。
画像がその結果です。無事ログイン名のフォルダが作成されています。

メインページの画面を作成していきます。
何はなくともファイルをアップロードできる機能が必要になりますので、まずはそのコードを追加します。
追加する場所は「body」タグ内になります。

ブラウザで起動して確認してみます。画像がその結果になります。
今回は、cssを後回しにして先に機能の実装を優先することにします。

ファイルのアップロードの入力画面は作成しましたので、そのデータを受け取り保存するコードを追記します。
コードは画像のとおりになります。

画面に保存されたファイルを表示するため、保存されたフォルダ・ファイル群を取得します。
取得方法は、「scandir」関数で可能になります。取得したフォルダ・ファイル群(配列)は変数「$files」に格納します。

保存されているフォルダ・ファイル群を表示させます。「ul」タグで表形式とし、各行にファイル名とダウンロード及び削除を実行 するファイルへのリンクを「a」タグで遷移するようにしています。また、リンク先のパスの後に「?」を付け、キーと値(file=ファイル名) を送るようにしています。これで受け取る側でファイル名を取得できるようにしておきます。
Step3
削除ファイルの作成1

アップロードされたファイルを削除する機能を実装します。
「新しいテキストファイル」を選択します。

名前を「delete.php」にして保存します。

最初の部分は「mypage.php」ファイルと同様になります。

削除の情報は「mypage.php」ファイルから「file=ファイル名」で送られてきますのでそれを「$_GET」で受け取ります。
今回は、合体演算子(??)を使用しています。これは、「$_GET['file']」がnullの場合、空文字('')を代入する命令文になります。

実際に削除を実行する処理をします。「unlink」でファイルは削除できるようです。
これで、「delete.php」の作業は完了になります。
Step4
ログアウトファイルの作成

ログアウト機能を実装します。
「新しいテキストファイル」を選択します。

名前を「logout.php」として保存します。

コードは画像のとおり簡素になります。これで、このファイルでの作業は完了になります。
Step5
CSSを追加する

css文でスタイルの設定をします。今は何も設定していないので画像のような画面の状態になります。

今回は、htmlファイルに直接css文を書き込まずに、別ファイルで作成することにします。
「新しいテキストファイル」を選択します。

名前を「style.css」として保存します。

css文のコードになります。内容は割愛します。

続きになります。

最後になります。これでcssファイルでの作業は完了になります。
Step6
マイページの作成2

「mypage.php」ファイルにcssを反映させます。まずは、cssファイルを指定します。
コードは画像のとおりになります。

適宜cssの設定をしていきます。

画像はcssを導入した画面になります。少し見栄えがよくなったような気がします。
Step7
フォルダ作成機能

ファイルマネージャー的な画面構成を目指しているので、やはりフォルダは作成できるようにしておきたい。
なので、その機能を実装しようと思います。「新しいテキストファイル」を選択します。

名前を「create_folder.php」として保存します。

これまでどおり、はじめは「mypage.php」のコードと同様になります。

フォルダを作成するコードになります。フォルダ名はPOST形成で送られてきた「folder_name」に格納されている値になります。
また、2行目の「trim」関数は先頭や末尾の空白等(空白文字、改行、タブ)を取り除く関数になります。
これで、受け側のファイルはすべて完了になりますので、次は入力側(mypage.php)にコードを追加していきます。
Step8
マイページの作成3

「mypage.php」ファイルに移動します。
フォルダ名を入力できる画面を作成します。コードは画像のとおりになります。

フォルダ名を表示できるようにします。
コードは画像のとおりになります。

ファイル表示の方ですが、このままのコードだとフォルダ名も表示されてしまいます。
なので、ファイルであれば表示するというコードに変更します。

画像は現段階までの画面になります。ここで「aaa」というフォルダをとりあえず作っていますが、 仮にこの「aaa」フォルダをクリックすると「folder="aaa"」という情報が再度このページ送られる コードになっています。これを利用して次に「aaa」フォルダに移動するコードを作成していきます。

送られた「folder="aaa"」から現在のディレクトリは「aaa」とわかるようにします。
まず、「folder="aaa"」のフォルダ名「aaa」をPOST形式で受け取ります。
その後、変数「$target_dir」に現在のディレクトリの場所を格納します。
最後にそのディレクトリ内のファイルのみを表示するようにパスを変更します。

再度ブラウザで画面を確認します。画面は「aaa」フォルダに移動したときの状況になります。
「aaa」のフォルダ内にはファイルをアップロードしていないので何も表示されないことがわかると思います。

フォルダ表示は完了しましたが、今のコードのままでは指定したフォルダ内にファイルをアップロードできません。
なのでコードを変更します。まず入力側のコードを変更します。変更内容は画像のとおりになります。

アップロードのコードに2行コードを追加します。これで指定したフォルダ内に保存ができるようになるはずです。

「delete.php」ファイルも変更する必要があります。まず送る側の情報量が足りないので追加します。
パスの情報を送りたいので「&path=パス名」を追加します。
Step9
削除ファイルの作成2

送られた情報を元に、「delete.php」のコードを変更します。
まずGETで「path」を受け取り、そのパス名で「unlink」を実行します。
Step10
マイページの作成4

「mypage.php」ファイルに戻ります。
現段階の機能では、ファイルを1つ1つアップロードする方法しかありません。
それは不便なので、まとめてアップロードできる機能を追加したいと思います。
まずは、入力側ですが必要ないですが「name」を変えてみました。

アップロードのコードを大幅に変更します。おいさんもここはコピペしてきた箇所なので中身が理解できていません。
それでもこれで複数のファイルをまとめてアップロードできるようになりました。
Step11
ダウンロードファイルの作成

やっとここまで来ました。ダウンロード機能を追加します。
「新しいテキストファイル」を選択します。

名前を「download.php」として保存します。

ファイルの先頭はいつもどおりログイン処理をします。

コードを追加します。ここもコピペの箇所で中身がよくわかっていません。でもダウンロードできました。
これで、このファイルでの作業はすべて完了になります。
Step12
マイページの作成5

ダウンロード機能を追加しましたが、1つ1つダウンロードするのでは大変なのでフォルダごとにダウンロードできるようにしていきます。
ということで「mypage.php」ファイルに戻ります。
入力箇所にコードを1行追加します。これで、まだ作っていない「download_folder.php」ファイルに遷移するようにします。
Step13
ZIP形成でダウンロードするファイルの作成

「download_folder.php」ファイルを作成します。
「新しいテキストファイル」を選択します。

当然、ファイル名は「download_folder.php」として保存します。

いつものログイン処理をします。

まずは、フォルダ名を取得し、そこまでのパスを変数「$folder_path」に格納します。

ここからはまったくわからないコードになります。それでも圧縮しダウンロードできました。
ただ、パスの数分フォルダが作成されており随分奥にファイルが格納されてしまっています。
コピペであるため解消しようにもできない状況です。なのでこのままになります。

ブラウザで一度確認してみます。現段階では画像の状態まで作りこみができています。
Step14
マイページの作成6

フォルダごとのダウンロード機能を追加しましたが、フォルダの削除機能を追加していません。
ということで「mypage.php」ファイルに戻り削除ができるようにします。
入力箇所にコードを1行追加します。これで、まだ作っていない「delete_folder.php」ファイルに遷移するようにします。
Step15
フォルダを削除するファイルの作成

「delete_folder.php」ファイルを作成します。
「新しいテキストファイル」を選択します。

名前を「delete_folder.php」とし保存します。

27行目までは、「download_folder.php」のコードと同様になるのでそのままコピペします。

フォルダ削除の場合、そのフォルダ内にファイルが残っている可能性があるのでその対策として先に関数を作成しておきます。
この中身は得意のコピペなので理解できていません。特に関数の中に関数を使用するという高等テクニックが使用されています。

関数を実行するコードになります。これでこのファイルでの作業は完了になります。

完成形を確認します。画像がブラウザを起動して表示される画面になります。機能としては少ないですが随分コードは長くなりました。
レンタルサーバへの移設は「Day5」と同様ですので割愛します。
また、フォルダを作成する際、権限の指定がいるようで、「0777」を追加する必要があるようです。ダウンロードにあるファイルは追加しています。
大容量転送ファイルのシステムは無料で多く存在しているにもかかわらず、あえて作ろうと思うアホなおいさんです。
さらに虚しいのは、利用する人もいない状況の中、システム作成に挑戦することです。
唯一の利点は、保存期間に制限がないことぐらいです。