(PHP) Use get_class in database query



  • I am coding a small hobby project (a webservice) in PHP which queries a backend database (MySQL).

    One of the database functions builds a query dynamically, including a different table depending on the object passed to this function.

    First I thought about using a switch statement to insert a table name depending in the input object. Then I thought it might be possible to use the class type of an object as the table name in the query, since all object names were virtually identical to the table names in the database. The idea behind this is that the code requires less maintenance when introducing more objects to the function (dont have to extend the switch statement). A samplified code snippet of this can be found below.

     

    The question is;  How acceptable is this solution?
    I can see the upside where I don't have to maintain a switch statement in myFunction. A downside however is that I am using 2 architecture layers; Passing a 'false' object will result in a database query, where it would perhaps be better to catch this 'error' in the server class.

    Speed is obvious not an issue since it concerns a small project with little users. It's more that I am trying to find an elegant solution, and I am wondering how acceptable this solution would be to people here.

     

    P.S.: I am aware I could use overloading as well, but I like the one function solution more. 

     

    <?php
    class myClient
    {
        public function __construct()
        {
            $server = new myServer();
            var_dump($server->myFunction(new myObject("firstname","lastname")));
        }
    }

    class myServer
    {    
        public function __construct()
        {
            mysql_connect("hostname", "username", "password") or die("Mein leben!");
            @mysql_select_db("databasename") or die("Mein leben!");
        }

        public function myFunction($inputObject)
        {
            if(gettype($inputObject) == "object")
            {
                $returnArray = array();
                
                $results = mysql_query("SELECT * FROM ".get_class($inputObject));
                
                if(!$results && mysql_errno() == 1146)
                {
                    die("that wasnt a valid object");
                }
                
                while($outputObject = mysql_fetch_object($results, get_class($inputObject)))
                {
                    array_push($returnArray, $outputObject);
                }
                
                return $returnArray;
            }
        }
    }

    class myObject
    {
        private $firstName;
        private $lastname;
        
        public function __construct($firstname, $lastname)
        {
            $this->firstname = $firstname;
            $this->lastname = $lastname;
        }
    }

    $client = new myClient();
    ?>



  • @kroesjnov said:


    The question is;  How acceptable is this solution?

    Not at all, IMO. I very seldom find it acceptable to use "SELECT *", as you're retrieving columns of data you probably don't need. Secondly, without knowing the table ahead of time, how do you build a WHERE clause? If you omit the WHERE, you're now not only retrieving [b]columns[/] you don't need, but potentially a lot of [b]rows[/b] of data as well. 



  • I'd say that using get_class is acceptable, but it's better to make the objects inherit from a single abstract base class that has the methods, say, "getTableName", "getWhereClause", etc. and make the function accept only the abstract base class type as its parameter. Another option is to use an interface. The more important problem is with your SQL query.



  • @KenW said:

    Not at all, IMO. I very seldom find it acceptable to use "SELECT *", as you're retrieving columns of data you probably don't need. Secondly, without knowing the table ahead of time, how do you build a WHERE clause? If you omit the WHERE, you're now not only retrieving [b]columns[/b] you don't need, but potentially a lot of [b]rows[/b] of data as well.

    @Tweenk said:

    The more important problem is with your SQL query.
     

    As stated the code has been samplified, I stripped all code which has nothing to do with the initial question, including quite some code to form a where clause.

    As for using [b]SELECT *[/b]; I will be using all attributes to rebuild the relations between the objects in my GUI (all objects share common attributes, except the attributes which denote a relation to another object), and I want to leave options open to change this [i]functionality[/i] when extending the GUI. [b]SELECT *[/b] would also defeat the use of using [b]get_class[/b] as I indeed would not know the structure of the table ahead of time. In that case I might as well overload and use the attributes per table/object in the query. In short; I am using a [b]WHERE[/b] clause, and I do in fact use all data retrieved from the database.

    Since the objects share attributes, I know in advance that all objects have for example a [b]name[/b] attribute, which I use in my [b]WHERE[/b] clause. This brings us to the suggestion that [b]Tweenk[/b] made;

    @Tweenk said:

    I'd say that using get_class is acceptable, but it's better to make the objects inherit from a single abstract base class that has the methods, say, "getTableName", "getWhereClause", etc. and make the function accept only the abstract base class type as its parameter. Another option is to use an interface.

    Ah, indeed, this is a very simple solution. I should have used inheritance already because of the common attributes between the object. Using the superclass to determine if the query should be fired is an elegant solution in this case imho. Thank you for that :) 


Log in to reply