0

I am passing a variable by reference to a class method with the intention that it will be set to a member of that same class (based on a selector to the function). Although this doesn't appear to violate the rules of PHP's deprecated call-time pass-by-reference, I must be missing something, because it doesn't work.

I've dumbed down my code to illustrate the issue:

<?php

class Database
{
    static $USER_TABLE = 1;
    static $INVOICE_TABLE = 2;
    static $PRODUCT_TABLE = 3;

    var $users;
    var $invoices;
    var $products;

    function __construct()
    {
        $this->users []= array ('id'=>0, 'first_name'=>'John', 'last_name'=>'Doe');
        $this->products []= array('id'=>0, 'user_id'=>'0', 'printer'=>'HP','computer'=>'Toshiba');
        $this->invoices []= array('id'=>0, 'user_id'=>'0', 'total_items'=>2, 'total_cost'=>700);
    }

    function getTable($table_name, &$table)
    {
        switch ($table_name)
        {
            case Database::$USER_TABLE: $table = $this->users; break;
            case Database::$INVOICE_TABLE: $table = $this->invoices; break;
            case Database::$PRODUCT_TABLE: $table = $this->products; break;
        }
    }

    function addEntry($table_name, $info_array)
    {
        $this->getTable($table_name, $table); // THIS FAILS!  WHY?
        //$table = &$this->users; // THIS WORKS
        if ($table !== null)
        {
            $id = 0;
            if (count($table))
                $id = ((int)$table[count($table)-1]['id'])+1;

            $entry['id'] = $id;
            foreach ($info_array as $k => $v)
            {
                $entry [$k]= $v;
            }
            $table []= $entry;
        }
    }
}

$db = new Database;

$db->addEntry(Database::$USER_TABLE, array('first_name'=>'Jane', 'last_name'=>'Plain'));
var_dump($db);

?>

The alternative is just to take the switch case out of getTable(...) and paste that to the top of all of my functions that would have called it, but that type of code duplication is not desirable.

Any insight is appreciated!

2
  • 2
    When you call $this->getTable($table_name, $table);, what value does $table_name actually have? I think that, since your switch($table_name) has no default case, then simple $table does not get assigned. Commented Feb 6, 2015 at 17:06
  • Hi Matteo. When I call $db->addEntry(Database::$USER_TABLE, array('first_name'=>'Jane', 'last_name'=>'Plain')); (at the bottom of my code posting) the addEntry functoin passes along that first parameter (Database::$USER_TABLE) as $table_name, triggering the first case in the switch. Commented Feb 6, 2015 at 21:48

1 Answer 1

1

It'd be a lot easier just to have your getTable actually return a table:

function getTable($table_name)
{
    switch ($table_name)
    {
        case Database::$USER_TABLE: return $this->users; break;
        case Database::$INVOICE_TABLE: return $this->invoices; break;
        case Database::$PRODUCT_TABLE: return $this->products; break;
    }
}

And then just call the following:

$table = $this->getTable($table_name);
Sign up to request clarification or add additional context in comments.

1 Comment

The problem is that when you then set the data in $table, it doesn't modify the underlying $this->users table (or whichever table was selected). So it's modifying a copy of the object. even $table = &$this->getTable($table_name); doesn't work

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.