Recent PHP versions offer a mysqli extension instead of the old mysql extension. Since Nucleus relies on the mysql_xxxx functions, it won't run when those are unavailable.
A database abstraction layer would be the ideal solution, but will take a long time to implement correctly and break most of the currently available plugins. Luckily, there is a workaround which works rather well: defining fake mysql_ methods that delegate the work to the new mysqli_ methods. This way, you can keep running the Nucleus core and most plugins.
Update 2005-09-28: These changes made it into CVS
The Idea
The idea is to check if the mysql_query method is available. If not, we'll define it ourselves and just call mysqli_query inside.
We'll also add an extra global $MYSQL_CONN variable which holds the MySQL connection id. While the old mysql_ functions never required this ID to be passed along, some of the new mysqli_ methods do.
A library
The library below is to be saved as /nucleus/libs/mysql.php.
<?php
$MYSQL_CONN = 0;
if (!function_exists('mysql_query'))
{
if (!function_exists('mysqli_query')
&& function_exists('startUpError'))
{
startUpError('<p>No suitable mySQL library found.</p>');
}
function mysql_query($query)
{
global $MYSQL_CONN;
return mysqli_query($MYSQL_CONN, $query);
}
function mysql_fetch_object($res)
{
return mysqli_fetch_object($res);
}
function mysql_fetch_array($res)
{
return mysqli_fetch_array($res);
}
function mysql_fetch_assoc($res)
{
return mysqli_fetch_assoc($res);
}
function mysql_fetch_row($res)
{
return mysqli_fetch_row($res);
}
function mysql_num_rows($res)
{
return mysqli_num_rows($res);
}
function mysql_free_result($res)
{
return mysqli_free_result($res);
}
function mysql_result($res, $row, $col)
{
if (($row != 0) || ($col != 0)) echo 'not implemented';
$row = mysqli_fetch_row($res);
return $row[$col];
}
function mysql_connect($host, $username, $pwd)
{
return mysqli_connect($host, $username, $pwd);
}
function mysql_error()
{
global $MYSQL_CONN;
return mysqli_error($MYSQL_CONN);
}
function mysql_select_db($db)
{
global $MYSQL_CONN;
return mysqli_select_db($MYSQL_CONN, $db);
}
function mysql_close()
{
global $MYSQL_CONN;
return mysqli_close($MYSQL_CONN);
}
function mysql_insert_id()
{
global $MYSQL_CONN;
return mysqli_insert_id($MYSQL_CONN);
}
function mysql_affected_rows()
{
global $MYSQL_CONN;
return mysqli_affected_rows($MYSQL_CONN);
}
}
?>
Adapting globalfunctions.php
We'll also need some small changes to globalfunctions.php. First of all, we need to include the new library. Find the following block of code and add a line for mysql.php.
include($DIR_LIBS . 'mysql.php'); // <- Add this line
include($DIR_LIBS . 'MEMBER.php');
include($DIR_LIBS . 'ACTIONLOG.php');
include($DIR_LIBS . 'MANAGER.php');
include($DIR_LIBS . 'PLUGIN.php');
Next up is storing the MySQL connection ID from the sql_connect function. Lookup this function and change it like this:
function sql_connect() {
global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DATABASE;
global $MYSQL_CONN; // <- new!
$MYSQL_CONN = @mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD) or startUpError('<p>Could not connect to MySQL database.</p>','Connect Error');
mysql_select_db($MYSQL_DATABASE) or startUpError('<p>Could not select database: '. mysql_error().'</p>', 'Connect Error');
return $MYSQL_CONN;
}
How about installing?
Installing through install.php won't work yet, though. You'll run into a Your PHP version does not have support for MySQL :( error because it checks for the existance of the mysql_query function.
To get past this error, also include the mysql.php file in install.php. Like this:
if (phpversion() >= '4.1.0')
include_once('nucleus/libs/vars4.1.0.php');
else
include_once('nucleus/libs/vars4.0.6.php');
include_once('nucleus/libs/mysql.php'); // <- Add this line!
// check if mysql support is installed
if (!function_exists('mysql_query'))
_doError('Your PHP version does not have support for MySQL :(');
Next to that, install.php also creates its own MySQL connection. We need to change this also, so $MYSQL_CONN ends up containing the connection ID.
// 2. try to log in to mySQL
global $MYSQL_CONN;
$MYSQL_CONN = mysql_connect($mysql_host, $mysql_user, $mysql_password);
if ($MYSQL_CONN == false)
_doError("Could not connect to mySQL server: " . mysql_error());
Words of caution
Some words of caution on this hack:
- I haven't tested this code very well, I added mapping functions until visiting a Nucleus website and its admin area appeared to work without errors.
- Not all
mysql_functions are present in the mapping. This means that you can still run into acall to an undefined function: mysql_xxxx. In that case, it should also be added to the mapping. - Since I couldn't find an exact match for
mysql_result, and because the only occurrences in the Nucleus core code use it to get the result at row 0 and field 0, that's how I implemented it. In other cases, an error message will show up in the output.
Posted by karma at 14:17:44. Filed under: Nucleus Hacks

Comments
Add Comment