2010-02-18 125 views
6

繼訪問一個全局變量的代碼片段:問題與PHP

function something() { 
$include_file = 'test.php'; 
if (file_exists($include_file)) { 
    require_once ($include_file); 
//  global $flag; 
//  echo 'in main global scope flag='.$flag; 
    test(); 
    } 
} 

something(); 

exit; 

//in test.php 

$flag = 4; 
function test() { 
    global $flag; 

    echo '<br/>in test flag="'.$flag.'"'; 
    if ($flag) { 
     echo 'flag works'; 
    //do something 
    } 
} 

上面的代碼片段,回聲「全球範圍內」 $標誌值正常,但犯規認識到了價值4 $標誌,假設空值爲$標誌。 請指出訪問$ flag全局變量時出了什麼問題。

由於提前, Anitha

+0

如果我添加'global $ flag'在函數的東西,然後它的作品,這意味着不給未定義的變量錯誤。我不明白這一點。 – CodeTweetie 2010-02-18 18:19:45

+1

如果您嘗試使用全局變量,則必須在函數內部聲明變量的範圍。 它最好不要使用全局變量。 – bonez 2010-02-18 18:22:31

回答

2

$flag = 4;不在全球範圍內。

If the include occurs inside a function within the calling file, then all of the code contained in the called file will behave as though it had been defined inside that function.

- PHP手冊頁include,這也適用於include_once,要求,和require_once

我打算做一個猜測,你得到的錯誤是在if ($flag)線,因爲在那個時候,$ flag是未初始化的,因爲全局的$ flag變量從來沒有被賦值。

順便說一句,echo 'global scope flag='.$flag;也不會被顯示全局標誌,因爲你在那個函數需要一個global $flag;顯示全局副本,其中也有使$flag = 4;影響包含文件中的全球複製的副作用。

2

可能給你帶來麻煩的線是這個:echo 'global scope flag'=$flag;

將其更改爲:echo 'global scope flag = '.$flag;

編輯: 既然你已經編輯你的代碼通過將代碼包裝到something()函數中,問題變得更加清晰。我認爲這裏發生的是當你用$flag = 4;初始化$標誌時,它的範圍在something()方法中。

嘗試放置$flag = 4;上方/之前的行function something() {。然後,一切都將與世界正確。

+0

嗨,謝謝你的回覆。 這是一個錯字,糾正它。 但原來的問題仍然存在。 – CodeTweetie 2010-02-18 18:12:17

+0

好的,修正了該行後,我發現您發佈的代碼沒有其他問題。你的問題在'test()'方法內?如果你直接訪問test.php會發生什麼?同樣的錯誤? – Bart 2010-02-18 18:19:51

0

不宜echo 'global scope flag'=$flag;echo 'global scope flag =' . $flag;

我收到了不同的錯誤。這幫助我快速解決了這個問題。

Parse error: parse error, unexpected '=', expecting ',' or ';' in D:\Websites (Apache)\Test Site1\test.php on line 6

0

就做這樣的事情:

$myFlag = getFlag(); 
echo $myFlag; // output: whatever 


// test.php 

$flag = 'whatever'; 

function getFlag(){ 
    global $flag; 
    return $flag; 
} 

在一個腳本中,我永遠不會設置一個變量,然後從另一個文件調用它。這會導致道路上的混亂。即使我的解決方案不是最好的。我會把這當作一個完美的課程來完成。

+0

不,我在require後回顯$ flag,這意味着已經定義了$ flag。不是嗎? – CodeTweetie 2010-02-18 18:31:51

7

由於PHP當前正在解釋您的文件,因此您正在運行一個問題。你有嵌套函數。

這裏是你的代碼,目前如何執行:

function something() { 
    $include_file = 'test.php'; 
    if (file_exists($include_file)) { 
     //require_once ($include_file); 

     $flag = 4; 
     function test() { 
      global $flag; 

      echo '<br/>in test flag="'.$flag.'"'; 
      if ($flag) { 
       echo 'flag works'; 
      //do something 
      } 
     } 

     //end require_once ($include_file); 

     test(); 
    } 
} 

something(); 

exit; 

正如你所看到的,當你指定的4$flag$flag = 4)的值,你的功能something()的範圍之內,而不是內部的全球範圍。

test()中,由於您聲明$flag在該函數內是全局的,因此$flag是一個完全不同的變量,對於整個腳本而言是全局變量。

爲了避免這個問題,使用超全球$GLOBALS。這比使用global反正快,這樣你就不會在範圍的問題混到如上的那些:

function something() { 
    $include_file = 'test.php'; 
    if (file_exists($include_file)) { 
     //require_once ($include_file); 

     $GLOBALS['flag'] = 4; 
     function test() { 
      global $flag; 

      echo '<br/>in test flag="'.$GLOBALS['flag'].'"'; 
      if ($GLOBALS['flag']) { 
       echo 'flag works'; 
      //do something 
      } 
     } 

     //end require_once ($include_file); 

     test(); 
    } 
} 

something(); 

echo $flag; //echos 4 

exit; 
+0

+1,只是爲了完整性:'global $ flag; require_once($ include_file);'也可以做到這一點。但是,無論如何,這整個全球/功能/需要的東西對我來說似乎都很討厭。 – VolkerK 2010-02-18 19:05:55

+0

實際上,儘管這基本上是正確的,但test()函數會移到something()函數之外:「在包含文件中定義的所有函數和類都具有全局範圍。」 http://php.net/include – Powerlord 2010-02-18 19:11:25

+0

但是,如果將函數定義直接寫入「外部」函數,情況也會如此。所以這個例子在這一點上也是正確的。 – VolkerK 2010-02-18 19:17:18

0

因爲你原來的問題已經回答讓我提出另一種方法避免全局變量都在一起。
您看起來有一個函數+一個默認值,您將其設置爲全局變量。您也可以定義default values for function parameters

<?php // test.php 
function test($flags=4) { 
    echo '<br/>in test flag="'.$flags.'"'; 
    if ($flags!=0) { 
    echo ' flag works'; 
    } 
} 

沒有全局變量,但你仍然可以調用測試()不帶參數和功能將使用默認值 - 您可以通過將參數覆蓋。

function something() { 
    $include_file = 'test.php'; 
    if (file_exists($include_file)) { 
    require_once ($include_file); 
    echo "\nwithout parameter: "; test(); 
    echo "\nwith a parameter: "; test(16); 
    } 
} 
something(); 
exit; 

打印

without parameter: <br/>in test flag="4" flag works 
with a parameter: <br/>in test flag="16" flag works 

這不正是相同的行爲,但它可能你首先想要的東西....

編輯:還有一點可能是

if (file_exists($include_file)) { 
    require_once ($include_file); 

您正在使用的構造。我並沒有強烈的意見(或任何有力的證據;-)),但你可能要考慮使用

$something = include $include_file; 
if (false!==$something) { /* error handling here... */ } 

改爲。 include如果php不能包含文件,則返回「false」。所有這些工作都需要包含的文件不顯式返回FALSE。這可能緩存友好(例如,當使用像APC之類的東西時)。但是,我再也無法證明這一點,只是一種預感。至少它讓你的代碼有機會處理「優雅」的錯誤。