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

処理の流れ (3/5 全5パターン) | ユーザの投稿一覧と投稿詳細処理の流れ サブメニュー

2017年11月25日 公開

2021年04月16日 更新


  • チェックポイント | オブジェクト指向 参照← ポイント
  • 投稿一覧 http://mini-blog.localhost/user/user1リンク user1
  • 投稿一覧 http://mini-blog.localhost/user/user2リンク user2   動画 (YouTube)パーフェクトPHP をデバッグしました (デバッグ例 応用編) DbManagerクラス 参照
  • 投稿一覧 http://mini-blog.localhost/user/user3URL欄   動画 (YouTube)パーフェクトPHP をデバッグしました ('フォローする' ボタン を表示) 参照
  • 画面 参照テストデータ 参照
  • ユーザID: user1、パスワード: 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'/user/user1''/user/user2''/user/user3'チェックポイント | Request 参照
  • Request (core)4getBaseUrl
  • Request (core)5getRequestUri
  • Request (core)4getRequestUri
  • Router (core)3resolve'status', 'user'$params['controller'], $params['action']チェックポイント | Router 参照← ポイント $params['user_name']'user1''user2''user3'
  • Application (core)3runAction'status', 'user'$params['user_name']'user1''user2''user3'
  • Application (core)4findController!class_exists'StatusController'
  • ClassLoader (core)5loadClass'StatusController'require'StatusController.php'/core  /models
  • Application (core)5getControllerDir
  • MiniBlogApplication6getRootDir
  • Application (core)5require_once'StatusController.php'/controllersチェックポイント | Application 参照
  • class StatusController extends Controller
  • ClassLoader (core)6loadClass'Controller'
  • ClassLoader (core)7require'Controller.php'
  • return new $controller_class($this)new 変数 使用詳細↓
  • Application (core)5new$controller_class = 'StatusController'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(StatusController)'status', 'user''userAction'$params['user_name']'user1''user2''user3'
  • needsAuthentication($action) && isAuthenticated()否定ログイン 無詳細↓
  • $auth_actions = array('index', 'post') (StatusController.php 10行目)
  • Controller (core)5needsAuthentication'user'falseログイン不要isAuthenticated 未処理 (ログイン中/未ログイン チェックしない)
  • 処理の開始 ~ アクション開始↘ の直前まで処理の流れは コントローラアクション以外は ほぼ同じですログイン画面への遷移 のみ、例外処理が追加されます

  • $content = $this->$action_method($params) 可変関数$content = StatusController->userAction($params)
  • StatusController5userActionアクション開始引数有 $params$params['user_name']'user1''user2''user3'
  • $user = $this->db_manager->get('User')->fetchByUserName($params['user_name'])'user1', 'user2', 'user3' 1レコード詳細↓
  • 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']
  • UserRepository6fetchByUserName($params['user_name'])SQL 参照
  • DbRepository (core)7fetchチェックポイント | DbRepository 参照
  • DbRepository (core)8execute
  • UserRepository6fetchByUserName
  • if (!$user)ユーザ 無 forward404()
  • $statuses = $this->db_manager->get('Status')->fetchAllByUserId($user['id'])status1~status2, status3~status4, status5詳細↓
  • DbManager (core)6get'Status'get('Status') 1回目StatusRepository
  • DbManager (core)7getConnectionForRepository'Status'DbManager->repository_connection_map['Status']
  • 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 = 'StatusRepository'$con
  • ClassLoader (core)8loadClass'StatusRepository'DbRepository ロード済
  • ClassLoader (core)9require'StatusRepository.php'
  • DbRepository (core)8__construct'$con'
  • DbRepository (core)9setConnectionStatusRepository->con = $con
  • DbManager (core)6getDbManager->repositories['Status']=>StatusRepository
  • DbManager (core)6getreturn DbManager->repositories['Status']
  • StatusRepository6fetchAllByUserIdSQL 参照
  • DbRepository (core)7fetchAllチェックポイント | DbRepository 参照
  • DbRepository (core)8execute
  • StatusRepository6fetchAllByUserId
  • if ($this->session->isAuthenticated())ログイン中
  • Session (core)6isAuthenticated
  • Session (core)7get'_authenticated'trueログイン中
  • Session (core)6get$my'user1' 1レコード (ログインユーザ)
  • フォロー開始
  • 'user2' $following true'user3' $following false'user1' $following nullテストデータ 参照
  • $my['id']: 1, $user['id']: 2, 3
  • if ($my['id'] !== $user['id']) {
  • $following = $this->db_manager->get('Following')->isFollowing($my['id'], $user['id'])
  • }
  • $following = $this->db_manager->get('Following')->isFollowing($my['id'], $user['id'])詳細↓
  • DbManager (core)6get'Following'get('Following') 1回目FollowingRepository
  • DbManager (core)7getConnectionForRepository'Following'DbManager->repository_connection_map['Following']
  • 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 = 'FollowingRepository'$con
  • ClassLoader (core)8loadClass'FollowingRepository'DbRepository ロード済
  • ClassLoader (core)9require'FollowingRepository.php'
  • DbRepository (core)8__construct'$con'
  • DbRepository (core)9setConnectionFollowingRepository->con = $con
  • DbManager (core)6getDbManager->repositories['Following']=>FollowingRepository
  • DbManager (core)6getreturn DbManager->repositories['Following']
  • FollowingRepository6isFollowingSQL 参照
  • DbRepository (core)7fetchチェックポイント | DbRepository 参照
  • DbRepository (core)8execute
  • FollowingRepository6isFollowing
  • フォロー終了
  • if ($this->session->isAuthenticated()) 終了ログイン中
  • return $this->render(array(... $this->generateCsrfToken ...)$user$statuses$following詳細↓
  • Controller (core)6generateCsrfToken'account/follow''_token'フォロー処理 http://mini-blog.localhost/follow checkCsrfTokenチェックポイント | Controller 参照
  • Session (core)7get'csrf_tokens/account/follow'チェックポイント | Session 参照
  • Session (core)7set'csrf_tokens/account/follow'
  • Controller (core)6render$layout = 'layout'$variables['user'], $variables['statuses'], $variables['following'], $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)7renderstatus/user$_layout = 'layout'実行順1チェックポイント | View (HTML構成) 参照← ポイント
  • extract(array_merge($this->defaults, $_variables))$_variables['user']$_variables['following']View->defaults['base_url']$_variables['_token']$_variables['statuses']
  • View (core)8require'/views/status/user.php'$user, $following, $base_url, $_token, $statuses
  • View (core)9setLayoutVar'title', 'user1' or 'user2' or 'user3'
  • user.phpif (!is_null($following)):
  • 'user2' $following true'user3' $following false'user1' $following nullテストデータ 参照
  • user.phpif ($following):
  • 'user2' 'フォローしています'
  • user.phpelse:
  • 'user3' 'フォローする' ボタン 'user3' '_token' 'following_name'
  • View (core)11'_token'hidden
  • View (core)11'following_name'hidden
  • View (core)11escape
  • View (user.php)9renderstatus/status$_layout = false実行順2 foreach (投稿 status1~status2, status3~status4, status5)render in user.php
  • extract(array_merge($this->defaults, $_variables))View->defaults['base_url']$_variables['status']
  • View (core)10require'/views/status/status.php'$base_url, $status
  • View (core)11escape
  • $content = ob_get_clean()出力順1 複数回status.php
  • View (user.php)9renderreturn $content出力順1 複数回
  • $content = ob_get_clean()出力順2user.php + status.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'true
  • layout10echo $_contentuser.php + status.php 複数回出力順2
  • $content = ob_get_clean()出力順3layout.php + user.php + status.php 複数回
  • View (core)8renderreturn $content出力順3
  • }
  • View (core)7renderreturn $content出力順3
  • Controller (core)6renderreturn View->render(...)
  • StatusController5userActionreturn StatusController->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/user/user1/status/1リンク 2017-11-01 00:00:00
  • 画面 参照テストデータ 参照
  • ユーザID: user1、パスワード: 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'/user/user1/status/1チェックポイント | Request 参照
  • Request (core)4getBaseUrl
  • Request (core)5getRequestUri
  • Request (core)4getRequestUri
  • Router (core)3resolve'status', 'show'$params['controller'], $params['action']チェックポイント | Router 参照← ポイント$params['id']1$params['user_name']'user1'
  • Application (core)3runAction'status', 'show'$params['id']1$params['user_name']'user1'
  • Application (core)4findController!class_exists'StatusController'
  • ClassLoader (core)5loadClass'StatusController'require'StatusController.php'/core  /models
  • Application (core)5getControllerDir
  • MiniBlogApplication6getRootDir
  • Application (core)5require_once'StatusController.php'/controllersチェックポイント | Application 参照
  • class StatusController extends Controller
  • ClassLoader (core)6loadClass'Controller'
  • ClassLoader (core)7require'Controller.php'
  • return new $controller_class($this)new 変数 使用詳細↓
  • Application (core)5new$controller_class = 'StatusController'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(StatusController)'status', 'show''showAction'$params['id']1$params['user_name']'user1'
  • needsAuthentication($action) && isAuthenticated()否定ログイン 無詳細↓
  • $auth_actions = array('index', 'post') (StatusController.php 10行目)
  • Controller (core)5needsAuthentication'show'falseログイン不要isAuthenticated 未処理 (ログイン中/未ログイン チェックしない)
  • 処理の開始 ~ アクション開始↘ の直前まで処理の流れは コントローラアクション以外は ほぼ同じですログイン画面への遷移 のみ、例外処理が追加されます

  • $content = $this->$action_method($params) 可変関数$content = StatusController->showAction($params)
  • StatusController5showActionアクション開始引数有 $params$params['id']1$params['user_name']'user1'
  • $status = $this->db_manager->get('Status')->fetchByIdAndUserName($params['id'], $params['user_name'])詳細↓
  • DbManager (core)6get'Status'get('Status') 1回目StatusRepository
  • DbManager (core)7getConnectionForRepository'Status'DbManager->repository_connection_map['Status']
  • 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 = 'StatusRepository'$con
  • ClassLoader (core)8loadClass'StatusRepository'
  • ClassLoader (core)9require'StatusRepository.php'
  • class StatusRepository extends DbRepository
  • ClassLoader (core)10loadClass'DbRepository'
  • ClassLoader (core)11require'DbRepository.php'
  • DbRepository (core)8__construct'$con'
  • DbRepository (core)9setConnectionStatusRepository->con = $con
  • DbManager (core)6getDbManager->repositories['Status']=>StatusRepository
  • DbManager (core)6getreturn DbManager->repositories['Status']
  • StatusRepository6fetchByIdAndUserName($params['id'], $params['user_name'])1, 'user1'SQL 参照
  • DbRepository (core)7fetchチェックポイント | DbRepository 参照
  • DbRepository (core)8execute
  • Status Repository6fetchByIdAndUserName
  • if (!$status)投稿詳細 無 forward404()
  • Controller (core)6render$layout = 'layout'$variables['status']
  • 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)7renderstatus/show$_layout = 'layout'実行順1チェックポイント | View (HTML構成) 参照← ポイント
  • extract(array_merge($this->defaults, $_variables))$_variables['status']
  • View (core)8require'/views/status/show.php'$status
  • View (core)9setLayoutVar'title', 'user1'
  • View (show.php)9renderstatus/status$_layout = false実行順2 (投稿 status1)render in show.php
  • extract(array_merge($this->defaults, $_variables))View->defaults['base_url']$_variables['status']
  • View (core)10require'/views/status/status.php'$base_url, $status
  • View (core)11escape
  • $content = ob_get_clean()出力順1status.php
  • View (show.php)9renderreturn $content出力順1
  • $content = ob_get_clean()出力順2(show.php) + status.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'true
  • layout10echo $_content(show.php) + status.php出力順2
  • $content = ob_get_clean()出力順3layout.php + (show.php) + status.php
  • View (core)8renderreturn $content出力順3
  • }
  • View (core)7renderreturn $content出力順3
  • Controller (core)6renderreturn View->render(...)
  • StatusController5showActionreturn StatusController->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

$this の表示
$this->request  →  MiniBlogApplication->request



SQL

SQL チェック (phpMyAdmin, SQL タブ 選択)  http://localhost/phpmyadmin/db_sql.php?db=mini_blog

fetchByUserName

SELECT * FROM user WHERE user_name = 'user1'
id user_name password created_at
1 user1 ee5281d035bd1bd7786301be4274a68b006ae916 2017-11-01 00:00:00
SELECT * FROM user WHERE user_name = 'user2'
id user_name password created_at
2 user2 ee5281d035bd1bd7786301be4274a68b006ae916 2017-11-01 00:00:00
SELECT * FROM user WHERE user_name = 'user3'
id user_name password created_at
3 user3 ee5281d035bd1bd7786301be4274a68b006ae916 2017-11-01 00:00:00

fetchAllByUserId

SELECT a.*, u.user_name
    FROM status a
        LEFT JOIN user u ON a.user_id = u.id
    WHERE u.id = 1
    ORDER BY a.created_at DESC
a.id a.user_id a.body a.created_at u.user_name
1 1 status1 user1 テスト1 2017-11-01 00:00:00 user1
2 1 status2 user1 テスト2 2017-11-01 00:00:00 user1
SELECT a.*, u.user_name
    FROM status a
        LEFT JOIN user u ON a.user_id = u.id
    WHERE u.id = 2
    ORDER BY a.created_at DESC
a.id a.user_id a.body a.created_at u.user_name
3 2 status3 user2 テスト3 2017-11-01 00:00:00 user2
4 2 status4 user2 テスト4 2017-11-01 00:00:00 user2
SELECT a.*, u.user_name
    FROM status a
        LEFT JOIN user u ON a.user_id = u.id
    WHERE u.id = 3
    ORDER BY a.created_at DESC
a.id a.user_id a.body a.created_at u.user_name
5 3 status5 user3 テスト5 2017-11-01 00:00:00 user3
(参考) LEFT JOIN user u ON a.user_id = u.id
SELECT a.*, u.user_name, u.id
    FROM status a
        LEFT JOIN user u ON a.user_id = u.id
    ORDER BY a.id
a.id a.user_id a.body a.created_at u.user_name u.id
1 1 status1 user1 テスト1 2017-11-01 00:00:00 user1 1
2 1 status2 user1 テスト2 2017-11-01 00:00:00 user1 1
3 2 status3 user2 テスト3 2017-11-01 00:00:00 user2 2
4 2 status4 user2 テスト4 2017-11-01 00:00:00 user2 2
5 3 status5 user3 テスト5 2017-11-01 00:00:00 user3 3

isFollowing

SELECT COUNT(user_id) as count
    FROM following
    WHERE user_id = 1
        AND following_id = 2
count 1
SELECT COUNT(user_id) as count
    FROM following
    WHERE user_id = 1
        AND following_id = 3
count 0
(参考) followingテーブル
user_id following_id
1 2

fetchByIdAndUserName

SELECT a.* , u.user_name
    FROM status a
        LEFT JOIN user u ON u.id = a.user_id
    WHERE a.id = 1
        AND u.user_name = 'user1'
a.id a.user_id a.body a.created_at u.user_name
1 1 status1 user1 テスト1 2017-11-01 00:00:00 user1
(参考) LEFT JOIN user u ON u.id = a.user_id
SELECT a.*, u.user_name, u.id
    FROM status a
        LEFT JOIN user u ON u.id = a.user_id
    ORDER BY a.id
a.id a.user_id a.body a.created_at u.user_name u.id
1 1 status1 user1 テスト1 2017-11-01 00:00:00 user1 1
2 1 status2 user1 テスト2 2017-11-01 00:00:00 user1 1
3 2 status3 user2 テスト3 2017-11-01 00:00:00 user2 2
4 2 status4 user2 テスト4 2017-11-01 00:00:00 user2 2
5 3 status5 user3 テスト5 2017-11-01 00:00:00 user3 3

Mini Blog Application

投稿一覧

http://mini-blog.localhost/user/user1
http://mini-blog.localhost/user/user2
http://mini-blog.localhost/user/user3
作成手順 クラス
データベース UserRepository
StatusRepository
FollowingRepository
fetchByUserName
fetchAllByUserId
isFollowing
ルーティング MiniBlogApplication '/user/:user_name'
  => array('controller' => 'status', 'action' => 'user')
コントローラ StatusController userActionn
ビューファイル status/user.php
status/status.php (in status/user.php)
StatusController   userAction
機能 クラス メソッド
チェック - if (!$user) ユーザ 無
Session isAuthenticated() ログイン状態 チェック (ログイン済)
- if ($my['id'] !== $user['id'])
  $my['id']: 1, $user['id']: 2, 3 (ログインユーザ, ユーザ)
FollowingRepository isFollowing($my['id'], $user['id'])  $following
  'user2' $following true
  'user3' $following false
  'user1' $following null (初期値)
データ設定 Controller generateCsrfToken('account/follow') render引数
  (フォロー 処理用 'user3')
データ取得 DbManager get('User') UserRepository
UserRepository fetchByUserName($params['user_name'])  $user
  'user1', 'user2', 'user3' 1レコード
DbManager get('Status') StatusRepository
StatusRepository fetchAllByUserId($user['id'])  $statuses
  status1~status2, status3~status4, status5
Session get('user') ログインユーザ ('user1' 1レコード)  $my
DbManager get('Following') FollowingRepository
データ出力
画面 Controller forward404() 404エラー画面 (ユーザ 無)
Controller render(...) 投稿一覧

投稿詳細

http://mini-blog.localhost/user/user1/status/1
作成手順 クラス
データベース StatusRepository fetchByIdAndUserName
ルーティング MiniBlogApplication '/user/:user_name/status/:id'
  => array('controller' => 'status', 'action' => 'show')
コントローラ StatusController showActionn
ビューファイル status/show.php
status/status.php (in status/show.php)
StatusController   showAction
機能 クラス メソッド
チェック - if (!$status) 投稿詳細 無
データ設定
データ取得 DbManager get('Status') StatusRepository
StatusRepository fetchByIdAndUserName($params['id'], $params['user_name']) status1
データ出力
画面 Controller forward404() 404エラー画面 (投稿詳細 無)
Controller render(...) 投稿詳細

ユーザID: user1、パスワード: password でログイン

投稿一覧 (user1)

投稿一覧 (user2)

投稿一覧 (user3)

投稿詳細

Page Top
Page Bottom