Tag Archive required

PHP: ดูการทำงานสร้าง flowchart (backtrace)

ถ้าเรียนเขียน program มาคงจะคุ้นเคยกับ flowchart การทำงานของของโปรแกรม แต่ในชีวิตการทำงานจริงๆ โดยเฉพาะถ้าเขียน code โดยใช้ framework ต่างๆ จะไม่เป็นเหมือนที่ได้ออกแบบไว้เสมอไป เพราะว่าบางครั้งโปรแกรมจะทำงานให้เราเองโดยที่ไม่ได้สั่ง สาเหตุคือ มีการเรียกใช้ hook หรือ tricker ทำให้เกิด process ที่อาจจะไม่ทราบที่มา หรือต้องมาแก้งานของคนอื่นโดนที่ไม่มีเอกสารให้

นอกจากการใช้วิธี PHP: list included หรือ required ไฟล์ที่ใช้ ถ้าเราใช้ตัว framework ต่างๆ มักจะมีการเตรียม function ในการสร้าง backtrace ไว้ให้ แต่ถ้าไม่มีหรือเป็น code ที่เขียนด้วยตัวเอง ยังสามารถใช้ debug_backtrace ในการค้นหาที่มาที่ไปได้เช่น[code language=”php” title=”debug.debug_backtrace.php”]<?php

function getBacktrace()
{
$backtrace = debug_backtrace();
echo ‘<pre>’, print_r($backtrace, true), ‘</pre>’;
fwrite(fopen(‘logs_debug_backtrace.txt’, ‘a+’), "\n\n" . __FILE__ . ‘ :’ . __LINE__ . "\n\n" . print_r($backtrace, true));
}

function getPhpInfo($what)
{
phpinfo($what);

/* จะดูว่า ทำไม่ getPhpInfo ถึงทำงาน */
getBacktrace();
}

function index()
{
getPhpInfo(INFO_ENVIRONMENT);
}

index();[/code]เมื่อทดสอบดูจะได้ผลลัพธ์[code language=”text” title=”logs_debug_backtrace.txt”]Array
(
[0] => Array
(
[file] => D:\xampp\htdocs\snippets\PHP\debug.debug_backtrace.php
[line] => 13
[function] => getBacktrace
[args] => Array
(
)

)

[1] => Array
(
[file] => D:\xampp\htdocs\snippets\PHP\debug.debug_backtrace.php
[line] => 18
[function] => getPhpInfo
[args] => Array
(
[0] => 16
)

)

[2] => Array
(
[file] => D:\xampp\htdocs\snippets\PHP\debug.debug_backtrace.php
[line] => 21
[function] => index
[args] => Array
(
)

)

)[/code]เพราะว่าเราเขียน function debug_backtrace() ไว้ใน function getBacktrace() อีกชั้น เพื่อที่ความง่ายในการค้นหา flow เมื่อต้องการดูว่า function หรือ class ที่เราสนใจมันมี flow มายังไงก็แค่ไปเรียกใน function ที่สงสัย เราก็จะได้ลำดับการทำงานย้อนกลับไป เราจะได้ทราบทั้งฟังก์ชั้น คลาส บรรทัด ไฟล์ แม้แต่ตัวแปรที่ส่งเข้าไปใน function นั้นๆ

PHP: list included หรือ required ไฟล์ที่ใช้

การเขียนโปรแกรมโดยใช้ php นิยมจะแยกไฟล์ออกเป็นส่วนๆ เพื่อความสะดวกในการเขียนและ reused ไฟล์เพื่อที่จะนำมาใช้ซ้ำอีกครั้ง เช่น ในเว็บทั่วไปมันจะมีส่วนของ header และ footer เหมือนกันทุกๆหน้า แทนนี้จะเขียนส่วนหัวและส่วนท้ายทุกครั้ง สำหรับทุกหน้าเพื่อแสดงผลเหมือนๆ กันก็จะนิยมสร้างเป็นไฟล์ แยกออกไป จากนั้นก็แทรกเข้ามาโดยใช้ function included หรือ required[code language=”php” title=”header.php”]<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title><?php echo $title; ?></title>
</head>
<body>[/code]และ[code language=”php” title=”footer.php”]</body>
</html>[/code]ถ้าหากต้องมีการเปลี่ยน design ก็สามารถแก้ได้โดยแก้ใน 2 ไฟล์นี้เท่านั้นแทนที่จะต้องไปไล่เปลี่ยนในทุกๆไฟล์ (มีแค่ 100 หน้าก็เหนื่อยแล้ว)

แต่เมื่อโครงสร้างไฟล์ใน project เริ่มมีความซับซ้อน เช่น ไม่ทราบว่าไฟล์ที่เราใช้คำสั่ง included หรือ required นั้นมีไฟล์ไหนบ้าง เพราะว่าไฟล์ที่ include เข้ามาสามารถแทรกไฟล์ส่วนอื่นๆ เข้ามาเพิ่มได้เหมือนกันเช่น header.php อาจจะมีการแทรกไฟล์ menu.php เพื่อแสดงส่วนของเมนู ภาษาพีเฮชพีจึงได้เตรียม function get_included_files เข้ามาช่วย debug ไฟล์ทั้งหมดที่แทรกเอาเข้ามา

ตัวอย่างการใช้งาน[code language=”php” title=”debug.get_included_files.php”]<?php
$title = ‘names of included or required files’;
include ‘header.php’;

function getIncludedFiles()
{
$files = get_included_files();
echo ‘<pre>’, print_r($files, true), ‘</pre>’;
fwrite(fopen(‘logs_get_included_files.txt’, ‘a+’), "\n\n" . __FILE__ . ‘ :’ . __LINE__ . "\n\n" . print_r($files, true));

}

getIncludedFiles();

include ‘footer.php’;[/code] ทดลองเรียกดู จะเห็นว่าจะแสดงเป็น array[code language=”text” title=”function get_included_files”]Array
(
[0] => D:\xampp\htdocs\snippets\PHP\get_included_files.php
[1] => D:\xampp\htdocs\snippets\PHP\header.php
)[/code]สังเกตดูจะเป็นว่าจะแสดง array ออกมาและเขียนไฟล์ logs_get_included_files.txt เพิ่มขึ้นมา โดยเริ่มจากไฟล์ debug.get_included_files.php เองและแสดงไฟล์ header.php ที่แทรกเข้ามา แต่กลับไม่แสดง footer.php เพราะว่าแทรกเข้ามาหลัง function get_included_files() ในการใช้งานจริงๆ จึงควรแทรกไว้ที่ลำดับการทำงานสุดท้ายเช่นไฟล์ footer.php จึงจะสามารถ list ไฟล์ที่ใช้ได้ครบ

นอกจากนี้ยังสามารถเขียนให้จบในบรรทัดเดียวได้[code language=”php”]fwrite(fopen(‘get_included_files.txt’, ‘a+’), print_r(get_included_files(), true));[/code]