这(我的代码的简化版)不起作用:
<?php
$sxml = new SimpleXMLElement('<somexml/>');
function foo(){
$child = $sxml->addChild('child');
}
foo();
?>
为什么呢?我想访问$sxml
,因为如果foo()
失败,我想在其上记录错误。 foo()
以递归方式调用自己来创建目录列表,因此我担心将整个$sxml
传递给自身(如在foo($sxml)
中)可能会影响性能。
有没有办法在$sxml
内访问$foo
而不将其作为参数传递? (PHP 5.2.x +)
编辑:如果代码看起来像这样,怎么办?
<?php
bar(){
$sxml = new SimpleXMLElement('<somexml/>');
function foo(){
$child = $sxml->addChild('child');
}
foo();
}
bar();
?>
答案 0 :(得分:108)
您必须将其传递给函数:
<?php
$sxml = new SimpleXMLElement('<somexml/>');
function foo($sxml){
$child = $sxml->addChild('child');
}
foo($sxml);
?>
或声明global:
<?php
$sxml = new SimpleXMLElement('<somexml/>');
function foo(){
global $sxml;
$child = $sxml->addChild('child');
}
foo();
?>
如果变量不是全局变量而是在外部函数中定义,则第一个选项(作为参数传递)的工作方式相同:
<?php
function bar() {
$sxml = new SimpleXMLElement('<somexml/>');
function foo($sxml) {
$child = $sxml->addChild('child');
}
foo($sxml);
}
bar();
?>
或者,通过在use
子句中声明变量来创建closure。
<?php
function bar() {
$sxml = new SimpleXMLElement('<somexml/>');
function foo() use(&$xml) {
$child = $sxml->addChild('child');
}
foo();
}
bar();
?>
答案 1 :(得分:20)
您需要明确邀请全局变量进入函数范围:
function foo(){
global $sxml;
$child = $sxml->addChild('child');
}
答案 2 :(得分:4)
使用global关键字在函数内声明$ sxml。
<?php
$sxml = new SimpleXMLElement('<somexml/>');
function foo(){
global $sxml;
$child = $sxml->addChild('child');
}
foo();
?>
答案 3 :(得分:3)
另一种解决方案是在声明该变量时使用 $ GLOBALS :
$my_var = 'blabla'; // not global
$GLOBALS['my_var'] = 'blabla'; // global (correct)
答案 4 :(得分:3)
虽然最佳答案提供了一个很好的解决方案,但我想说大多数现代PHP应用程序中的适当解决方案是创建一个带有静态变量的类,如下所示:
<?php
class xmlHelper {
private static $sxml;
public function getXML() {
return self::$sxml;
}
public function setXML($xml) {
self::$sxml = $xml;
}
}
xmlHelper::setXML(new SimpleXMLElement('<somexml/>'));
function foo(){
$child = xmlHelper::getXML()->addChild('child');
}
foo();
此方法允许您按照自己的需要从$sxml
内访问foo()
,但与global
方法相比,它有一些优势。
setXML()
中放置一个断点,以找出应用程序的哪个部分操纵了此值,这在操作全局变量时无法执行。sxml
来污染全局命名空间。