-1

I have read almost all references here about this topic. My individual problem is that I have an OOP CMS which had been coded using the long since deprecated mysql database access. Now my task is to upgrade everything from PHP 5.6 to PHP 7.x. The choice was either PDO or mysqli and I have decided for the latter since its syntax comes nearer to my code reading and understanding.

Here is my mysql code:

Credentials are defined in DBSettings.php:

    <?php
        // Variablen fuer den Datenbankzugriff
        $DATABASESERVER   = 'localhost';
        $DATABASENAME     = 'whatever_db';
        $DATABASEUSERNAME = 'blithering_idiot';
        $DATABASEPASSWORD = 'moronic_fool_1234_$%&/';
        $DATABASETYPE     = 'MySQL';

        //require_once($_SERVER['DOCUMENT_ROOT'].'/DBSettings.inc.php');
    ?>

A file called PHP5_classDatabase.php contains the class:

    <?php
        error_reporting(-1);
        //ini_set('display_errors', 'On');

        class database extends object
        {
            private $rConnection;
            private $sDatabaseType;
            private $sDatabaseServer;
            private $sDatabaseName;
            private $sUserName;
            private $sPassword;

            public function __construct($sDatabaseServer, $sUserName, $sPassword, $sDatabaseType = 'MySQL')
            {
                switch ($sDatabaseType) {
                    case 'MySQL':
                        $this->setConnection(mysqli_connect($sDatabaseServer, $sUserName, $sPassword));
                        $this->setDatabaseType($sDatabaseType);
                    break;
                    case 'MSSQL':
                        $this->setConnection(mssql_connect($sDatabaseServer, $sUserName, $sPassword));
                        $this->setDatabaseType($sDatabaseType);
                    break;
                    default:
                        $this->setConnection(mysqli_connect($sDatabaseServer, $sUserName, $sPassword));
                    $this->setDatabaseType('MySQL');
                }
                $this->setDatabaseServer($sDatabaseServer);
                $this->setUserName($sUserName);
                $this->setPassword($sPassword);
                $this->setDatabaseName('');
            }

            public function setConnection($rConnection)
            {
                $this->rConnection = $rConnection;
            }

            public function setDatabaseType($sDatabaseType)
            {
                $this->sDatabaseType = $sDatabaseType;
            }

            public function setDatabaseServer($sDatabaseServer)
            {
                $this->sDatabaseServer = $sDatabaseServer;
            }

            public function setDatabaseName($sDatabaseName)
            {
                $this->sDatabaseName = $sDatabaseName;
            }

            public function setUserName($sUserName)
            {
                $this->sUserName = $sUserName;
            }

            public function setPassword($sPassword)
            {
                $this->sPassword = $sPassword;
            }

            public function getConnection()
            {
                return ($this->rConnection);
            }

            public function getDatabaseType()
            {
                return ($this->sDatabaseType);
            }

            public function getDatabaseServer()
            {
                return ($this->sDatabaseServer);
            }

            public function getDatabaseName()
            {
                return ($this->sDatabaseName);
            }

            public function getUserName()
            {
                return ($this->sUserName);
            }

            public function getPassword()
            {
                return ($this->sPassword);
            }

            public function selectDatabase($sDatabaseName)
            {
                switch ($this->getDatabaseType()) {
                    case 'MySQL':
                        mysqli_select_db($sDatabaseName);
                    break;
                    case 'MSSQL':
                        mssql_select_db($sDatabaseName);
                    break;
                    default:
                        mysql_select_db($sDatabaseName);
                }
            $this->setDatabaseName = $sDatabaseName;
            }
        }
    ?>

This file contains much more database-specific stuff but without meaning for this principal access description.

Now comes the last part, the file functionsDatabase.php in which the function "connectToDB()" is being taken care of:

    <?php
        function connectToDB() {
            global $DATABASESERVER, $DATABASEUSERNAME, $DATABASEPASSWORD, $DATABASENAME, $oDatabase;

            $oDatabase = new database($DATABASESERVER, $DATABASEUSERNAME, $DATABASEPASSWORD);
            $oDatabase->selectDatabase($DATABASENAME);
        }

        [... functions with database association, not important here ...]

    ?>

The connectToDB(); is then executed by a file called general.php which is referenced to by any other PHP script within this CMS.

This code has, so far, worked flawlessly, and the subsequent tons of database save and read and update and delete procedures worked just fine.

Now, I have tried several times to switch that code to mysqli and I do know the theory about its native object-oriented and procedural construction as to be read from, for instance, w3school.

My way to change things into mysqli has looked like this:

In PHP5_classDatabase.php I changed the tp the following code (display only of the changed context):

    [...]

    public function __construct($sDatabaseServer, $sUserName, $sPassword, $sDatabaseType = 'MySQL', $sDatabaseName = 'adipositas')
    {
        switch ($sDatabaseType) {
            case 'MySQL':
                //Change 1: $this->setConnection(mysqli_connect($sDatabaseServer, $sUserName, $sPassword, $sDatabaseName));
                //Change 2: $this->db = mysqli_connect($sDatabaseServer, $sUserName, $sPassword, $sDatabaseName);
                $db = mysqli_connect($sDatabaseServer, $sUserName, $sPassword, $sDatabaseName);
                $this->setDatabaseType($sDatabaseType);
                break;

    [...]

    public function selectDatabase($sDatabaseName = 'adipositas')
    {
        switch ($this->getDatabaseType()) {
            case 'MySQL':
                mysqli_select_db($this->$db, $sDatabaseName);
                break;

    [...]

    }

And in functionsDatabase.php I made the following changes:

    [...]

    function connectToDB() {
        global $DATABASESERVER, $DATABASEUSERNAME, $DATABASEPASSWORD, $DATABASENAME, $oDatabase;

        $oDatabase = new database($DATABASESERVER, $DATABASEUSERNAME, $DATABASEPASSWORD, $DATABASENAME);
        $oDatabase->selectDatabase($DATABASENAME);
    }

Using XDebug, I get various error messages depending on my play with how to change the potential access to the database. In the described change, they are as such:

Notice: Undefined variable: db in C:\wamp64\apps\adipositas\resources\PHP5_classDatabase.php on line 167

... referring to:

mysqli_select_db($this->$db, $sDatabaseName);

... and ...

Fatal error: Cannot access empty property in C:\wamp64\apps\adipositas\resources\PHP5_classDatabase.php on line 167

... referring to the same line, of course.

Has anybody an idea how to handle this or where my error is?

mtjmohr
  • 99
  • 9
  • 1
    The mssql_ library doesn't exist either anymore in PHP 7 :) My recommendation is PDO (you get MS-Server, Mysql, Postgres, and some more RDBMS with the same wrappers...) – Honk der Hase Dec 07 '19 at 18:30
  • Right, I should have told you that I was never using this for MSSQL since I did not have any customer (from medicine, they all liked the flavor of the cost-free MySQL Community Edition). But I asked for **mysqli** since there are other CMS-like programs with even different database access codes but for MySQL, so I would like to keep this for these code bases wheres for my more recent endeavours I have already switched to PDO but with different OO coding. – mtjmohr Dec 07 '19 at 18:45
  • 1
    use $db instead of $this->$db – nbk Dec 07 '19 at 19:31
  • Don't shoot yourself in the foot with MySQLi. Go straight for PDO. Even better use a proper DB abstraction library e.g. EasyDB. – Dharman Dec 07 '19 at 19:31
  • 1
    See [How to change mysql to mysqli?](https://stackoverflow.com/a/56997881/1839439) – Dharman Dec 07 '19 at 19:32
  • 1
    Do not refer to w3schools for PHP tutorials. They have very bad examples. Try something better like https://phpdelusions.net/ – Dharman Dec 07 '19 at 19:33
  • @nbk: No change in error messages. – mtjmohr Dec 07 '19 at 19:51
  • @Dharman: Thank you very much especially for the advice to EasyDB. The issue, however, is that once I will have set up a successful database connection using mysqli I will be able to easily adapt all the queries which follow. – mtjmohr Dec 07 '19 at 19:52
  • @mtjmohr That is the point. Don't do it! You need to replace all old queries with prepared statements and switch on error reporting(preferably). This will make your code completely different from the old `mysql_*` functions. – Dharman Dec 07 '19 at 19:56
  • 1
    is $db from your connection a global variable? if not make it so – nbk Dec 07 '19 at 19:59
  • @nbk: Just done so: Warning: mysqli_select_db() expects parameter 1 to be mysqli, null given in C:\wamp64\apps\adipositas\resources\PHP5_classDatabase.php on line – mtjmohr Dec 07 '19 at 20:05
  • 1
    add also an error handling for your connection.function, – nbk Dec 07 '19 at 20:07
  • Well, I found out myself how to do it. I will post that as an answer to my own question. – mtjmohr Dec 07 '19 at 20:56
  • Special thanks again to Dharman and @nbk: you brought me to the right idea of solving this issue. – mtjmohr Dec 08 '19 at 20:16
  • And finally, just a small comment: I do not know whether this was automatically done through the chosen topic or actively by human hand: The subtraction of two reputation points from someone looking for help in an individual problem setting is an abject and pedantic move to make. – mtjmohr Dec 08 '19 at 20:20
  • 1
    @mtjmohr You lost two reputation points automatically because your question received a downvote. It is neither an abject nor a pedantic move, it's just someone voting on the content. Don't worry about a single downvote, it's not meant personally. See [Why is voting important?](https://stackoverflow.com/help/why-vote) – Modus Tollens Dec 08 '19 at 20:32

1 Answers1

0

So the solution is as follows:

Here is my mysqli code:

Credentials are defined in DBSettings.php (remains the same):

    <?php
        // Variablen fuer den Datenbankzugriff
        $DATABASESERVER   = 'localhost';
        $DATABASENAME     = 'whatever_db';
        $DATABASEUSERNAME = 'blithering_idiot';
        $DATABASEPASSWORD = 'moronic_fool_1234_$%&/';
        $DATABASETYPE     = 'MySQL';
    ?>

The constructor in PHP5_classDatabase.php is slightly changed (the lines affected are indicated by *NEW*:

    <?php
        error_reporting(-1);
        //ini_set('display_errors', 'On');

        class database extends object
        {
            private $rConnection;
            private $sDatabaseType;
            private $sDatabaseServer;
            private $sDatabaseName;
            private $sUserName;
            private $sPassword;
            *NEW* private $db;

            public function __construct($sDatabaseServer, $sUserName, $sPassword, *NEW* $sDatabaseName, $sDatabaseType = 'MySQL')
            {
                switch ($sDatabaseType) {
                    case 'MySQL':
                        *NEW* $db = $this->setConnection(mysqli_connect($sDatabaseServer, $sUserName, $sPassword, $sDatabaseName));
                        $this->setDatabaseType($sDatabaseType);
                    break;
                    case 'MSSQL':
                        $this->setConnection(mssql_connect($sDatabaseServer, $sUserName, $sPassword));
                        $this->setDatabaseType($sDatabaseType);
                    break;
                    default:
                        *NEW* $db = $this->setConnection(mysqli_connect($sDatabaseServer, $sUserName, $sPassword, $sDatabaseName));
                    $this->setDatabaseType('MySQL');
                }
                $this->setDatabaseServer($sDatabaseServer);
                $this->setUserName($sUserName);
                $this->setPassword($sPassword);
                *NEW* this->setDatabaseName($sDatabaseName);
            }

            [...]

            public function selectDatabase(*NEW* $db, $sDatabaseName)
            {
                *NEW* global $sDatabaseServer, $sUserName, $sPassword, $sDatabaseName, $db;

                *NEW* $db = mysqli_connect('localhost', 'root', '', 'adipositas');
                *NEW* if (!$db) {
                    *NEW* echo "Error: Unable to connect to MySQL." . PHP_EOL;
                    *NEW* echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
                    *NEW* echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
                    *NEW* exit;
                *NEW* }

                switch ($this->getDatabaseType()) {
                    case 'MySQL':
                        mysqli_select_db(*NEW* $db, $sDatabaseName);
                    break;
                    case 'MSSQL':
                        mssql_select_db($sDatabaseName);
                    break;
                    default:
                        mysql_select_db(*NEW* $db, $sDatabaseName);
                }
            $this->setDatabaseName = $sDatabaseName;
            }
        }
    ?>

And finally, functionsDatabase.php is changed accordingly:

    function connectToDB()
    {
        global $DATABASESERVER, $DATABASEUSERNAME, $DATABASEPASSWORD, $DATABASENAME, $oDatabase, $db;

        $oDatabase = new database($DATABASESERVER, $DATABASEUSERNAME, $DATABASEPASSWORD, $DATABASENAME);
        $oDatabase->selectDatabase($db, $DATABASENAME);
    }

Now it was only for the adaptation of the mysql components to myslqi. Since there is no mysqli_result(), I took the adaptation from this very good StackOverflow reference.

Most of the exchange work could be done using simple global research and replace modes.

mtjmohr
  • 99
  • 9