我需要创建约。 5-7个班级,每个班级都会包含很多成员(让我们说每个班级将包含20个成员)。我可以使用公共访问创建它们,例如:
class A {
public $myPropertyOne = '';
public $myPropertyTwo = '';
...
}
我首选的方法是将这些成员设为私有,并为每个属性创建get / set方法。即。
class A {
private $myPropertyOne = '';
private $myPropertyTwo = '';
public function getMyPropertyOne() {
return $this->myPropertyOne;
}
public function setMyPropertyOne($myPropertyOne) {
$this->myPropertyOne = $myPropertyOne;
}
public function getMyPropertyTwo() {
return $this->myPropertyTwo;
}
public function setMyPropertyTwo($myPropertyTwo) {
$this->myPropertyTwo = $myPropertyTwo;
}
}
但考虑到一个类将有20个属性,我将除此之外还添加40个方法。我在这里关注的是如何减慢脚本速度以及需要更多内存(请记住我将有几个这样的类)。
另一个解决方案可能是使用魔术函数__set,__但我不想这样做,因为开发IDE中的代码完成不会建议对我来说至关重要的属性。
如果这是一个编译语言(比如C ++),我就不会有问题,并且会使用getter,setter的解决方案但是因为PHP是解释语言,所以我对我的脚本感兴趣使用更少的RAM并且速度快尽可能。
在此先感谢,对此问题的任何想法都将不胜感激!
我的意见
谢谢大家的回答,我只想分享我的意见,以防有人寻找这个问题的答案。
我不能完全同意那些说你不应该关心性能的人,因为这是优化者的任务,我认为这是重要的因素(至少对我而言),当我们处理像PHP这样的解释语言时我们将永远不得不考虑内存和速度(这一切都让我想起了我为DOS开发系统应用程序的时候,呵呵:)你总是受限于CPU和CPU总内存不足,所以如果可以的话你会很开心保存一个额外的字节),在PHP开发中你有相同的图片,无论你添加多少服务器,用户的数量总是会更高,所以你总是要决定是否要遵循经典/安全/正确的方法或者避免这种情况,并获得速度或记忆的一些增益。
所以....我认为这里最好的方法是对所有成员使用公共访问,并避免所有属性的getter / setter,并使用带有get / set方法的私有访问,这些属性需要数据验证或初始化之前将设置一个值。
例如:
class B {
public $myPropertyOne = '';
public $myPropertyTwo = '';
private $myPropertyThree = array();
public function getMyPropertyThree() {
return $this->myPropertyThree;
}
public function setMyPropertyThree($val) {
if(!is_array($val)) {
return;
}
$this->myPropertyThree = $val;
}
}
感谢您花时间在我的问题上!
答案 0 :(得分:5)
简单测试显示实例占用相同数量的内存,不受类中方法数量的影响:
没有方法的类:
class Test1 { }
有20种方法的类:
class Test2 {
function test1() { return true; }
function test2() { return true; }
function test3() { return true; }
function test4() { return true; }
function test5() { return true; }
function test6() { return true; }
function test7() { return true; }
function test8() { return true; }
function test9() { return true; }
function test10() { return true; }
function test11() { return true; }
function test12() { return true; }
function test13() { return true; }
function test14() { return true; }
function test15() { return true; }
function test16() { return true; }
function test17() { return true; }
function test18() { return true; }
function test19() { return true; }
function test20() { return true; }
}
测试循环,两个测试都相同:
$test = array();
$base = memory_get_usage();
for ($i = 0; $i < 10000; $i++) {
$test[] = new ClassToBeTested();
}
$used = memory_get_usage() - $base;
print("used: $used\n");
类Test1(无方法)的结果:
used: 3157408
Test2类的结果(20种方法):
used: 3157408
我在两个单独的脚本中运行它,因为在一个脚本中运行两个测试显然暴露了一些PHP内部分配,第二个测试比第一个测试消耗更少的内存,无论哪个是第一个或第二个。< / p>
虽然您确实需要为实际的类定义占用更多内存,但显然这个成本每个类只发生一次,而不是每个实例。您不必担心内存使用情况。
答案 1 :(得分:5)
但考虑一个班级将有20个属性
拥有这么多属性通常是错误信息的指标。检查是否可以将其中的一些分组为自己的类。
除此之外我还会添加40种方法。
完全没有。除非这些类是哑数据结构,否则你不希望它们上有任何Getter和Setter因为它们打破了封装。将方法放在公共API中,用它告诉对象做事。
我在这里关注的是如何减慢脚本速度以及需要更多内存(请记住我将有几个这样的类)。
这不是问题。
另一个解决方案可能是使用魔术函数__set,__但我不想这样做,因为开发IDE中的代码完成不会建议对我来说至关重要的属性。
现代IDE可以在魔术方法上自动完成。
但是,如果您已经关注微观级别的性能,那么您不需要魔术方法,因为这些方法肯定更慢。
除此之外,Magic Methods不能替代getter和setter,而是在调用不可访问的属性或方法时触发的错误处理程序。
此外,魔术方法并不明显,难以阅读API。
答案 2 :(得分:0)
请记住,我的代码认为属性的名称已经用小写声明...
<?php
class Modelo {
var $attr1 = "default";
var $attr2 = 0;
public function __call($name, $arguments)
{
if (method_exists($this, ($method = $name))){
return $this->$method();
}
else{
$attribute = split("get",$name);
if(count($attribute)==2){
$attribute = strtolower($attribute[1]);
if(isset($this->$attribute)){
return ($this->$attribute);
}
}else{
$attribute = split("set",$name);
if(count($attribute)==2){
$attribute = strtolower($attribute[1]);
if(isset($this->$attribute) && count($arguments)==1){
$this->$attribute=$arguments[0];
}else{
die("$name number of arguments error: ".join($arguments,","));
}
}else{
die("$name doesn't exist!");
}
}
}
}
}
echo "<pre>";
$m = new Modelo();
print_r(
array(
"objetct"=>$m
,"getAttr1"=>$m->getAttr1()
,"getAttr2"=>$m->getAttr2()
)
);
echo "setAttr1\n";
$m->setAttr1("by set method");
print_r(
array(
"objetct"=>$m
,"getAttr1"=>$m->getAttr1()
,"getAttr2"=>$m->getAttr2()
)
);
?>
答案 3 :(得分:0)
如前所述,你的班级应该有这么多属性,这很奇怪。但是,它有时(尽管很少)会发生。但通常情况下,这些属性应该有一种链接:所以你可以将它们存储在一个hashmap而不是一个属性中。然后你只需要一个方法作为吸气剂。
现在,它肯定会消耗更多资源,这是真的。至于自动完成,使用常量:你只需输入类似:
$my_class->getFromHashMap($parameter)
在输入参数时,您将使用存储在类中的常量:此处,自动完成应该能够帮助您。
答案 4 :(得分:0)
要使通过魔术方法实现的类的属性由IDE高亮显示,只需使用@property PHPDoc @property
标记,如下所示:
<?php
/**
* @property int id Blog post ID
* @property string title Blog post Title
*/
class Post {
}
有关PHPDoc的更多信息'@property here:http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.property.pkg.html
至于其他受质疑的问题 - Karoly Horvath的评论完全涵盖了那些PHP OOP a lot of setters, getters。
答案 5 :(得分:0)
你可以试试这个:
特质get_set {
public function set($what, $value)
{
$this->{$what} = $value;
}
public function get($what)
{
return $this->{$what};
}
}
它适用于公共变量和受保护变量。您可以添加if(!isset($ this-&gt; {$ what})error()