'mysql', 'db_server' => 'localhost', 'db_name' => 'test', 'db_user' => 'root', 'db_pass' => 'toor', 'db_charset' => 'latin2', 'page_charset' => 'iso-8859-2', 'remember' => 1 ); foreach ($cookie as $k => $v) { if ('db_pass' == $k) { $v = base64_encode($v); } $k = COOKIE_PREFIX.$k; if (!isset($_COOKIE[$k])) { $_COOKIE[$k] = $v; } } require './dbkiss.php'; --------------------------------------------------------------------- */ /* Changelog: 1.14 * IIS server fixes: $_SERVER['SERVER_ADDR'] missing 1.13 * Table names and column names may start with numeric values ex. `52-644` as table name is now allowed. 1.12 * Fixed "order by" bug in views. 1.11 * Links in data output are now clickable. Clicking them does not reveal the location of your dbkiss script to external sites. 1.10 * Support for views in Postgresql (mysql had it already). * Views are now displayed in a seperate listing, to the right of the tables on main page. * Secure redirection - no referer header sent - when clicking external links (ex. powered by), so that the location of the dbkiss script on your site is not revealed. 1.09 * CSV export in sql editor and table view (feature sponsored by Patrick McGovern) 1.08 * date.timezone E_STRICT error fixed 1.07 * mysql tables with dash in the name generated errors, now all tables in mysql driver are enquoted with backtick. 1.06 * postgresql fix 1.05 * export of all structure and data does take into account the table name filter on the main page, so you can filter the tables that you want to export. 1.04 * exporting all structure/data didn't work (ob_gzhandler flush bug) * cookies are now set using httponly option * text editor complained about bad cr/lf in exported sql files (mysql create table uses \n, so insert queries need to be seperated by \n and not \r\n) 1.03 * re-created array_walk_recursive for php4 compatibility * removed stripping slashes from displayed content * added favicon (using base64_encode to store the icon in php code, so it is still one-file database browser) 1.02 * works with short_open_tag disabled * code optimizations/fixes * postgresql error fix for large tables 1.01 * fix for mysql 3.23, which doesnt understand "LIMIT x OFFSET z" 1.00 * bug fixes * minor feature enhancements * this release is stable and can be used in production environment 0.61 * upper casing keywords in submitted sql is disabled (it also modified quoted values) * sql error when displaying table with 0 rows * could not connect to database that had upper case characters */ // todo: php error handler which cancels buffer output and exits on error // todo: XSS and CSRF protection. // todo: connect screen: [x] create database (if not exists) [charset] // todo: connect screen: database (optional, if none provided will select the first database the user has access to) // todo: mysqli driver (check if mysql extension is loaded, if not try to use mysqli) // todo: support for the enum field type when editing row // todo: search whole database form should appear also on main page // todo: improve detecting primary keys when editing row (querying information_schema , for mysql > 4) // todo: when dbkiss_sql dir is missing, display a message in sql editor that some features won't work (templates, pagination) currently it displays a message to create that dir and EXIT, but should allow basic operations // todo: "Insert" on table view page // todo: edit table structure error_reporting(-1); ini_set('display_errors', true); if (!ini_get('date.timezone')) { ini_set('date.timezone', 'Europe/Warsaw'); } // Fix IIS missing variables in $_SERVER: if (!isset($_SERVER['REQUEST_URI'])) { $_SERVER['REQUEST_URI'] = $_SERVER['PHP_SELF']; if (isset($_SERVER['QUERY_STRING'])) { $_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING']; } } if (!isset($_SERVER['SERVER_ADDR'])) { if (isset($_SERVER['LOCAL_ADDR'])) { $_SERVER['SERVER_ADDR'] = $_SERVER['LOCAL_ADDR']; } else { $_SERVER['SERVER_ADDR'] = 'unknown'; } } set_error_handler('errorHandler'); register_shutdown_function('errorHandler_last'); ini_set('display_errors', 1); global $Global_LastError; function errorHandler_last() { if (function_exists("error_get_last")) { $error = error_get_last(); if ($error) { errorHandler($error['type'], $error['message'], $error['file'], $error['line']); } } } function errorHandler($errno, $errstr, $errfile, $errline) { global $Global_LastError; $Global_LastError = $errstr; // Check with error_reporting, if statement is preceded with @ we have to ignore it. if (!($errno & error_reporting())) { return; } // Headers. if (!headers_sent()) { header('HTTP/1.0 503 Service Unavailable'); while (ob_get_level()) { ob_end_clean(); } // This will cancel ob_gzhandler, so later we set Content-encoding to none. header('Content-Encoding: none'); // Fix gzip encoding header. header("Content-Type: text/html; charset=utf-8"); header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); } // Error short message. $errfile = basename($errfile); $msg = sprintf('%s
In %s on line %d.', nl2br($errstr), $errfile, $errline); // Display error. printf("PHP Error"); printf(""); printf(""); printf(""); printf("

PHP Error

"); printf($msg); if ("127.0.0.1" == $_SERVER["SERVER_ADDR"] && "127.0.0.1" == $_SERVER["REMOTE_ADDR"]) { // Showing backtrace only on localhost, cause it shows full arguments passed to functions, // that would be a security hole to display such data, cause it could contain some sensitive // data fetched from tables or could even contain a database connection user and password. printf("

Backtrace

"); ob_start(); debug_print_backtrace(); $trace = ob_get_clean(); $trace = preg_replace("/^#0[\s\S]+?\n#1/", "#1", $trace); // Remove call to errorHandler() from trace. $trace = trim($trace); print nl2br($trace); } printf(""); // Log error to file. if ("127.0.0.1" == $_SERVER["SERVER_ADDR"] && "127.0.0.1" == $_SERVER["REMOTE_ADDR"]) { error_log($msg); } // Email error. exit(); } // You can access this function only on localhost. if ("127.0.0.1" == $_SERVER["SERVER_ADDR"] && "127.0.0.1" == $_SERVER["REMOTE_ADDR"]) { function dump($data) { // @dump if (!headers_sent()) { header('HTTP/1.0 503 Service Unavailable'); while (ob_get_level()) { ob_end_clean(); } // This will cancel ob_gzhandler, so later we set Content-encoding to none. header('Content-encoding: none'); // Fix gzip encoding header. header("Content-type: text/html"); header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); } if (func_num_args() > 1) { $data = func_get_args(); } if ($data && count($data) == 2 && isset($data[1]) && "windows-1250" == strtolower($data[1])) { $charset = "windows-1250"; $data = $data[0]; } else if ($data && count($data) == 2 && isset($data[1]) && "iso-8859-2" == strtolower($data[1])) { $charset = "iso-8859-2"; $data = $data[0]; } else { $charset = "utf-8"; } printf('dump()'); printf('

dump()

'); ob_start(); print_r($data); $html = ob_get_clean(); $html = htmlspecialchars($html); printf('
%s
', $html); printf(''); exit(); } } if (isset($_GET['dbkiss_favicon'])) { $favicon = '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C///////vmsO//////++Zwv//////75mC/++Zwv/vmkN/wCpxv8C6fL/AHmm/8xmAO3ntoX2//////////++Zgv/37OG///////ftoj/v24S///////FcBL/x3AS/8VuEP8wpsn/BXCh/wCDrP/MZgDtzGYA7cxmAO3MZgDtvmYL/8ZwEv/DbxL/v24S/79uEv/CbxL/xXAS/8dwEv/GbxH/Ssvl/xyp0v8AZpn/AAAAAAAAAAAAAAAAAAAAAABmmf+E+P//TOX//xXT//8V0///O+D//2Tu//+M+v//eOn0/0rL5f8drNb/AGaZ/wAAAAAAAAAAAAAAAAAAAAAAZpn/hPj//0zl//8V0///FdP//zvg//9k7v//jPr//3jp9P9Ky+X/HazW/wBmmf8AAAAAAAAAAAAAAAAAAAAAAGaZ/3Xt+f8estv/BJDC/wB7rv8Ab6L/AGaZ/wBmmf8OdaT/Gou1/xijzv8AZpn/AAAAAAAAAAAAAAAAAAAAAABmmf8prNb/l9fq/77w9//B////qf///5r///+Z////huzy/2DG2f8Ufan/AGaZ/wAAAAAAAAAAAAAAAAAAAAAAZpn/7/n8//L////a////wf///6n///+a////mf///5n///+Z////j/X5/wBmmf8AAAAAAAAAAAAAAAAAAAAAAGaZ7+/1+f/y////2v///8H///+p////mv///5n///+Z////mf///4/1+f8AZpn/AAAAAAAAAAAAAAAAAAAAAABmmWAngqz/l8bZ/7/z+f/B////qf///5r///+Z////jfT4/2DG2f8Wfqr/AGaZYAAAAAAAAAAAAAAAAAAAAAAAAAAAAGaZIABmmY8AZpm/AGaZ/wBmmf8AZpn/AGaZ/wBmmb8AZpmPAGaZIAAAAAAAAQICAAA1EwAABAkAABEAAAACAgAASRIAAAcUAABRTvAAARrwAAEB8AABAfAAVgPwAAIB8AAiAfAABxT4AU0D'; header('Content-type: image/vnd.microsoft.icon'); echo base64_decode($favicon); exit(); } if (!function_exists('array_walk_recursive')) { function array_walk_recursive(&$array, $func) { foreach ($array as $k => $v) { if (is_array($v)) { array_walk_recursive($array[$k], $func); } else { $func($array[$k], $k); } } } } function create_links($text) { // Protocols: http, https, ftp, irc, svn // Parse emails also? $text = preg_replace('#([a-z]+://[a-zA-Z0-9\.\,\;\:\[\]\{\}\-\_\+\=\!\@\#\%\&\(\)\/\?\`\~]+)#e', 'create_links_eval("\\1")', $text); // Excaptions: // 1) cut last char if link ends with ":" or ";" or "." or "," - cause in 99% cases that char doesnt belong to the link // (check if previous char was "=" then let it stay cause that could be some variable in a query, some kind of separator) // (should we add also "-" ? But it is a valid char in links and very common, many links might end with it when creating from some title of an article?) // 2) brackets, the link could be inside one of 3 types of brackets: // [http://...] , {http://...} // and most common: (http://some.com/) OR http://some.com(some description of the link) // In these cases regular expression will catch: "http://some.com/)" AND "http://some.com(some" // So when we catch some kind of bracket in the link we will cut it unless there is also a closing bracket in the link: // We will not cut brackets in this link: http://en.wikipedia.org/wiki/Common_(entertainer) - wikipedia often uses brackets. return $text; } function create_links_eval($link) { $orig_link = $link; $cutted = ""; if (in_array($link[strlen($link)-1], array(":", ";", ".", ","))) { $link = substr($link, 0, -1); $cutted = $orig_link[strlen($orig_link)-1]; } if (($pos = strpos($link, "(")) !== false) { if (strpos($link, ")") === false) { $link = substr($link, 0, $pos); $cutted = substr($orig_link, $pos); } } else if (($pos = strpos($link, ")")) !== false) { if (strpos($link, "(") === false) { $link = substr($link, 0, $pos); $cutted = substr($orig_link, $pos); } } else if (($pos = strpos($link, "[")) !== false) { if (strpos($link, "]") === false) { $link = substr($link, 0, $pos); $cutted = substr($orig_link, $pos); } } else if (($pos = strpos($link, "]")) !== false) { if (strpos($link, "[") === false) { $link = substr($link, 0, $pos); $cutted = substr($orig_link, $pos); } } else if (($pos = strpos($link, "{")) !== false) { if (strpos($link, "}") === false) { $link = substr($link, 0, $pos); $cutted = substr($orig_link, $pos); } } else if (($pos = strpos($link, "}")) !== false) { if (strpos($link, "{") === false) { $link = substr($link, 0, $pos); $cutted = substr($orig_link, $pos); } } return "$link$cutted"; } function truncate_html($string, $length, $break_words = false, $end_str = '..') { // Does not break html tags whilte truncating, does not take into account chars inside tags: a = 1 char length. // Break words is always TRUE - no breaking is not implemented. // Limits: no handling of

Driver:  -  Server:  -  User:  -  Execute SQL ( open in Popup )  -  Database:  -  Db charset:  -  Page charset:  -  Disconnect

'&', '<' => '<', '>' => '>', '"' => '"', '\'' => ''' ); $s = preg_replace('/&#(\d+)/', '@@@@@#$1', $s); $s = str_replace(array_keys($html), array_values($html), $s); $s = preg_replace('/@@@@@#(\d+)/', '&#$1', $s); return trim($s); } function html_undo($s) { $html = array( '&' => '&', '<' => '<', '>' => '>', '"' => '"', '\'' => ''' ); return str_replace(array_values($html), array_keys($html), $s); } function html_once($s) { $s = str_replace(array('<','>','&lt;','&gt;'),array('<','>','<','>'),$s); return str_replace(array('<','>','<','>'),array('&lt;','&gt;','<','>'),$s); } function html_tags($s) { // succession of str_replace array is important! double escape bug.. return str_replace(array('<','>','<','>'), array('&lt;','&gt;','<','>'), $s); } function html_tags_undo($s) { return str_replace(array('<','>','&lt;', '&gt;'), array('<','>','<','>'), $s); } function html_allow_tags($s, $allow) { $s = html_once(trim($s)); preg_match_all('#<([a-z]+)>#i', $allow, $match); foreach ($match[1] as $tag) { $s = preg_replace('#<'.$tag.'\s+style\s*=\s*"([^"<>]+)"\s*>#i', '<'.$tag.' style="$1">', $s); $s = str_replace('<'.$tag.'>', '<'.$tag.'>', $s); $s = str_replace('</'.$tag.'>', '', $s); } return $s; } function str_truncate($string, $length, $etc = ' ..', $break_words = true) { if ($length == 0) { return ''; } if (strlen($string) > $length + strlen($etc)) { if (!$break_words) { $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1)); } return substr($string, 0, $length) . $etc; } return $string; } function str_bind($s, $dat = array(), $strict = false, $recur = 0) { if (!is_array($dat)) { return trigger_error('str_bind() failed. Second argument expects to be an array.', E_USER_ERROR); } if ($strict) { foreach ($dat as $k => $v) { if (strpos($s, "%$k%") === false) { return trigger_error(sprintf('str_bind() failed. Strict mode On. Key not found = %s. String = %s. Data = %s.', $k, $s, print_r($dat, 1)), E_USER_ERROR); } $s = str_replace("%$k%", $v, $s); } if (preg_match('#%\w+%#', $s, $match)) { return trigger_error(sprintf('str_bind() failed. Unassigned data for = %s. String = %s.', $match[0], $sBase), E_USER_ERROR); } return $s; } $sBase = $s; preg_match_all('#%\w+%#', $s, $match); $keys = $match[0]; $num = array(); foreach ($keys as $key) { $key2 = str_replace('%', '', $key); if (is_numeric($key2)) $num[$key] = true; /* ignore! if (!array_key_exists($key2, $dat)) { return trigger_error(sprintf('str_bind() failed. No data found for key: %s. String: %s.', $key, $sBase), E_USER_ERROR); } */ $val = $dat[$key2]; /* insecure! if (preg_match('#%\w+%#', $val) && $recur < 5) { $val = str_bind($val, $dat, $strict, ++$recur); } */ $s = str_replace($key, $val, $s); } if (count($num)) { if (count($dat) != count($num)) { return trigger_error('str_bind() failed. When using numeric data binding you need to use all data passed to the string. You also cannot mix numeric and name binding.', E_USER_ERROR); } } if (preg_match('#%\w+%#', $s, $match)) { /* ignore! return trigger_error(sprintf('str_bind() failed. Unassigned data for = %s. String = %s. Data = %s.', $match[0], htmlspecialchars(print_r($sBase, true)), print_r($dat, true)), E_USER_ERROR);*/ } return $s; } function dir_read($dir, $ignore_ext = array(), $allow_ext = array(), $sort = null) { if (is_null($ignore_ext)) $ignore_ext = array(); if (is_null($allow_ext)) $allow_ext = array(); foreach ($allow_ext as $k => $ext) { $allow_ext[$k] = str_replace('.', '', $ext); } $ret = array(); if ($handle = opendir($dir)) { while (($file = readdir($handle)) !== false) { if ($file != '.' && $file != '..') { $ignore = false; foreach ($ignore_ext as $ext) { if (file_ext_has($file, $ext)) { $ignore = true; } } if (is_array($allow_ext) && count($allow_ext) && !in_array(file_ext($file), $allow_ext)) { $ignore = true; } if (!$ignore) { $ret[] = array( 'file' => $dir.'/'.$file, 'time' => filemtime($dir.'/'.$file) ); } } } closedir($handle); } if ('date_desc' == $sort) { $ret = array_sort_desc($ret, 'time'); } return array_col($ret, 'file'); } function array_col($arr, $col) { $ret = array(); foreach ($arr as $k => $row) { $ret[] = $row[$col]; } return $ret; } function array_sort($arr, $col_key) { if (is_array($col_key)) { foreach ($arr as $k => $v) { $arr[$k]['__array_sort'] = ''; foreach ($col_key as $col) { $arr[$k]['__array_sort'] .= $arr[$k][$col].'_'; } } $col_key = '__array_sort'; } uasort($arr, create_function('$a,$b', 'if (is_null($a["'.$col_key.'"]) && !is_null($b["'.$col_key.'"])) return 1; if (!is_null($a["'.$col_key.'"]) && is_null($b["'.$col_key.'"])) return -1; return strnatcasecmp($a["'.$col_key.'"], $b["'.$col_key.'"]);')); if ('__array_sort' == $col_key) { foreach ($arr as $k => $v) { unset($arr[$k]['__array_sort']); } } return $arr; } function array_sort_desc($arr, $col_key) { if (is_array($col_key)) { foreach ($arr as $k => $v) { $arr[$k]['__array_sort'] = ''; foreach ($col_key as $col) { $arr[$k]['__array_sort'] .= $arr[$k][$col].'_'; } } $col_key = '__array_sort'; } uasort($arr, create_function('$a,$b', 'return strnatcasecmp($b["'.$col_key.'"], $a["'.$col_key.'"]);')); if ('__array_sort' == $col_key) { foreach ($arr as $k => $v) { unset($arr[$k]['__array_sort']); } } return $arr; } function options($options, $selected = null, $ignore_type = false) { $ret = ''; foreach ($options as $k => $v) { //str_replace('"', '\"', $k) $ret .= '