Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
840 views
in Technique[技术] by (71.8m points)

oop - Object Oriented PHP Best Practices

Say I have a class which represents a person, a variable within that class would be $name.

Previously, In my scripts I would create an instance of the object then set the name by just using:

$object->name = "x";

However, I was told this was not best practice? That I should have a function set_name() or something similar like this:

function set_name($name)
{
    $this->name=$name;
}

Is this correct?

If in this example I want to insert a new "person" record into the db, how do I pass all the information about the person ie $name, $age, $address, $phone etc to the class in order to insert it, should I do:

function set($data)
{
    $this->name= $data['name'];
    $this->age = $data['age'];
    etc
    etc

}

Then send it an array? Would this be best practice? or could someone please recommend best practice?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You should have setter/getter methods. They are a pain but you don't necessarily have to write them yourself. An IDE (for example Eclipse or Netbeans) can generate these for you automatically as long as you provide the class member. If, however, you don't want to deal with this at all and you're on PHP5 you can use its magic methods to address the issue:

   protected $_data=array(); 
   public function __call($method, $args) {
        switch (substr($method, 0, 3)) {
            case 'get' :
                $key = strtolower(substr($method,3));
                $data = $this->_data[$key];
                return $data;
                break;
            case 'set' :
                $key = strtolower(substr($method,3));
                $this->_data[$key] = isset($args[0]) ? $args[0] : null;
                return $this;
                break;
            default :
                die("Fatal error: Call to undefined function " . $method);
        }
    } 

This code will run every time you use a nonexistent method starting with set or get. So you can now set/get (and implicitly declare) variables like so:

$object->setName('Bob');
$object->setHairColor('green');

echo $object->getName(); //Outputs Bob
echo $object->getHairColor(); //Outputs Green

No need to declare members or setter/getter functions. If in the future you need to add functionality to a set/get method you simply declare it, essentially overriding the magic method. Also since the setter method returns $this you can chain them like so:

 $object->setName('Bob')
        ->setHairColor('green')
        ->setAddress('someplace');

which makes for code that is both easy to write and read.

The only downside to this approach is that it makes your class structure more difficult to discern. Since you're essentially declaring members and methods on run time, you have to dump the object during execution to see what it contains, rather than reading the class. If your class needs to declare a clearly defined interface (because it's a library and/or you want phpdoc to generate the API documentation) I'd strongly advice declaring public facing set/get methods along with the above code.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...