escapeMysqlWildcards() public static method

Note: This function does not escape backslashes!
public static escapeMysqlWildcards ( string $name ) : string
$name string the string to escape
return string the escaped string
/**
 * Prepares queries for adding users and
 * also create database and return query and message
 *
 * @param boolean $_error         whether user create or not
 * @param string  $real_sql_query SQL query for add a user
 * @param string  $sql_query      SQL query to be displayed
 * @param string  $username       username
 * @param string  $hostname       host name
 * @param string  $dbname         database name
 *
 * @return array  $sql_query, $message
 */
function PMA_addUserAndCreateDatabase($_error, $real_sql_query, $sql_query, $username, $hostname, $dbname)
{
    if ($_error || !empty($real_sql_query) && !$GLOBALS['dbi']->tryQuery($real_sql_query)) {
        $_REQUEST['createdb-1'] = $_REQUEST['createdb-2'] = $_REQUEST['createdb-3'] = null;
        $message = Message::rawError($GLOBALS['dbi']->getError());
    } else {
        $message = Message::success(__('You have added a new user.'));
    }
    if (isset($_REQUEST['createdb-1'])) {
        // Create database with same name and grant all privileges
        $q = 'CREATE DATABASE IF NOT EXISTS ' . Util::backquote(Util::sqlAddSlashes($username)) . ';';
        $sql_query .= $q;
        if (!$GLOBALS['dbi']->tryQuery($q)) {
            $message = Message::rawError($GLOBALS['dbi']->getError());
        }
        /**
         * Reload the navigation
         */
        $GLOBALS['reload'] = true;
        $GLOBALS['db'] = $username;
        $q = 'GRANT ALL PRIVILEGES ON ' . Util::backquote(Util::escapeMysqlWildcards(Util::sqlAddSlashes($username))) . '.* TO \'' . Util::sqlAddSlashes($username) . '\'@\'' . Util::sqlAddSlashes($hostname) . '\';';
        $sql_query .= $q;
        if (!$GLOBALS['dbi']->tryQuery($q)) {
            $message = Message::rawError($GLOBALS['dbi']->getError());
        }
    }
    if (isset($_REQUEST['createdb-2'])) {
        // Grant all privileges on wildcard name (username\_%)
        $q = 'GRANT ALL PRIVILEGES ON ' . Util::backquote(Util::sqlAddSlashes($username) . '\\_%') . '.* TO \'' . Util::sqlAddSlashes($username) . '\'@\'' . Util::sqlAddSlashes($hostname) . '\';';
        $sql_query .= $q;
        if (!$GLOBALS['dbi']->tryQuery($q)) {
            $message = Message::rawError($GLOBALS['dbi']->getError());
        }
    }
    if (isset($_REQUEST['createdb-3'])) {
        // Grant all privileges on the specified database to the new user
        $q = 'GRANT ALL PRIVILEGES ON ' . Util::backquote(Util::sqlAddSlashes($dbname)) . '.* TO \'' . Util::sqlAddSlashes($username) . '\'@\'' . Util::sqlAddSlashes($hostname) . '\';';
        $sql_query .= $q;
        if (!$GLOBALS['dbi']->tryQuery($q)) {
            $message = Message::rawError($GLOBALS['dbi']->getError());
        }
    }
    return array($sql_query, $message);
}
 /**
  * returns array of all tables in given db or dbs
  * this function expects unquoted names:
  * RIGHT: my_database
  * WRONG: `my_database`
  * WRONG: my\_database
  * if $tbl_is_group is true, $table is used as filter for table names
  *
  * <code>
  * $GLOBALS['dbi']->getTablesFull('my_database');
  * $GLOBALS['dbi']->getTablesFull('my_database', 'my_table'));
  * $GLOBALS['dbi']->getTablesFull('my_database', 'my_tables_', true));
  * </code>
  *
  * @param string          $database     database
  * @param string          $table        table name
  * @param boolean         $tbl_is_group $table is a table group
  * @param mixed           $link         mysql link
  * @param integer         $limit_offset zero-based offset for the count
  * @param boolean|integer $limit_count  number of tables to return
  * @param string          $sort_by      table attribute to sort by
  * @param string          $sort_order   direction to sort (ASC or DESC)
  * @param string          $table_type   whether table or view
  *
  * @todo    move into Table
  *
  * @return array           list of tables in given db(s)
  */
 public function getTablesFull($database, $table = '', $tbl_is_group = false, $link = null, $limit_offset = 0, $limit_count = false, $sort_by = 'Name', $sort_order = 'ASC', $table_type = null)
 {
     if (true === $limit_count) {
         $limit_count = $GLOBALS['cfg']['MaxTableList'];
     }
     // prepare and check parameters
     if (!is_array($database)) {
         $databases = array($database);
     } else {
         $databases = $database;
     }
     $tables = array();
     if (!$GLOBALS['cfg']['Server']['DisableIS']) {
         $sql_where_table = $this->_getTableCondition($table, $tbl_is_group, $table_type);
         // for PMA bc:
         // `SCHEMA_FIELD_NAME` AS `SHOW_TABLE_STATUS_FIELD_NAME`
         //
         // on non-Windows servers,
         // added BINARY in the WHERE clause to force a case sensitive
         // comparison (if we are looking for the db Aa we don't want
         // to find the db aa)
         $this_databases = array_map('PMA\\libraries\\Util::sqlAddSlashes', $databases);
         $sql = $this->_getSqlForTablesFull($this_databases, $sql_where_table);
         // Sort the tables
         $sql .= " ORDER BY {$sort_by} {$sort_order}";
         if ($limit_count) {
             $sql .= ' LIMIT ' . $limit_count . ' OFFSET ' . $limit_offset;
         }
         $tables = $this->fetchResult($sql, array('TABLE_SCHEMA', 'TABLE_NAME'), null, $link);
         if ($sort_by == 'Name' && $GLOBALS['cfg']['NaturalOrder']) {
             // here, the array's first key is by schema name
             foreach ($tables as $one_database_name => $one_database_tables) {
                 uksort($one_database_tables, 'strnatcasecmp');
                 if ($sort_order == 'DESC') {
                     $one_database_tables = array_reverse($one_database_tables);
                 }
                 $tables[$one_database_name] = $one_database_tables;
             }
         } elseif ($sort_by == 'Data_length') {
             // Size = Data_length + Index_length
             foreach ($tables as $one_database_name => $one_database_tables) {
                 uasort($one_database_tables, function ($a, $b) {
                     $aLength = $a['Data_length'] + $a['Index_length'];
                     $bLength = $b['Data_length'] + $b['Index_length'];
                     return $aLength == $bLength ? 0 : $aLength < $bLength ? -1 : 1;
                 });
                 if ($sort_order == 'DESC') {
                     $one_database_tables = array_reverse($one_database_tables);
                 }
                 $tables[$one_database_name] = $one_database_tables;
             }
         }
     }
     // end (get information from table schema)
     // If permissions are wrong on even one database directory,
     // information_schema does not return any table info for any database
     // this is why we fall back to SHOW TABLE STATUS even for MySQL >= 50002
     if (empty($tables)) {
         foreach ($databases as $each_database) {
             if ($table || true === $tbl_is_group || !empty($table_type)) {
                 $sql = 'SHOW TABLE STATUS FROM ' . Util::backquote($each_database) . ' WHERE';
                 $needAnd = false;
                 if ($table || true === $tbl_is_group) {
                     $sql .= " `Name` LIKE '" . Util::escapeMysqlWildcards(Util::sqlAddSlashes($table, true)) . "%'";
                     $needAnd = true;
                 }
                 if (!empty($table_type)) {
                     if ($needAnd) {
                         $sql .= " AND";
                     }
                     if ($table_type == 'view') {
                         $sql .= " `Comment` = 'VIEW'";
                     } else {
                         if ($table_type == 'table') {
                             $sql .= " `Comment` != 'VIEW'";
                         }
                     }
                 }
             } else {
                 $sql = 'SHOW TABLE STATUS FROM ' . Util::backquote($each_database);
             }
             $useStatusCache = false;
             if (extension_loaded('apc') && isset($GLOBALS['cfg']['Server']['StatusCacheDatabases']) && !empty($GLOBALS['cfg']['Server']['StatusCacheLifetime'])) {
                 $statusCacheDatabases = (array) $GLOBALS['cfg']['Server']['StatusCacheDatabases'];
                 if (in_array($each_database, $statusCacheDatabases)) {
                     $useStatusCache = true;
                 }
             }
             $each_tables = null;
             if ($useStatusCache) {
                 $cacheKey = 'phpMyAdmin_tableStatus_' . sha1($GLOBALS['cfg']['Server']['host'] . '_' . $sql);
                 $each_tables = apc_fetch($cacheKey);
             }
             if (!$each_tables) {
                 $each_tables = $this->fetchResult($sql, 'Name', null, $link);
             }
             if ($useStatusCache) {
                 apc_store($cacheKey, $each_tables, $GLOBALS['cfg']['Server']['StatusCacheLifetime']);
             }
             // Sort naturally if the config allows it and we're sorting
             // the Name column.
             if ($sort_by == 'Name' && $GLOBALS['cfg']['NaturalOrder']) {
                 uksort($each_tables, 'strnatcasecmp');
                 if ($sort_order == 'DESC') {
                     $each_tables = array_reverse($each_tables);
                 }
             } else {
                 // Prepare to sort by creating array of the selected sort
                 // value to pass to array_multisort
                 // Size = Data_length + Index_length
                 if ($sort_by == 'Data_length') {
                     foreach ($each_tables as $table_name => $table_data) {
                         ${$sort_by}[$table_name] = strtolower($table_data['Data_length'] + $table_data['Index_length']);
                     }
                 } else {
                     foreach ($each_tables as $table_name => $table_data) {
                         ${$sort_by}[$table_name] = strtolower($table_data[$sort_by]);
                     }
                 }
                 if (!empty(${$sort_by})) {
                     if ($sort_order == 'DESC') {
                         array_multisort(${$sort_by}, SORT_DESC, $each_tables);
                     } else {
                         array_multisort(${$sort_by}, SORT_ASC, $each_tables);
                     }
                 }
                 // cleanup the temporary sort array
                 unset(${$sort_by});
             }
             if ($limit_count) {
                 $each_tables = array_slice($each_tables, $limit_offset, $limit_count);
             }
             foreach ($each_tables as $table_name => $each_table) {
                 if (!isset($each_tables[$table_name]['Type']) && isset($each_tables[$table_name]['Engine'])) {
                     // pma BC, same parts of PMA still uses 'Type'
                     $each_tables[$table_name]['Type'] =& $each_tables[$table_name]['Engine'];
                 } elseif (!isset($each_tables[$table_name]['Engine']) && isset($each_tables[$table_name]['Type'])) {
                     // old MySQL reports Type, newer MySQL reports Engine
                     $each_tables[$table_name]['Engine'] =& $each_tables[$table_name]['Type'];
                 }
                 // MySQL forward compatibility
                 // so pma could use this array as if every server
                 // is of version >5.0
                 // todo : remove and check usage in the rest of the code,
                 // MySQL 5.0 is required by current PMA version
                 $each_tables[$table_name]['TABLE_SCHEMA'] = $each_database;
                 $each_tables[$table_name]['TABLE_NAME'] =& $each_tables[$table_name]['Name'];
                 $each_tables[$table_name]['ENGINE'] =& $each_tables[$table_name]['Engine'];
                 $each_tables[$table_name]['VERSION'] =& $each_tables[$table_name]['Version'];
                 $each_tables[$table_name]['ROW_FORMAT'] =& $each_tables[$table_name]['Row_format'];
                 $each_tables[$table_name]['TABLE_ROWS'] =& $each_tables[$table_name]['Rows'];
                 $each_tables[$table_name]['AVG_ROW_LENGTH'] =& $each_tables[$table_name]['Avg_row_length'];
                 $each_tables[$table_name]['DATA_LENGTH'] =& $each_tables[$table_name]['Data_length'];
                 $each_tables[$table_name]['MAX_DATA_LENGTH'] =& $each_tables[$table_name]['Max_data_length'];
                 $each_tables[$table_name]['INDEX_LENGTH'] =& $each_tables[$table_name]['Index_length'];
                 $each_tables[$table_name]['DATA_FREE'] =& $each_tables[$table_name]['Data_free'];
                 $each_tables[$table_name]['AUTO_INCREMENT'] =& $each_tables[$table_name]['Auto_increment'];
                 $each_tables[$table_name]['CREATE_TIME'] =& $each_tables[$table_name]['Create_time'];
                 $each_tables[$table_name]['UPDATE_TIME'] =& $each_tables[$table_name]['Update_time'];
                 $each_tables[$table_name]['CHECK_TIME'] =& $each_tables[$table_name]['Check_time'];
                 $each_tables[$table_name]['TABLE_COLLATION'] =& $each_tables[$table_name]['Collation'];
                 $each_tables[$table_name]['CHECKSUM'] =& $each_tables[$table_name]['Checksum'];
                 $each_tables[$table_name]['CREATE_OPTIONS'] =& $each_tables[$table_name]['Create_options'];
                 $each_tables[$table_name]['TABLE_COMMENT'] =& $each_tables[$table_name]['Comment'];
                 if (strtoupper($each_tables[$table_name]['Comment']) === 'VIEW' && $each_tables[$table_name]['Engine'] == null) {
                     $each_tables[$table_name]['TABLE_TYPE'] = 'VIEW';
                 } elseif ($each_database == 'information_schema') {
                     $each_tables[$table_name]['TABLE_TYPE'] = 'SYSTEM VIEW';
                 } else {
                     /**
                      * @todo difference between 'TEMPORARY' and 'BASE TABLE'
                      * but how to detect?
                      */
                     $each_tables[$table_name]['TABLE_TYPE'] = 'BASE TABLE';
                 }
             }
             $tables[$each_database] = $each_tables;
         }
     }
     // cache table data
     // so Table does not require to issue SHOW TABLE STATUS again
     $this->_cacheTableData($tables, $table);
     if (is_array($database)) {
         return $tables;
     }
     if (isset($tables[$database])) {
         return $tables[$database];
     }
     if (isset($tables[mb_strtolower($database)])) {
         // on windows with lower_case_table_names = 1
         // MySQL returns
         // with SHOW DATABASES or information_schema.SCHEMATA: `Test`
         // but information_schema.TABLES gives `test`
         // bug #2036
         // https://sourceforge.net/p/phpmyadmin/bugs/2036/
         return $tables[mb_strtolower($database)];
     }
     return $tables;
 }
示例#3
0
文件: Util.php 项目: nijel/phpmyadmin
    /**
     * Gets the list of tables in the current db, taking into account
     * that they might be "in use"
     *
     * @param string $db             database name
     * @param object $db_info_result result set
     *
     * @return array $tables list of tables
     *
     */
    public static function getTablesWhenOpen($db, $db_info_result)
    {
        $sot_cache = $tables = array();

        while ($tmp = $GLOBALS['dbi']->fetchAssoc($db_info_result)) {
            $sot_cache[$tmp['Table']] = true;
        }
        $GLOBALS['dbi']->freeResult($db_info_result);

        // is there at least one "in use" table?
        if (isset($sot_cache)) {
            $tblGroupSql = "";
            $whereAdded = false;
            if (PMA_isValid($_REQUEST['tbl_group'])) {
                $group = Util::escapeMysqlWildcards($_REQUEST['tbl_group']);
                $groupWithSeparator = Util::escapeMysqlWildcards(
                    $_REQUEST['tbl_group']
                    . $GLOBALS['cfg']['NavigationTreeTableSeparator']
                );
                $tblGroupSql .= " WHERE ("
                    . Util::backquote('Tables_in_' . $db)
                    . " LIKE '" . $groupWithSeparator . "%'"
                    . " OR "
                    . Util::backquote('Tables_in_' . $db)
                    . " LIKE '" . $group . "')";
                $whereAdded = true;
            }
            if (PMA_isValid($_REQUEST['tbl_type'], array('table', 'view'))) {
                $tblGroupSql .= $whereAdded ? " AND" : " WHERE";
                if ($_REQUEST['tbl_type'] == 'view') {
                    $tblGroupSql .= " `Table_type` != 'BASE TABLE'";
                } else {
                    $tblGroupSql .= " `Table_type` = 'BASE TABLE'";
                }
            }
            $db_info_result = $GLOBALS['dbi']->query(
                'SHOW FULL TABLES FROM ' . Util::backquote($db) . $tblGroupSql,
                null, DatabaseInterface::QUERY_STORE
            );
            unset($tblGroupSql, $whereAdded);

            if ($db_info_result && $GLOBALS['dbi']->numRows($db_info_result) > 0) {
                $names = array();
                while ($tmp = $GLOBALS['dbi']->fetchRow($db_info_result)) {
                    if (! isset($sot_cache[$tmp[0]])) {
                        $names[] = $tmp[0];
                    } else { // table in use
                        $tables[$tmp[0]] = array(
                            'TABLE_NAME' => $tmp[0],
                            'ENGINE' => '',
                            'TABLE_TYPE' => '',
                            'TABLE_ROWS' => 0,
                            'TABLE_COMMENT' => '',
                        );
                    }
                } // end while
                if (count($names) > 0) {
                    $tables = array_merge(
                        $tables,
                        $GLOBALS['dbi']->getTablesFull($db, $names)
                    );
                }
                if ($GLOBALS['cfg']['NaturalOrder']) {
                    uksort($tables, 'strnatcasecmp');
                }

            } elseif ($db_info_result) {
                $GLOBALS['dbi']->freeResult($db_info_result);
            }
            unset($sot_cache);
        }
        return $tables;
    }