Jump to content

Upgrade from php 7 to 8 broke class code


Go to solution Solved by mac_gyver,

Recommended Posts

As the title states I upgraded to php 8 from 7 and the class code no longer functions. I don't get any errors in the php-fpm/www-error.log to provide insight. I've tried to outline the code flow as follows. I hope someone can make sense of this and provide the changes needed.

What I uncovered is the class code receives the correct information to create the postgresql connection, but in php8 the $this->CONN is now empty.

  1. index.php includes PicSql.inc.php
  2. PiSql.inc.php includes DbSql.inc.php 
  3. DbSql.inc.php includes const.inc.php
  4. const.inc.php contains the variables with the values to create the connection to postgresql

1. index.php 

require("PicSql.inc.php");
$db = new PicSQL($DBName);

<p> Open Jobs <?=$db->getNumOpenJobs("Off Campus")?> </p>

 

2. PicSql.inc.php

require("DbSql.inc.php");

Class PicSQL extends DBSQL{

    function PicSQL($DBName = ""){
        $this->DBSQL($DBName);
    }
   
    function getNumOpenJobs($in, $workstudy=false, $neo=false){
        ...
        $result = $this->select($sql);
        ...
    }

}

 

3. DbSql.inc.php

require("const.inc.php");

//error_log dispalys all the correct values for the connecton from the const.inc.php include
error_log ("DbSql start const: " . $DBName . $DBUser .$DBPassword . $DBHost . $DBPort);

Class DBSQL{
    
    function DBSQL($DBName){     
        global $DBHost,$DBUser,$DBPassword,$DBPort,$DBName;
        $conn=pg_connect("host=$DBHost port=$DBPort user=$DBUser dbname=$DBName");
        $this->CONN = $conn;
        return true;
    }
   
   function select($sql=""){ 
      if (empty($sql)) return false; //$sql is not empty here
      if (empty($this->CONN)) return false; //$this->CONN is empty thus the code stops here
      
      $conn = $this->CONN; 
      $results = pg_exec($conn,$sql) or die(pg_errormessage()."<br />");
      
      if ((!$results) or (empty($results))){       
        return false; 
      }
      $count = 0;
      $data = array();
      
      while ($row = pg_fetch_array($results)){
         $data[$count] = $row;
         
         $count++;
      }
      
      pg_freeresult($results);
      return $data;
   }

}


 

there is no password parameter in the pg_connect() call. does the database have a password set for the connection? is this the exact code that has previously worked?

note: because you are passing the database name as a call time parameter and also using the global keyword to get the database name into the function, i'm not sure which takes precedence or if the call time parameter value sets the global variable. the only reason why this would have previously worked, is because the same value is being used in both cases. if you have any DBSQL(...) calls that are using a different value than $DBName, this probably won't work the way you think it should.

you can try to use echo pg_last_error(); to see if it provides some information (doubtful.)

for the error logging, do other types of php errors get logged? if so, use a phpinfo() statement and check if error_reporting is set to E_ALL, so that ALL php errors will get logged.

putting the error_log(...); statement right before the pg_connect(...) call would let you know what values are actually being used inside the function.

short-version: there's nothing apparent in the code that is php version specific. the connection is failing and is probably returning a false value. you can use var_dump($conn); right after the connection statement to check. therefore, you need to determine why the connection is failing.

Edited by mac_gyver
  1. does the database have a password set for the connection? No
  2. is this the exact code that has previously worked? Yes
  3. do other types of php errors get logged? Yes

The function DBSQL($DBName) in DbSql.inc.php is no longer being accessed, for the error_log statement, which I put inside as the first statement, is not showing in the log.

Also I put an error_log statement inside the function PicSQL and it does not execute. 

Class PicSQL extends DBSQL{

function PicSQL($DBName = "")
   {
      error_log("picsql dbsql call");
      $this->DBSQL($DBName);
   }

The server with php7 and the same class code, the error_log statement does execute from inside the function PicSQL($DBName = ""). Thus the class syntax is no longer working in php8.

Quote

[21-Jun-2022 21:06:19 America/Los_Angeles] picsql dbsql call

The same is with the function DBSQL($DBName). the error_log statement in front of the connection statement lists of the values for the connection variables.

Class DBSQL{   
   function DBSQL($DBName)

Edited by whichiso
additional information
  • Solution

i just tried the code, and there is one php version difference. a method named the same as the class is no longer automatically called when an instance of the class is created. you must specifically name the method __construct. change function PicSQL($DBName = ""){ to function __construct($DBName = ""){

see the 4th item under 'Other incompatible Changes' at this link -  https://www.php.net/manual/en/migration80.incompatible.php

also see the 'Old-style constructors' at this link - https://www.php.net/manual/en/language.oop5.decon.php

  • Thanks 1

@mac_gyverSince the issue with the $DBName was brought up, is there a better way to code this. Also should function DBSQL be renamed to function __contruct like function PicSQL was?

require("DbSql.inc.php");
Class PicSQL extends DBSQL{
   function __construct($DBName = "") {
      $this->DBSQL($DBName);
   }


 

require("const.inc.php"); //defines $DBName variable
Class DBSQL{   
   function DBSQL($DBName) {     
      global $DBHost,$DBUser,$DBPassword,$DBPort,$DBName;
      $conn=pg_connect("host=$DBHost port=$DBPort user=$DBUser dbname=$DBName");
      $this->CONN = $conn;
      return true;
   }

 

the intended purpose of having the database name as a call-time parameter is so that you can make multiple connections, each with their own selected database. for this to work, $DBName must be removed from the global ... ; line of code, so that the call-time parameter will be the value that gets used.

6 hours ago, whichiso said:

Also should function DBSQL be renamed to function __contruct like function PicSQL was?

if there's ever a case of directly making an instance of the DBSQL class, yes. the line $this->DBSQL($DBName); would need to be changed to parent::__construct($DBName); as well.

  • Thanks 1
24 minutes ago, mac_gyver said:

the intended purpose of having the database name as a call-time parameter is so that you can make multiple connections, each with their own selected database.

You only need separate connections if you are working on multiple servers. One connection is suffucient to work with several database on the same server. The connection is to the server, the database name merely defines the default database.

$con->query("SELECT username FROM user");                // if querying default db

$con->query("SELECT username FROM DB2.user");            // if DB2 is not the default db.

To copy a table from DB1 to DB2

$con->query("CREATE TABLE DB2.tablea LIKE DB1.tablea");
$con->query("INSERT INTO DB2.tablea SELECT * FROM DB1.tablea");

 

  • Thanks 1

@mac_gyver I made the changes and they work great. I always thought something wasn't quite right in this code that I inherited with passing $DBName and then setting the global.

--PicSql.inc.php

require("DbSql.inc.php");
Class PicSQL extends DBSQL
{
   function __construct($DBName = "")
   {
      //$this->DBSQL($DBName);
      parent::__construct($DBName);
   }

--DbSql.inc.php   

require("const.inc.php");

Class DBSQL
{
   //function DBSQL($DBName)
   function __construct($DBName)
   {   
      //global $DBHost,$DBUser,$DBPassword,$DBPort,$DBName;
      //$DBName removed so call-time parameter $DBName is used
      global $DBHost,$DBUser,$DBPassword,$DBPort;
      $conn=pg_connect("host=$DBHost port=$DBPort user=$DBUser dbname=$DBName");
      $this->CONN = $conn;
      return true;
   }

 

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.