My host has upgraded it's PHP to version 5.5 and MySQL to 5.6.
We are still using Opencart 1.4.9.6 and cannot upgrade immediately as the store is live and we have a lot of own modifications.
Right now we are unable to view our administration area and this message is shown on top of all of our pages:
Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in /home/public_html/system/database/mysql.php on line 8
How should we proceed if we want the message to disappear and be able to log in to our admin pages? Is it possible to just change mysql_connect to mysqli?
Here is the code which is used in mysql.php:
<?php
final class MySQL {
private $connection;
public function __construct($hostname, $username, $password, $database) {
if (!$this->connection = mysql_connect($hostname, $username, $password)) {
exit('Error: Could not make a database connection using ' . $username . '#' . $hostname);
}
if (!mysql_select_db($database, $this->connection)) {
exit('Error: Could not connect to database ' . $database);
}
mysql_query("SET NAMES 'utf8'", $this->connection);
mysql_query("SET CHARACTER SET utf8", $this->connection);
// mic changed 20100824 instead of SET NAMES and CHARACTER SET
// see: http://at2.php.net/manual/en/function.mysql-set-charset.php
//mysql_set_charset( 'utf8', $this->connection );
mysql_query("SET CHARACTER_SET_CONNECTION=utf8", $this->connection);
mysql_query("SET SQL_MODE = ''", $this->connection);
}
public function query($sql) {
$resource = mysql_query($sql, $this->connection);
if ($resource) {
if (is_resource($resource)) {
$i = 0;
$data = array();
while ($result = mysql_fetch_assoc($resource)) {
$data[$i] = $result;
$i++;
}
mysql_free_result($resource);
$query = new stdClass();
$query->row = isset($data[0]) ? $data[0] : array();
$query->rows = $data;
$query->num_rows = $i;
unset($data);
return $query;
} else {
return TRUE;
}
} else {
exit('Error: ' . mysql_error($this->connection) . '<br />Error No: ' . mysql_errno($this->connection) . '<br />' . $sql);
}
}
public function escape($value) {
return mysql_real_escape_string($value, $this->connection);
}
public function countAffected() {
return mysql_affected_rows($this->connection);
}
public function getLastId() {
return mysql_insert_id($this->connection);
}
public function __destruct() {
mysql_close($this->connection);
}
}
?>
How should we proceed if we want the message to disappear and be able to log in to our admin pages?
Open the file <OC_ROOT>/system/startup.php
Change this line:
error_reporting(E_ALL)
to
error_reporting(E_ALL ^ E_DEPRECATED) , now all deprecation warnings will disappear
Is it possible to just change mysql_connect to mysqli?
I don't know if OC 1.4.9 has a built in driver for mysqli, to check that, open the directory <OC_ROOT>/system/database and make sure that there is a file named mysqli.php, if it's there, then apply the following steps: (if not, you need to change all mysql_* functions in the project)
Open configuration files <OC_ROOT>/config.php and <OC_ROOT>/admin/config.php
Change this line:
define('DB_DRIVER', 'mysql')
to
define('DB_DRIVER', 'mysqli')
Is it possible to just change mysql_connect to mysqli?
No, that's not enough. You have to change all functions started from mysql_. It is not that hard, though. All you need is programmer who is given a hour of time.
How should we proceed if we want the message to disappear
Just disable it.
error_reporting(E_ALL & ~E_DEPRECATED);
and be able to log in to our admin pages?
That's hardest question of them all. And you better ask aforementioned programmer for this, as there could be other errors that prevent you from logging in.
Related
I'm doing an operation that inserts hundreds of records into a MySQL database.
After inserting exactly 176 records I get this error:
[PDOException] SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
Any ideas of how could I solve it?
The process is with PHP.
I would venture to say the problem is with wait_timeout. It is set to 30 seconds on my shared host and on my localhost is set for 28800.
I found that I can change it for the session, so you can issue the query: SET session wait_timeout=28800
UPDATE The OP determined that he also needed to change the variable interactive_timeout as well. This may or may not be needed for everyone.
The code below shows the setting before and after the change to verify that it has been changed.
So, set wait_timeout=28800 (and interactive_timeout = 28800) at the beginning of your query and see if it completes.
Remember to insert your own db credentials in place of DB_SERVER, DB_USER, DB_PASS, DB_NAME
UPDATE Also, if this does work, you want to be clear on what you are doing by setting wait_timeout higher. Setting it to 28800 is 8 hours and is a lot.
The following is from this site. It recommends setting wait_timeout to 300 - which I will try and report back with my results (after a few weeks).
wait_timeout variable represents the amount of time that MySQL will
wait before killing an idle connection. The default wait_timeout
variable is 28800 seconds, which is 8 hours. That's a lot.
I've read in different forums/blogs that putting wait_timeout too low
(e.g. 30, 60, 90) can result in MySQL has gone away error messages. So
you'll have to decide for your configuration.
<?php
$db = new db();
$results = $db->query("SHOW VARIABLES LIKE '%timeout%'", TRUE);
echo "<pre>";
var_dump($results);
echo "</pre>";
$results = $db->query("SET session wait_timeout=28800", FALSE);
// UPDATE - this is also needed
$results = $db->query("SET session interactive_timeout=28800", FALSE);
$results = $db->query("SHOW VARIABLES LIKE '%timeout%'", TRUE);
echo "<pre>";
var_dump($results);
echo "</pre>";
class db {
public $mysqli;
public function __construct() {
$this->mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if (mysqli_connect_errno()) {
exit();
}
}
public function __destruct() {
$this->disconnect();
unset($this->mysqli);
}
public function disconnect() {
$this->mysqli->close();
}
function query($q, $resultset) {
/* create a prepared statement */
if (!($stmt = $this->mysqli->prepare($q))) {
echo("Sql Error: " . $q . ' Sql error #: ' . $this->mysqli->errno . ' - ' . $this->mysqli->error);
return false;
}
/* execute query */
$stmt->execute();
if ($stmt->errno) {
echo("Sql Error: " . $q . ' Sql error #: ' . $stmt->errno . ' - ' . $stmt->error);
return false;
}
if ($resultset) {
$result = $stmt->get_result();
for ($set = array(); $row = $result->fetch_assoc();) {
$set[] = $row;
}
$stmt->close();
return $set;
}
}
}
Thanks #mseifert.
Your idea worked by doing the same with two variables.
interactive_timeout & wait_timeout
I copied the config from a local database:
SHOW VARIABLES LIKE '%timeout%'
Local db:
Remote db:
I did this inside the connect and disconnect and worked:
mysql_query("SET SESSION interactive_timeout = 28800;");
$result = mysql_query("SHOW VARIABLES LIKE 'interactive_timeout';");
$row = mysql_fetch_array($result);
$interactive_timeout = $row["Value"];
echo("interactive_timeout" . " = " . $interactive_timeout . "\n");
mysql_query("SET SESSION wait_timeout = 28800;");
$result = mysql_query("SHOW VARIABLES LIKE 'wait_timeout';");
$row = mysql_fetch_array($result);
$wait_timeout = $row["Value"];
echo("wait_timeout" . " = " . $wait_timeout . "\n");
Surprisingly it worked with GoDaddy.
I will accept your answer as valid #mseifert since you gave me the original idea.
Thanks a lot.
Let us hope this is useful in the future to solve the 2006 MySQL error for other developers.
In my case, when I got this error on the client side, the server side was
(Got a packet bigger than 'max_allowed_packet' bytes)
So I increase the value of the max_allowed_packet, and so far, no more issues.
On Google Cloud Platform, I edit the DB and add a Database flag and set the value to
max_allowed_packet=134217728
(which is 2^27 = 128M)
As you can only input numbers.
On regular instances, you can follow the doc here :
https://dev.mysql.com/doc/refman/8.0/en/packet-too-large.html
Assume your codes is:
// your codes
$pdo = db::connection()->getPdo();
$stmt = $pdo->prepare($sql);
$result = $stmt->execute($params);
So add below codes before your sql query:
$pdo = db::connection()->getPdo();
// Increase interactive_timeout
$prepend_sql = "SET SESSION interactive_timeout = 28800;";
$stmt = $pdo->prepare($prepend_sql);
$stmt->execute($params);
// Increase wait_timeout
$prepend_sql = "SET SESSION wait_timeout = 28800;";
$stmt = $pdo->prepare($prepend_sql);
$stmt->execute($params);
// your codes
/* $pdo = db::connection()->getPdo(); */
$stmt = $pdo->prepare($sql);
$result = $stmt->execute($params);
Another possible reason would be your client is trying to connect using SSL. while the MySQL/MariaDB server is not expecting that.
a solution is to check if the connection is active, if not re-establishing the connection, here it worked perfectly
<?php
require_once ('config.php');
class DB {
private static $instance;
private function __construct() {
;
}
public static function getInstance() {
if (!isset(self::$instance)) {
try {
self::$instance = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASS);
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$instance->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
} catch (PDOException $e) {
echo $e->getMessage();
}
}
try {
$testConn = self::$instance->prepare('SELECT 1');
$testConn->execute();
$testConn = $testConn->fetchAll(PDO::FETCH_ASSOC)[0];
} catch (Exception $ex) {
try {
self::$instance = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASS);
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$instance->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
} catch (PDOException $e) {
echo $e->getMessage();
}
}
return self::$instance;
}
public static function prepare($sql) {
return self::getInstance()->prepare($sql);
}
public static function lastInsertId() {
return self::getInstance()->lastInsertId();
}
}
I have been trying to migrate the following mysql connection function to PDO:
function validate_email_input($email)
{
$dbc = #mysql_connect('localhost', 'userName', '******');
mysql_select_db('users', $dbc);
$query = "SELECT email FROM user_list WHERE email='$email'";
if ($result = mysql_query($query, $dbc))
{
$row = mysql_fetch_array($result);
if ($row['email'] == $email)
{
return TRUE;
}
else
{
return FALSE;
}
}
else
{
echo '<p class="error">Could not retrieve he data because:<br />' . mysql_error($dbc) . '.</p>
<p>The query being run was: ' . $query . '</p>';
}
}
This works just fine. But I get an error when I try the following PDO function to achieve the same result:
function validate_email_input($email)
{
// Step 1: Establish a connection
$db = new PDO("mysql:host=localhost;dbname=users", "userName", "******");
// Step 2: Construct a query
$query = "SELECT * FROM user_list WHERE email = '$email'";
// Step 3: Send the query
$result = $db->query($query);
// Step 4: Iterate over the results
if ($result)
{
$row = $result->fetch(PDO::FETCH_ASSOC);
if ($row['email'] == $email)
{
return TRUE;
}
else
{
return FALSE;
}
}
// Step 5: Free used resources
$result->closeCursor();
$db = null;
}
And yes - I did try the above function with try-catch but that doesn't affect anything. I still get the error:
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [1049] Unknown database 'users''
I'm using the apache2 module included with Bitnami RubyStack (v. 1.9.3-25), which uses PHP version 5.4.3
Already checked php.ini file and all the PDO extensions are uncommented.
Please help! Thanks
Found the solution! Apparently it wanted me to specify the port number (localhost:3307) instead of just localhost when creating the PDO object. Anyone know how to change the default localhost port in Bitnami RubyStack for Windows?
Using the following code, the database can be connected to successfully. However, when trying to execute a query using the function 'executeNonQuery' I get the error { Access denied for user ''#'localhost' to database 'photobook' }. The user has full privileges, although strangely the query 'show grants' will not display that fact. However, when looking at user privileges in the GUI of mysql workbench it is. What can be the problem? I even used root, but the query is denied with the same error. The user can connect, but can't issue a query.
file: class.database.php
<?php
class Database {
function __construct(){
}
public function connect($host, $user, $pass){
$dbcnct = mysqli_connect($host, $user, $pass);
if(!$dbcnct){
die("Couldn't Connect: " . mysql_error());
}else{
echo "Connected Successfully";
}
}
public function disconnect(){
mysql_close($dbcnct);
if(!$dbcnct){
echo "Disconnected Successfully";
}
}
public function executeNonQuery($database, $sql){
mysql_select_db($database);
$retval = mysql_query($sql, $dbcnct);
if(!$retval){
die("Couldn't Update Data: " . mysql_error());
}
echo "Update Successful";
}
}
?>
<?php
include 'class.database.php';
$db = new Database;
$db->connect("localhost", "user", "pass");
$userdata=$_GET['data'];
$index=$_GET['index'];
echo $index . "<br/>";
foreach($userdata as $data){
$sql = "update photobook set photoName='" . $data . "' where photoPosition=" . $index;
$db->executeNonQuery("photoBook", $sql);
echo $data . "<br/>";
}
$db->disconnect();
?>
Your $dbcnct variable is only defined for the function where you use it, not the whole class. You need to use class variables so you can share variables throughout the different functions :
<?php
class Database
{
public $dbcnct;
function __construct()
{
// Nothing
}
public function connect($host, $user, $pass){
$this->dbcnct = mysqli_connect($host, $user, $pass);
if(!$this->dbcnct){
die("Couldn't Connect: " . mysql_error());
}else{
echo "Connected Successfully";
}
}
public function disconnect(){
mysql_close($this->dbcnct);
if(!$this->dbcnct){
echo "Disconnected Successfully";
}
}
public function executeNonQuery($database, $sql){
mysql_select_db($database);
$retval = mysql_query($sql, $this->dbcnct);
if(!$retval){
die("Couldn't Update Data: " . mysql_error());
}
echo "Update Successful";
}
}
?>
Now all you need to do is :
$database->connect("host", "user", "pass");
$database->executeNonQuery("database", "sql");
But first of all you need to fix the mysql_ and mysqli_ mixups :)
Try this: Adding users to MySQL
You need grant privileges to the user if you want external acess to database(ie. web pages).
http://dev.mysql.com/doc/refman/5.1/en/adding-users.html
CREATE USER 'a_project'#'%' IDENTIFIED BY 'password';
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON a_database.* TO 'a_project'#'%';
i suggest you keeping $dbcnct as a variable in the database class so that when you call function executeNonQuery,the mysql connection won't be lost.
Put your connect script in the __construct() section, this initialize connection to call new Database; and make available to all functions in the Database Class without request new connection every time you run a query.
I'm getting this error:
Call to a member function
real_escape_string() on a non-object
and here's $db
$db = new mysqli("127.0.0.1", "username", "password", "sch5400");
in code:
function readSession($sessionId) {
global $db;
$sessionId = session_id();
// escape session ID
$sessionId = $db->real_escape_string($sessionId);
$time = time();
$result = $db->query("SELECT sessiondata FROM sessions WHERE sessionid='$sessionId' AND expiry > $time");
if ($result->num_rows > 0) {
$row = $result->fetchRow();
return $row['sessiondata'];
}
// return empty string
return "";
}
It appears on line 5, relative to code above. Didn't I instantiate $db?
Probably the better solution would be to create a singleton function:
function get_my_db()
{
static $db;
if (!$db) {
$db = new mysqli("127.0.0.1", "username", "password", "sch5400");
}
return $db;
}
and use it like
$db = get_my_db();
in every function that needs db instance.
You haven't initialized $db anywhere in the code that's shown, and from the error it sounds like it hasn't been initialized anywhere else (yet) either.
If you are initializing $db somewhere, make sure it's before readSession is called. Also check for an error message when you make the connection. It returns false on error, which is not an object.
from the PHP manual, you should using one of these error checking methods to ensure the connection is established successfully:
/*
* This is the "official" OO way to do it,
* BUT $connect_error was broken until PHP 5.2.9 and 5.3.0.
*/
if ($mysqli->connect_error) {
die('Connect Error (' . $mysqli->connect_errno . ') '
. $mysqli->connect_error);
}
/*
* Use this instead of $connect_error if you need to ensure
* compatibility with PHP versions prior to 5.2.9 and 5.3.0.
*/
if (mysqli_connect_error()) {
die('Connect Error (' . mysqli_connect_errno() . ') '
. mysqli_connect_error());
}
There is also a global function that doesnt require a db reference.
$sessionId = mysql_real_escape_string($sessionId);
http://php.net/mysql_real_escape_string
I am trying to build a self-hosted PHP site, but I am having trouble connecting to the database from my PHP script.
Please note the following
1). This code allows me to connect to MAMP from my terminus without problem so I know MySQL is working etc
mysql --host=127.0.0.1 --port=8889 --user=root -p
2) When I tried to build a site on a remote hosted platform, this code allowed me to connect from my php script to MySQL on the remove server, so I know there is nothing wrong with this code per se, but it didn't work on my computer.
defined('DB_SERVER') ? null : define("DB_SERVER","host");
defined('DB_USER') ? null : define("DB_USER","username");
defined('DB_PASS') ? null : define("DB_PASS","password");
defined('DB_NAME') ? null : define("DB_NAME","photo_gallery");
3 I have been able to run a self-hosted wordpress site on my computer, but I didn't establish the database connection for that (it's somewhere in the code) so I don't what I'm doing wrong. That site is accessible at the following path. http://localhost:8888/wordpress/ even though it is connected at port 8889 (according to mysql)
4 MAMP tells me that I can connect to the database from my own scripts using this format
Host localhost
Port 8889
User root
Password root
Therefore, I added this line
defined('DB_PORT') ? null : define("DB_PORT","8889");
to this group, like so
defined('DB_SERVER') ? null : define("DB_SERVER","host");
**defined('DB_PORT') ? null : define("DB_PORT","8889");**
defined('DB_USER') ? null : define("DB_USER","username");
defined('DB_PASS') ? null : define("DB_PASS","password");
defined('DB_NAME') ? null : define("DB_NAME","photo_gallery");
but it still didn't work. I'm being told database connection fails when I try to test it.
Any ideas?
EDIT. I tried to put the port next to the localhost but it's not working.
defined('DB_SERVER') ? null : define("DB_SERVER","localhost:8889");
defined('DB_USER') ? null : define("DB_USER","root");
defined('DB_PASS') ? null : define("DB_PASS","root");
defined('DB_NAME') ? null : define("DB_NAME","photo_gallery");
EDIT. The above code was in the config.php which was included into the database.php which is this
<?php
require_once("config.php");
class MySQLDatabase {
private $connection;
function __construct(){
$this->open_connection();
}
public function open_connection(){
$this->connection = mysql_connect(DB_SERVER, DB_USER, DB_PASS);
if(!$connection){
die("Database connection failed:" . mysql_error());
} else {
$db_select = mysql_select_db(DB_NAME, $this->connection);
if (!$db_select) {
die("Database selection failed: " . mysql_error());
}
}
}
public function close_connection(){
if(isset($this->connection)){
mysql_close($this->connection);
unset($this->connection);
}
}
public function query($sql) {
$result = mysql_query($sql, $this->connection);
$this->confirm_query($result);
return $result;
}
public function mysql_prep( $value ) {
$magic_quotes_active = get_magic_quotes_gpc();
$new_enough_php = function_exists( "mysql_real_escape_string" ); // i.e. PHP >= v4.3.0
if( $new_enough_php ) { // PHP v4.3.0 or higher
// undo any magic quote effects so mysql_real_escape_string can do the work
if( $magic_quotes_active ) { $value = stripslashes( $value ); }
$value = mysql_real_escape_string( $value );
} else { // before PHP v4.3.0
// if magic quotes aren't already on then add slashes manually
if( !$magic_quotes_active ) { $value = addslashes( $value ); }
// if magic quotes are active, then the slashes already exist
}
return $value;
}
private function confirm_query($result){
if(!$result){
die("Database query failed:" . mysql_error());
}
}
}
$database = new MySQLDatabase();
?>
What is the output of the following snippet?
<?php
// test.php
$host = 'localhost:8889';
$username = 'root';
$password = 'root';
$database = 'your_database';
if(!$connection = mysql_connect($host, $username, $password))
die('Error connecting to '.$host.'. '.mysql_error());
if(!mysql_select_db($database))
die('Error selecting '.$database.'. '.mysql_error());
echo 'Connection successful.';
?>
If this executes without an error, then you're probably just setting your constants incorrectly. Note that mysql_connect takes the port as part of the host parameter, not as a separate argument.
try 127.0.0.1:3307
it worked for me
Can you try to use:
define("DB_SERVER","127.0.0.1");
important:
checking defined or not is done by defined() but not by comparing it to null so sample:
http://www.php.net/defined
defined('DBSERVER') or define('DBSERVER', 'localhost:8889');
providing port information while making connection is just to add it along with server name i.e if your mysql server is localhost then while connecting just make it
localhost:8889
so your sample script may look like:
$strServer = "localhost:8889";
$strUser = "root";
$strPassword = "root";
$strDB = "test_db";
$conn = #mysql_connect($strServer, $strUser, $strPassword);
if(!$conn) {
die('Unable to connect to database: ' . mysql_error());
}else{
$db=mysql_select_db($strDB);
if(!$db){die('Error Selecting Database: '.$strDB.' [Error : '.mysql_error().']');}
}
Example with the default port 3306 of MySQL:
mysql_connect('localhost:3306', 'root', 'password');
This really makes things easier when copying scripts between the distant server and the local web server.