NetBeans Debugging methods
2019-06-17 release
2021-01-14 update
NetBeans Debugging methods (Process flow, Variable value) Autoload
Basic usage of debugging
Debugging Session
e.g. ClassLoader.php autoload
ClassLoader.php line 27 | check $dir, $this->dirs[] |
ClassLoader.php line 37 | check 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 }
file | line | |
---|---|---|
index.php | 3 | check Process flow (optional) |
index.php | 4 | check Process flow (optional) |
ClassLoader.php | 27 | - |
ClassLoader.php | 37 | - |
action | file | line | variable value (oher) |
---|---|---|---|
Start Session (Ctrl+F5) | index.php | 3 | require '../bootstrap.php'; |
ClassLoader.php | registerDir($dir) | check $dir, $this->dirs[] | |
Resume (F5) | ClassLoader.php | 27 |
$this->dirs[] = $dir; before setting variable (line 27 before execution) |
Step Over (F8) | ClassLoader.php | 28 |
} after setting variable (line 27 after execution) hover over variable to see variable value $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 |
Resume (F5) | ClassLoader.php | 27 |
$this->dirs[] = $dir; (set $this->dirs[0]) |
Step Over (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 |
Resume (F5) | index.php | 4 | require '../MiniBlogApplication.php'; |
ClassLoader.php | loadClass($class) | check foreach | |
Resume (F5) | ClassLoader.php | 37 |
foreach ($this->dirs as $dir) { $class "Application" |
Step Over (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 |
Step Over (F8) | ClassLoader.php | 39 |
if (is_readable($file)) { $file "C:\XAMPP\xampp_5.6.31\htdocs\mini-blog.localhost/core/Application.php" (Note there is no line feed) $file = $dir . '/' . $class . '.php'; reference if there is $class . '.php' in models, loop one more time |
Step Over (F8) | ClassLoader.php | 40 | require $file; |
Step Into (F7) | Application.php | 9 | { |
Step Into (F7) | ClassLoader.php | 42 | return; |
index.php | 6 | $app = new MiniBlogApplication(false); | |
Finish Session (Shift+F5) |
Caution
basically there is no need to use URL during debugging
use action (Step Into etc) for Process flow
exception (Contribution list) http://mini-blog.localhost/user/user3 ('Follow' button)
Disable All | debug state OFF (until just before debug process OFF) |
Enable All | debug state ON |
you can switch between Disable All and Enable All for efficient debugging See
NetBeans IDE 8.2 bug
variable value Variables Window See
Operation
set | click line's left margin to set breakpoint |
unset |
click square shape at line number to cancel breakpoint right-click in Breakpoints Window, select Delete All |
check | hover over variable to see variable value |
check (details) |
you can also check in Variables Window all items not displayed by "how to use mouse pointer" are also displayed bug (subwindow in Variables Window) contents change when you use Cancel button or Close in subwindow that displays value. (measures: use OK button every time) right "C:\XAMPP\xampp_5.6.31\htdocs\mini-blog.localhost/core" wrong "C:(new line)MPP(new line)mpp_5.6.31\htdocs\mini-blog.localhost/core" |
Step Into (F7) | Step into a function call (use properly Step Over (F8)) |
Step Over (F8) | Step over an execution statement (use properly Step Into (F7)) |
Resume (F5) | Resume debugging session |
Finish Session (Shift+F5) | Finish debugging session |
Run to Cursor (F4) | Run execution to the position of the cursor |
menu | click Debug | Debug Project(mini-blog.localhost) |
icon | click Debug Project(mini-blog.localhost) (Ctrl+F5) icon |
Disable All | debug state OFF (until just before debug process OFF) |
Enable All | debug state ON |
Superglobals | example |
---|---|
$_POST | $_POST[_token] "117d0e6d9da8ec9e595110d7e517993901ee77ce" |
$_REQUEST | $_REQUEST[_token] "117d0e6d9da8ec9e595110d7e517993901ee77ce" |
$_SERVER | $_SERVER[REQUEST_METHOD] "POST" |
$_SESSION | $_SESSION[csrf_tokens/account/signup][0] "117d0e6d9da8ec9e595110d7e517993901ee77ce" |
variable value | you can also manually change variable value by clicking in value column |
Convenient Operation
jump where method is defined | Ctrl+B or Ctrl+left-click |
cursor history (back, forward) | ALT+← (arrow key), ALT+→ (arrow key) |
bootstrap.php
1 <?php 2 3 require 'core/ClassLoader.php'; 4 5 $loader = new ClassLoader();
6$loader->
registerDir(dirname(__FILE__).'/core');
/* Ctrl+B or Ctrl+left-click */7 $loader->registerDir(dirname(__FILE__).'/models'); 8 $loader->register();
Ctrl+B or Ctrl+left-click on registerDir, jump ClassLoader.php line 25
ClassLoader.php
25
public function
registerDir($dir)
/* ALT+← (arrow key) */26 { 27 $this->dirs[] = $dir; 28 }
ALT+← (arrow key), back bootstrap.php line 6
NetBeans Debugging methods (Change Variable value to change Process flow)
in order to follow error processing, an error is generated intentionally
render404Page execution
e.g. Process flow (Transition to Login)
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 }
changed $params value to 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 }
file | line | |
---|---|---|
Application.php | 177 | - |
action | file other | line | |
---|---|---|---|
Start Session (Ctrl+F5) | Application.php | 177 |
Variables Window change $params value to false (input false, output 0) |
Step Over (F8) | Application.php | 178 | throw new HttpNotFoundException('No route found for ' . $this->request->getPathInfo()); |
Step Over (F8) | Application.php | 186 | $this->render404Page($e); |
Step Into (F7) | Application.php | 249 | $this->response->setStatusCode(404, 'Not Found'); |
Step Over (F8) | Application.php | 250 | $message = $this->isDebugMode() ? $e->getMessage() : 'Page not found.'; |
Step Into (F7) | Application.php | 85 |
return $this->debug; (use index.php) change debug value to true (debug mode) |
Resume (F5) | browser |
Page not found. or No route found for (debug mode) |
|
Finish Session (Shift+F5) |
forward404 execution (POST check)
e.g. Process flow (Account registration screen (User registration screen) & User registration)
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 ... it is omitted below
Request.php (isPost)
15 public function
isPost()16 { 17 if (
$_SERVER['REQUEST_METHOD']=== 'POST') { 18 return true; 19 } 20 21 return
false; 22 }
changed Superglobals $_SERVER['REQUEST_METHOD'] value to "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 }
file | line | |
---|---|---|
AccountController.php | 31 | - |
action | file other | line | |
---|---|---|---|
Start Session (Ctrl+F5) |
Login click Account registration or New User registration User ID: user4, Password: password click Registration button |
||
AccountController.php | 31 | if (!$this->request->isPost()) { | |
Step Into (F7) | Request.php | 17 |
if ($_SERVER['REQUEST_METHOD'] === 'POST') { Variables Window change Superglobals $_SERVER['REQUEST_METHOD'] value to "GET" (change to string other than "POST") |
Step Over (F8) | Request.php | 21 | return false; |
Step Over (F8) | AccountController.php | 32 | $this->forward404(); |
Step Into (F7) | Controller.php | 96 | throw new HttpNotFoundException('Forwarded 404 page from ' |
Step Over (F8) | Application.php | 186 | $this->render404Page($e); |
Step Into (F7) | Application.php | 249 | $this->response->setStatusCode(404, 'Not Found'); |
Step Over (F8) | Application.php | 250 | $message = $this->isDebugMode() ? $e->getMessage() : 'Page not found.'; |
Step Into (F7) | Application.php | 85 |
return $this->debug; (use index.php) change debug value to true (debug mode) |
Resume (F5) | browser |
Page not found. or Forwarded 404 page from account/register (debug mode) |
|
Finish Session (Shift+F5) |
redirect execution (Token check)
e.g. Process flow (Account registration screen (User registration screen) & User registration)
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 ... it is omitted below
changed $token value
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 }
file | line | |
---|---|---|
index.php | 3 | check Process flow (not optional) & for Disable All |
AccountController.php | 36 | change $token value |
AccountController.php | 37 | - |
Controller.php | 160 | - |
Controller.php | 115 | - |
Response.php | 20 | - |
DbManager.php | 111 | check Process flow (not optional) |
action | file other | line | |
---|---|---|---|
Start Session (Ctrl+F5) | index.php | 3 |
require '../bootstrap.php'; Breakpoints Window (right-click) Disable All |
Resume (F5) | browser |
Login click Account registration or New User registration Account registration screen User ID: user4, Password: password |
|
Breakpoints Window (right-click) Enable All |
|||
click Registration button | |||
User registration | |||
index.php | 3 | require '../bootstrap.php'; | |
Resume (F5) | AccountController.php | 36 |
if (!$this->checkCsrfToken('account/signup', $token)) { Variables Window change $token value "add" + "original value" (change to string other than "original value") |
Step Into (F7) | Controller.php | 150 | $key = 'csrf_tokens/' . $form_name; |
Resume (F5) | Controller.php | 160 | return false; |
Resume (F5) | AccountController.php | 37 | return $this->redirect('/account/signup'); |
Step Into (F7) | Controller.php | 107 | if (!preg_match('#https?://#', $url)) { |
Resume (F5) | Controller.php | 115 | $this->response->setStatusCode(302, 'Found'); |
Step Over (F8) | Controller.php | 116 | $this->response->setHttpHeader('Location', $url); |
Resume (F5) | Response.php | 20 |
header('HTTP/1.1 ' . $this->status_code . ' ' . $this->status_text); $this->status_code 302 $this->status_text "Found" |
Step Over (F8) | Response.php | 22 | foreach ($this->http_headers as $name => $value) { |
Step Over (F8) | Response.php | 23 |
header($name . ': ' . $value); $name "Location" $value "http://localhost/mini-blog.localhost/web/index.php/account/signup" |
Resume (F5) | DbManager.php | 111 | foreach ($this->repositories as $repository) { |
Account registration screen | |||
Resume (F5) | index.php | 3 | require '../bootstrap.php'; |
Resume (F5) | Response.php | 20 |
header('HTTP/1.1 ' . $this->status_code . ' ' . $this->status_text); $this->status_code 200 $this->status_text "OK" |
Resume (F5) | DbManager.php | 111 | foreach ($this->repositories as $repository) { |
Resume (F5) | browser | Account registration screen | |
Finish Session (Shift+F5) |