如果我用引用覆盖原始变量,内部会发生什么? 意思是这么糟糕,它会花费额外的时间或资源吗?
<?php
function db(){
global $db;
if( empty($db)) $db = new PDO('sqlite:/tmp/default.db3');
return &$db;
}
$db = db();
?>
答案 0 :(得分:3)
如果您使用
global $db;
这会将全局变量$db
导入本地范围。
然后存在另一个变量(表示全局变量)。您最后尝试返回对该变量的引用:
return &$db;
但这不是return by reference。相反,你只需返回值。
然后在全局变量表上用$db
覆盖它自己的值。这就是这里发生的一切。
是否需要额外的时间或资源?
您所做的一切都是多余的时间或资源。然而,PHP有一个称为写入时复制(COW)的优化,所以通常你不需要太在意这里。 PHP可以很好地消除负担。
就代码中的对象而言。只需改变方式:
<?php
$db = new PDO('sqlite:/tmp/default.db3');
?>
然后将db对象传递到需要它的位置。保持简单,愚蠢。
答案 1 :(得分:0)
它不应该消耗更多的资源,因为你返回的对象的地址总是比对象小。
如果我没有弄错,当在PHP 5中返回一个对象时,即使你没有在它前面添加(&amp;),它也会被引用返回。 (我认为纠正的物品不是由referance返回的):
http://php.net/manual/en/language.references.return.php
我从其他所有编程语言中都知道,对象是通过引用传递/返回的,而本地数据类型是通过复制返回的。
在您使用全局变量的示例中,您已经在函数外部重新声明了变量。由于您已经覆盖它,因此不需要返回值。
答案 2 :(得分:0)
这不是你通过引用返回的方式。 你必须声明这样的函数:
function &return_by_ref()
{
$something="";
return $something;
}
您不需要通过引用返回对象,该语言指定所有对象都是通过引用自动返回的,并且手册也强烈建议不要对对象使用by引用操作符。
这就是你的意思:
class DB{
private function __construct(){}
public static $db=null;
}
function db($db)
{
if(!isset(DB::$db))
DB::$db=new PDO('sqlite:/tmp/default.db3');
return DB::$db;
}
用法:
function create_user()
{
db()->exec("INSERT INTO `users` SET `name`='John Doe'");
return db()->lastInsertId();
}
function get_users()
{
return db()
->query("SELECT * FROM `users`")
->fetchAll(PDO::FETCH_ASSOC)
;
}
答案 3 :(得分:0)
由于您的原始示例是语法错误,我认为这是您想要编写的内容:
function db(){
static $db = null;
if ($db === null) {
$db = new PDO('sqlite:/tmp/default.db3');
}
return $db;
}
如果您真的那么倾向,可以使用vulcan logic disassembler运行脚本并获取操作码。唯一值得注意的区别是带引用的版本使用RETURN_BY_REF和ASSIGN_REF操作码而不是RETURN和ASSIGN。确定引擎执行时引擎的作用并非易事,但主要是写时复制行为通常会阻止复制。