PHP 5.3+ Undefined Method Error

Hey,

I moved my files from php 4+ on linux (worked great) to a new server to php 5.3.4 and now I experience these errors:

1.) The Error:

“Call to undefined method admin::curPage()”

2.) The Line of Code:


         return admin_queries::$this->[B]curPage[/B]($this);

The class (first 40+ lines)




[B]class admin [/B]{
    
    var $qryStart;
    var $qryEnd;
    var $curPage;
    var $va;
    var $ERR_DISPLAY;
    var $results_perpage=50;
    var $orders_remain_active=20;
    


     function admin ($page, $va=NULL) {
        $this->[B]curPage[/B] = substr(str_replace("/","_",$page),0,-4);
        $this->va = $va;
        
    }


    public function post_check () {
    
    print_r($_POST);
    
        if (($this->va != NULL) && ($this->va['posttype'] == "entry")) {
            return TRUE;
        } else {
            return FALSE;
        }
    }

    
    public function post_run () {
        GLOBAL $LOG;
        $this->query_selector();

        include_once "class.admin_queries.php";
         [B]return admin_queries::$this->curPage($this);[/B] // ERROR LINE
    }


So how should I approach the class, or the post_run, admin functions in this class to prevent these errors?
For reference, the last line you see, in bold, including a file ‘class.admin.queries’ which has a class called admin_queries
which format an SQL query for a POST submission (update/insert record). It breaks so I am obviously not able to update records in this new server.

Thanks.

admin_queries::$this->curPage($this);
This looks wrong.

Instead it should probably be simply: return $this->curPage;

Actually I have no idea since you did not provide the whole class. Am I just suppose to guess what other methods you have in your class?

Hey.

It removed the error but it also didn’t keep the functionality of the admin_queries class in class.admin_queries.php.

Usually, this code allows a product in the admin to be updated/deleted/inserted and then redirect to a page that lists all products/whichever category you are modifying.

The redirect comes from the page that includes the pages which had the code you saw above:


[B]require 'class.admin.php'; // The page whose code you saw above[/B]

$[B]admin = new admin[/B]($_SERVER['PHP_SELF'], $_POST);
if ($admin->post_check()) {
    if (!$admin->[B]post_run[/B]()) { // located as a function in the code in my first post.

        die($ERR->display("Error Connecting To Your Information.  Please Try Again Later."));
    } else {
        header("Location:http://".HOST."/admin/staff/staff_merchandise.php");
    }
}

So it’s just a matter of me finding a way to keep the query, that is built in the last section of my first post, while allowing the ‘post_run’ function to be recognized as !Null so the redirect still takes place.

I might just blow this up and modify it. The issue is that this code is Smarty and was built for php 4+ and none of these pages (which were built by previous engineers) do not use public/private/php 5 ++ OOP practices.

Thanks.

Your best bet is to turn up error reporting all the way and then just examing the php error.log

or you may turn on the display_error and it will show error on the screen.
try to add this to the top of your script
ini_set(‘display_errors’, 1);

Do you see any specific errors now?

Oddly enough, no, I do not. So it’s baffling to see why the query won’t load. The db settings are proper and, with this line added:

ini_set(‘display_errors’, 1);

at the top of the key pages I see nothing.

Hrm…

It has nothing to do with db settings. It has to do with a way your class is written, which was probably still wrong even in php4, but was still working because php4 is more tolerant of bad script than 5.3

If you want to post your entire class, maybe someone will spot the problem. Also error log is your friend when debugging.

I posted this to smarty forum as it was smarty template the prior engineers worked on.
It basically runs on the smarty class file, the admin queries class file and the admin class file. I only posted this code as it was the relevant part of the issue. The rest is redundant.

I will certainly check the error log. My q is, if you do not use private/protected/public for functions and vars in php 5.3, the odds are, you will get errors like this. Right? I think anytime I upgrade a php 4+ script to a php 5++ server I get issues like this. Just curious if you or others went through the same thing. In the meantime, I will just build a patch until I can get the go ahead to use a real framework so we can finally move on from Smarty.

Thanks for your time. I do appreciate it.

You don’t have to say private/protected/public
it defaults to public. You may want to change
the
var $something; to
public $something;

Since I don’t know if it needs to be public or not, I go with public just to make sure there will not be any error due to access restrictions.

For a method, you don’t have to say public or private, if it just
function post_check ()
it is assumed to be public.

There could be a problem with using static methods if they are not declared as static.

See this:
admin_queries::$this->curPage($this);

There has to be a class admin_queries
and it must have a static method that matches the name of $this->curPage and must accept the object of type admin as parameter.

Now, you should find the value of $this->curPage
maybe add echo $this->curPage;
then find a method of that name if admin_queries
and make sure it’s declared as
public static function

Here is the function in the admin queries page that we reference. The output of
echo $this->curPage();

was the name of the function I am about to post. I realize what happens is it looks for a function based on the name of the page that needs it. Here is that function name:

_admin_staff_staff_edit_merch

Path of the file that calls it upon form submission:
admin/staff/staff_edit_merch

Function code from the admin_queries class in question:





    function _admin_staff_staff_edit_merch ($obj) {
        GLOBAL $db, $LOG, $_FILES, $ERR;
        if(isset($_FILES['product_image']) && isset($_FILES) && is_array($_FILES['product_image'])  && $_FILES['product_image']['name']) {
            include_once "class.util_functions.php";
            list($success,$response) = util_functions::captureUpload(DOCUMENT_ROOT.'/admin/staff/product_images/',false,'product_image');

            if (!$success) {
                $LOG->error($response);
                return FALSE;
            }
            $photo_upload = ", photo='".$response."'";
        } else {
            $photo_upload = "";
        }
        
        if (isset($obj->va['newartlabel']) && !empty($obj->va['newartlabel']) && isset($obj->va['new_artist_label']) && !empty($obj->va['new_artist_label'])) {
            if (isset($obj->va['artist']) && ($obj->va['artist'] != 0)) {
                $LOG->info("Please enter a new user or select an old one, but not both.");
                die($ERR->display("Please enter a new user or select an old one, but not both. Click to <a href=\\"staff_merchandise.php\\">go back</a> "));
            }
                
            // INSERT NEW ACCOUNT
            // set the data types
            if ($obj->va['newartlabel'] == "artist") {
                $user_type = 3;
            } elseif ($obj->va['newartlabel'] == "label") {
                $user_type = 4;
            } else {
                $LOG->info("Invalid User Type");
                die($ERR->display("Invalid User Type. Click to <a href=\\"staff_merchandise.php\\">go back</a> "));;
            }
                
            $data = Array("username" => "".$obj->va['new_artist_label']."",
                              "password" => "!!N0_PA55W0RD!!",
                              "type" => $user_type,
                              "email" => "",
                              "account_status" => "Inactive",
                              "ssn_tax_id" => "",
                              "website_display" => "off",
                              "featured" => "n");

            
            require_once "class.admin.php";
            if (!$last_id = admin::add_accounts($data)) {
                $LOG->error("Could not insert the artist.");
                die($ERR->display("Could not insert the artist. Click to <a href=\\"staff_merchandise.php\\">go back</a> "));
            }
            $artist_id = $last_id;
        } else {
            if (!isset($obj->va['artist']) || ($obj->va['artist'] == 0)) {
                $LOG->info("Invalid User Type");
                die($ERR->display("Invalid User Type. Click to <a href=\\"staff_merchandise.php\\">go back</a> "));;
            }
            $artist_id = $obj->va['artist'];
        }
    
        $sql = $obj->qryStart." products set 
            product_name='".$obj->va['product_name']."', 
            uid='".$artist_id."', 
            product_type='".$obj->va['category']."', 
            publish_status='".$obj->va['publish_status']."',
            price='".$obj->va['price']."',
            short_description='".$obj->va['short_description']."',
            long_description='".$obj->va['long_description']."'";

        $sql .= $photo_upload;
        
        $sql .= $obj->qryEnd." id='".$obj->va['product_id']."'";
        
        return $sql;

        $LOG->debug($sql);

        $res = $db->query($sql);

        if (DB::isError($res)) {
            $LOG->error($res->getDebugInfo());
            return FALSE;
        }

        # return TRUE;
    }

Explains the need for this function in the class.admin.php page:


function admin ($page, $va=NULL) {
        [B]$this->curPage [/B]= substr(str_replace("/","_",$page),0,-4);
        $this->va = $va;
        
    }


If you see $obj->qryStart it is referring to the next function in the admin class, next to post_run (posted in first post)


    function query_selector () {
        if ($this->va['dbr'] == 0) {
            $this->qryStart = "INSERT INTO";
            $this->qryEnd = ",";
            $this->qryCreate = "date_created=now(),";
            $this->qryType = "insert";
        } else {
            $this->qryStart = "UPDATE";
            $this->qryEnd = "WHERE";
            $this->qryCreate = "";
            $this->qryType = "update";
        }
    }

I hope this better explains it. The only reason I don’t post the entire class/classes is they are gigantic and would make you want to throw a cute furry animal out a window :slight_smile:

Well, if anything, it is a challenge and I like those.

Thanks, again.

In short, what they tried to do was use this:

    return admin_queries::$this-&gt;curPage($this);

to do this:

    return admin_queries::_admin_staff_staff_edit_merch($this);

The idea that $this->curPage does =_admin_staff_staff_edit_merch and they are dynamically
calling a function name based on the url of the admin page that needs it to be called.

So that is the name of the function that processes the form and updates the admin merchandise data. Worked in php 4, as is.