パーフェクトPHP デバッグ (フレームワーク サンプルコード)

処理の流れ (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

アカウント登録画面 (ユーザ登録画面)

http://mini-blog.localhost/account/signup
作成手順 クラス
データベース
ルーティング MiniBlogApplication '/account/:action'
  => array('controller' => 'account')
コントローラ AccountController signupAction
ビューファイル account/signup.php
account/inputs.php (in account/signup.php)
AccountController   signupAction
機能 クラス メソッド
チェック Session isAuthenticated() ログイン状態 チェック
データ設定 Controller generateCsrfToken('account/signup') render引数
データ取得
データ出力
画面 Controller redirect('/account') アカウント情報トップ (ログイン済 エラー)
Controller render(...) 登録画面 (未ログイン)

ユーザ登録

http://mini-blog.localhost/account/register
作成手順 クラス
データベース UserRepository isUniqueUserName
insert
  (hashPassword)
fetchByUserName
ルーティング MiniBlogApplication '/account/:action'
  => array('controller' => 'account')
コントローラ AccountController registerAction
ビューファイル
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 で登録

アカウント登録画面 (ユーザ登録画面)

Page Top
Page Bottom