NetBeans デバッグ方法
2019年06月17日 公開
2021年01月14日 更新
動画 (YouTube)
- パーフェクトPHP をデバッグしました (デバッグ例 基本編) オートロード デバッグ例↓
- パーフェクトPHP をデバッグしました (render404Page) render404Page 実行↓
- パーフェクトPHP をデバッグしました (forward404 POST チェック) forward404 実行 (POST チェック)↓
- パーフェクトPHP をデバッグしました (デバッグ例 応用編) トークン チェック redirect 実行↓
目次
NetBeans デバッグ方法 (変数の値と処理の流れを調べる) オートロード
デバッグの基本的な使い方です。
デバッグ例
例 ClassLoader.php オートロード
ClassLoader.php 27行目 | $dir と $this->dirs[] の値を調べる |
ClassLoader.php 37行目 | foreach の動きを調べる |
index.php
1 <?php 2
3require '../bootstrap.php';
4require '../MiniBlogApplication.php'; 5 6 $app = new MiniBlogApplication(false); 7 $app->run(); 8
ClassLoader.php (registerDir)
25 public function registerDir($dir) 26 {
27$this->dirs[]
=
$dir; 28 }
ClassLoader.php (loadClass)
35 public function loadClass($class) 36 {
37foreach
($this->dirs as $dir) { 38 $file = $dir . '/' . $class . '.php'; 39 if (is_readable($file)) { 40 require $file; 41 42 return; 43 } 44 } 45 }
ファイル | 行 | |
---|---|---|
index.php | 3 | 処理の流れ を確認するため (省略可) |
index.php | 4 | 処理の流れ を確認するため (省略可) |
ClassLoader.php | 27 | - |
ClassLoader.php | 37 | - |
アクション | ファイル | 行 | 変数の値 (他) |
---|---|---|---|
開始 (Ctrl+F5) | index.php | 3 | require '../bootstrap.php'; |
ClassLoader.php | registerDir($dir) | $dir と $this->dirs[] の値を調べる | |
続行 (F5) | ClassLoader.php | 27 |
$this->dirs[] = $dir; 変数 設定前 (27行目 実行前) |
ステップ・オーバー (F8) | ClassLoader.php | 28 |
} 変数 設定後 (27行目 実行後) 変数の上にマウス・ポインタを置くと、変数の値が表示されます $dir "C:\XAMPP\xampp_5.6.31\htdocs\mini-blog.localhost/core" $this->dirs[0] "C:\XAMPP\xampp_5.6.31\htdocs\mini-blog.localhost/core" $this ClassLoader object |
続行 (F5) | ClassLoader.php | 27 |
$this->dirs[] = $dir; ($this->dirs[0] は設定済) |
ステップ・オーバー (F8) | ClassLoader.php | 28 |
} $dir "C:\XAMPP\xampp_5.6.31\htdocs\mini-blog.localhost/models" $this->dirs[0] "C:\XAMPP\xampp_5.6.31\htdocs\mini-blog.localhost/core" $this->dirs[1] "C:\XAMPP\xampp_5.6.31\htdocs\mini-blog.localhost/models" $this ClassLoader object |
続行 (F5) | index.php | 4 | require '../MiniBlogApplication.php'; |
ClassLoader.php | loadClass($class) | foreach の動きを調べる | |
続行 (F5) | ClassLoader.php | 37 |
foreach ($this->dirs as $dir) { $class "Application" |
ステップ・オーバー (F8) | ClassLoader.php | 38 |
$file = $dir . '/' . $class . '.php'; $this->dirs[0] "C:\XAMPP\xampp_5.6.31\htdocs\mini-blog.localhost/core" $this->dirs[1] "C:\XAMPP\xampp_5.6.31\htdocs\mini-blog.localhost/models" $dir "C:\XAMPP\xampp_5.6.31\htdocs\mini-blog.localhost/core" $this ClassLoader object |
ステップ・オーバー (F8) | ClassLoader.php | 39 |
if (is_readable($file)) { $file "C:\XAMPP\xampp_5.6.31\htdocs\mini-blog.localhost/core/Application.php" (注 改行はされていません) $file = $dir . '/' . $class . '.php'; 参考 $class . '.php' が models にある場合、もう一回ループ |
ステップ・オーバー (F8) | ClassLoader.php | 40 | require $file; |
ステップ・イン (F7) | Application.php | 9 | { |
ステップ・イン (F7) | ClassLoader.php | 42 | return; |
index.php | 6 | $app = new MiniBlogApplication(false); | |
終了 (Shift+F5) |
注意点
基本的に、デッバグ中 URL欄 を使うことはありません
ステップ・インなどの アクション を使って、処理の流れ を進めます
例外 投稿一覧 http://mini-blog.localhost/user/user3 ('フォローする' ボタン表示)
すべて無効化 | デバッグ状態 OFF (デバッグする処理の 直前 まで OFF) |
すべて有効化 | デバッグ状態 ON |
すべて無効化 と すべて有効化 を切り替えて、効率良くデバッグができます 参照
NetBeans IDE 8.2 バグ
変数の値 変数 ウィンドウ 参照
操作
設定 | ブレークポイントを設定する行の左マージンをクリックします |
解除 |
ブレークポイントを解除するには、行番号位置の四角い図形をクリックします ブレークポイント ウィンドウ で右クリックし、すべて削除 等を選択することもできます |
確認 | 変数の上にマウス・ポインタを置くと、変数の値が表示されます |
確認 (詳細) |
変数 ウィンドウ でも確認できます 「マウス・ポインタを置く方法」で表示されない項目も、すべて表示されます バグ (変数 ウィンドウ の サブウィンドウ) 値を表示する サブウィンドウ で 取消ボタン or 閉じる を使用すると、内容が変わります (対策: 毎回 OKボタン を使用する) 正 "C:\XAMPP\xampp_5.6.31\htdocs\mini-blog.localhost/core" 誤 "C:(改行)MPP(改行)mpp_5.6.31\htdocs\mini-blog.localhost/core" |
ステップ・イン (F7) | 関数コールにステップ・イン (ステップ・オーバー (F8) と使い分けます) |
ステップ・オーバー (F8) | 実行文をステップ・オーバー (ステップ・イン (F7) と使い分けます) |
続行 (F5) | デバッグ・セッションを続行 |
終了 (Shift+F5) | デバッグ・セッションを終了 |
カーソルまで実行 (F4) | カーソルまで実行 |
メニュー | デバッグ | ファイルをデバッグ をクリックします |
アイコン | プロジェクト(mini-blog.localhost)をデバッグ (Ctrl+F5) アイコン をクリックします |
すべて無効化 | デバッグ状態 OFF (デバッグする処理の 直前 まで OFF) |
すべて有効化 | デバッグ状態 ON |
Superglobals | 例 |
---|---|
$_POST | $_POST[_token] "117d0e6d9da8ec9e595110d7e517993901ee77ce" |
$_REQUEST | $_REQUEST[_token] "117d0e6d9da8ec9e595110d7e517993901ee77ce" |
$_SERVER | $_SERVER[REQUEST_METHOD] "POST" |
$_SESSION | $_SESSION[csrf_tokens/account/signup][0] "117d0e6d9da8ec9e595110d7e517993901ee77ce" |
変数の値 | 値列内をクリックして、変数の値を手動で変更することもできます |
便利な操作
メソッドが定義されているところにジャンプ | Ctrl+B または Ctrl+左クリック |
カーソルの履歴 (戻る 進む) | ALT+← (矢印キー) ALT+→ (矢印キー) |
bootstrap.php
1 <?php 2 3 require 'core/ClassLoader.php'; 4 5 $loader = new ClassLoader();
6$loader->
registerDir(dirname(__FILE__).'/core');
/* Ctrl+B または Ctrl+左クリック */7 $loader->registerDir(dirname(__FILE__).'/models'); 8 $loader->register();
registerDir上で Ctrl+B または Ctrl+左クリック をすると、ClassLoader.php 25行目 にジャンプ
ClassLoader.php
25
public function
registerDir($dir)
/* ALT+← (矢印キー) */26 { 27 $this->dirs[] = $dir; 28 }
ALT+← (矢印キー) をすると、bootstrap.php 6行目 に戻る
NetBeans デバッグ方法 (変数の値を変更して 処理の流れを変える)
エラー処理の流れを追うために、意図的にエラーを発生させます。
render404Page 実行
例 処理の流れ (ログイン画面への遷移)
Application.php (run)
173 public function run() 174 { 175 try { 176 $params = $this->router->resolve($this->request->getPathInfo());
177if (
$params===
false) { 178
throw new HttpNotFoundException('No route found for ' . $this->request->getPathInfo()); 179 } 180 181 $controller = $params['controller']; 182 $action = $params['action']; 183 184 $this->runAction($controller, $action, $params); 185 }
catch (HttpNotFoundException $e){ 186 $this->
render404Page($e); 187 } catch (UnauthorizedActionException $e) { 188 list($controller, $action) = $this->login_action; 189 $this->runAction($controller, $action); 190 } 191 192 $this->response->send(); 193 }
$params の値を false に変更後

Application.php (render404Page)
247 protected function
render404Page($e)248 { 249 $this->response->setStatusCode(
404,
'Not Found'); 250 $message = $this->
isDebugMode()? $e->getMessage() : 'Page not found.'; 251 $message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8'); 252 253 $this->response->setContent(<<<EOF 254<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 255"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 256<html> 257<head> 258 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 259 <title>404</title> 260</head> 261<body> 262 {$message} 263</body> 264</html> 265EOF 266 ); 267 }
Application.php (isDebugMode)
83 public function isDebugMode() 84 { 85 return $this->debug; 86 }
ファイル | 行 | |
---|---|---|
Application.php | 177 | - |
アクション | ファイル 他 | 行 | |
---|---|---|---|
開始 (Ctrl+F5) | Application.php | 177 |
変数 ウィンドウ $params の値を false に変更する (入力 false, 表示 0) |
ステップ・オーバー (F8) | Application.php | 178 | throw new HttpNotFoundException('No route found for ' . $this->request->getPathInfo()); |
ステップ・オーバー (F8) | Application.php | 186 | $this->render404Page($e); |
ステップ・イン (F7) | Application.php | 249 | $this->response->setStatusCode(404, 'Not Found'); |
ステップ・オーバー (F8) | Application.php | 250 | $message = $this->isDebugMode() ? $e->getMessage() : 'Page not found.'; |
ステップ・イン (F7) | Application.php | 85 |
return $this->debug; (index.php 使用) debug の値を true に変更する (デバッグモード) |
続行 (F5) | ブラウザに表示 |
Page not found. or No route found for (デバッグモード) |
|
終了 (Shift+F5) |
forward404 実行 (POST チェック)
例 処理の流れ (アカウント登録画面 (ユーザ登録画面) & ユーザ登録)
AccountController.php (registerAction)
25 public function registerAction() 26 { 27 if ($this->session->isAuthenticated()) { 28 return $this->redirect('/account'); 29 } 30
31if (!$this->request->
isPost()) { 32 $this->
forward404(); 33 } 34 ... 省略
Request.php (isPost)
15 public function
isPost()16 { 17 if (
$_SERVER['REQUEST_METHOD']=== 'POST') { 18 return true; 19 } 20 21 return
false; 22 }
Superglobals $_SERVER['REQUEST_METHOD'] の値を "GET" に変更後

Controller.php (forward404)
94 protected function
forward404()95 { 96
throw new HttpNotFoundException('Forwarded 404 page from '97
. $this->controller_name . '/' . $this->action_name); 98 }
Application.php (run)
173 public function run() 174 { 175 try { 176 $params = $this->router->resolve($this->request->getPathInfo()); 17 if ($params === false) { 178 throw new HttpNotFoundException('No route found for ' . $this->request->getPathInfo()); 179 } 180 181 $controller = $params['controller']; 182 $action = $params['action']; 183 184 $this->runAction($controller, $action, $params); /*
registerAction in runAction*/ 185 }
catch (HttpNotFoundException $e){ 186 $this->render404Page($e); 187 } catch (UnauthorizedActionException $e) { 188 list($controller, $action) = $this->login_action; 189 $this->runAction($controller, $action); 190 } 191 192 $this->response->send(); 193 }
Application.php (render404Page)
247 protected function
render404Page($e)248 { 249 $this->response->setStatusCode(
404,
'Not Found'); 250 $message = $this->
isDebugMode()? $e->getMessage() : 'Page not found.'; 251 $message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8'); 252 253 $this->response->setContent(<<<EOF 254<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 255"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 256<html> 257<head> 258 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 259 <title>404</title> 260</head> 261<body> 262 {$message} 263</body> 264</html> 265EOF 266 ); 267 }
Application.php (isDebugMode)
83 public function isDebugMode() 84 { 85 return $this->debug; 86 }
ファイル | 行 | |
---|---|---|
AccountController.php | 31 | - |
アクション | ファイル 他 | 行 | |
---|---|---|---|
開始 (Ctrl+F5) |
ログイン画面 アカウント登録 or 新規ユーザ登録 クリック ユーザID: user4, パスワード: password 登録ボタンクリック |
||
AccountController.php | 31 | if (!$this->request->isPost()) { | |
ステップ・イン (F7) | Request.php | 17 |
if ($_SERVER['REQUEST_METHOD'] === 'POST') { 変数 ウィンドウ Superglobals $_SERVER['REQUEST_METHOD'] の値を "GET" に変更する ("POST" 以外の文字列に変更する) |
ステップ・オーバー (F8) | Request.php | 21 | return false; |
ステップ・オーバー (F8) | AccountController.php | 32 | $this->forward404(); |
ステップ・イン (F7) | Controller.php | 96 | throw new HttpNotFoundException('Forwarded 404 page from ' |
ステップ・オーバー (F8) | Application.php | 186 | $this->render404Page($e); |
ステップ・イン (F7) | Application.php | 249 | $this->response->setStatusCode(404, 'Not Found'); |
ステップ・オーバー (F8) | Application.php | 250 | $message = $this->isDebugMode() ? $e->getMessage() : 'Page not found.'; |
ステップ・イン (F7) | Application.php | 85 |
return $this->debug; (index.php 使用) debug の値を true に変更する (デバッグモード) |
続行 (F5) | ブラウザに表示 |
Page not found. or Forwarded 404 page from account/register (デバッグモード) |
|
終了 (Shift+F5) |
redirect 実行 (トークン チェック)
例 処理の流れ (アカウント登録画面 (ユーザ登録画面) & ユーザ登録)
index.php
1 <?php 2
3require '../bootstrap.php'; 4 require '../MiniBlogApplication.php'; 5 6 $app = new MiniBlogApplication(false); 7 $app->run(); 8
AccountController.php (registerAction)
25 public function registerAction() 26 { 27 if ($this->session->isAuthenticated()) { 28 return $this->redirect('/account'); 29 } 30 31 if (!$this->request->isPost()) { 32 $this->forward404(); 33 } 34 35 $token = $this->request->getPost('_token');
36if (!$this->
checkCsrfToken('account/signup',
$token)) {
37return $this->
redirect('/account/signup'); 38 } 39 ... 省略
$token の値を変更後

Controller.php (checkCsrfToken)
148 protected function
checkCsrfToken($form_name, $token) 149 { 150 $key = 'csrf_tokens/' . $form_name; 151 $tokens = $this->session->get($key, array()); 152 153 if (false !== ($pos = array_search($token, $tokens, true))) { 154 unset($tokens[$pos]); 155 $this->session->set($key, $tokens); 156 157 return true; 158 } 159
160return
false; 161 }
Controller.php (redirect)
105 protected function
redirect($url)106 { 107 if (!preg_match('#https?://#', $url)) { 108 $protocol = $this->request->isSsl() ? 'https://' : 'http://'; 109 $host = $this->request->getHost(); 110 $base_url = $this->request->getBaseUrl(); 111 112 $url = $protocol . $host . $base_url . $url; 113 } 114
115$this->response->setStatusCode(
302,
'Found'); 116 $this->response->setHttpHeader(
'Location',
$url); 117 } 118
Response.php (send)
18 public function send() 19 {
20header
('HTTP/1.1 ' . $this->
status_code. ' ' . $this->
status_text); 21 22 foreach ($this->http_headers as $name => $value) { 23
header(
$name. ': ' .
$value); 24 } 25 26 echo $this->content; 27 }
DbManager.php (__destruct)
109 public function __destruct() 110 {
111foreach ($this->repositories as $repository) { 112 unset($repository); 113 } 114 115 foreach ($this->connections as $con) { 116 unset($con); 117 } 118 }
ファイル | 行 | |
---|---|---|
index.php | 3 | 処理の流れ を確認するため (省略不可) & すべて無効化 のため |
AccountController.php | 36 | $token の値を変更する |
AccountController.php | 37 | - |
Controller.php | 160 | - |
Controller.php | 115 | - |
Response.php | 20 | - |
DbManager.php | 111 | 処理の流れ を確認するため (省略不可) |
アクション | ファイル 他 | 行 | |
---|---|---|---|
開始 (Ctrl+F5) | index.php | 3 |
require '../bootstrap.php'; ブレークポイント ウィンドウ (右クリック) すべて無効化 |
続行 (F5) | ブラウザに表示 |
ログイン画面 アカウント登録 or 新規ユーザ登録 クリック アカウント登録画面 ユーザID: user4, パスワード: password |
|
ブレークポイント ウィンドウ (右クリック) すべて有効化 |
|||
登録ボタンクリック | |||
ユーザ登録 | |||
index.php | 3 | require '../bootstrap.php'; | |
続行 (F5) | AccountController.php | 36 |
if (!$this->checkCsrfToken('account/signup', $token)) { 変数 ウィンドウ $token の値を変更する "add" + "元の値" ("元の値" 以外の文字列に変更する) |
ステップ・イン (F7) | Controller.php | 150 | $key = 'csrf_tokens/' . $form_name; |
続行 (F5) | Controller.php | 160 | return false; |
続行 (F5) | AccountController.php | 37 | return $this->redirect('/account/signup'); |
ステップ・イン (F7) | Controller.php | 107 | if (!preg_match('#https?://#', $url)) { |
続行 (F5) | Controller.php | 115 | $this->response->setStatusCode(302, 'Found'); |
ステップ・オーバー (F8) | Controller.php | 116 | $this->response->setHttpHeader('Location', $url); |
続行 (F5) | Response.php | 20 |
header('HTTP/1.1 ' . $this->status_code . ' ' . $this->status_text); $this->status_code 302 $this->status_text "Found" |
ステップ・オーバー (F8) | Response.php | 22 | foreach ($this->http_headers as $name => $value) { |
ステップ・オーバー (F8) | Response.php | 23 |
header($name . ': ' . $value); $name "Location" $value "http://localhost/mini-blog.localhost/web/index.php/account/signup" |
続行 (F5) | DbManager.php | 111 | foreach ($this->repositories as $repository) { |
アカウント登録画面 | |||
続行 (F5) | index.php | 3 | require '../bootstrap.php'; |
続行 (F5) | Response.php | 20 |
header('HTTP/1.1 ' . $this->status_code . ' ' . $this->status_text); $this->status_code 200 $this->status_text "OK" |
続行 (F5) | DbManager.php | 111 | foreach ($this->repositories as $repository) { |
続行 (F5) | ブラウザに表示 | アカウント登録画面 | |
終了 (Shift+F5) |