Files
mrbs-equbao-2026/dbsys.inc
T
人事系统开发 1ba6efd8ed MRBS 1.12.2 等保2.0二级整改完整提交
包含:登录失败锁定、90天密码有效期、30分钟会话超时、
强制改密、登录审计日志、屏幕水印、企业背景图、
备案信息固定底部、favicon、JS空集合保护、
会话过期体验优化(403 JSON)、display_errors 关闭、
固定 key 根治 Integrity check failed 等全部改动

注意:config.inc.php/.htaccess/.user.ini 含敏感信息,
通过 .gitignore 排除,勿推送到公开仓库。
2026-09-09 16:55:02 +08:00

137 lines
4.0 KiB
PHP

<?php
declare(strict_types=1);
namespace MRBS;
// Returns the full table name including schema and prefix for a given table.
// Needs to be dynamic rather than static in case we are running a multisite
// installation and want to switch sites, eg during a database upgrade.
use MRBS\DB\DB;
use MRBS\DB\DBFactory;
use MRBS\Errors\Errors;
use PDO;
function _tbl(string $short_name, bool $include_schema=true) : string
{
global $dbsys, $db_tbl_prefix, $db_schema;
// Do some sanity checking
if (!isset($short_name))
{
throw new \Exception('$short_name not set.');
}
$result = $db_tbl_prefix . $short_name;
// Prepend the schema name if set and form a qualified name for all databases
// other than MySQL, which is one of the few that doesn't support schemas.
// (Although in practice this means PostgreSQL at the moment, it's possible that
// in the future support for more databases may be added)
if ($include_schema && (mb_strpos($dbsys, 'mysql') === false) && isset($db_schema))
{
$result = $db_schema . '.' . $result;
}
return $result;
}
function get_table_short_name(string $table) : string
{
global $db_tbl_prefix;
// Get everything after the last '.', ie strip off any database
// and schema names
if (false !== ($pos = mb_strrpos($table, '.')))
{
$result = mb_substr($table, $pos + 1);
}
else
{
$result = $table;
}
// Strip the prefix off the table name
return mb_substr($result, mb_strlen($db_tbl_prefix));
}
// Convenience wrapper function to provide access to a DB object for
// default MRBS database
function db() : DB
{
global $db_persist, $db_host, $db_login, $db_password,
$db_database, $db_port, $dbsys, $db_options;
static $db_obj = null;
try
{
if (is_null($db_obj))
{
throw new \Exception("DB object not yet created");
}
// Check to see if the connection is still there. If it isn't - perhaps because it
// has been timed out, eg by MySQL's wait_timeout - then we throw an exception which
// will cause us to re-create a connection.
// (Note that we cannot try a "SELECT 1" query or something similar to check if the
// connection is still there, because if it is then the query will cause the last insert
// id to be lost.)
// TODO: sometimes the symptom of a lost connection is a warning of the form "Packets
// TODO: out of order. Expected 1 received 0. Packet size=145". Need to work out why
// TODO: this happens and do something about it.
if ($db_obj->getAttribute(PDO::ATTR_SERVER_INFO) == 'MySQL server has gone away')
{
// On most recent versions of PHP the call to getAttribute() on a lost connection will
// throw an exception anyway, but just in case it doesn't we'll throw one. See
// https://stackoverflow.com/questions/21595402/php-pdo-how-to-get-the-current-connection-status
throw new \Exception('MySQL server has gone away');
}
}
catch (\Exception $e)
{
try
{
$db_obj = DBFactory::create(
$dbsys,
$db_host,
$db_login,
$db_password,
$db_database,
(bool)$db_persist,
$db_port,
$db_options
);
}
catch (\Exception $e)
{
trigger_error($e->getMessage(), E_USER_WARNING);
Errors::fatalError(get_vocab('fatal_db_error'));
}
}
return $db_obj;
}
// Returns the db schema version as recorded in the database. If there is no version
// recorded then returns 0. If $local is true then the local db schema version is returned.
function db_schema_version(DB $handle, bool $local=false) : int
{
if ($handle->table_exists(_tbl('variables')))
{
$sql_params = [':variable_name' => ($local) ? 'local_db_version' : 'db_version'];
$sql = "SELECT variable_content
FROM " . _tbl('variables') . "
WHERE variable_name=:variable_name";
$result = $handle->query1($sql, $sql_params);
}
else
{
// Default version is 0, before we had schema versions
$result = 0;
}
return max($result, 0);
}