สอบถาม error 500 / php / MariaDB / host / laragon / JavaScript / html ครับ
อยากสอบถามครับ ทำไม code ตัว ViewPattern.php ทำไมถึงเข้าใช้งานไม่ได้ เวลาอัปลง host ครับ แต่ ตัว laragon เข้าใช้งานได้ปกติครับ user / pass / DB ใส่ถูกครับ ตัวอื่นใช้งานได้ปกติหมดเลย ยกเว้น ViewPattern.php
Code
function loadPattern(ref, prefixRef) {
fetch(`controllers/ViewPattern.php?ref=${ref}&prefixRef=${prefixRef}`)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json();
})
.then(data => {
const leftPanel = document.getElementById('panel-pattern-left');
const rightPanel = document.getElementById('panel-pattern-right');
leftPanel.innerHTML = '';
rightPanel.innerHTML = '';
if (data.error) {
leftPanel.innerHTML = '<p>' + data.error + '</p>';
rightPanel.innerHTML = '<p>' + data.error + '</p>';
return;
}
// ตรวจสอบและโหลดข้อมูลสำหรับ panel "left"
if (data.left && Array.isArray(data.left) && data.left.length > 0) {
data.left.forEach(item => {
let element = createElementByTitle(item);
if (element) leftPanel.appendChild(element);
});
} else {
leftPanel.innerHTML = '<p>ไม่มีข้อมูลสำหรับ Left Panel</p>';
}
// ตรวจสอบและโหลดข้อมูลสำหรับ panel "right"
if (data.right && Array.isArray(data.right) && data.right.length > 0) {
data.right.forEach(item => {
let element = createElementByTitle(item);
if (element) rightPanel.appendChild(element);
});
} else {
rightPanel.innerHTML = '<p>ไม่มีข้อมูลสำหรับ Right Panel</p>';
}
addPatternDragAndDropListeners(leftPanel);
addPatternDragAndDropListeners(rightPanel);
})
.catch(error => {
console.error('Error loading pattern:', error);
});
}
// ฟังก์ชันช่วยสร้าง element ตาม title
function createElementByTitle(item) {
let element = null;
if (item.title === 'pre') {
element = document.createElement('pre');
element.classList.add('mainpre', 'draggable');
element.style.borderLeft = `4px solid ${item.border}`;
element.style.backgroundColor = item.background;
element.style.padding = '10px';
element.textContent = item.pattern;
element.dataset.refPattern = item.ref_pattern; // Add ref_pattern as data attribute
} else if (item.title === 'span') {
element = document.createElement('span');
element.textContent = item.pattern;
element.dataset.refPattern = item.ref_pattern; // Add ref_pattern as data attribute
const centerWrapper = document.createElement('center');
centerWrapper.appendChild(element);
element = centerWrapper;
element.classList.add('draggable');
} else if (item.title === 'img' && item.pattern) {
element = document.createElement('img');
element.src = `assets/images/${item.pattern}`;
element.style.width = '98%';
element.style.borderRadius = '10px';
element.setAttribute('onclick', 'onClick(this)');
element.dataset.refPattern = item.ref_pattern; // Add ref_pattern as data attribute
element.classList.add('draggable');
}
return element;
}
// ฟังก์ชันโหลดข้อมูลอัตโนมัติเมื่อมี active
function loadActivePattern() {
const activeSidebar = document.querySelector('#sidebar .active');
const activeFooter = document.querySelector('.footer .activefooter');
if (activeSidebar && activeFooter) {
const ref = activeSidebar.dataset.ref;
const prefixRef = activeFooter.dataset.prefixRef;
// อัปเดต URL ด้วยค่า ref และ prefixRef โดยใช้ history.pushState
const newUrl = `${window.location.pathname}?ref=${ref}&prefixRef=${prefixRef}`;
history.pushState({ path: newUrl }, '', newUrl); // อัปเดต URL โดยไม่รีโหลดหน้า
loadPattern(ref, prefixRef);
}
}
// ฟังก์ชันเพิ่มการลากและวาง
function addPatternDragAndDropListeners(panel) {
const items = panel.querySelectorAll('.draggable');
items.forEach(item => {
item.addEventListener('mousedown', handlePatternMouseDown);
item.addEventListener('dragstart', handlePatternDragStart);
item.addEventListener('dragover', handlePatternDragOver);
item.addEventListener('drop', handlePatternDrop);
item.addEventListener('dragend', handlePatternDragEnd);
});
}
function handlePatternMouseDown(event) {
if (event.ctrlKey && event.shiftKey) {
event.target.setAttribute('draggable', true);
event.target.style.cursor = 'move';
} else {
event.target.setAttribute('draggable', false);
event.target.style.cursor = 'default';
}
}
function handlePatternDragStart(event) {
if (event.ctrlKey && event.shiftKey) {
event.dataTransfer.setData('text/plain', event.target.getAttribute('data-ref-pattern'));
event.target.classList.add('dragging');
} else {
event.preventDefault();
}
}
function handlePatternDragOver(event) {
event.preventDefault();
const draggingItem = document.querySelector('.dragging');
const targetItem = event.target.closest('.draggable');
if (targetItem && targetItem !== draggingItem) {
const panel = targetItem.parentNode;
const items = Array.from(panel.querySelectorAll('.draggable'));
const draggingIndex = items.indexOf(draggingItem);
const targetIndex = items.indexOf(targetItem);
if (draggingIndex < targetIndex) {
panel.insertBefore(draggingItem, targetItem.nextSibling);
} else {
panel.insertBefore(draggingItem, targetItem);
}
}
}
function handlePatternDrop(event) {
event.preventDefault();
const draggingItem = document.querySelector('.dragging');
draggingItem.classList.remove('dragging');
updatePatternDisplayOrder();
}
function handlePatternDragEnd(event) {
event.target.classList.remove('dragging');
event.target.setAttribute('draggable', false);
event.target.style.cursor = 'default';
}
function updatePatternDisplayOrder() {
const leftPanelItems = document.querySelectorAll('#panel-pattern-left .draggable');
const rightPanelItems = document.querySelectorAll('#panel-pattern-right .draggable');
const updatedOrder = [];
leftPanelItems.forEach((item, index) => {
updatedOrder.push({
ref_pattern: item.getAttribute('data-ref-pattern'),
display_order: index + 1
});
});
rightPanelItems.forEach((item, index) => {
updatedOrder.push({
ref_pattern: item.getAttribute('data-ref-pattern'),
display_order: index + 1
});
});
fetch('controllers/update_pattern_display_order.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(updatedOrder)
})
.then(response => response.json())
.then(data => {
if (!data.success) {
console.error('Error updating display order:', data.error);
}
})
.catch(error => console.error('Error:', error));
}
// เรียกใช้ฟังก์ชันเมื่อ DOM โหลดเสร็จ
document.addEventListener("DOMContentLoaded", () => {
loadFooter();
loadButtons();
addPatternDragAndDropListeners(document.getElementById('panel-pattern-left'));
addPatternDragAndDropListeners(document.getElementById('panel-pattern-right'));
});
ViewPattern.php
<?php
include_once __DIR__ . '/../config/database_config.php';
$connection = db_connect();
// ตรวจสอบว่าการเชื่อมต่อฐานข้อมูลสำเร็จหรือไม่
if (!$connection) {
header('Content-Type: application/json');
echo json_encode(['error' => 'Database connection failed']);
exit();
}
// ใช้ ?? เพื่อป้องกัน Undefined Index
$ref_pattern = mysqli_real_escape_string($connection, $_GET['ref'] ?? '');
$prefixRef_menu = mysqli_real_escape_string($connection, $_GET['prefixRef'] ?? '');
// ใช้ Prepared Statement ป้องกัน SQL Injection
$query = "SELECT p.title_pattern, p.pattern_all, p.border_table, p.background_table, p.set_position, p.ref_pattern
FROM patterns p
JOIN ref_pattern_display_order rpdo ON p.ref_pattern = rpdo.ref_pattern
WHERE p.ref_menu = ? AND p.agent = ?
ORDER BY rpdo.display_order";
$stmt = mysqli_prepare($connection, $query);
if ($stmt) {
mysqli_stmt_bind_param($stmt, "ss", $ref_pattern, $prefixRef_menu);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
} else {
// ถ้า Query Error ให้คืน JSON error แทนการขึ้น HTTP ERROR 500
header('Content-Type: application/json');
echo json_encode(['error' => 'Database query failed']);
exit();
}
$content = ['left' => [], 'right' => []];
if ($result && mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_assoc($result)) {
$item = [
'title' => $row['title_pattern'],
'pattern' => $row['pattern_all'],
'border' => $row['border_table'],
'background' => $row['background_table'],
'ref_pattern' => $row['ref_pattern']
];
if ($row['set_position'] === 'left') {
$content['left'][] = $item;
} elseif ($row['set_position'] === 'right') {
$content['right'][] = $item;
}
}
} else {
// ไม่ต้อง error_log เพราะมันอาจทำให้เกิด 500
$content['error'] = 'ไม่มีข้อมูล';
}
// ตรวจสอบ JSON Encoding
$jsonOutput = json_encode($content);
if ($jsonOutput === false) {
header('Content-Type: application/json');
echo json_encode(['error' => 'JSON Encoding Error']);
exit();
}
// ส่ง JSON ออกไป
header('Content-Type: application/json');
echo $jsonOutput;
mysqli_close($connection);
?>
Code
<?php
error_reporting(0);
@session_start();
set_time_limit(0);
function db_connect(): bool|mysqli|string|null {
static $connection;
$username = ""; // ใส่ยูสเซอร์
$password = ""; // ใส่รหัส
$dbname = "";// DB
$host = "localhost";
if (!isset($connection)) {
$connection = mysqli_connect($host, $username, $password, $dbname);
}
if ($connection === false) {
return mysqli_connect_error();
}
return $connection;
}
function db_query($query): bool|mysqli_result {
$connection = db_connect();
$result = mysqli_query($connection, $query);
return $result;
}
function db_error(): string {
$connection = db_connect();
return mysqli_error($connection);
}
function db_num_rows($result): int {
return mysqli_num_rows($result);
}
function db_fetch_assoc($result): array|null {
return mysqli_fetch_assoc($result);
}
function checkUserSession() {
if (!isset($_SESSION['auth_code']) || empty($_SESSION['auth_code'])) {
echo json_encode(["error" => "unauthorized"]);
exit();
}
if (!isset($_SESSION['user']['username']) || !isset($_SESSION['user']['token_session'])) {
echo json_encode(['error' => 'unauthorized']);
exit();
}
$username = $_SESSION['user']['username'];
$token_session = $_SESSION['user']['token_session'];
$query = "SELECT token_session FROM employees WHERE username = '$username'";
$result = db_query($query);
if ($result && db_num_rows($result) > 0) {
$row = db_fetch_assoc($result);
if ($row['token_session'] !== $token_session) {
echo json_encode(['error' => 'unauthorized']);
exit();
}
} else {
echo json_encode(['error' => 'unauthorized']);
exit();
}
$lastLogin = new DateTime($_SESSION['user']['last_login']);
$currentDateTime = new DateTime();
$interval = $lastLogin->diff($currentDateTime);
if ($interval->h >= 24 || $interval->days > 0) {
echo json_encode(['error' => 'session_expired']);
exit();
}
}
$connect = db_connect();
if (!isset($_SESSION['token'])) {
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
$_SESSION['token_time'] = time();
} else {
$token = $_SESSION['token'];
}
?>
Tag : PHP, MySQL, HTML5, JavaScript
Date :
2025-03-07 06:07:12
By :
pharyu
View :
60
Reply :
6
แก้ไขได้ยัง ViewPattern.php เหมือนมันหากันไม่เจอ check ดูดีๆ ยัง Parameter จาก HTML และ script ที่ส่งไป
ดูที่ SQL ด้วยมันถูกไหม Debug ไปที่ละตัว check Path
======================================
มือใหม่เขียนแนว OOP or MVC จะยากหน่อย ถ้าส่งค่าไปถูก Request => Back End check ถูก เรียกจาก Databases => Responsive ผ่าน HTML แสดงผล จัด Logistics ก่อน ค่อยๆ check ไม่ยาก
Date :
2025-03-08 12:00:51
By :
Hararock
ไปปิด error report แถมไม่มี error log ไว้อีก แล้วจะไปหาข้อผิดพลาดที่ทำงานไม่ได้ ได้อย่างไร??
เรื่องนี้เคยบอกนับครั้งไม่ถ้วนแล้ว ปัญหาทำบน localhost ได้แต่ host จริงไม่ได้ ส่วนหนึ่งส่วนมากก็มาจากมัน config ไม่เหมือนกันและหรือเขียนโค้ดผิด ซึ่งถ้าอย่างน้อยสุดบน production site มีการ log ไว้เอามาดูทีเดียวก็เห็นแล้ว
Date :
2025-03-09 16:39:25
By :
mr.v
ขอบคุณครับ
เคยลองใส่ error แล้ว มันขึ้น Database connection failed ครับ ตัวข้อมูลอื่นๆ ที่ใช้งาน
Code
<?php
include_once '../config/database_config.php';
session_start(); // เริ่มต้น session
$connection = db_connect();
if (!$connection) {
die("Connection failed: " . mysqli_connect_error());
}
checkUserSession();
// รับค่าจาก URL
$prefixRef = isset($_GET['prefixRef']) ? $_GET['prefixRef'] : '';
$department = $_SESSION['user']['department'];
$role = $_SESSION['user']['role'];
$prefix = $_SESSION['user']['prefix'];
// ตรวจสอบว่ามีการส่ง prefixRef มาหรือไม่
if (empty($prefixRef)) {
header('Content-Type: application/json');
echo json_encode(['error' => 'ไม่มีข้อมูล prefixRef ที่ส่งมา']);
exit;
}
// ตรวจสอบสิทธิ์
if ($department === 'programmer' || $department === 'agent') {
$query = "SELECT m.ref_menu, m.name_menu
FROM menu m
JOIN ref_menu_display_order r ON m.ref_menu = r.ref_menu AND m.prefix = r.prefix
WHERE m.prefix = ? AND m.agent = ?
ORDER BY r.display_order";
} else {
//สิทธิ์ ทั่วไป
$query = "SELECT m.ref_menu, m.name_menu
FROM menu m
JOIN ref_menu_display_order r ON m.ref_menu = r.ref_menu AND m.prefix = r.prefix
WHERE m.prefix = ? AND m.agent = ? AND {$department}_{$role} = 'on'
ORDER BY r.display_order";
}
$stmt = mysqli_prepare($connection, $query);
if (!$stmt) {
header('Content-Type: application/json');
echo json_encode(['error' => 'Error preparing statement: ' . mysqli_error($connection)]);
exit;
}
mysqli_stmt_bind_param($stmt, "ss", $prefix, $prefixRef);
// รันคำสั่ง SQL
if (!mysqli_stmt_execute($stmt)) {
header('Content-Type: application/json');
echo json_encode(['error' => 'Error executing statement: ' . mysqli_stmt_error($stmt)]);
exit;
}
$result = mysqli_stmt_get_result($stmt);
$buttons = [];
if ($result && mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_assoc($result)) {
$buttons[] = [
'ref' => $row['ref_menu'],
'name' => $row['name_menu']
];
}
} else {
$buttons = ['error' => 'ไม่พบ ข้อมูล'];
}
// ส่งข้อมูลกลับในรูปแบบ JSON
header('Content-Type: application/json');
echo json_encode($buttons);
// ปิดการเชื่อมต่อ
mysqli_stmt_close($stmt);
mysqli_close($connection);
?>
Code
function loadButtons(prefixRef) {
fetch(`controllers/menu.php?prefixRef=${prefixRef}`)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json();
})
.then(data => {
const sidebar = document.getElementById('sidebar');
sidebar.innerHTML = ''; // ล้างเนื้อหาเก่าใน Sidebar
if (data.error) {
sidebar.innerHTML = '<h6>' + data.error + '</h6>';
} else {
data.forEach((item, index) => {
const button = document.createElement('button');
button.textContent = item.name;
button.dataset.ref = item.ref;
button.addEventListener('click', () => {
// ดึง ref และ prefixRef เพื่อโหลดข้อมูลเพิ่มเติม
const activeFooter = document.querySelector('.footer .activefooter');
const prefixRef = activeFooter ? activeFooter.dataset.prefixRef : '';
const newUrl = `${window.location.pathname}?ref=${item.ref}&prefixRef=${prefixRef}`;
history.pushState({ path: newUrl }, '', newUrl); // อัปเดต URL โดยไม่รีโหลดหน้า
loadPattern(item.ref, prefixRef);
// เปลี่ยน active state ใน Sidebar
const buttons = sidebar.querySelectorAll('button');
buttons.forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
});
// ตั้ง active ให้ปุ่มแรกใน Sidebar
if (index === 0) {
button.classList.add('active');
}
sidebar.appendChild(button);
});
// โหลดข้อมูลปุ่มแรกใน Sidebar ที่ active
loadActivePattern();
}
})
.catch(error => {
console.error('Error loading buttons:', error);
});
}
ตัวนี้ ข้อมูลมาปกติครับ ใช้งานได้ปกติครับ
ลองเช็ค แต่ละรอบ ค่อยๆ ป้อนใส่ทีละ code แล้ว ช่วงแรก ๆ ไม่เป็นไร แต่พอ ใส่ครบแล้ว up ใหม่ เป็นแบบเดิมครับ
Date :
2025-03-10 20:00:35
By :
pharyu
ได้แล้วครับ ตั้งค่า DB ผิดครับ
Date :
2025-03-10 21:28:42
By :
pharyu
พยายามจำให้ขึ้นใจไว้
1. ทิ้งร่องรอย error ไว้เสมอบน production site หรือที่ออนไลน์ใช้จริง แม้จะเป็น error log ก็จำเป็น เพราะมันช่วยลดเวลาหาปัญหาได้เยอะ
2. เปิดแสดง error เสมอบน development site หรือที่ๆเราเขียนโค้ด เพราะมันจะแก้ไขได้ง่ายกว่า มีอะไรผิดก็เห็นและแก้ได้เลย
อื่นๆนอกจากนี้ เป็นคห.ส่วนตัวจากที่เคยทำมาเยอะ ไม่คิดว่าเป็นหลักการที่ถูกหรือผิดฝ่ายเดียว คือ ในขั้นตอนเชื่อมต่อฐานข้อมูลหรืออะไรก็ตามที่เป็นการเริ่มทำงานของโค้ด ควรมีการตรวจสอบและถ้ามันตั้งค่าผิดจนทำงานต่อไม่ได้ ก็ควร throw exception แล้ว exit ไปเลย (ต้อง exit ด้วยเพื่อป้องกัน try catch ของเราโดยไม่ได้ตั้งใจ). บน production site ก็ปิด error เหลือไว้แค่หน้าขาวๆไม่ต้องทำอะไร เราแค่ไปตรวจ error log.
เหตุผลเพราะในเมื่อมันตั้งค่าผิดทำงานต่อไม่ได้แล้วก็ไม่ควรแสดงอะไรออกมาให้คนใช้งานที่คิดไม่ดีเดาทางได้ เผื่อมันเห็นช่องโหว่อื่นๆแล้วเอาไปเดาทางต่อได้ก่อนเรา. สำหรับกรณีฐานข้อมูลแบบนี้ ถ้าหากใช้ PDO มันสามารถตั้งให้ throw exception ได้อัตโนมัติ ก็จะสะดวกดี.
Date :
2025-03-10 22:07:42
By :
mr.v
Load balance : Server 00