├── .gitignore ├── README.md ├── changelog.md ├── phpminiadmin.php └── samples ├── phpminiconfig.magento.php ├── phpminiconfig.php ├── phpminiconfig.sugarcrm.php ├── phpminiconfig.typo3.php ├── phpminiconfig.vtiger.php └── phpminiconfig.wordpress.php /.gitignore: -------------------------------------------------------------------------------- 1 | /phpminiconfig.php 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](http://phpminiadmin.sourceforge.net/img/scr_select.gif) 2 | 3 | [other screenshots](https://sourceforge.net/projects/phpminiadmin/#screenshots) 4 | 5 | ## How to Install 6 | - Download [phpminiadmin.php](https://raw.github.com/osalabs/phpminiadmin/master/phpminiadmin.php) file 7 | - example: `wget https://raw.github.com/osalabs/phpminiadmin/master/phpminiadmin.php` 8 | - Copy/Upload it to your webserver public directory (www or public_html or whatever...) 9 | - Open in your browser `http://yoursite.com/phpminiadmin.php` 10 | 11 | **Recommended:** For additional security you may edit phpminiadmin.php file and set some password (see `$ACCESS_PWD` variable) 12 | 13 | ### Dependencies 14 | The only required php extension is `mysqli`. Therefore if you got a white screen install it: 15 | 16 | `sudo apt-get install php-mysql` on Debian 17 | or enable `extension=php_mysqli.dll` in php.ini on Windows 18 | 19 | ## Config file (optional) 20 | 21 | You can also create phpminiconfig.php in the same directory as phpminiadmin.php with database credentials or password. 22 | This way you can easily install future releases of phpminiadmin.php 23 | 24 | In the directory samples you'll find phpminiconfig.php for known OpenSource packages 25 | 26 | - See phpminiconfig.php for an empty example 27 | - See phpminiconfig.magento.php to read Magento its app/etc/local.xml ($ACCESS_PWD is required) 28 | - See phpminiconfig.sugarcrm.php to read SugarCRM its config.php ($ACCESS_PWD is required) 29 | - See phpminiconfig.wordpress.php to read Wordpress its wp-config.php ($ACCESS_PWD is required) 30 | - See phpminiconfig.vtiger.php to read Vtiger its config.inc.php ($ACCESS_PWD is required) 31 | 32 | ## Links 33 | - [Screenshots](http://sourceforge.net/project/screenshots.php?group_id=181023) 34 | - [Live demo](http://phpminiadmin.sourceforge.net/phpminiadmin.php) (pwd: pmaiscool) 35 | - [Download latest version](https://raw.githubusercontent.com/osalabs/phpminiadmin/master/phpminiadmin.php) 36 | - [SourceForge page of the phpMiniAdmin](http://phpminiadmin.sourceforge.net/) 37 | - [My X/Twitter](https://x.com/osalabs) 38 | - [My website](http://osalabs.com) 39 | 40 | ## Change Log 41 | 42 | ### changes in phpMiniAdmin 1.9.240801 (latest) 43 | - fixed one php short open tag 44 | 45 | ### changes in phpMiniAdmin 1.9.240727 46 | - support for PHP 8.3 (cleaned up some PHP Warnings, deprecations) 47 | - enhancements: 48 | - multiple db servers support - define server's configs via `$DBSERVERS` and quickly switch between servers via top navbar dropdown 49 | - "ps" menu item in top navbar - shortcut for "show processlist" 50 | - "SHOW TABLE STATUS" now works quicker because emulated via select from `information_schema.TABLES` 51 | - "WITH" (Common Table Expressions (CTEs)) support 52 | - moved include for phpminiconfig a bit further, so it allows override more things 53 | - security improvements: 54 | - `$ACCESS_PWD` now is enforced except for local usage 55 | - added by default "SET GLOBAL local_infile=0" to prevent unwanted use of `LOAD DATA LOCAL INFILE`. Controlled by `$IS_LOCAL_INFILE` on the beginning of the script. 56 | 57 | ### changes in phpMiniAdmin 1.9.210705 58 | - removed use of function `get_magic_quotes_gpc` deprecated since PHP 7.4.0 59 | - utf8mb4 is now default charset 60 | - tested in PHP 8, cleaned up several PHP Warnings 61 | 62 | [see older changes in changelog](changelog.md) 63 | 64 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | ### changes in phpMiniAdmin 1.9.240727 (latest) 2 | - support for PHP 8.3 (cleaned up some PHP Warnings, deprecations) 3 | - enhancements: 4 | - multiple db servers support - define server's configs via `$DBSERVERS` and quickly switch between servers via top navbar dropdown 5 | - "ps" menu item in top navbar - shortcut for "show processlist" 6 | - "SHOW TABLE STATUS" now works quicker because emulated via select from `information_schema.TABLES` 7 | - "WITH" (Common Table Expressions (CTEs)) support 8 | - moved include for phpminiconfig a bit further, so it allows override more things 9 | - security improvements: 10 | - `$ACCESS_PWD` now is enforced except for local usage 11 | - added by default "SET GLOBAL local_infile=0" to prevent unwanted use of `LOAD DATA LOCAL INFILE`. Controlled by `$IS_LOCAL_INFILE` on the beginning of the script. 12 | 13 | ### changes in phpMiniAdmin 1.9.210705 (latest) 14 | - removed use of function `get_magic_quotes_gpc` deprecated since PHP 7.4.0 15 | - utf8mb4 is now default charset 16 | - tested in PHP 8, cleaned up several PHP Warnings 17 | 18 | ### changes in phpMiniAdmin 1.9.210129 19 | - limited max packet size during export to aviod PHP memory exhausted errors on huge tables 20 | 21 | ### changes in phpMiniAdmin 1.9.200928 22 | - added ability to setup SSL connection (define at least "ssl_ca" in `$DBDEF`) 23 | 24 | ### changes in phpMiniAdmin 1.9.190822 25 | - added ability to set socket for db connection 26 | 27 | ### changes in phpMiniAdmin 1.9.170203 28 | - added "compact view" option. If checked - width/height of grid cells limited, so you can see more rows/columns in case your data is large. And in this mode you can double-click on cells to "expand" just that particular cell. 29 | 30 | ### changes in phpMiniAdmin 1.9.170117 31 | - greatly optimized memory usage for large result sets (especially in export) 32 | 33 | ### changes in phpMiniAdmin 1.9.161116 34 | - added ability to dump exports right on server, without need to download 35 | - added ability to import from .sql or .gz file right on server, without need to upload one 36 | - fixed export, now it won't dump data for VIEWs 37 | 38 | ### changes in phpMiniAdmin 1.9.160705 39 | - screen appearance changes/fixes 40 | - added buttons which inserts standard "template" queries for Select, Insert, Update, Delete 41 | - disabled counting total number of records for pagination as it slows down response, especially on large datasets. Set `$IS_COUNT=true` to enable this feature back. 42 | 43 | ### changes in phpMiniAdmin 1.9.160630 44 | 45 | - all queries now base64 encoded to bypass applications firewalls. Note, **IE10 browser or later required from now** 46 | - SHOW TABLE STATUS fixed to display views, also Comments column added 47 | - fixed Settings/Login/Logoff 48 | 49 | ### changes in phpMiniAdmin 1.9.150729 50 | 51 | - switched to MySQLi because MySQL extension deprecated in PHP7 52 | 53 | ### changes in phpMiniAdmin 1.9.150108 54 | 55 | - httponly cookies so your plain password cannot be stolen by javascript 56 | - export disables foreign key checks 57 | - ask for super privilege(otherwise you get a error on import) 58 | - added support for a config file with credentials 59 | 60 | ### changes in phpMiniAdmin 1.9.141219 61 | 62 | - added: total count of records displayed for selects with pagination (example: 50 out of 104) 63 | - fixed: labels on forms, so inputs can be correctly narrated for blind users 64 | 65 | ### changes in phpMiniAdmin 1.9.140405 66 | 67 | - fixed: couple low risk XSS vulnerabilities 68 | - fixed: CSV export in UTF-8 69 | - added: ability to quickly create new database without SQL knowledge 70 | - added: autofocus to login pwd field 71 | - added: some minor compatibility changes for PHP 4.x 72 | - changed: yellow row highlight removed if clicked again 73 | - changed: if field contains binary data (char codes < 32), only first 16 hex will be displayed (if you want to dump full content - select just one this field) 74 | 75 | ### changes in phpMiniAdmin 1.8.120510 76 | 77 | - fixed: Undefined offset in get_rand_str 78 | - fixed: automatic relogin on XSS error 79 | - added: page navigator at the bottom 80 | - added: row counts, table sizes on the table list 81 | - added: MIT license 82 | - added: query history via browser's localStorage 83 | - added: if database empty - show databases 84 | - added: after import - show tables 85 | - changed: moved from html 4.01 to html 5 86 | - changed: simplified settings form 87 | 88 | ### changes in phpMiniAdmin 1.7.111025 89 | 90 | - fixed: unable to relogin on XSS error 91 | - fixed: truncate button doesn't work 92 | - minor changes in text labels and css styles 93 | 94 | -------------------------------------------------------------------------------- /phpminiadmin.php: -------------------------------------------------------------------------------- 1 | http://osalabs.com 5 | 6 | Light standalone PHP script for quick and easy access MySQL databases. 7 | http://phpminiadmin.sourceforge.net 8 | 9 | Dual licensed: GPL v2 and MIT, see texts at http://opensource.org/licenses/ 10 | */ 11 | 12 | $ACCESS_PWD=''; #!!!IMPORTANT!!! this is script access password, SET IT if you want to protect you DB from public access 13 | 14 | #DEFAULT db connection settings 15 | # --- WARNING! --- if you set defaults - it's recommended to set $ACCESS_PWD to protect your db! 16 | $DBSERVERS=[]; #array of arrays ['iname'=>'srv name', 'config'=>[see $DBDEF]] - define if you need manage multiple db servers 17 | $DBDEF=array( 18 | 'user'=>"",#required 19 | 'pwd'=>"", #required 20 | #optional: 21 | 'db'=>"", #default DB 22 | 'host'=>"", 23 | 'port'=>"", 24 | 'socket'=>"", 25 | 'chset'=>"utf8mb4",#optional, default charset 26 | #optional paths for ssl 27 | 'ssl_key'=>NULL, 28 | 'ssl_cert'=>NULL, 29 | 'ssl_ca'=>'',#minimum this is required for ssl connections, if set - ssl connection will try to be established. Example: /path/to/cacert.pem 30 | ); 31 | $IS_LOCAL_INFILE=false; #by default disable LOAD DATA LOCAL INFILE 32 | $IS_COUNT=false; #set to true if you want to see Total records when pagination occurs (SLOWS down all select queries!) 33 | $DUMP_FILE=dirname(__FILE__).'/pmadump'; #path to file without extension used for server-side exports (timestamp, .sql/.csv/.gz extension added) or imports(.sql) 34 | if (function_exists('date_default_timezone_set')) date_default_timezone_set('UTC');#required by PHP 5.1+ 35 | 36 | //constants 37 | $VERSION='1.9.240801'; 38 | $MAX_ROWS_PER_PAGE=50; #max number of rows in select per one page 39 | $D="\r\n"; #default delimiter for export 40 | $BOM=chr(239).chr(187).chr(191); 41 | $SHOW_D="SHOW DATABASES"; 42 | $SHOW_T="SHOW TABLE STATUS"; 43 | $DB=[]; #working copy for DB settings 44 | $SRV='';#selected server iname 45 | $self=$_SERVER['PHP_SELF']; 46 | 47 | $secure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on'; 48 | @session_set_cookie_params(0, null, null, $secure, true); 49 | ini_set('session.use_only_cookies', 1); 50 | @session_start(); 51 | 52 | if (!isset($_SESSION['XSS'])) $_SESSION['XSS']=get_rand_str(16); 53 | $xurl='XSS='.$_SESSION['XSS']; 54 | 55 | ini_set('display_errors',0); #turn on to debug db or script issues 56 | error_reporting(E_ALL ^ E_NOTICE); 57 | 58 | file_exists($f=dirname(__FILE__) . '/phpminiconfig.php')&&require($f); // Read from config (easier to update/override) 59 | 60 | if(isset($_REQUEST['login'])){ 61 | if ($_REQUEST['pwd']!=$ACCESS_PWD){ 62 | $err_msg="Invalid password. Try again"; 63 | }else{ 64 | $_SESSION['is_logged']=true; 65 | loadcfg(); 66 | } 67 | } 68 | 69 | if(isset($_REQUEST['logoff'])){ 70 | check_xss(); 71 | $_SESSION=[]; 72 | savecfg(); 73 | session_destroy(); 74 | $url=$self; 75 | if (!$ACCESS_PWD) $url='/'; 76 | header("location: $url"); 77 | exit; 78 | } 79 | 80 | if (!isset($_SESSION['is_logged'])){ 81 | if (empty($ACCESS_PWD)){ 82 | if (isTrusted()){ 83 | $_SESSION['is_logged']=true; 84 | loadcfg(); 85 | }else{ 86 | die("Set ACCESS_PWD to protect your database."); 87 | } 88 | }else{ 89 | print_login(); 90 | exit; 91 | } 92 | } 93 | if (isset($_REQUEST['savecfg'])){ 94 | check_xss(); 95 | savecfg(); 96 | } 97 | 98 | loadsess(); 99 | 100 | if (isset($_REQUEST['showcfg'])){ 101 | print_cfg(); 102 | exit; 103 | } 104 | 105 | //get initial values 106 | $SQLq=trim(b64d($_REQUEST['q']??'')); 107 | $page=intval($_REQUEST['p']??0); 108 | $isRefresh=intval($_REQUEST['refresh']??0); 109 | if ($isRefresh && $DB['db'] && preg_match('/^show/',$SQLq) ) $SQLq=$SHOW_T; 110 | 111 | if (db_connect('nodie')){ 112 | $time_start=microtime_float(); 113 | 114 | if ($_REQUEST['pi']??0){ 115 | ob_start();phpinfo();$html=ob_get_clean();preg_match("/]*>(.*?)<\/body>/is",$html,$m); 116 | $sqldr='
'.$m[1].'
'; 117 | }else{ 118 | if ($DB['db']){ 119 | if ($_REQUEST['shex']??0){ 120 | print_export(); 121 | }elseif ($_REQUEST['doex']??0){ 122 | check_xss();do_export(); 123 | }elseif ($_REQUEST['shim']??0){ 124 | print_import(); 125 | }elseif ($_REQUEST['doim']??0){ 126 | check_xss();do_import(); 127 | }elseif ($_REQUEST['dosht']??0){ 128 | check_xss();do_sht(); 129 | }elseif (!$isRefresh || preg_match('/^select|with|show|explain|desc/i',$SQLq) ){ 130 | if ($SQLq)check_xss(); 131 | do_sql($SQLq);#perform non-select SQL only if not refresh (to avoid dangerous delete/drop) 132 | } 133 | }else{ 134 | if ( $isRefresh ){ 135 | check_xss();do_sql($SHOW_D); 136 | }elseif ($_REQUEST['crdb']??0){ 137 | check_xss();do_sql('CREATE DATABASE '.dbqid($_REQUEST['new_db']));do_sql($SHOW_D); 138 | }elseif ( preg_match('/^(?:show\s+(?:databases|status|variables|process)|create\s+database|grant\s+)/i',$SQLq) ){ 139 | check_xss();do_sql($SQLq); 140 | }else{ 141 | $err_msg="Select Database first"; 142 | if (!$SQLq) do_sql($SHOW_D); 143 | } 144 | } 145 | } 146 | $time_all=ceil((microtime_float()-$time_start)*10000)/10000; 147 | 148 | print_screen(); 149 | }else{ 150 | print_cfg(); 151 | } 152 | 153 | function do_sql($q){ 154 | global $dbh,$last_sth,$last_sql,$reccount,$out_message,$SQLq,$SHOW_T,$DB; 155 | $SQLq=$q; 156 | 157 | $is_shts=0; 158 | if ($q==$SHOW_T){ 159 | #emulate show table status faster 160 | $is_shts=1; 161 | $q="select TABLE_NAME as Name,Engine,Version,Row_format,TABLE_ROWS as `Rows`,Avg_row_length,Data_length,Max_data_length,Index_length,TABLE_COMMENT as Comment 162 | from information_schema.TABLES where TABLE_TYPE IN ('BASE TABLE','VIEW') 163 | and TABLE_SCHEMA=".dbq($DB['db']); 164 | } 165 | 166 | if (!do_multi_sql($q)){ 167 | $out_message="Error: ".mysqli_error($dbh); 168 | }else{ 169 | if ($last_sth && $last_sql){ 170 | if($is_shts)$last_sql=$SHOW_T; 171 | $SQLq=$last_sql; 172 | if (preg_match("/^select|with|show|explain|desc/i",$last_sql)) { 173 | if ($q!=$last_sql) $out_message="Results of the last select displayed:"; 174 | display_select($last_sth,$last_sql); 175 | } else { 176 | $reccount=mysqli_affected_rows($dbh); 177 | $out_message="Done."; 178 | if (preg_match("/^insert|replace/i",$last_sql)) $out_message.=" Last inserted id=".get_identity(); 179 | if (preg_match("/^drop|truncate/i",$last_sql)) do_sql($SHOW_T); 180 | } 181 | } 182 | } 183 | } 184 | 185 | function display_select($sth,$q){ 186 | global $dbh,$SRV,$DB,$sqldr,$reccount,$is_sht,$xurl,$is_sm; 187 | $rc=["o","e"]; 188 | $srvn=ue($SRV); 189 | $dbn=ue($DB['db']); 190 | $sqldr=''; 191 | 192 | $is_shd=(preg_match('/^show\s+databases/i',$q)); 193 | $is_sht=(preg_match('/^show\s+tables|^SHOW\s+TABLE\s+STATUS/',$q)); 194 | $is_show_crt=(preg_match('/^show\s+create\s+table/i',$q)); 195 | 196 | if ($sth===FALSE or $sth===TRUE) return;#check if $sth is not a mysql resource 197 | 198 | $reccount=mysqli_num_rows($sth); 199 | $fields_num=mysqli_field_count($dbh); 200 | 201 | $w=''; 202 | if ($is_sm) $w='sm '; 203 | if ($is_sht || $is_shd) {$w='wa'; 204 | $url='?'.$xurl."&db=$dbn&srv=$srvn"; 205 | $sqldr.="
206 | MySQL Server: 207 | · Show Configuration Variables 208 | · Show Statistics 209 | · Show Processlist "; 210 | if ($is_shd) $sqldr.="· "; 211 | $sqldr.="
"; 212 | if ($is_sht) $sqldr.="Database: · Show Table Status"; 213 | $sqldr.="
"; 214 | } 215 | $abtn=''; 216 | if ($is_sht){ 217 | $abtn="
218 | 219 | 220 | 221 | selected tables
"; 222 | $sqldr.=$abtn.""; 223 | } 224 | 225 | $sqldr.="
"; 226 | $headers=""; 227 | if ($is_sht) $headers.=""; 228 | for($i=0;$i<$fields_num;$i++){ 229 | if ($is_sht && $i>0) break; 230 | $meta=mysqli_fetch_field($sth); 231 | $headers.=""; 232 | } 233 | if ($is_shd) $headers.=""; 234 | if ($is_sht) $headers.=""; 235 | $headers.="\n"; 236 | $sqldr.=$headers; 237 | $swp=false; 238 | while($row=mysqli_fetch_row($sth)){ 239 | $sqldr.=""; 240 | $v=$row[0]; 241 | if ($is_sht){ 242 | $vq=dbqid($v); 243 | $url='?'.$xurl."&db=$dbn&srv=$srvn&t=".b64u($v); 244 | $sqldr.="" 245 | ."" 246 | ."" 247 | ."" 248 | ."" 249 | ."" 250 | ."" 251 | ."" 252 | ."" 253 | ."" 254 | ."" 255 | ."" 256 | ."" 257 | ."" 258 | .""; 259 | }elseif ($is_shd){ 260 | $url='?'.$xurl."&db=".ue($v)."&srv=$srvn"; 261 | $sqldr.="" 262 | ."" 263 | ."" 264 | .""; 265 | }else{ 266 | for($i=0;$i<$fields_num;$i++){ 267 | $v=$row[$i]; 268 | if (is_null($v)) $v="NULL"; 269 | elseif (preg_match('/[\x00-\x09\x0B\x0C\x0E-\x1F]+/',$v)){#all chars <32, except \n\r(0D0A) 270 | $vl=strlen($v);$pf=''; 271 | if ($vl>16 && $fields_num>1){#show full dump if just one field 272 | $v=substr($v, 0, 16);$pf='...'; 273 | } 274 | $v='BINARY: '.chunk_split(strtoupper(bin2hex($v)),2,' ').$pf; 275 | }else $v=hs($v); 276 | if ($is_show_crt) $v="
$v
"; 277 | $sqldr.=""; 278 | } 279 | } 280 | $sqldr.="\n"; 281 | } 282 | $sqldr.="
".hs($meta->name)."
show create databaseshow table statusshow triggersengine~rowsdata sizeindex sizeshow create tableexplainindexesexportdroptruncateoptimizerepaircomment
".hs($v)."".hs($row[1])."".hs($row[4])."".hs($row[6])."".hs($row[8])."·sct·exp·ind·export·dr·tr·opt·rpr".hs($row[$fields_num-1])."".hs($v)."scdstatustrig
$v".(!strlen($v)?"
":'')."
\n".$abtn; 283 | } 284 | 285 | function print_header(){ 286 | global $err_msg,$VERSION,$DBSERVERS,$SRV,$DB,$dbh,$self,$is_sht,$xurl,$SHOW_T; 287 | $dbn=$DB['db']; 288 | ?> 289 | 290 | 291 | phpMiniAdmin 292 | 293 | 334 | 335 | 463 | 464 | 465 | 466 |
467 | 468 | 469 | 470 | 471 |
472 | phpMiniAdmin 473 | 475 | | Servers: 477 | 479 | · ">ps 480 | | ">Databases: 482 | 483 | '>show tables 484 | &shex=1'>export 485 | &shim=1'>import 486 | 487 | | Settings 488 | 489 | | Logoff 490 | | phpinfo 491 |
492 | 493 |
494 | 495 | =$MAX_ROWS_PER_PAGE) ){ 503 | $nav=""; 504 | } 505 | 506 | print_header(); 507 | ?> 508 | 509 |
510 |  
511 |
512 | 513 | 514 | 515 | 516 |
517 | 518 | 519 | 520 | 521 |

522 | 523 |
524 |
525 |
526 | Records: in sec
527 | 528 |
529 | 530 | 536 |
537 |
© 2004-2024 Oleg Savchuk
538 | 539 | 545 |
546 |

Access protected by password

547 |
548 | 549 | 550 | 551 |
552 |
553 | 562 |
563 |

DB Connection Settings

564 |
565 |
566 |
567 |
advanced settings
568 | 574 |
575 | 576 | 577 |
578 |
579 |
580 | \n".mysqli_error($dbh1)."
\n$sql"); 642 | return $sth; 643 | } 644 | 645 | function db_array($sql, $dbh1=NULL, $skiperr=0, $isnum=0){#array of rows 646 | $sth=db_query($sql, $dbh1, $skiperr, MYSQLI_USE_RESULT); 647 | if (!$sth) return; 648 | $res=[]; 649 | if ($isnum){ 650 | while($row=mysqli_fetch_row($sth)) $res[]=$row; 651 | }else{ 652 | while($row=mysqli_fetch_assoc($sth)) $res[]=$row; 653 | } 654 | mysqli_free_result($sth); 655 | return $res; 656 | } 657 | 658 | function db_row($sql){ 659 | $sth=db_query($sql); 660 | return mysqli_fetch_assoc($sth); 661 | } 662 | 663 | function db_value($sql,$dbh1=NULL,$skiperr=0){ 664 | $sth=db_query($sql,$dbh1,$skiperr); 665 | if (!$sth) return; 666 | $row=mysqli_fetch_row($sth); 667 | return $row[0]; 668 | } 669 | 670 | function get_identity($dbh1=NULL){ 671 | $dbh1=db_checkconnect($dbh1); 672 | return mysqli_insert_id($dbh1); 673 | } 674 | 675 | function get_db_select($sel=''){ 676 | global $DB,$SHOW_D; 677 | if (is_array($_SESSION['sql_sd']??0) && ($_REQUEST['db']??'')!='*'){//check cache 678 | $arr=$_SESSION['sql_sd']; 679 | }else{ 680 | $arr=db_array($SHOW_D,NULL,1); 681 | if (!is_array($arr)){ 682 | $arr=[0 => array('Database' => $DB['db'])]; 683 | } 684 | $_SESSION['sql_sd']=$arr; 685 | } 686 | return @sel($arr,'Database',$sel); 687 | } 688 | 689 | function chset_select($sel=''){ 690 | global $DBDEF; 691 | if (isset($_SESSION['sql_chset'])){ 692 | $arr=$_SESSION['sql_chset']; 693 | }else{ 694 | $arr=db_array("show character set",NULL,1); 695 | if (!is_array($arr)) $arr=[['Charset'=>$DBDEF['chset']]]; 696 | $_SESSION['sql_chset']=$arr; 697 | } 698 | 699 | return @sel($arr,'Charset',$sel); 700 | } 701 | 702 | function sel($arr,$n,$sel=''){ 703 | $res=''; 704 | foreach($arr as $a){ 705 | # echo $a[0]; 706 | $b=$a[$n]; 707 | $res.=""; 708 | } 709 | return $res; 710 | } 711 | 712 | function microtime_float(){ 713 | list($usec,$sec)=explode(" ",microtime()); 714 | return ((float)$usec+(float)$sec); 715 | } 716 | 717 | /* page nav 718 | $pg=int($_[0]); #current page 719 | $all=int($_[1]); #total number of items 720 | $PP=$_[2]; #number if items Per Page 721 | $ptpl=$_[3]; #page url /ukr/dollar/notes.php?page= for notes.php 722 | $show_all=$_[5]; #print Totals? 723 | */ 724 | function get_nav($pg, $all, $PP, $ptpl, $show_all=''){ 725 | $n=' '; 726 | $sep=" $n|$n\n"; 727 | if (!$PP) $PP=10; 728 | $allp=floor($all/$PP+0.999999); 729 | 730 | $pname=''; 731 | $res=''; 732 | $w=['Less','More','Back','Next','First','Total']; 733 | 734 | $sp=$pg-2; 735 | if($sp<0) $sp=0; 736 | if($allp-$sp<5 && $allp>=5) $sp=$allp-5; 737 | 738 | $res=""; 739 | 740 | if($sp>0){ 741 | $pname=pen($sp-1,$ptpl); 742 | $res.="$w[0]"; 743 | $res.=$sep; 744 | } 745 | for($p_p=$sp;$p_p<$allp && $p_p<$sp+5;$p_p++){ 746 | $first_s=$p_p*$PP+1; 747 | $last_s=($p_p+1)*$PP; 748 | $pname=pen($p_p,$ptpl); 749 | if($last_s>$all){ 750 | $last_s=$all; 751 | } 752 | if($p_p==$pg){ 753 | $res.="$first_s..$last_s"; 754 | }else{ 755 | $res.="$first_s..$last_s"; 756 | } 757 | if($p_p+1<$allp) $res.=$sep; 758 | } 759 | if($sp+5<$allp){ 760 | $pname=pen($sp+5,$ptpl); 761 | $res.="$w[1]"; 762 | } 763 | $res.="
\n"; 764 | 765 | if($pg>0){ 766 | $pname=pen($pg-1,$ptpl); 767 | $res.="$w[2] $n|$n "; 768 | $pname=pen(0,$ptpl); 769 | $res.="$w[4]"; 770 | } 771 | if($pg>0 && $pg+1<$allp) $res.=$sep; 772 | if($pg+1<$allp){ 773 | $pname=pen($pg+1,$ptpl); 774 | $res.="$w[3]"; 775 | } 776 | if ($show_all) $res.=" ($w[5] - $all) "; 777 | 778 | return $res; 779 | } 780 | 781 | function pen($p,$np=''){ 782 | return str_replace('%p%',$p, $np); 783 | } 784 | 785 | function savecfg(){ 786 | global $DBDEF; 787 | $v=$_REQUEST['v']??[]; 788 | if(!is_array($v))$v=[]; 789 | unset($v['ssl_ca']);unset($v['ssl_key']);unset($v['ssl_cert']);#don't allow override ssl paths from web 790 | $_SESSION['DB']=array_merge($DBDEF,$v); 791 | unset($_SESSION['sql_sd']); 792 | 793 | if ($_REQUEST['rmb']??0){ 794 | $tm=time()+60*60*24*30; 795 | newcookie("conn[db]", $v['db'],$tm); 796 | newcookie("conn[user]",$v['user'],$tm); 797 | newcookie("conn[pwd]", $v['pwd'],$tm); 798 | newcookie("conn[host]",$v['host'],$tm); 799 | newcookie("conn[port]",$v['port'],$tm); 800 | newcookie("conn[socket]",$v['socket'],$tm); 801 | newcookie("conn[chset]",$v['chset'],$tm); 802 | }else{ 803 | newcookie("conn[db]", FALSE,-1); 804 | newcookie("conn[user]",FALSE,-1); 805 | newcookie("conn[pwd]", FALSE,-1); 806 | newcookie("conn[host]",FALSE,-1); 807 | newcookie("conn[port]",FALSE,-1); 808 | newcookie("conn[socket]",FALSE,-1); 809 | newcookie("conn[chset]",FALSE,-1); 810 | } 811 | } 812 | 813 | // Allow httponly cookies, or the password is stored plain text in a cookie 814 | function newcookie($n,$v,$e){$x='';return setcookie($n,$v,$e,$x,$x,!!$x,!$x);} 815 | 816 | //during login only - from cookies or use defaults; 817 | function loadcfg(){ 818 | global $DBDEF; 819 | 820 | if( isset($_COOKIE['conn']) ){ 821 | $_SESSION['DB']=array_merge($DBDEF,$_COOKIE['conn']); 822 | }else{ 823 | $_SESSION['DB']=$DBDEF; 824 | } 825 | if (!strlen($_SESSION['DB']['chset'])) $_SESSION['DB']['chset']=$DBDEF['chset'];#don't allow empty charset 826 | } 827 | 828 | //each time - from session to $DB_* 829 | function loadsess(){ 830 | global $SRV,$DBSERVERS,$DB,$is_sm; 831 | 832 | $DB=$_SESSION['DB']; 833 | $rdb=$_REQUEST['db']??''; 834 | if ($rdb=='*') $rdb=''; 835 | 836 | #if server passed - use that srv config 837 | $SRV=$_REQUEST['srv']??''; 838 | if($SRV) { 839 | foreach ($DBSERVERS as $v) { 840 | if($v['iname']==$SRV) { 841 | if($DB['user'] . '|' . $DB['host'] != $v['config']['user'] . '|' . $v['config']['host']) $rdb = '';#reset db if host changed 842 | $DB=$v['config']; 843 | break; 844 | } 845 | } 846 | } 847 | 848 | if ($rdb) { 849 | $DB['db']=$rdb; 850 | } 851 | if($_REQUEST['GoSQL']??'') $_SESSION['is_sm']=intval($_REQUEST['is_sm']??0); 852 | $is_sm=intval($_SESSION['is_sm']??0); 853 | } 854 | 855 | function print_export(){ 856 | global $self,$xurl,$SRV,$DB,$DUMP_FILE; 857 | $t=$_REQUEST['rt']; 858 | $l=($t)?"Table $t":"whole DB"; 859 | print_header(); 860 | ?> 861 |
862 |

Export

863 |
864 | Structure
865 | Data

866 |
 
867 |
868 | 869 | 870 | 871 | (to export as csv - go to 'show tables' and export just ONE table) 872 | 873 |
874 |
875 |
876 |
877 |
878 | 879 | 880 | 881 | 882 | 883 |

"Dump on Server" exports to file:

884 |
885 |
886 | name).(($i<$fn-1)?",":"")); 925 | } 926 | ex_w($D); 927 | while($row=mysqli_fetch_row($sth)) ex_w(to_csv_row($row)); 928 | mysqli_free_result($sth); 929 | }else{ 930 | ex_start('.sql'); 931 | ex_hdr($ctp?$ctp:'text/plain',$DB['db'].(($ct==1&&$t[0])?".$t[0]":(($ct>1)?'.'.$ct.'tables':'')).".sql$aext"); 932 | ex_w("-- phpMiniAdmin dump $VERSION$D-- Datetime: ".date('Y-m-d H:i:s')."$D-- Host: {$DB['host']}$D-- Database: {$DB['db']}$D$D"); 933 | if ($DB['chset']) ex_w("/*!40030 SET NAMES {$DB['chset']} */;$D"); 934 | $ex_super && ex_w("/*!40030 SET GLOBAL max_allowed_packet=16777216 */;$D$D"); 935 | ex_w("/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;$D$D"); 936 | 937 | $sth=db_query("show full tables from ".dbqid($DB['db'])); 938 | while($row=mysqli_fetch_row($sth)){ 939 | if (!$rt||array_key_exists($row[0],$th)) do_export_table($row[0],$row[1],$MAXI); 940 | } 941 | 942 | ex_w("/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;$D$D"); 943 | ex_w("$D-- phpMiniAdmin dump end$D"); 944 | } 945 | ex_end(); 946 | if (!$ex_issrv) exit; 947 | $out_message='Export done successfully'; 948 | } 949 | 950 | function do_export_table($t='',$tt='',$MAXI=838860){ 951 | global $D,$ex_issrv; 952 | @set_time_limit(600); 953 | $qt=dbqid($t); 954 | 955 | if($_REQUEST['s']??0){ 956 | $sth=db_query("show create table $qt"); 957 | $row=mysqli_fetch_row($sth); 958 | $ct=preg_replace("/\n\r|\r\n|\n|\r/",$D,$row[1]); 959 | ex_w("DROP TABLE IF EXISTS $qt;$D$ct;$D$D"); 960 | } 961 | 962 | if ($_REQUEST['d']&&$tt!='VIEW'){//no dump for views 963 | $exsql=''; 964 | ex_w("/*!40000 ALTER TABLE $qt DISABLE KEYS */;$D"); 965 | $sth=db_query("select * from $qt",NULL,0,MYSQLI_USE_RESULT); 966 | while($row=mysqli_fetch_row($sth)){ 967 | $values=''; 968 | foreach($row as $v) $values.=(($values)?',':'').dbq($v); 969 | $exsql.=(($exsql)?',':'')."(".$values.")"; 970 | if (strlen($exsql)>$MAXI) { 971 | ex_w("INSERT INTO $qt VALUES $exsql;$D");$exsql=''; 972 | } 973 | } 974 | mysqli_free_result($sth); 975 | if ($exsql) ex_w("INSERT INTO $qt VALUES $exsql;$D"); 976 | ex_w("/*!40000 ALTER TABLE $qt ENABLE KEYS */;$D$D"); 977 | } 978 | if (!$ex_issrv) flush(); 979 | } 980 | 981 | function ex_hdr($ct,$fn){ 982 | global $ex_issrv; 983 | if ($ex_issrv) return; 984 | header("Content-type: $ct"); 985 | header("Content-Disposition: attachment; filename=\"$fn\""); 986 | } 987 | function ex_start($ext){ 988 | global $ex_isgz,$ex_gz,$ex_tmpf,$ex_issrv,$ex_f,$DUMP_FILE; 989 | if ($ex_isgz){ 990 | $ex_tmpf=($ex_issrv?export_fname($DUMP_FILE,true).$ext:tmp_name()).'.gz'; 991 | if (!($ex_gz=gzopen($ex_tmpf,'wb9'))) die("Error trying to create gz tmp file"); 992 | }else{ 993 | if ($ex_issrv) { 994 | if (!($ex_f=fopen(export_fname($DUMP_FILE,true).$ext,'wb'))) die("Error trying to create dump file"); 995 | } 996 | } 997 | } 998 | function ex_w($s){ 999 | global $ex_isgz,$ex_gz,$ex_issrv,$ex_f; 1000 | if ($ex_isgz){ 1001 | gzwrite($ex_gz,$s,strlen($s)); 1002 | }else{ 1003 | if ($ex_issrv){ 1004 | fwrite($ex_f,$s); 1005 | }else{ 1006 | echo $s; 1007 | } 1008 | } 1009 | } 1010 | function ex_end(){ 1011 | global $ex_isgz,$ex_gz,$ex_tmpf,$ex_issrv,$ex_f; 1012 | if ($ex_isgz){ 1013 | gzclose($ex_gz); 1014 | if (!$ex_issrv){ 1015 | readfile($ex_tmpf); 1016 | unlink($ex_tmpf); 1017 | } 1018 | }else{ 1019 | if ($ex_issrv) fclose($ex_f); 1020 | } 1021 | } 1022 | 1023 | function print_import(){ 1024 | global $self,$xurl,$SRV,$DB,$DUMP_FILE; 1025 | print_header(); 1026 | ?> 1027 |
1028 |

Import DB

1029 |
1030 |
1031 |
1032 |
1033 |
1035 |
1037 | 1038 | 1039 |
1040 |


1041 | 1065 |
1066 | '(? '(? '\*\/', 1201 | '#' => '[\r\n]+', 1202 | '--' => '[\r\n]+', 1203 | ]; 1204 | if ( $aCLOSE[$ochar] && preg_match("/(".$aCLOSE[$ochar].")/", $str, $m, PREG_OFFSET_CAPTURE, $pos ) ) { 1205 | $clchar=$m[1][0]; 1206 | $clpos=$m[1][1]; 1207 | $sl=strlen($m[2][0]??''); 1208 | if ($ochar=="'" && $sl){ 1209 | if ($sl % 2){ #don't count as CLOSE char if number of slashes before ' ODD 1210 | list($clchar, $clpos)=get_close_char($str, $clpos+strlen($clchar), $ochar); 1211 | }else{ 1212 | $clpos+=strlen($clchar)-1;$clchar="'";#correction 1213 | } 1214 | } 1215 | } 1216 | return [$clchar, $clpos]; 1217 | } 1218 | 1219 | function do_one_sql($sql){ 1220 | global $last_sth,$last_sql,$MAX_ROWS_PER_PAGE,$page,$is_limited_sql,$last_count,$IS_COUNT; 1221 | $sql=trim($sql); 1222 | $sql=preg_replace("/;$/","",$sql); 1223 | if ($sql){ 1224 | $last_sql=$sql;$is_limited_sql=0; 1225 | $last_count=NULL; 1226 | if (preg_match("/^select/i",$sql) && !preg_match("/limit +\d+/i", $sql)){ 1227 | if ($IS_COUNT){ 1228 | #get total count 1229 | $sql1='select count(*) from ('.$sql.') ___count_table'; 1230 | $last_count=db_value($sql1,NULL,'noerr'); 1231 | } 1232 | $offset=$page*$MAX_ROWS_PER_PAGE; 1233 | $sql.=" LIMIT $offset,$MAX_ROWS_PER_PAGE"; 1234 | $is_limited_sql=1; 1235 | } 1236 | $last_sth=db_query($sql,0,'noerr'); 1237 | return $last_sth; 1238 | } 1239 | return 1; 1240 | } 1241 | 1242 | function do_sht(){ 1243 | global $SHOW_T; 1244 | $cb=$_REQUEST['cb']??[]; 1245 | if(!is_array($cb))$cb=[]; 1246 | $sql=''; 1247 | switch ($_REQUEST['dosht']??''){ 1248 | case 'exp':$_REQUEST['rt']=join(",",$cb);print_export();exit; 1249 | case 'drop':$sq='DROP TABLE';break; 1250 | case 'trunc':$sq='TRUNCATE TABLE';break; 1251 | case 'opt':$sq='OPTIMIZE TABLE';break; 1252 | } 1253 | if ($sq){ 1254 | foreach($cb as $v){ 1255 | $sql.=$sq." $v;\n"; 1256 | } 1257 | } 1258 | if ($sql) do_sql($sql); 1259 | do_sql($SHOW_T); 1260 | } 1261 | 1262 | function to_csv_row($adata){ 1263 | global $D; 1264 | $r=''; 1265 | foreach ($adata as $a){ 1266 | $r.=(($r)?",":"").qstr($a); 1267 | } 1268 | return $r.$D; 1269 | } 1270 | function qstr($s){ 1271 | $s=nl2br($s??''); 1272 | $s=str_replace('"','""',$s); 1273 | return '"'.$s.'"'; 1274 | } 1275 | 1276 | function get_rand_str($len){ 1277 | $result=''; 1278 | $chars=preg_split('//','ABCDEFabcdef0123456789'); 1279 | for($i=0;$i<$len;$i++) $result.=$chars[rand(0,count($chars)-1)]; 1280 | return $result; 1281 | } 1282 | 1283 | function check_xss(){ 1284 | global $self; 1285 | if ($_SESSION['XSS']!=trim($_REQUEST['XSS'])){ 1286 | unset($_SESSION['XSS']); 1287 | header("location: $self"); 1288 | exit; 1289 | } 1290 | } 1291 | 1292 | function rw($s){#for debug 1293 | echo hs(var_dump($s))."
\n"; 1294 | } 1295 | 1296 | function tmp_name() { 1297 | if ( function_exists('sys_get_temp_dir')) return tempnam(sys_get_temp_dir(),'pma'); 1298 | 1299 | if( !($temp=getenv('TMP')) ) 1300 | if( !($temp=getenv('TEMP')) ) 1301 | if( !($temp=getenv('TMPDIR')) ) { 1302 | $temp=tempnam(__FILE__,''); 1303 | if (file_exists($temp)) { 1304 | unlink($temp); 1305 | $temp=dirname($temp); 1306 | } 1307 | } 1308 | return $temp ? tempnam($temp,'pma') : null; 1309 | } 1310 | 1311 | function hs($s){ 1312 | return htmlspecialchars(is_null($s)?'':$s, ENT_QUOTES,'UTF-8'); 1313 | } 1314 | function eo($s){//echo+escape 1315 | echo hs($s); 1316 | } 1317 | function ue($s){ 1318 | return urlencode($s); 1319 | } 1320 | 1321 | function b64e($s){ 1322 | return base64_encode($s); 1323 | } 1324 | function b64u($s){ 1325 | return ue(base64_encode($s)); 1326 | } 1327 | function b64d($s){ 1328 | return base64_decode($s??''); 1329 | } 1330 | 1331 | function isTrusted() { 1332 | $trstd=['127.0.0.1','::1']; #do not require ACCESS_PWD for local 1333 | if (in_array($_SERVER['REMOTE_ADDR'], $trstd)) return true; 1334 | return false; 1335 | } 1336 | -------------------------------------------------------------------------------- /samples/phpminiconfig.magento.php: -------------------------------------------------------------------------------- 1 | ()?#"; 25 | if (!preg_match_all($regexp, preg_replace("#^.*\s*([\s\S]+)\s*.*$#s", "\\1", implode('', file($config))), $match)) {return false;} 26 | 27 | // Create connection array 28 | $keys = array_combine($match[1], $match[3]); 29 | 30 | // Set variables from the database definition 31 | if (isset($keys['host'])) { 32 | $keys['host'] = explode(':', $keys['host']); 33 | $DBDEF['host'] = $keys['host'][0]; 34 | isset($keys['host'][1]) && ($DBDEF['port'] = $keys['host'][1]); 35 | } 36 | if (isset($keys['dbname'])) {$DBDEF['db'] = $keys['dbname'];} 37 | if (isset($keys['username'])) {$DBDEF['user'] = $keys['username'];} 38 | if (isset($keys['password'])) {$DBDEF['pwd'] = $keys['password'];} 39 | if (isset($keys['initStatements'])) {$DBDEF['chset'] = str_replace('SET NAMES ', '', $keys['initStatements']);} 40 | 41 | return true; 42 | }function mo_q() {return isset($_REQUEST['q'])||($_REQUEST['q']='SHOW TABLE STATUS');} // Initial query 43 | $ACCESS_PWD&&mo_c($config, $DBDEF)&&mo_q(); 44 | unset($config); 45 | -------------------------------------------------------------------------------- /samples/phpminiconfig.php: -------------------------------------------------------------------------------- 1 | '',#required 8 | 'pwd'=>'', #required 9 | 'db'=>'', #optional, default DB 10 | 'host'=>'',#optional 11 | 'port'=>'',#optional 12 | 'socket'=>'',#optional 13 | 'chset'=>'utf8mb4',#optional, default charset 14 | #optional paths for ssl 15 | 'ssl_key'=>NULL, 16 | 'ssl_cert'=>NULL, 17 | 'ssl_ca'=>"",#minimum this is required for ssl connections, if set - ssl connection will try to be established. Example: /path/to/cacert.pem 18 | ); 19 | 20 | #EXAMPLE for multiple db servers 21 | $DBSERVERS = array( 22 | [ 23 | 'iname' => 'localhost', #just a visible name 24 | 'config' => $DBDEF, #server connection config - same structure as $DBDEF 25 | ], 26 | [ 27 | 'iname' => 'localhost2', 28 | 'config' => $DBDEF, 29 | ], 30 | ); 31 | -------------------------------------------------------------------------------- /samples/phpminiconfig.sugarcrm.php: -------------------------------------------------------------------------------- 1 | \s*['\"]([^'\"]+)['\"]#"; 24 | if (!preg_match_all($regexp, implode('', file($config)), $match)) {return false;} 25 | 26 | // Create connection array 27 | $keys = array_combine($match[1], $match[2]); 28 | 29 | // Set variables from the database definition 30 | if (isset($keys['host_name'])) {$DBDEF['host'] = $keys['host_name'];} 31 | if (isset($keys['port'])) {$DBDEF['port'] = $keys['port'];} 32 | if (isset($keys['user_name'])) {$DBDEF['user'] = $keys['user_name'];} 33 | if (isset($keys['name'])) {$DBDEF['db'] = $keys['name'];} 34 | if (isset($keys['password'])) {$DBDEF['pwd'] = $keys['password'];} 35 | 36 | return true; 37 | }function sc_q() {return isset($_REQUEST['q'])||($_REQUEST['q']='SHOW TABLE STATUS');} // Initial query 38 | $ACCESS_PWD&&sc_c($config, $DBDEF)&&sc_q(); 39 | unset($config); 40 | 41 | -------------------------------------------------------------------------------- /samples/phpminiconfig.typo3.php: -------------------------------------------------------------------------------- 1 |