| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- <?php
- // db.php – shared bootstrap: error handling + PDO helper.
- // Included by every script that needs a database connection, so the error
- // configuration below applies site-wide.
- require_once __DIR__ . '/config.php';
- // $appEnv comes from config.php. Anything other than an explicit
- // 'development' is treated as production, so a missing or misspelt value
- // fails closed and never leaks internals to visitors.
- define('APP_DEBUG', (isset($appEnv) ? $appEnv : 'production') === 'development');
- error_reporting(E_ALL);
- ini_set('display_errors', APP_DEBUG ? '1' : '0');
- ini_set('display_startup_errors', APP_DEBUG ? '1' : '0');
- ini_set('log_errors', '1');
- /**
- * Log the real reason, show the visitor something harmless, stop.
- * Detail only reaches the browser in development.
- */
- function fail_hard(string $logMessage): void {
- error_log('PackIt: ' . $logMessage);
- if (!headers_sent()) {
- http_response_code(500);
- header('Content-Type: text/html; charset=utf-8');
- }
- if (APP_DEBUG) {
- echo '<p style="font-family:monospace;color:#c00">'
- . htmlspecialchars($logMessage) . '</p>';
- } else {
- echo '<p style="font-family:system-ui,sans-serif">Something went wrong on our side. '
- . 'Please try again in a moment.</p>';
- }
- exit;
- }
- // Uncaught exceptions (a dropped connection mid-query, a constraint we did not
- // anticipate) would otherwise print file paths and SQL to the page.
- set_exception_handler(function (Throwable $e): void {
- fail_hard(get_class($e) . ': ' . $e->getMessage()
- . ' in ' . $e->getFile() . ':' . $e->getLine());
- });
- /**
- * True when the visitor reached us over TLS, including through a reverse proxy
- * that terminates it and forwards X-Forwarded-Proto.
- */
- function request_is_https(): bool {
- if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
- return true;
- }
- if (strtolower($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https') {
- return true;
- }
- return (int)($_SERVER['SERVER_PORT'] ?? 0) === 443;
- }
- function get_pdo(): PDO {
- global $host, $dbname, $username, $password, $charset;
- static $pdo = null;
- if ($pdo === null) {
- $dsn = "mysql:host=$host;dbname=$dbname;charset=$charset";
- $options = [
- PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
- PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
- PDO::ATTR_EMULATE_PREPARES => false,
- ];
- try {
- $pdo = new PDO($dsn, $username, $password, $options);
- } catch (PDOException $e) {
- // The message names the host, database and user – log only.
- fail_hard('Database connection failed: ' . $e->getMessage());
- }
- }
- return $pdo;
- }
|