-3

I have this error in a Component in Joomla

That's my code (the error is in line 263):

<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

JLoader::register('JDatabaseMySQL', dirname(__FILE__) . '/mysql.php');
JLoader::register('JDatabaseQueryMySQLi', dirname(__FILE__) . '/mysqliquery.php');
JLoader::register('JDatabaseExporterMySQLi', dirname(__FILE__) . '/mysqliexporter.php');
JLoader::register('JDatabaseImporterMySQLi', dirname(__FILE__) . '/mysqliimporter.php');

/**
 * MySQLi database driver
 *
 * @package     Joomla.Platform
 * @subpackage  Database
 * @see         http://php.net/manual/en/book.mysqli.php
 * @since       11.1
 */
class JDatabaseMySQLi extends JDatabaseMySQL
{
    /**
     * The name of the database driver.
     *
     * @var    string
     * @since  11.1
     */
    public $name = 'mysqli';

    /**
     * Constructor.
     *
     * @param   array  $options  List of options used to configure the connection
     *
     * @since   11.1
     */
    protected function __construct($options)
    {
        // Get some basic values from the options.
        $options['host'] = (isset($options['host'])) ? $options['host'] : 'localhost';
        $options['user'] = (isset($options['user'])) ? $options['user'] : 'root';
        $options['password'] = (isset($options['password'])) ? $options['password'] : '';
        $options['database'] = (isset($options['database'])) ? $options['database'] : '';
        $options['select'] = (isset($options['select'])) ? (bool) $options['select'] : true;
        $options['port'] = null;
        $options['socket'] = null;

        /*
         * Unlike mysql_connect(), mysqli_connect() takes the port and socket as separate arguments. Therefore, we
         * have to extract them from the host string.
         */
        $tmp = substr(strstr($options['host'], ':'), 1);
        if (!empty($tmp))
        {
            // Get the port number or socket name
            if (is_numeric($tmp))
            {
                $options['port'] = $tmp;
            }
            else
            {
                $options['socket'] = $tmp;
            }

            // Extract the host name only
            $options['host'] = substr($options['host'], 0, strlen($options['host']) - (strlen($tmp) + 1));

            // This will take care of the following notation: ":3306"
            if ($options['host'] == '')
            {
                $options['host'] = 'localhost';
            }
        }

        // Make sure the MySQLi extension for PHP is installed and enabled.
        if (!function_exists('mysqli_connect'))
        {

            // Legacy error handling switch based on the JError::$legacy switch.
            // @deprecated  12.1
            if (JError::$legacy)
            {
                $this->errorNum = 1;
                $this->errorMsg = JText::_('JLIB_DATABASE_ERROR_ADAPTER_MYSQLI');
                return;
            }
            else
            {
                throw new JDatabaseException(JText::_('JLIB_DATABASE_ERROR_ADAPTER_MYSQLI'));
            }
        }

        $this->connection = @mysqli_connect(
            $options['host'], $options['user'], $options['password'], null, $options['port'], $options['socket']
        );

        // Attempt to connect to the server.
        if (!$this->connection)
        {
            // Legacy error handling switch based on the JError::$legacy switch.
            // @deprecated  12.1
            if (JError::$legacy)
            {
                $this->errorNum = 2;
                $this->errorMsg = JText::_('JLIB_DATABASE_ERROR_CONNECT_MYSQL');
                return;
            }
            else
            {
                throw new JDatabaseException(JText::_('JLIB_DATABASE_ERROR_CONNECT_MYSQL'));
            }
        }

        // Finalize initialisation
        JDatabase::__construct($options);

        // Set sql_mode to non_strict mode
        mysqli_query($this->connection, "SET @@SESSION.sql_mode = '';");

        // If auto-select is enabled select the given database.
        if ($options['select'] && !empty($options['database']))
        {
            $this->select($options['database']);
        }
    }

    /**
     * Destructor.
     *
     * @since   11.1
     */
    public function __destruct()
    {
        if (is_callable(array($this->connection, 'close')))
        {
            mysqli_close($this->connection);
        }
    }

    /**
     * Method to escape a string for usage in an SQL statement.
     *
     * @param   string   $text   The string to be escaped.
     * @param   boolean  $extra  Optional parameter to provide extra escaping.
     *
     * @return  string  The escaped string.
     *
     * @since   11.1
     */
    public function escape($text, $extra = false)
    {
        $result = mysqli_real_escape_string($this->getConnection(), $text);

        if ($extra)
        {
            $result = addcslashes($result, '%_');
        }

        return $result;
    }

    /**
     * Test to see if the MySQL connector is available.
     *
     * @return  boolean  True on success, false otherwise.
     *
     * @since   11.1
     */
    public static function test()
    {
        return (function_exists('mysqli_connect'));
    }

    /**
     * Determines if the connection to the server is active.
     *
     * @return  boolean  True if connected to the database engine.
     *
     * @since   11.1
     */
    public function connected()
    {
        if (is_object($this->connection))
        {
            return mysqli_ping($this->connection);
        }

        return false;
    }

    /**
     * Get the number of affected rows for the previous executed SQL statement.
     *
     * @return  integer  The number of affected rows.
     *
     * @since   11.1
     */
    public function getAffectedRows()
    {
        return mysqli_affected_rows($this->connection);
    }

    /**
     * Gets an exporter class object.
     *
     * @return  JDatabaseExporterMySQLi  An exporter object.
     *
     * @since   11.1
     * @throws  JDatabaseException
     */
    public function getExporter()
    {
        // Make sure we have an exporter class for this driver.
        if (!class_exists('JDatabaseExporterMySQLi'))
        {
            throw new JDatabaseException(JText::_('JLIB_DATABASE_ERROR_MISSING_EXPORTER'));
        }

        $o = new JDatabaseExporterMySQLi;
        $o->setDbo($this);

        return $o;
    }

    /**
     * Gets an importer class object.
     *
     * @return  JDatabaseImporterMySQLi  An importer object.
     *
     * @since   11.1
     * @throws  JDatabaseException
     */
    public function getImporter()
    {
        // Make sure we have an importer class for this driver.
        if (!class_exists('JDatabaseImporterMySQLi'))
        {
            throw new JDatabaseException(JText::_('JLIB_DATABASE_ERROR_MISSING_IMPORTER'));
        }

        $o = new JDatabaseImporterMySQLi;
        $o->setDbo($this);

        return $o;
    }

    /**
     * Get the number of returned rows for the previous executed SQL statement.
     *
     * @param   resource  $cursor  An optional database cursor resource to extract the row count from.
     *
     * @return  integer   The number of returned rows.
     *
     * @since   11.1
     */
    public function getNumRows($cursor = null)
    {
        return mysqli_num_rows($cursor ? $cursor : $this->cursor);
    }

    /**
     * Get the current or query, or new JDatabaseQuery object.
     *
     * @param   boolean  $new  False to return the last query set, True to return a new JDatabaseQuery object.
     *
     * @return  mixed  The current value of the internal SQL variable or a new JDatabaseQuery object.
     *
     * @since   11.1
     * @throws  JDatabaseException
     */
    public function getQuery($new = false)
    {
        if ($new)
        {
            // Make sure we have a query class for this driver.
            if (!class_exists('JDatabaseQueryMySQLi'))
            {
                throw new JDatabaseException(JText::_('JLIB_DATABASE_ERROR_MISSING_QUERY'));
            }
            return new JDatabaseQueryMySQLi($this);
        }
        else
        {
            return $this->sql;
        }
    }

    /**
     * Get the version of the database connector.
     *
     * @return  string  The database connector version.
     *
     * @since   11.1
     */
    public function getVersion()
    {
        return mysqli_get_server_info($this->connection);
    }

    /**
     * Determines if the database engine supports UTF-8 character encoding.
     *
     * @return  boolean  True if supported.
     *
     * @since   11.1
     * @deprecated 12.1
     */
    public function hasUTF()
    {
        JLog::add('JDatabaseMySQLi::hasUTF() is deprecated.', JLog::WARNING, 'deprecated');
        return true;
    }

    /**
     * Method to get the auto-incremented value from the last INSERT statement.
     *
     * @return  integer  The value of the auto-increment field from the last inserted row.
     *
     * @since   11.1
     */
    public function insertid()
    {
        return mysqli_insert_id($this->connection);
    }

    /**
     * Execute the SQL statement.
     *
     * @return  mixed  A database cursor resource on success, boolean false on failure.
     *
     * @since   11.1
     * @throws  JDatabaseException
     */
    public function execute()
    {
        if (!is_object($this->connection))
        {
            // Legacy error handling switch based on the JError::$legacy switch.
            // @deprecated  12.1
            if (JError::$legacy)
            {
                if ($this->debug)
                {
                    JError::raiseError(500, 'JDatabaseMySQLi::query: ' . $this->errorNum . ' - ' . $this->errorMsg);
                }
                return false;
            }
            else
            {
                JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database');
                throw new JDatabaseException($this->errorMsg, $this->errorNum);
            }
        }

        // Take a local copy so that we don't modify the original query and cause issues later
        $sql = $this->replacePrefix((string) $this->sql);
        if ($this->limit > 0 || $this->offset > 0)
        {
            $sql .= ' LIMIT ' . $this->offset . ', ' . $this->limit;
        }

        // If debugging is enabled then let's log the query.
        if ($this->debug)
        {
            // Increment the query counter and add the query to the object queue.
            $this->count++;
            $this->log[] = $sql;

            JLog::add($sql, JLog::DEBUG, 'databasequery');
        }

        // Reset the error values.
        $this->errorNum = 0;
        $this->errorMsg = '';

        // Execute the query.
        $this->cursor = mysqli_query($this->connection, $sql);

        // If an error occurred handle it.
        if (!$this->cursor)
        {
            $this->errorNum = (int) mysqli_errno($this->connection);
            $this->errorMsg = (string) mysqli_error($this->connection) . ' SQL=' . $sql;

            // Legacy error handling switch based on the JError::$legacy switch.
            // @deprecated  12.1
            if (JError::$legacy)
            {
                if ($this->debug)
                {
                    JError::raiseError(500, 'JDatabaseMySQLi::query: ' . $this->errorNum . ' - ' . $this->errorMsg);
                }
                return false;
            }
            else
            {
                JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'databasequery');
                throw new JDatabaseException($this->errorMsg, $this->errorNum);
            }
        }

        return $this->cursor;
    }

    /**
     * Select a database for use.
     *
     * @param   string  $database  The name of the database to select for use.
     *
     * @return  boolean  True if the database was successfully selected.
     *
     * @since   11.1
     * @throws  JDatabaseException
     */
    public function select($database)
    {
        if (!$database)
        {
            return false;
        }

        if (!mysqli_select_db($this->connection, $database))
        {
            // Legacy error handling switch based on the JError::$legacy switch.
            // @deprecated  12.1
            if (JError::$legacy)
            {
                $this->errorNum = 3;
                $this->errorMsg = JText::_('JLIB_DATABASE_ERROR_DATABASE_CONNECT');
                return false;
            }
            else
            {
                throw new JDatabaseException(JText::_('JLIB_DATABASE_ERROR_DATABASE_CONNECT'));
            }
        }

        return true;
    }

    /**
     * Set the connection to use UTF-8 character encoding.
     *
     * @return  boolean  True on success.
     *
     * @since   11.1
     */
    public function setUTF()
    {
        mysqli_query($this->connection, "SET NAMES 'utf8'");
    }

    /**
     * Method to fetch a row from the result set cursor as an array.
     *
     * @param   mixed  $cursor  The optional result set cursor from which to fetch the row.
     *
     * @return  mixed  Either the next row from the result set or false if there are no more rows.
     *
     * @since   11.1
     */
    protected function fetchArray($cursor = null)
    {
        return mysqli_fetch_row($cursor ? $cursor : $this->cursor);
    }

    /**
     * Method to fetch a row from the result set cursor as an associative array.
     *
     * @param   mixed  $cursor  The optional result set cursor from which to fetch the row.
     *
     * @return  mixed  Either the next row from the result set or false if there are no more rows.
     *
     * @since   11.1
     */
    protected function fetchAssoc($cursor = null)
    {
        return mysqli_fetch_assoc($cursor ? $cursor : $this->cursor);
    }

    /**
     * Method to fetch a row from the result set cursor as an object.
     *
     * @param   mixed   $cursor  The optional result set cursor from which to fetch the row.
     * @param   string  $class   The class name to use for the returned row object.
     *
     * @return  mixed   Either the next row from the result set or false if there are no more rows.
     *
     * @since   11.1
     */
    protected function fetchObject($cursor = null, $class = 'stdClass')
    {
        return mysqli_fetch_object($cursor ? $cursor : $this->cursor, $class);
    }

    /**
     * Method to free up the memory used for the result set.
     *
     * @param   mixed  $cursor  The optional result set cursor from which to fetch the row.
     *
     * @return  void
     *
     * @since   11.1
     */
    protected function freeResult($cursor = null)
    {
        mysqli_free_result($cursor ? $cursor : $this->cursor);
    }

    /**
     * Execute a query batch.
     *
     * @param   boolean  $abortOnError     Abort on error.
     * @param   boolean  $transactionSafe  Transaction safe queries.
     *
     * @return  mixed  A database resource if successful, false if not.
     *
     * @deprecated  12.1
     * @since   11.1
     */
    public function queryBatch($abortOnError = true, $transactionSafe = false)
    {
        // Deprecation warning.
        JLog::add('JDatabaseMySQLi::queryBatch() is deprecated.', JLog::WARNING, 'deprecated');

        $sql = $this->replacePrefix((string) $this->sql);
        $this->errorNum = 0;
        $this->errorMsg = '';

        // If the batch is meant to be transaction safe then we need to wrap it in a transaction.
        if ($transactionSafe)
        {
            $sql = 'START TRANSACTION;' . rtrim($sql, "; \t\r\n\0") . '; COMMIT;';
        }
        $queries = $this->splitSql($sql);
        $error = 0;
        foreach ($queries as $query)
        {
            $query = trim($query);
            if ($query != '')
            {
                $this->cursor = mysqli_query($this->connection, $query);
                if ($this->debug)
                {
                    $this->count++;
                    $this->log[] = $query;
                }
                if (!$this->cursor)
                {
                    $error = 1;
                    $this->errorNum .= mysqli_errno($this->connection) . ' ';
                    $this->errorMsg .= mysqli_error($this->connection) . " SQL=$query <br />";
                    if ($abortOnError)
                    {
                        return $this->cursor;
                    }
                }
            }
        }
        return $error ? false : true;
    }
}
000
  • 26,951
  • 10
  • 71
  • 101
user2596095
  • 1
  • 1
  • 1
  • 1
    It usually means your DB settings are incorrect and thus connecting results in a boolean false. – Maerlyn Jul 18 '13 at 15:08
  • Change this wrapper... Beside the fact, your query fails and you are recieveing boolean instead of result, the wrapper is bunch of spaghetti with broken standards, staticly called dependencies and also called constructors, as they are assumed to be called when the class is instantiated – Royal Bg Jul 18 '13 at 15:09
  • He can't change it, as he's working inside joomla. – Maerlyn Jul 18 '13 at 15:16
  • Possible duplicate [mysql_fetch_array() expects parameter 1 to be resource, boolean given in select](http://stackoverflow.com/questions/2973202/mysql-fetch-array-expects-parameter-1-to-be-resource-boolean-given-in-select?answertab=votes#tab-top). – John Conde Jul 18 '13 at 15:19
  • See [this answer](http://stackoverflow.com/a/11674313/250259) for how to troubleshoot this. – John Conde Jul 18 '13 at 15:19
  • What do you mean "this is my code"? Are you attempting to rewrite JDatabasequeryMysqli? Where is the code where you actually use this class? How are you loading results? In general you should be able to just do $db->getNumRows(); after loading your results with $db->loadObjectList(); or whatever type of return you are asking for. – Elin Jul 21 '13 at 10:00

2 Answers2

0

As the link Jon Conde provided says, you are getting this because you have an error in your query. You have not provided the query so it's impossible to know what the problem is. Unfortunately some of the advice you are getting on the whole is going to make it worse because the problem is not in JDatabaseQueryMysqli it is in the code where you are calling it. You are getting a boolean false instead of the expected results because your query has failed.

To see your generated query you can use

echo $query->dump();

put it before you are calling getNumRows(). You may need a die; depending on the context or just log it or if in the cms you can turn on the debugger and see the generated queries (global configuration, debug on).

If you provide your code (not a copy of the api) then people can help debug your query.

I will say it's a bug that it's not testing for that and throwing an exception if your query has failed.

Elin
  • 6,507
  • 3
  • 25
  • 47
0

If you're using joomla 2.5, please check again of your php version ; It must be php 5.3 at least.