问题
I'm using Enterprise Architect to make a UML class diagram and generate PHP5 code with it. Using this, one can make getters and setters for an attribute, which looks like this in the code (only relevant lines shown):
private $id;
public function getId()
{
return $this->id;
}
/**
*
* @param newVal
*/
public function setId($newVal)
{
$this->id = $newVal;
}
I'd like to use the magic methods __get($property)
and __set($property, $value)
instead of seperate methods for each property. Is it possible, and if so, how?
It could look like this, for the getter:
public function __get($property)
{
switch ($property) {
case 'id': return $this->id; break;
default: return null;
}
}
回答1:
I agree with other people on this page that it's bad practise and you should stick to plain old getters and setters over the magic methods. Once you need validation or other computations in the accessors/mutators your switch/case will explode. It's a mess to maintain and not exactly inheritance friendly. A child class with the magic methods is technically overwriting the parent's magic method.
However, you can do that by modifing the Code Templates with the Code Template Editor of EA.
Quoting from Enterprise Architect User Guide on Code Templates:
Code templates enable you to customize code generation of existing languages. For example:
- Modify the file headers created when generating new files
- Change the style of the generated code (such as indenting or brace position) to match the required coding standards
- Handle particular stereotypes to generate things like specialized method bodies and extra methods.
and further:
Enterprise Architect's base code templates specify the transformation from UML elements to the various parts of a given programming language. The templates are written as plain text with a syntax that shares some aspects of both mark-up languages and scripting languages.
Here is a sample picture of the Code Editor with some template loaded into it:
I am not familiar with the Editor nor the template language they use, so I cannot provide you with a working example. But I guess you can figure it out from there if you really want to modify the template.
回答2:
Not really an answer but you should consider if you want this done that way. This will not bring any benefits but will cause problems with IDE code completion features and will in fact make maintaining the code harder. In my opinion magic __get/__set should be used only for dynamic properties, otherwise use separate set/get methods or use public properties. This answer pretty much sums it up.
If you still want to go this road, I would recommend simpler approach.
回答3:
You can implement a universal magic getter/setter like this :
public function __get($name)
{
if (property_exists($this, $name))
return $this->{$name};
return null;
}
public function __set($name, $value)
{
if (property_exists($this, $name) && true/*Sanity checks here on $value instead of true if you want*/)
$this->{$name} = $value;
}
But keep this in mind:
This is a really bad design pattern for your code (even if it's a DRY-compliant practice)
Also, this code is strictly equivalent to making all your properties public, and you won't have the overhead due to magic methods. The nice thing is that if you want to perform the same sanity checks on every setter, you can do it there.
回答4:
I'd like to use the magic methods __get($property) and __set($property, $value) instead of seperate methods for each property. Is it possible, and if so, how?
You should not define each property then. One simple array container will be great enough for them. So, this is exactly what you're looking for:
class Foo
{
private $container = array();
public function __set($property, $value)
{
$this->container[$property] = $value;
}
public function __get($property)
{
if (array_key_exists($property, $this->container)){
return $this->container[$property];
} else {
trigger_error(sprintf('Undefined property "%s"', $property));
}
}
}
$foo = new Foo();
$foo->bar = "123";
print $foo->bar; // prints 123
$foo->id = "test string";
print $foo->id; // test string
print $foo->nonExistingProp; //issues E_NOTICE
If you insist on accessors/modifiers, then you only need to overload them. using __call()
class Foo
{
private $container = array();
public function __call($method, array $args)
{
$property = substr($method, 3);
if (substr($method, 0, 3) == 'get'){
// getter is being used
if (isset($this->container[$property])){
return $this->container[$property];
}
}
if (substr($method, 0, 3) == 'set'){
//setter is being used
$this->container[$property] = $args[0];
}
}
}
$foo = new Foo();
$foo->setId('__BAR__');
$foo->setStuff('__YEAH__');
print $foo->getId(); // prints __BAR__
print $foo->getStuff(); //prints __YEAH__
回答5:
I do not know if You are using an IDE for developing or pure Notepad. Because You are asking that type of question I'd guess it is Notepad. Then I'd recommend You trying one of many free IDEs (I use NetBeans for a years, others may be satisfied with Eclipse, too).
If You are using EA and doing Class Models I'd guess You are taking OOP seriously. If so, You should strictly define the properties visibility and like e.g. Zend Framework 2 forget about the public property
visibility (that concludes also a static
or public static
property). Then You end up with properties being private
or protected
and the need of getters/setters is on Earth.
Now if You use magic __get()
/__set()
methods how would You debug Your code? How can a man tell what happens in a class \One\Two\Three\Four
with the property \First\Second\Third::$bang
? How was it set? Why am I getting this value instead of another?
And on the other hand - when using modern IDE that follows property visibility, think of this class:
Class A
{
private $foo;
private $bar;
protected $foobar;
public function __get()
{
...
}
public function __set()
{
...
}
}
without setters or getters. If You are writing Your code, Your IDE won't hint You the properties' names (from outside the class) and You have to type them all long. Using getters and setters (that are public methods giving You the access to private or protected properties) You can use code-hinting and spead up Your developing process while using modern OOP principles.
来源:https://stackoverflow.com/questions/15448423/magic-getters-and-setters-in-enterprise-architect