2

As title say i'm starting to learn object oriented aspect of PHP. In this regard i made small "exercise" of sort "translating" one of my php functions into oo mode of php. I'm asking of your kind folks is there any recommendations you can give me concerning my predicament.

Example of non-oo PHP:

    <?php
    function pristup($servername, $username, $password, $dbname, $sql){

        $conn=new mysqli($servername, $username, $password, $dbname);

        if($conn->connect_error){

            die("Neuspela konekcija: ".$conn->connect_error);

        }

        $result = $conn->query($sql);
        if ($result == TRUE) {
        //echo "Uspela konekcija";
    } else {
        echo "Neuspešno izvršavanje upita: " . $conn->error;
    }
        return $result;

        $conn->close();

    }

    ?>

Example of this done in object oriented manner:

<?php

class konekcija{

    private $servername;
    private $username;
    private $password;
    private $dbname;
    private $sql;

    //Setter functions
    public function setServername($par){

        $this->servername = $par; 

    }

    public function setUsername($par){ 

        $this->username = $par; 

    }

    public function setPassword($par){ 

        $this->password = $par; 

    }

    public function setDBname($par){ 

        $this->dbname = $par; 

    }

    public function setSQL($par){ 

        $this->sql = $par; 

    }

    //Getter functions
    public function getServername() { 
        return $this->servername;
    }

    public function getUsername() { 
        return $this->username;
    }

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

    public function getDBname() { 
        return $this->dbname;
    }

    public function getSQL() { 
        return $this->sql;
    }

    //Function that executes query.
    public function pristup($server_name, $user_name, $pass_word, $db_name, $sql_query){

        $conn=new mysqli($server_name, $user_name, $pass_word, $db_name);

        if($conn->connect_error){

            die("Neuspela konekcija: ".$conn->connect_error);

        }

        $result = $conn->query($sql_query);

        if ($result == TRUE){

        echo "Uspela konekcija";

        } 
        else{

                echo "Neuspešno izvršavanje upita: " . $conn->error;

            }

        return $this->$result;

        $conn->close();

    }

}


$kon = new konekcija(); //Creation of an object.

//Setting values.
$kon -> setServername("localhost"); 
$kon -> setUsername("root");
$kon -> setPassword("");
$kon -> setDBname("test"); 

$kon -> setSQL("CREATE TABLE example(
                id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                firstname VARCHAR(30) NOT NULL,
                lastname VARCHAR(30) NOT NULL,
                email VARCHAR(50),
                reg_date TIMESTAMP
                )"
            );

//Getting values and inserting them into class method.
$kon -> pristup($kon->getServername(), $kon->getUsername(), $kon->getPassword(), $kon->getDBname(), $kon->getSQL());

?>

This works.What i'm asking is code any good? Is there better/more established way of doing this? Any advice will be appreciated. PS: I'm getting "Notice: Undefined property: konekcija::$1 in C:\xampp\htdocs\www\klase\tab_klass.php on line 87" why is this happening?

8
  • This might be more appropriate on codereview.stackexchange.com Commented Dec 30, 2017 at 3:23
  • Using OOP doesn't mean that you're using objects, and you nailed it. Wrapping your code in a class isn't OOP. You can start by looking at concepts like encapsulations and dependency injection. Commented Dec 30, 2017 at 3:28
  • @j08691 Understood. Done. What about a "Notice" thing? Should i delete whole post or just non-oo code because of "Notice" and live oo stuff? Commented Dec 30, 2017 at 3:29
  • @Federkun So its good code? What about notice thingy? Commented Dec 30, 2017 at 3:31
  • @j08691 well i have to wait 40min. to post to codereview.stackexchange.com. Perhaps because of this post? Commented Dec 30, 2017 at 3:41

1 Answer 1

3

Just brief example:

<?php

// class konekcija{ - ONLY ENGLISH!
class SimpleDB{
    private $conn;

    //Setter functions - NOOO!
    //Getter functions - NOOO!

    // hide all data inside class instance
    public function __construct($server_name, $user_name, $password, $db_name){
        $this->conn=new mysqli($server_name, $user_name, $password, $db_name);

        if($this->conn->connect_error){
            die("ERROR: " . $this->conn->connect_error);
        }
    }

    function __destruct() {
        $this->conn->close();
    }

    //Function that executes query.
    // public function pristup( - ONLY ENGLISH!
    public function execute($sql_query){
        $result = $this->conn->query($sql_query);
        if ($result == TRUE){
            echo "Uspela konekcija";
        } else {
            echo "Neuspešno izvršavanje upita: " . $conn->error;
        }

        return $result;
    }
}


$kon = new SimpleDB("localhost", "root", "", "test"); 

$SQL = "CREATE TABLE example(
        id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
        firstname VARCHAR(30) NOT NULL,
        lastname VARCHAR(30) NOT NULL,
        email VARCHAR(50),
        reg_date TIMESTAMP
        )";
$kon->execute($SQL);
?>

- Why only English?

First of all, because 99% of good developers know/use English, despite that it's isn't they mother-language. If in code only English words, that it's much easier to understand code, so 99% of good developers will help you with your code. Secondary, it's all about consistence: while($running) doJob(); is much easier for reading than while($zapushen) rabotat() (Russian students style, yeah).


- Why did you remove the getter / setter?

Using getter / setter is a very common practice, but it kills the entire meaning of OOP. Using them, we, as it were, turn the objects inside out. The object must itself be able to perform the necessary operations, but we as if say "NO! Give us the data, we know better how to work with them!".

SOMETIMES getter / setter is a necessary evil, so as not to over-code it, but in the long run they only harm. I do not urge you to completely abandon getter / setter, but it's better to think twice with what ACTIONS you can replace them.


Also i moved my post to codereview.stackexchange.com/questions/183916/… . One user suggested on codereview use of paradigm MVC. After short read about it, what are benefits in this particular example comparing to this example and how would you do "translate" your example to MVC paradigm?

First of all, MVC is not a paradigm, it's a pattern. And this pattern, mainly, for the UI, in some form of it. At the very least, trying to use it for DB is not a very good solution. It seems to me that the person got excited with MVC and used it for other purposes.

I personally did not like the attempt to apply MVC here. Moreover, I do not like this pattern at all. Maybe I worked with him a little, maybe I did not see any good examples of it, but I do not like it. I especially like the code like use \ MyApp \ Database \ Model as Connection;. If it's Connection, then why call it a model? Just to name this MVC? And in that example there are a lot of controversial points, as for me.

In general, I would say that the correct application of any paradigms, patterns, etc. benefits in the long term. The more complex we apply them, the more large the project should be, so that all of their benefits will be revealed. One query to the database is not a good project, even for OOP, not to mention different patterns.

Is there a desire to apply / learn MVC? - Do more complex project, for example, some kind of organizer.


A small addition about the logging and errors.

I would throw exceptions. But what about logging? Well, I would do something like this:

interface IQuery{
    public function execute($sql);
}

class SimpleDB implements IQuery{
    ......

    public function execute($sql_query){
        $result = $this->conn->query($sql_query);
        if($result === FALSE){
            throw new EMyCustomException($conn->error);
        }

        return $result;
    }
}

class LoggedDB implements IQuery{
    private $db;

    public function __construct($DB){
        $this->db = $db;
    }

    public function execute($sql_query){
        try{
            return $this->db->execute($sql_query);
        } catch (EMyCustomException $e) {
            // perform logging
            throw $e; // rethrow
        }
    }
}

$db = new LoggedDB(new SimpleDB(......));
$db->execute("not a valid sql here");

As for me, it's much better approach, especially for a beginners.

Sign up to request clarification or add additional context in comments.

5 Comments

Using constructors then destroying "it" after it's done it's a good call. The reason i didn't use it, beside that i'm new to this oo PHP, is that many of these tutorials including posts on SO, did it with getters/setters so i assumed it's correct way. Also i moved my post to codereview.stackexchange.com/questions/183916/… . One user suggested on codereview use of paradigm MVC. After short read about it, what are benefits in this particular example comparing to this example and how would you do "translate" your example to MVC paradigm?
Also additional thanks for your code review and code itself since it's clean and understandable for a newbie in oo PHP like me. And thanks since there's no more that annoying "Notice: Undefined property: konekcija::$1 in C:\xampp\htdocs\www\klase\tab_klass.php on line 87" . Could you explain why this "notice" happened in the first place just for clarity sake?
I don't really understand the purpose of the LoggedDB class. Would you use anything like that in any real life project or is it just a random musing to illustrate some abstract idea?
@your-common-sense LoggerDB is more of an example, although it is quite applicable. An example of a nested "hierarchy" from a real project: CRealUser -> CDBUser -> CCachedRow -> CDBUserRow. Each class / level adds very little functionality that is easy to test and maintain. CDBUserRow - direct work with DB. CCachedRow - prevents unnecessary queries on the DB. CDBUser - adds user connections to the history of payments, storage, etc.` CRealUser` - high-level business logic. Unusually, I agree, but very flexible and simple. By the way, at the lowest level I use SafeMySql. :)

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.