処理の流れ (1/5 全5パターン) | ユーザ登録機能作成処理の流れ サブメニュー
2017年11月25日 公開
2021年03月09日 更新
- チェックポイント | オブジェクト指向 参照← ポイント
- アカウント登録画面 (ユーザ登録画面) http://mini-blog.localhost/account/signupリンク アカウント登録, リンク 新規ユーザ登録
- 画面 参照テストデータ 参照
- 未ログイン
- index.php1require'../bootstrap.php'オートロード 設定チェックポイント | ClassLoader 参照← ポイント 動画 (YouTube)パーフェクトPHP をデバッグしました (デバッグ例 基本編) オートロード 参照
- bootstrap2require'core/ClassLoader.php'
- bootstrap2newClassLoader$loader = new ClassLoader()
- bootstrap2$loader->registerDir(dirname(__FILE__).'/core')
- ClassLoader (core)3registerDir'/core'
- bootstrap2$loader->registerDir(dirname(__FILE__).'/models')
- ClassLoader (core)3registerDir'/models'
- bootstrap2$loader->register()
- ClassLoader (core)3register
- spl_autoload_registerClassLoader'loadClass'loadClass と extends, new の関係↓
- index.php1require'../MiniBlogApplication.php'
- class MiniBlogApplication extends ApplicationApplication.php は require されていませんloadClass を実行後 extends (以下同)
- ClassLoader (core)2loadClass'Application'
- ClassLoader (core)3require'Application.php'
- index.php1newMiniBlogApplication$app = new MiniBlogApplication(false)
- Application (core)2__construct
- Application (core)3setDebugMode
- Application (core)3initialize
- Application (core)4newRequestMiniBlogApplication->request = RequestRequest.php は require されていませんloadClass を実行後 new (以下同)
- ClassLoader (core)5loadClass'Request'
- ClassLoader (core)6require'Request.php'
- Application (core)4newResponseMiniBlogApplication->response = Response
- ClassLoader (core)5loadClass'Response'
- ClassLoader (core)6require'Response.php'
- Application (core)4newSessionMiniBlogApplication->session = Session
- ClassLoader (core)5loadClass'Session'
- ClassLoader (core)6require'Session.php'
- Session (core)5__construct$sessionStarted false$sessionIdRegenerated false
- session_start()$sessionStarted trueチェックポイント | Session 参照
- Application (core)4newDbManagerMiniBlogApplication->db_manager = DbManager
- ClassLoader (core)5loadClass'DbManager'
- ClassLoader (core)6require'DbManager.php'
- Application (core)4newRouter$this->registerRoutes()MiniBlogApplication->router = Router
- ClassLoader (core)5loadClass'Router'
- ClassLoader (core)6require'Router.php'
- MiniBlogApplication7registerRoutes
- Router (core)5__construct
- Router (core)6compileRoutesチェックポイント | Router 参照← ポイント 動画 (YouTube)パーフェクトPHP をデバッグしました (デバッグ例 応用編) ルーティング 参照
- Application (core)3configure
- MiniBlogApplication4configure
- DbManager (core)5connect'master'$params['dsn'], $params['user'], $params['password'], $params['options']チェックポイント | DbManager 参照
- $con = new PDO'mysql:dbname=mini_blog;host=localhost;charset=utf8', 'root', '', ''上記 $params
- $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)PDO の内部でエラーが起きた場合に例外を発生させる
- DbManager->connections['master'] = $con
- index.php1run$app->run()
- Application (core)2run
- $params = $this->router->resolve($this->request->getPathInfo())詳細↓
- Request (core)3getPathInfo'/account/signup'チェックポイント | Request 参照
- Request (core)4getBaseUrl
- Request (core)5getRequestUri
- Request (core)4getRequestUri
- Router (core)3resolve'account', 'signup'$params['controller'], $params['action']チェックポイント | Router 参照← ポイント 動画 (YouTube)パーフェクトPHP をデバッグしました (デバッグ例 応用編) ルーティング 参照
- Application (core)3runAction'account', 'signup'
- Application (core)4findController!class_exists'AccountController'
- ClassLoader (core)5loadClass'AccountController'require'AccountController.php'/core /models
- Application (core)5getControllerDir
- MiniBlogApplication6getRootDir
- Application (core)5require_once'AccountController.php'/controllersチェックポイント | Application 参照
- class AccountController extends Controller
- ClassLoader (core)6loadClass'Controller'
- ClassLoader (core)7require'Controller.php'
- return new $controller_class($this)new 変数 使用詳細↓
- Application (core)5new$controller_class = 'AccountController'MiniBlogApplication
- Controller (core)6__constructMiniBlogApplicationチェックポイント | Controller 参照
- Application (core)7getRequest
- Application (core)7getResponse
- Application (core)7getSession
- Application (core)7getDbManager
- $content = $controller->run($action, $params)詳細↓
- Controller (core)4run(AccountController)'account', 'signup''signupAction'
- needsAuthentication($action) && isAuthenticated()否定ログイン 無詳細↓
- $auth_actions = array('index', 'signout', 'follow') (AccountController.php 10行目)
- Controller (core)5needsAuthentication'signup'falseログイン不要isAuthenticated 未処理 (ログイン中/未ログイン チェックしない)
- 処理の開始 ~ アクション開始↘ の直前まで処理の流れは コントローラとアクション以外は ほぼ同じですログイン画面への遷移 のみ、例外処理が追加されます
- $content = $this->$action_method($params) 可変関数$content = AccountController->signupAction()
- AccountController5signupActionアクション開始
- Session (core)6isAuthenticated
- Session (core)7get'_authenticated'false未ログインtrue ログイン中 redirect('/account')
- return $this->render(array(... $this->generateCsrfToken ...)詳細↓
- Controller (core)6generateCsrfToken'account/signup''_token'ユーザ登録 http://mini-blog.localhost/account/register checkCsrfTokenチェックポイント | Controller 参照 動画 (YouTube)パーフェクトPHP をデバッグしました (デバッグ例 応用編) CSRF対策 参照
- Session (core)7get'csrf_tokens/account/signup'チェックポイント | Session 参照
- Session (core)7set'csrf_tokens/account/signup'
- Controller (core)6render$layout = 'layout'$variables['user_name'], $variables['password'], $variables['_token']
- Request (core)7getBaseUrl
- Request (core)8getRequestUri
- Controller (core)7newView
- ClassLoader (core)8loadClass'View'
- ClassLoader (core)9requireView.php'
- Application (core)8getViewDir
- MiniBlogApplication9getRootDir
- View (core)8__construct$base_dir, $defaults
- View (core)7renderaccount/signup$_layout = 'layout'実行順1チェックポイント | View (HTML構成) 参照← ポイント 動画 (YouTube)パーフェクトPHP をデバッグしました (デバッグ例 応用編) アウトプットバッファリング 参照
- extract(array_merge($this->defaults, $_variables))View->defaults['base_url']$_variables['_token']$_variables['user_name']$_variables['password']
- View (core)8require'/views/account/signup.php'$base_url, $_token, $user_name, $password
- View (core)9setLayoutVar'title', 'アカウント登録'
- View (core)9'_token'hidden
- View (core)9escape
- View (signup.php)9renderaccount/inputs$_layout = false実行順2render in signup.php
- extract(array_merge($this->defaults, $_variables))$_variables['user_name']$_variables['password']
- View (core)10require'/views/account/inputs.php'$user_name, $password
- View (core)11escape
- $content = ob_get_clean()出力順1inputs.php
- View (signup.php)9renderreturn $content出力順1
- $content = ob_get_clean()出力順2signup.php + inputs.php
- if ($_layout) {$_layout = 'layout'
- $content = $this->render($_layout, array_merge($this->layout_variables, array('_content' => $content,)))
- View (core)8renderlayout$_layout = false実行順3render in render
- extract(array_merge($this->defaults, $_variables))$_variables['title']View->defaults['base_url']View->defaults['session']$_variables['_content']
- View (core)9require'/views/layout.php'$title, $base_url, $session, $_content
- View (core)10escape
- Session (core)10isAuthenticated
- Session (core)11get'_authenticated'false
- layout10echo $_contentsignup.php + inputs.php出力順2
- $content = ob_get_clean()出力順3layout.php + signup.php + inputs.php
- View (core)8renderreturn $content出力順3
- }
- View (core)7renderreturn $content出力順3
- Controller (core)6renderreturn View->render(...)
- AccountController5signupActionreturn AccountController->render(...)アクション終了
- Controller (core)4runreturn $content
- Response (core)4setContentResponse->content = $content
- Application (core)3runAction
- Response (core)3sendecho Response->content
- Application (core)2run
- DbManager (core)2__destruct
- ユーザ登録 http://mini-blog.localhost/account/register登録 ボタン
- 画面 参照テストデータ 参照
- ユーザID: user4、パスワード: password で登録
- index.php1require'../bootstrap.php'オートロード 設定以下 省略アカウント登録画面 (ユーザ登録画面) 参照
- index.php1require'../MiniBlogApplication.php'以下 省略
- index.php1newMiniBlogApplication$app = new MiniBlogApplication(false)以下 省略
- index.php1run$app->run()
- Application (core)2run
- $params = $this->router->resolve($this->request->getPathInfo())詳細↓
- Request (core)3getPathInfo'/account/register'チェックポイント | Request 参照
- Request (core)4getBaseUrl
- Request (core)5getRequestUri
- Request (core)4getRequestUri
- Router (core)3resolve'account', 'register'$params['controller'], $params['action']チェックポイント | Router 参照← ポイント
- Application (core)3runAction'account', 'register'
- Application (core)4findController!class_exists'AccountController'
- ClassLoader (core)5loadClass'AccountController'require'AccountController.php'/core /models
- Application (core)5getControllerDir
- MiniBlogApplication6getRootDir
- Application (core)5require_once'AccountController.php'/controllersチェックポイント | Application 参照
- class AccountController extends Controller
- ClassLoader (core)6loadClass'Controller'
- ClassLoader (core)7require'Controller.php'
- return new $controller_class($this)new 変数 使用詳細↓
- Application (core)5new$controller_class = 'AccountController'MiniBlogApplication
- Controller (core)6__constructMiniBlogApplicationチェックポイント | Controller 参照
- Application (core)7getRequest
- Application (core)7getResponse
- Application (core)7getSession
- Application (core)7getDbManager
- $content = $controller->run($action, $params)詳細↓
- Controller (core)4run(AccountController)'account', 'register''registerAction'
- needsAuthentication($action) && isAuthenticated()否定ログイン 無詳細↓
- $auth_actions = array('index', 'signout', 'follow') (AccountController.php 10行目)
- Controller (core)5needsAuthentication'register'falseログイン不要isAuthenticated 未処理 (ログイン中/未ログイン チェックしない)
- 処理の開始 ~ アクション開始↘ の直前まで処理の流れは コントローラとアクション以外は ほぼ同じですログイン画面への遷移 のみ、例外処理が追加されます
- $content = $this->$action_method($params) 可変関数$content = AccountController->registerAction()
- AccountController5registerActionアクション開始
- Session (core)6isAuthenticated
- Session (core)7get'_authenticated'false未ログインtrue ログイン中 redirect('/account')
- Request (core)6isPosttruePOSTfalse POSTでない forward404()
- Request (core)6getPost'_token'アカウント登録画面 (ユーザ登録画面) http://mini-blog.localhost/account/signup generateCsrfTokenチェックポイント | Request 参照
- Controller (core)6checkCsrfToken'account/signup'trueトークン有false トークン無 redirect('/account/signup')チェックポイント | Controller 参照 動画 (YouTube)パーフェクトPHP をデバッグしました (デバッグ例 応用編) CSRF対策 参照
- Session (core)7get'csrf_tokens/account/signup'チェックポイント | Session 参照
- Session (core)7set'csrf_tokens/account/signup'
- Request (core)6getPost'user4'$user_name
- Request (core)6getPost'password'$password
- $this->db_manager->get('User')->isUniqueUserName($user_name)詳細↓
- DbManager (core)6get'User'get('User') 1回目UserRepository
- DbManager (core)7getConnectionForRepository'User'DbManager->repository_connection_map['User']
- DbManager (core)8getConnection
- DbManager (core)8getConnectionreturn current(DbManager->connections)DbManager->connections['master'] = $con↙
- DbManager (core)7getConnectionForRepositoryreturn $con
- $repository = new $repository_class($con)new 変数 使用詳細↓
- DbManager (core)7new$repository_class = 'UserRepository'$con
- ClassLoader (core)8loadClass'UserRepository'
- ClassLoader (core)9require'UserRepository.php'
- class UserRepository extends DbRepository
- ClassLoader (core)10loadClass'DbRepository'
- ClassLoader (core)11require'DbRepository.php'
- DbRepository (core)8__construct'$con'
- DbRepository (core)9setConnectionUserRepository->con = $con↗
- DbManager (core)6getDbManager->repositories['User']=>UserRepository
- DbManager (core)6getreturn DbManager->repositories['User']
- UserRepository6isUniqueUserName'user4'$user_nametrue重複無false 重複有テストデータ 参照SQL 参照
- DbRepository (core)7fetch'user4'チェックポイント | DbRepository 参照
- DbRepository (core)8execute
- UserRepository6isUniqueUserName
- エラー無 開始if (count($errors) === 0)
- $this->db_manager->get('User')->insert($user_name, $password)詳細↓
- DbManager (core)6get'User'get('User') 2回目以降UserRepository
- DbManager (core)6getreturn DbManager->repositories['User']
- UserRepository6insert'user4', 'password'$user_name, $passwordSQL 参照
- UserRepository7hashPassword'password'
- DbRepository (core)7executeチェックポイント | DbRepository 参照
- UserRepository6insert
- Session (core)6setAuthenticatedtrue
- Session (core)7set'_authenticated'trueログイン中
- Session (core)7regeneratetrueセッション固定攻撃対策 (ログイン状態の変更)
- Session (core)7regeneratesession_regenerate_id (true)セッションID を新しく発行$sessionIdRegenerated trueチェックポイント | Session 参照
- $user = $this->db_manager->get('User')->fetchByUserName($user_name)詳細↓
- DbManager (core)6get'User'get('User') 2回目以降UserRepository
- DbManager (core)6getreturn DbManager->repositories['User']
- UserRepository6fetchByUserName'user4'$user_name'user4' 1レコードSQL 参照
- DbRepository (core)7fetchチェックポイント | DbRepository 参照
- DbRepository (core)8execute
- UserRepository6fetchByUserName
- Session (core)6set'user'$user'user4' 1レコード (ログインユーザ)
- Controller (core)6redirect'/'
- Request (core)7isSslfalse
- Request (core)7getHost
- Request (core)7getBaseUrl
- Request (core)8getRequestUri
- $urlhttp://mini-blog.localhost/
- Response (core)7setStatusCode
- Response (core)7setHttpHeader
- Controller (core)6redirect
- エラー無 終了
- エラー有 開始
- return $this->render(array(... $this->generateCsrfToken ...), ), 'signup')詳細↓
- Controller (core)6generateCsrfToken'account/signup''_token'ユーザ登録 http://mini-blog.localhost/account/register checkCsrfTokenチェックポイント | Controller 参照
- Session (core)7get'csrf_tokens/account/signup'チェックポイント | Session 参照
- Session (core)7set'csrf_tokens/account/signup'
- Controller (core)6render$template = 'signup' (エラー有)$layout = 'layout'$variables['user_name'], $variables['password'], $variables['errors'], $variables['_token']
- Request (core)7getBaseUrl
- Request (core)8getRequestUri
- Controller (core)7newView
- ClassLoader (core)8loadClass'View'
- ClassLoader (core)9requireView.php'
- Application (core)8getViewDir
- MiniBlogApplication9getRootDir
- View (core)8__construct$base_dir, $defaults
- $path = $this->controller_name . '/' . $templateaccount/signup
- View (core)7renderaccount/signup$_layout = 'layout'$path実行順1チェックポイント | View (HTML構成) 参照← ポイント
- extract(array_merge($this->defaults, $_variables))View->defaults['base_url']$_variables['_token']$_variables['errors']$_variables['user_name']$_variables['password']
- View (core)8require'/views/account/signup.php'$base_url, $_token, $errors, $user_name, $password
- View (core)9setLayoutVar'title', 'アカウント登録'
- View (core)9'_token'hidden
- View (core)9escape
- View (signup.php)9rendererrors$_layout = false実行順2 (エラー)render in signup.php
- extract(array_merge($this->defaults, $_variables))$_variables['errors']
- View (core)10require'/views/errors.php'$errors
- View (core)11escape
- $content = ob_get_clean()出力順1errors.php
- View (signup.php)9renderreturn $content出力順1
- View (signup.php)9renderaccount/inputs$_layout = false実行順3render in signup.php
- extract(array_merge($this->defaults, $_variables))$_variables['user_name']$_variables['password']
- View (core)10require'/views/account/inputs.php'$user_name, $password
- View (core)11escape
- $content = ob_get_clean()出力順2inputs.php
- View (signup.php)9renderreturn $content出力順2
- $content = ob_get_clean()出力順3signup.php + errors.php + inputs.php
- if ($_layout) {$_layout = 'layout'
- $content = $this->render($_layout, array_merge($this->layout_variables, array('_content' => $content,)))
- View (core)8renderlayout$_layout = false実行順4render in render
- extract(array_merge($this->defaults, $_variables))$_variables['title']View->defaults['base_url']View->defaults['session']$_variables['_content']
- View (core)9require'/views/layout.php'$title, $base_url, $session, $_content
- View (core)10escape
- Session (core)10isAuthenticated
- Session (core)11get'_authenticated'false
- layout10echo $_contentsignup.php + errors.php + inputs.php出力順3
- $content = ob_get_clean()出力順4layout.php + signup.php + errors.php + inputs.php
- View (core)8renderreturn $content出力順4
- }
- View (core)7renderreturn $content出力順4
- Controller (core)6renderreturn View->render(...)
- エラー有 終了
- AccountController5registerActionreturn AccountController->...アクション終了
- Controller (core)4runreturn $contentエラー無の時 $content: null
- Response (core)4setContentResponse->content = $content
- Application (core)3runAction
- Response (core)3sendecho Response->content
- Application (core)2run
- DbManager (core)2__destruct
注 $this の表示
例 $this->request → MiniBlogApplication->request
SQL
SQL チェック (phpMyAdmin, SQL タブ 選択) http://localhost/phpmyadmin/db_sql.php?db=mini_blog
isUniqueUserName
SELECT COUNT(id) as count FROM user WHERE user_name = '
user4'
count | 0 |
insert
INSERT INTO user(user_name, password, created_at)
VALUES('user4', 'ee5281d035bd1bd7786301be4274a68b006ae916', '2017-11-01 00:00:00')
id | user_name | password | created_at |
---|---|---|---|
4 | user4 | ee5281d035bd1bd7786301be4274a68b006ae916 | 2017-11-01 00:00:00 |
fetchByUserName
SELECT * FROM user WHERE user_name = '
user4'
id | user_name | password | created_at |
---|---|---|---|
4 | user4 | ee5281d035bd1bd7786301be4274a68b006ae916 | 2017-11-01 00:00:00 |
Mini Blog Application
アカウント登録画面 (ユーザ登録画面)
作成手順 | クラス | |
---|---|---|
データベース | ||
ルーティング | MiniBlogApplication | '/account/:action' => array('controller' => 'account') |
コントローラ | AccountController | signupAction |
ビューファイル | account/signup.php account/inputs.php (in account/signup.php) |
機能 | クラス | メソッド |
---|---|---|
チェック | Session | isAuthenticated() ログイン状態 チェック |
データ設定 | Controller | generateCsrfToken('account/signup') render引数 |
データ取得 | ||
データ出力 | ||
画面 | Controller | redirect('/account') アカウント情報トップ (ログイン済 エラー) |
Controller | render(...) 登録画面 (未ログイン) |
ユーザ登録
作成手順 | クラス | |
---|---|---|
データベース | UserRepository | isUniqueUserName insert (hashPassword) fetchByUserName |
ルーティング | MiniBlogApplication | '/account/:action' => array('controller' => 'account') |
コントローラ | AccountController | registerAction |
ビューファイル |
機能 | クラス | メソッド |
---|---|---|
チェック | Session | isAuthenticated() ログイン状態 チェック (開始時 未ログイン) |
Request | isPost POST チェック | |
Controller | checkCsrfToken('account/signup', $token) トークン チェック | |
UserRepository | isUniqueUserName($user_name) ユーザ名 重複チェック ('user4', バリデーション内) |
|
- | バリデーション (エラー カウント) | |
データ設定 | Session | setAuthenticated(true) ログイン済 (登録時) |
Session | set('user', $user) ログインユーザ ('user4' 1レコード) (登録時) | |
Controller | generateCsrfToken('account/signup') render引数 (バリデーション エラー) | |
データ取得 | Request |
getPost('_token') '117d0e6d9da8ec9e595110d7e517993901ee77ce' getPost('user_name') 'user4' getPost('password') 'password' |
DbManager | get('User') UserRepository | |
UserRepository | fetchByUserName($user_name) 'user4' 1レコード | |
データ出力 | UserRepository | insert($user_name, $password) 'user4', 'password' (登録時) |
画面 | Controller |
redirect('/account') アカウント情報トップ (ログイン済 エラー) redirect('/account/signup') 登録画面 (トークン エラー) redirect('/') ホームページ (登録後, 'user4' のホーム) |
Controller | forward404() 404エラー画面 (POST エラー) | |
Controller | render(...) 再度 登録画面 (バリデーション エラー) |
ユーザID: user4、パスワード: password で登録