PMA\libraries\Util::mysqlDie PHP Method

mysqlDie() public static method

Returns the error message otherwise.
public static mysqlDie ( string | boolean $server_msg = '', string $sql_query = '', boolean $is_modify_link = true, string $back_url = '', boolean $exit = true ) : string
$server_msg string | boolean Server's error message.
$sql_query string The SQL query that failed.
$is_modify_link boolean Whether to show a "modify" link or not.
$back_url string URL for the "back" link (full path is not required).
$exit boolean Whether execution should be stopped or the error message should be returned.
return string
    public static function mysqlDie($server_msg = '', $sql_query = '', $is_modify_link = true, $back_url = '', $exit = true)
    {
        global $table, $db;
        /**
         * Error message to be built.
         * @var string $error_msg
         */
        $error_msg = '';
        // Checking for any server errors.
        if (empty($server_msg)) {
            $server_msg = $GLOBALS['dbi']->getError();
        }
        // Finding the query that failed, if not specified.
        if (empty($sql_query) && !empty($GLOBALS['sql_query'])) {
            $sql_query = $GLOBALS['sql_query'];
        }
        $sql_query = trim($sql_query);
        /**
         * The lexer used for analysis.
         * @var Lexer $lexer
         */
        $lexer = new Lexer($sql_query);
        /**
         * The parser used for analysis.
         * @var Parser $parser
         */
        $parser = new Parser($lexer->list);
        /**
         * The errors found by the lexer and the parser.
         * @var array $errors
         */
        $errors = ParserError::get(array($lexer, $parser));
        if (empty($sql_query)) {
            $formatted_sql = '';
        } elseif (count($errors)) {
            $formatted_sql = htmlspecialchars($sql_query);
        } else {
            $formatted_sql = self::formatSql($sql_query, true);
        }
        $error_msg .= '<div class="error"><h1>' . __('Error') . '</h1>';
        // For security reasons, if the MySQL refuses the connection, the query
        // is hidden so no details are revealed.
        if (!empty($sql_query) && !mb_strstr($sql_query, 'connect')) {
            // Static analysis errors.
            if (!empty($errors)) {
                $error_msg .= '<p><strong>' . __('Static analysis:') . '</strong></p>';
                $error_msg .= '<p>' . sprintf(__('%d errors were found during analysis.'), count($errors)) . '</p>';
                $error_msg .= '<p><ol>';
                $error_msg .= implode(ParserError::format($errors, '<li>%2$s (near "%4$s" at position %5$d)</li>'));
                $error_msg .= '</ol></p>';
            }
            // Display the SQL query and link to MySQL documentation.
            $error_msg .= '<p><strong>' . __('SQL query:') . '</strong>' . "\n";
            $formattedSqlToLower = mb_strtolower($formatted_sql);
            // TODO: Show documentation for all statement types.
            if (mb_strstr($formattedSqlToLower, 'select')) {
                // please show me help to the error on select
                $error_msg .= self::showMySQLDocu('SELECT');
            }
            if ($is_modify_link) {
                $_url_params = array('sql_query' => $sql_query, 'show_query' => 1);
                if (strlen($table) > 0) {
                    $_url_params['db'] = $db;
                    $_url_params['table'] = $table;
                    $doedit_goto = '<a href="tbl_sql.php' . URL::getCommon($_url_params) . '">';
                } elseif (strlen($db) > 0) {
                    $_url_params['db'] = $db;
                    $doedit_goto = '<a href="db_sql.php' . URL::getCommon($_url_params) . '">';
                } else {
                    $doedit_goto = '<a href="server_sql.php' . URL::getCommon($_url_params) . '">';
                }
                $error_msg .= $doedit_goto . self::getIcon('b_edit.png', __('Edit')) . '</a>';
            }
            $error_msg .= '    </p>' . "\n" . '<p>' . "\n" . $formatted_sql . "\n" . '</p>' . "\n";
        }
        // Display server's error.
        if (!empty($server_msg)) {
            $server_msg = preg_replace("@((\r\n)|(\r)|(\n)){3,}@", "\n\n", $server_msg);
            // Adds a link to MySQL documentation.
            $error_msg .= '<p>' . "\n" . '    <strong>' . __('MySQL said: ') . '</strong>' . self::showMySQLDocu('Error-messages-server') . "\n" . '</p>' . "\n";
            // The error message will be displayed within a CODE segment.
            // To preserve original formatting, but allow word-wrapping,
            // a couple of replacements are done.
            // All non-single blanks and  TAB-characters are replaced with their
            // HTML-counterpart
            $server_msg = str_replace(array('  ', "\t"), array('&nbsp;&nbsp;', '&nbsp;&nbsp;&nbsp;&nbsp;'), $server_msg);
            // Replace line breaks
            $server_msg = nl2br($server_msg);
            $error_msg .= '<code>' . $server_msg . '</code><br/>';
        }
        $error_msg .= '</div>';
        $_SESSION['Import_message']['message'] = $error_msg;
        if (!$exit) {
            return $error_msg;
        }
        /**
         * If this is an AJAX request, there is no "Back" link and
         * `Response()` is used to send the response.
         */
        if (!empty($GLOBALS['is_ajax_request'])) {
            $response = Response::getInstance();
            $response->setRequestStatus(false);
            $response->addJSON('message', $error_msg);
            exit;
        }
        if (!empty($back_url)) {
            if (mb_strstr($back_url, '?')) {
                $back_url .= '&amp;no_history=true';
            } else {
                $back_url .= '?no_history=true';
            }
            $_SESSION['Import_message']['go_back_url'] = $back_url;
            $error_msg .= '<fieldset class="tblFooters">' . '[ <a href="' . $back_url . '">' . __('Back') . '</a> ]' . '</fieldset>' . "\n\n";
        }
        exit($error_msg);
    }

Usage Example

Esempio n. 1
0
 /**
  * Handles the whole import logic
  *
  * @param array &$sql_data 2-element array with sql data
  *
  * @return void
  */
 public function doImport(&$sql_data = array())
 {
     global $db, $table, $csv_terminated, $csv_enclosed, $csv_escaped, $csv_new_line, $csv_columns, $err_url;
     // $csv_replace and $csv_ignore should have been here,
     // but we use directly from $_POST
     global $error, $timeout_passed, $finished, $message;
     $replacements = array('\\n' => "\n", '\\t' => "\t", '\\r' => "\r");
     $csv_terminated = strtr($csv_terminated, $replacements);
     $csv_enclosed = strtr($csv_enclosed, $replacements);
     $csv_escaped = strtr($csv_escaped, $replacements);
     $csv_new_line = strtr($csv_new_line, $replacements);
     $param_error = false;
     if (mb_strlen($csv_terminated) < 1) {
         $message = PMA\libraries\Message::error(__('Invalid parameter for CSV import: %s'));
         $message->addParam(__('Columns terminated with'), false);
         $error = true;
         $param_error = true;
         // The default dialog of MS Excel when generating a CSV produces a
         // semi-colon-separated file with no chance of specifying the
         // enclosing character. Thus, users who want to import this file
         // tend to remove the enclosing character on the Import dialog.
         // I could not find a test case where having no enclosing characters
         // confuses this script.
         // But the parser won't work correctly with strings so we allow just
         // one character.
     } elseif (mb_strlen($csv_enclosed) > 1) {
         $message = PMA\libraries\Message::error(__('Invalid parameter for CSV import: %s'));
         $message->addParam(__('Columns enclosed with'), false);
         $error = true;
         $param_error = true;
         // I could not find a test case where having no escaping characters
         // confuses this script.
         // But the parser won't work correctly with strings so we allow just
         // one character.
     } elseif (mb_strlen($csv_escaped) > 1) {
         $message = PMA\libraries\Message::error(__('Invalid parameter for CSV import: %s'));
         $message->addParam(__('Columns escaped with'), false);
         $error = true;
         $param_error = true;
     } elseif (mb_strlen($csv_new_line) != 1 && $csv_new_line != 'auto') {
         $message = PMA\libraries\Message::error(__('Invalid parameter for CSV import: %s'));
         $message->addParam(__('Lines terminated with'), false);
         $error = true;
         $param_error = true;
     }
     // If there is an error in the parameters entered,
     // indicate that immediately.
     if ($param_error) {
         PMA\libraries\Util::mysqlDie($message->getMessage(), '', false, $err_url);
     }
     $buffer = '';
     $required_fields = 0;
     if (!$this->_getAnalyze()) {
         $sql_template = 'INSERT';
         if (isset($_POST['csv_ignore'])) {
             $sql_template .= ' IGNORE';
         }
         $sql_template .= ' INTO ' . PMA\libraries\Util::backquote($table);
         $tmp_fields = $GLOBALS['dbi']->getColumns($db, $table);
         if (empty($csv_columns)) {
             $fields = $tmp_fields;
         } else {
             $sql_template .= ' (';
             $fields = array();
             $tmp = preg_split('/,( ?)/', $csv_columns);
             foreach ($tmp as $key => $val) {
                 if (count($fields) > 0) {
                     $sql_template .= ', ';
                 }
                 /* Trim also `, if user already included backquoted fields */
                 $val = trim($val, " \t\r\n\v`");
                 $found = false;
                 foreach ($tmp_fields as $field) {
                     if ($field['Field'] == $val) {
                         $found = true;
                         break;
                     }
                 }
                 if (!$found) {
                     $message = PMA\libraries\Message::error(__('Invalid column (%s) specified! Ensure that columns' . ' names are spelled correctly, separated by commas' . ', and not enclosed in quotes.'));
                     $message->addParam($val);
                     $error = true;
                     break;
                 }
                 $fields[] = $field;
                 $sql_template .= PMA\libraries\Util::backquote($val);
             }
             $sql_template .= ') ';
         }
         $required_fields = count($fields);
         $sql_template .= ' VALUES (';
     }
     // Defaults for parser
     $i = 0;
     $len = 0;
     $lastlen = null;
     $line = 1;
     $lasti = -1;
     $values = array();
     $csv_finish = false;
     $tempRow = array();
     $rows = array();
     $col_names = array();
     $tables = array();
     $col_count = 0;
     $max_cols = 0;
     $csv_terminated_len = mb_strlen($csv_terminated);
     while (!($finished && $i >= $len) && !$error && !$timeout_passed) {
         $data = PMA_importGetNextChunk();
         if ($data === false) {
             // subtract data we didn't handle yet and stop processing
             $GLOBALS['offset'] -= strlen($buffer);
             break;
         } elseif ($data === true) {
             // Handle rest of buffer
         } else {
             // Append new data to buffer
             $buffer .= $data;
             unset($data);
             // Force a trailing new line at EOF to prevent parsing problems
             if ($finished && $buffer) {
                 $finalch = mb_substr($buffer, -1);
                 if ($csv_new_line == 'auto' && $finalch != "\r" && $finalch != "\n") {
                     $buffer .= "\n";
                 } elseif ($csv_new_line != 'auto' && $finalch != $csv_new_line) {
                     $buffer .= $csv_new_line;
                 }
             }
             // Do not parse string when we're not at the end
             // and don't have new line inside
             if ($csv_new_line == 'auto' && mb_strpos($buffer, "\r") === false && mb_strpos($buffer, "\n") === false || $csv_new_line != 'auto' && mb_strpos($buffer, $csv_new_line) === false) {
                 continue;
             }
         }
         // Current length of our buffer
         $len = mb_strlen($buffer);
         // Currently parsed char
         $ch = mb_substr($buffer, $i, 1);
         if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) {
             $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len);
             $i += $csv_terminated_len - 1;
         }
         while ($i < $len) {
             // Deadlock protection
             if ($lasti == $i && $lastlen == $len) {
                 $message = PMA\libraries\Message::error(__('Invalid format of CSV input on line %d.'));
                 $message->addParam($line);
                 $error = true;
                 break;
             }
             $lasti = $i;
             $lastlen = $len;
             // This can happen with auto EOL and \r at the end of buffer
             if (!$csv_finish) {
                 // Grab empty field
                 if ($ch == $csv_terminated) {
                     if ($i == $len - 1) {
                         break;
                     }
                     $values[] = '';
                     $i++;
                     $ch = mb_substr($buffer, $i, 1);
                     if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) {
                         $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len);
                         $i += $csv_terminated_len - 1;
                     }
                     continue;
                 }
                 // Grab one field
                 $fallbacki = $i;
                 if ($ch == $csv_enclosed) {
                     if ($i == $len - 1) {
                         break;
                     }
                     $need_end = true;
                     $i++;
                     $ch = mb_substr($buffer, $i, 1);
                     if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) {
                         $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len);
                         $i += $csv_terminated_len - 1;
                     }
                 } else {
                     $need_end = false;
                 }
                 $fail = false;
                 $value = '';
                 while ($need_end && ($ch != $csv_enclosed || $csv_enclosed == $csv_escaped) || !$need_end && !($ch == $csv_terminated || $ch == $csv_new_line || $csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n"))) {
                     if ($ch == $csv_escaped) {
                         if ($i == $len - 1) {
                             $fail = true;
                             break;
                         }
                         $i++;
                         $ch = mb_substr($buffer, $i, 1);
                         if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) {
                             $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len);
                             $i += $csv_terminated_len - 1;
                         }
                         if ($csv_enclosed == $csv_escaped && ($ch == $csv_terminated || $ch == $csv_new_line || $csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n"))) {
                             break;
                         }
                     }
                     $value .= $ch;
                     if ($i == $len - 1) {
                         if (!$finished) {
                             $fail = true;
                         }
                         break;
                     }
                     $i++;
                     $ch = mb_substr($buffer, $i, 1);
                     if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) {
                         $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len);
                         $i += $csv_terminated_len - 1;
                     }
                 }
                 // unquoted NULL string
                 if (false === $need_end && $value === 'NULL') {
                     $value = null;
                 }
                 if ($fail) {
                     $i = $fallbacki;
                     $ch = mb_substr($buffer, $i, 1);
                     if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) {
                         $i += $csv_terminated_len - 1;
                     }
                     break;
                 }
                 // Need to strip trailing enclosing char?
                 if ($need_end && $ch == $csv_enclosed) {
                     if ($finished && $i == $len - 1) {
                         $ch = null;
                     } elseif ($i == $len - 1) {
                         $i = $fallbacki;
                         $ch = mb_substr($buffer, $i, 1);
                         if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) {
                             $i += $csv_terminated_len - 1;
                         }
                         break;
                     } else {
                         $i++;
                         $ch = mb_substr($buffer, $i, 1);
                         if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) {
                             $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len);
                             $i += $csv_terminated_len - 1;
                         }
                     }
                 }
                 // Are we at the end?
                 if ($ch == $csv_new_line || $csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n") || $finished && $i == $len - 1) {
                     $csv_finish = true;
                 }
                 // Go to next char
                 if ($ch == $csv_terminated) {
                     if ($i == $len - 1) {
                         $i = $fallbacki;
                         $ch = mb_substr($buffer, $i, 1);
                         if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) {
                             $i += $csv_terminated_len - 1;
                         }
                         break;
                     }
                     $i++;
                     $ch = mb_substr($buffer, $i, 1);
                     if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) {
                         $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len);
                         $i += $csv_terminated_len - 1;
                     }
                 }
                 // If everything went okay, store value
                 $values[] = $value;
             }
             // End of line
             if ($csv_finish || $ch == $csv_new_line || $csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n")) {
                 if ($csv_new_line == 'auto' && $ch == "\r") {
                     // Handle "\r\n"
                     if ($i >= $len - 2 && !$finished) {
                         break;
                         // We need more data to decide new line
                     }
                     if (mb_substr($buffer, $i + 1, 1) == "\n") {
                         $i++;
                     }
                 }
                 // We didn't parse value till the end of line, so there was
                 // empty one
                 if (!$csv_finish) {
                     $values[] = '';
                 }
                 if ($this->_getAnalyze()) {
                     foreach ($values as $val) {
                         $tempRow[] = $val;
                         ++$col_count;
                     }
                     if ($col_count > $max_cols) {
                         $max_cols = $col_count;
                     }
                     $col_count = 0;
                     $rows[] = $tempRow;
                     $tempRow = array();
                 } else {
                     // Do we have correct count of values?
                     if (count($values) != $required_fields) {
                         // Hack for excel
                         if ($values[count($values) - 1] == ';') {
                             unset($values[count($values) - 1]);
                         } else {
                             $message = PMA\libraries\Message::error(__('Invalid column count in CSV input' . ' on line %d.'));
                             $message->addParam($line);
                             $error = true;
                             break;
                         }
                     }
                     $first = true;
                     $sql = $sql_template;
                     foreach ($values as $key => $val) {
                         if (!$first) {
                             $sql .= ', ';
                         }
                         if ($val === null) {
                             $sql .= 'NULL';
                         } else {
                             $sql .= '\'' . PMA\libraries\Util::sqlAddSlashes($val) . '\'';
                         }
                         $first = false;
                     }
                     $sql .= ')';
                     if (isset($_POST['csv_replace'])) {
                         $sql .= " ON DUPLICATE KEY UPDATE ";
                         foreach ($fields as $field) {
                             $fieldName = PMA\libraries\Util::backquote($field['Field']);
                             $sql .= $fieldName . " = VALUES(" . $fieldName . "), ";
                         }
                         $sql = rtrim($sql, ', ');
                     }
                     /**
                      * @todo maybe we could add original line to verbose
                      * SQL in comment
                      */
                     PMA_importRunQuery($sql, $sql, $sql_data);
                 }
                 $line++;
                 $csv_finish = false;
                 $values = array();
                 $buffer = mb_substr($buffer, $i + 1);
                 $len = mb_strlen($buffer);
                 $i = 0;
                 $lasti = -1;
                 $ch = mb_substr($buffer, 0, 1);
             }
         }
         // End of parser loop
     }
     // End of import loop
     if ($this->_getAnalyze()) {
         /* Fill out all rows */
         $num_rows = count($rows);
         for ($i = 0; $i < $num_rows; ++$i) {
             for ($j = count($rows[$i]); $j < $max_cols; ++$j) {
                 $rows[$i][] = 'NULL';
             }
         }
         if (isset($_REQUEST['csv_col_names'])) {
             $col_names = array_splice($rows, 0, 1);
             $col_names = $col_names[0];
             // MySQL column names can't end with a space character.
             foreach ($col_names as $key => $col_name) {
                 $col_names[$key] = rtrim($col_name);
             }
         }
         if (isset($col_names) && count($col_names) != $max_cols || !isset($col_names)) {
             // Fill out column names
             for ($i = 0; $i < $max_cols; ++$i) {
                 $col_names[] = 'COL ' . ($i + 1);
             }
         }
         if (mb_strlen($db)) {
             $result = $GLOBALS['dbi']->fetchResult('SHOW TABLES');
             $tbl_name = 'TABLE ' . (count($result) + 1);
         } else {
             $tbl_name = 'TBL_NAME';
         }
         $tables[] = array($tbl_name, $col_names, $rows);
         /* Obtain the best-fit MySQL types for each column */
         $analyses = array();
         $analyses[] = PMA_analyzeTable($tables[0]);
         /**
          * string $db_name (no backquotes)
          *
          * array $table = array(table_name, array() column_names, array()() rows)
          * array $tables = array of "$table"s
          *
          * array $analysis = array(array() column_types, array() column_sizes)
          * array $analyses = array of "$analysis"s
          *
          * array $create = array of SQL strings
          *
          * array $options = an associative array of options
          */
         /* Set database name to the currently selected one, if applicable */
         list($db_name, $options) = $this->getDbnameAndOptions($db, 'CSV_DB');
         /* Non-applicable parameters */
         $create = null;
         /* Created and execute necessary SQL statements from data */
         PMA_buildSQL($db_name, $tables, $analyses, $create, $options, $sql_data);
         unset($tables);
         unset($analyses);
     }
     // Commit any possible data in buffers
     PMA_importRunQuery('', '', $sql_data);
     if (count($values) != 0 && !$error) {
         $message = PMA\libraries\Message::error(__('Invalid format of CSV input on line %d.'));
         $message->addParam($line);
         $error = true;
     }
 }
All Usage Examples Of PMA\libraries\Util::mysqlDie
Util