PHP中的const vs static

时间:2010-03-07 15:44:19

标签: php performance oop

在PHP5中,我可以向类声明一个const值:

class config
{
     const mailserver = 'mx.google.com';
}

但我也可以宣布公开静态:

class config
{
     public static $mailserver = 'mx.google.com';
}

如果是配置文件我将在稍后使用,例如:

imap_connect(config::$mailserver ...
imap_connect(config::mailserver ...

您认为哪个选项更适合使用? (更快,更少的内存负载等。)

感谢。

6 个答案:

答案 0 :(得分:43)

静态变量可以改变,const不能改变。应该主要考虑配置变量是否应该能够在运行时更改,而不是更快。两者之间的速度差异(如果有的话)非常小,不值得考虑。

答案 1 :(得分:9)

使用函数return global

0.0096,0.0053,0.0056,0.0054,0.0072,0.0063,0.006,0.0054,0.0054,0.0055,0.005,0.057,0.0053,0.0049,0.0064,0.054,0.0053,0.0053,0.0061,0.0059,0.0076,config1

使用get instance normal class

0.0101,0.0089,0.0105,0.0088,0.0107,0.0083,0.0094,0.0081,0.0106,0.0093,0.0098,0.0092,0.009,0.0087,0.0087,0.0093,0.0095,0.0101,0.0086,0.0088,0.0082,config2

使用static var

0.0029,0.003,0.003,0.0029,0.0029,0.0029,0.003,0.0029,0.003,0.0031,0.0032,0.0031,0.0029,0.0029,0.0029,0.0029,0.0031,0.0029,0.0029,0.0029,0.0029,config3

使用const var 0.0033,0.0031,0.0031,0.0031,0.0031,0.0031,0.0032,0.0031,0.0031,0.0031,0.0031,0.0034,0.0031,0.0031,0.0033,0.0031,0.0037,0.0031,0.0031,0.0032,0.0031,config4

function getTime() { 
    $timer = explode( ' ', microtime() ); 
    $timer = $timer[1] + $timer[0]; 
    return $timer; 
}

$config["time"] = "time";

class testconfig2
{
    public  $time = "time";
    static $instance;
    static function getInstance()
    {
        if(!isset(self::$instance))
            self::$instance = new testconfig2();
        return self::$instance;
    }
}

class testconfig3
{
    static $time = "time";
}

class testconfig4
{
    const time = "time";
}

function getConfig1()
{
    global $config;
    return $config;
}

$burncount = 2000;
$bcount = 22;

for($lcnt =1;$lcnt < $bcount;$lcnt++){
$start = getTime(); 
for($i=1;$i< $burncount;$i++)
{
    $gs=getConfig1();
    $t = $gs["time"];
} 
$end = getTime(); 
echo  round($end - $start,4).', ';
}
echo  ' config1<br/>';



for($lcnt =1;$lcnt < $bcount;$lcnt++){
$start = getTime(); 
for($i=1;$i< $burncount;$i++)
{
    $gs=testconfig2::getInstance();
    $t = $gs->time;
} 
$end = getTime(); 
echo  round($end - $start,4).', ';
}
echo  ' config2<br/>';



for($lcnt =1;$lcnt < $bcount;$lcnt++){
$start = getTime(); 
for($i=1;$i< $burncount;$i++)
{
    $gs=testconfig3::$time;
    $t = $gs;
} 
$end = getTime(); 
echo  round($end - $start,4).', ';
}
echo  ' config3<br/>';



for($lcnt =1;$lcnt < $bcount;$lcnt++){
$start = getTime(); 
for($i=1;$i< $burncount;$i++)
{
    $gs=testconfig4::time;
    $t = $gs;
} 
$end = getTime(); 
echo  round($end - $start,4).', ';
}
echo  ' config4<br/>';
?>

function getTime() { $timer = explode( ' ', microtime() ); $timer = $timer[1] + $timer[0]; return $timer; } $config["time"] = "time"; class testconfig2 { public $time = "time"; static $instance; static function getInstance() { if(!isset(self::$instance)) self::$instance = new testconfig2(); return self::$instance; } } class testconfig3 { static $time = "time"; } class testconfig4 { const time = "time"; } function getConfig1() { global $config; return $config; } $burncount = 2000; $bcount = 22; for($lcnt =1;$lcnt < $bcount;$lcnt++){ $start = getTime(); for($i=1;$i< $burncount;$i++) { $gs=getConfig1(); $t = $gs["time"]; } $end = getTime(); echo round($end - $start,4).', '; } echo ' config1<br/>'; for($lcnt =1;$lcnt < $bcount;$lcnt++){ $start = getTime(); for($i=1;$i< $burncount;$i++) { $gs=testconfig2::getInstance(); $t = $gs->time; } $end = getTime(); echo round($end - $start,4).', '; } echo ' config2<br/>'; for($lcnt =1;$lcnt < $bcount;$lcnt++){ $start = getTime(); for($i=1;$i< $burncount;$i++) { $gs=testconfig3::$time; $t = $gs; } $end = getTime(); echo round($end - $start,4).', '; } echo ' config3<br/>'; for($lcnt =1;$lcnt < $bcount;$lcnt++){ $start = getTime(); for($i=1;$i< $burncount;$i++) { $gs=testconfig4::time; $t = $gs; } $end = getTime(); echo round($end - $start,4).', '; } echo ' config4<br/>'; ?>

答案 2 :(得分:4)

您可以将常量用于默认函数参数值,其中不允许使用静态变量。

答案 3 :(得分:3)

const和static之间的另一个区别是类常量中不允许使用像数组这样的变量,所以

class mytest
{
    public static $c = array(1=> 'hello', 2=>'world');
}

有效,但

class mytest
{
    const c = array(1=> 'hello', 2=>'world');
}

不会。

答案 4 :(得分:1)

另请注意,由于Yacoby上面所说的,您可以使用静态变量执行某些操作,而不能使用CONST,例如将运行时方法调用的结果分配给变量。

答案 5 :(得分:-2)

'const'和'public static'都是邪恶的!

正如Keith Humm所说 - const不能是运行时方法的结果。而且,虽然我最初认为他说你可以“将运行时方法调用的结果分配给(静态)变量”是正确的,但我的测试显示你必须跳过一些箍来做这件事。

这似乎是一个小问题,但它可能是未来灾难的种子。假设我将来被迫转向初始化方法以获得一些不可预知的原因。如果这意味着我必须在我的控制下对文件进行一些更改,我没有问题。但是,如果我将我已远程发送的库更改为其他开发人员,该怎么办?

我打算写一下,至少,如果他们想升级到我的新版本,我必须告诉其他人(以及'Future Me')对他们的文件进行更改。在'const'的情况下,他们必须在他们使用它的地方添加'$'。在其他情况下,我今天的测试表明他们可能需要做更少但有些更改。

假设面向对象的代码,我遵循我已经看到的许多语言的一般建议,并且需要额外强调PHP - 任何类型的避免可见属性,无论是const,静态还是其他任何东西。使用'getter'方法!

这可能看起来像一个荒谬的性能打击和丑陋的代码风格,但除非你能预测未来,否则它是唯一的出路。

请参阅:Tjeerd Visser对How to initialize static variables的回答并给出了一个提示。忽略他的批评者 - 如果你关注的是性能,可能存在的错误和其他灾难,那么请切换到另一种语言。